diff -r 000000000000 -r b97547f5f1fa server/utils.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server/utils.py Wed Nov 05 15:52:50 2008 +0100 @@ -0,0 +1,138 @@ +"""Some utilities for the CubicWeb server. + +:organization: Logilab +:copyright: 2001-2008 LOGILAB S.A. (Paris, FRANCE), all rights reserved. +:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr +""" +__docformat__ = "restructuredtext en" + +import sys +import string +from threading import Timer, Thread +from getpass import getpass +from random import choice + +try: + from crypt import crypt +except ImportError: + # crypt is not available (eg windows) + from cubicweb.md5crypt import crypt + + +def getsalt(chars=string.letters + string.digits): + """generate a random 2-character 'salt'""" + return choice(chars) + choice(chars) + + +def crypt_password(passwd, salt=None): + """return the encrypted password using the given salt or a generated one + """ + if passwd is None: + return None + if salt is None: + salt = getsalt() + return crypt(passwd, salt) + + +def cartesian_product(seqin): + """returns a generator which returns the cartesian product of `seqin` + + for more details, see : + http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/302478 + """ + def rloop(seqin, comb): + """recursive looping function""" + if seqin: # any more sequences to process? + for item in seqin[0]: + newcomb = comb + [item] # add next item to current combination + # call rloop w/ remaining seqs, newcomb + for item in rloop(seqin[1:], newcomb): + yield item # seqs and newcomb + else: # processing last sequence + yield comb # comb finished, add to list + return rloop(seqin, []) + + +def cleanup_solutions(rqlst, solutions): + for sol in solutions: + for vname in sol.keys(): + if not (vname in rqlst.defined_vars or vname in rqlst.aliases): + del sol[vname] + + +DEFAULT_MSG = 'we need a manager connection on the repository \ +(the server doesn\'t have to run, even should better not)' + +def manager_userpasswd(user=None, passwd=None, msg=DEFAULT_MSG, confirm=False): + if not user: + print msg + while not user: + user = raw_input('login: ') + passwd = getpass('password: ') + if confirm: + while True: + passwd2 = getpass('confirm password: ') + if passwd == passwd2: + break + print 'password doesn\'t match' + passwd = getpass('password: ') + user = unicode(user, sys.stdin.encoding) + elif not passwd: + assert not confirm + passwd = getpass('password for %s: ' % user) + # XXX decode password using stdin encoding then encode it using appl'encoding + return user, passwd + + +class LoopTask(object): + """threaded task restarting itself once executed""" + def __init__(self, interval, func): + self.interval = interval + def auto_restart_func(self=self, func=func): + try: + func() + finally: + self.start() + self.func = auto_restart_func + self.name = func.__name__ + + def start(self): + self._t = Timer(self.interval, self.func) + self._t.start() + + def cancel(self): + self._t.cancel() + + def join(self): + self._t.join() + + +class RepoThread(Thread): + """subclass of thread so it auto remove itself from a given list once + executed + """ + def __init__(self, target, running_threads): + def auto_remove_func(self=self, func=target): + try: + func() + finally: + self.running_threads.remove(self) + Thread.__init__(self, target=target) + self.running_threads = running_threads + self._name = target.__name__ + + def start(self): + self.running_threads.append(self) + Thread.start(self) + + @property + def name(self): + return '%s(%s)' % (self._name, Thread.getName(self)) + + +from logilab.common.deprecation import class_moved +from cubicweb.server import pool +Operation = class_moved(pool.Operation) +PreCommitOperation = class_moved(pool.PreCommitOperation) +LateOperation = class_moved(pool.LateOperation) +SingleLastOperation = class_moved(pool.SingleLastOperation)