#!/usr/bin/env python
#
# lock-revprop-change.py
#     Check/Patch revprop for locking purposes
#
# Author: Stein Roger Skaflotten
#
# $HeadURL$
# $LastChangedDate$
# $LastChangedBy$
# $LastChangedRevision$
#
# USAGE: lock-revprop-change.py ["pre" | "post"] REPOS-DIR PROPNAME USER
#
#

import os
import sys
import string
import time
import re
import svn.fs
import svn.repos
import svn.core
import base64

def main(pool, action, repos_dir, locktoken, username):
  repos = Repository(repos_dir, pool)

  rp = RevProp(pool, repos)
  if action == "pre":
    rp.checkLocks(locktoken, username)
  elif action == "post":
    rp.patchRevProp(locktoken, username)
  else:
    sys.stderr.write("Invalid action passed to locks-pre-revprop-change.py")
    sys.exit(1)

class RevProp:

  def __init__(self, pool, repos):
    self.pool = pool
    self.repos = repos

  # called by post-revprop-change
  def patchRevProp(self, locktoken, username):
    # R-prefix means remove lock => remove revprop
    if locktoken[0] == 'R':
      svn.fs.change_rev_prop(self.repos.fs_ptr, 0, locktoken[1:], None, 
self.repos.pool)
    else:
      # drop the force flag and set propval to username
      svn.fs.change_rev_prop(self.repos.fs_ptr, 0, locktoken[1:], username, 
self.repos.pool)

  # called by pre-revprop-change
  def checkLocks(self, locktoken, username):

    # we're interested in lock token revprops only
    if not locktoken[1:].startswith("lock-"):
      sys.exit(0)

    # get current owner, if any
    currentLockOwner = svn.fs.revision_prop(self.repos.fs_ptr, 0, 
locktoken[1:], self.repos.pool)

    # check it out...
    if type(currentLockOwner) == type(None):
      sys.exit(0) # not locked, so we're fine
    elif currentLockOwner == username:
      sys.exit(0) # locked by locker, so we're fine
    elif locktoken[0] == 'F':
      sys.exit(0) # hostile takeover
    else:
      sys.stderr.write("\nThe resource is locked by "+currentLockOwner+"\n")
      sys.exit(1)

# keeps some repos state
class Repository:

  def __init__(self, repos_dir, pool):
    self.repos_dir = repos_dir
    self.pool = pool

    db_path = svn.repos.svn_repos_find_root_path(repos_dir, pool)
    if not db_path:
      db_path = repos_dir

    self.fs_ptr = svn.repos.svn_repos_fs(svn.repos.svn_repos_open(db_path, 
pool))

# enable True/False in older vsns of Python
try:
  _unused = True
except NameError:
  True = 1
  False = 0

if __name__ == '__main__':
  def usage():
    sys.stderr.write('USAGE: %s ["pre" | "post"] REPOS-DIR PROPNAME 
USER\n\n' % (sys.argv[0]))
    sys.exit(1)

  if len(sys.argv) != 5:
    usage()

  action   = sys.argv[1]
  repos_dir= sys.argv[2]
  locktoken= sys.argv[3]
  username = sys.argv[4]

  # run main as svn app
  svn.core.run_app(main, action, repos_dir, locktoken, username)


