def render_for_cond(cond): """Decorator helper to register a view for a given condition In: - ``cond`` -- the condition Return: - closure """ return when(render, cond)
def init_for(cls, cond=None): """Decorator helper to register an URL for a class of objects In: - ``cls`` -- the class - ``cond`` -- a generic condition Return: - a closure """ if cond is not None: cond = "isinstance(self, %s) and (%s)" % (cls.__name__, cond) else: # No condition given, dispatch on the class cond = (cls,) return when(init, cond)
def render_for(cls, model=None): """Decorator helper to register a view for a class of objects In: - ``cls`` -- the class - ``model`` -- the name of the view Return: - a closure """ if model is not None: cond = 'isinstance(self, %s) and (model=="%s")' % (cls.__name__, model) else: # No name give, dispatch only on the arguments type cond = (cls, object, object, types.NoneType) return when(render, cond)
def init_for(cls, cond=None): """Decorator helper to register an URL for a class of objects In: - ``cls`` -- the class - ``cond`` -- a generic condition Return: - a closure """ if cond is not None: cond = "isinstance(self, %s) and (%s)" % (cls.__name__, cond) else: # No condition given, dispatch on the class cond = (cls, ) return when(init, cond)
def route_for(cls, cond=None, methods=('GET', 'HEAD')): """Decorator helper to register an URL for a class of objects In: - ``cls`` -- the class - ``cond`` -- a generic condition Return: - a closure """ conds = [] if not cond and not methods: # No condition given, dispatch on the class conds.append((cls,)) if cond: conds.append('isinstance(o, %s) and (%s)' % (cls.__name__, cond)) if methods: conds.append('(http_method in %r)' % (methods,)) return when(route, ' and '.join(conds))
def write_extension_data_for(cls): cond = 'isinstance(card_extension, %s)' % cls.__name__ return when(write_extension_data, cond)
def get_extension_title_for(cls): cond = 'card_extension_class.__name__ == "%s"' % cls.__name__ return when(get_extension_title, cond)
class DoulaBot(QBot): """ Bot for pushing and releasing """ default_gitssh = "*****@*****.**" default_ghuser = "******" svnprefix = "svn://svn/s" default_svntree = "py" nickname = 'doula' username = nickname mcmd = "command.startswith('%s:')" cmd = "command.startswith('%s')" cmd_is = "command == '%s'" notification_list = rq.notify_channel index_url = "http://yorick:9003/index" channel = '#release' v_regex = re.compile('^[a-zA-Z]+-([a-zA-Z0-9\.]+).tar.gz') v_splitter = re.compile('(rc|a|b|dev|\.)') re_d = re.compile('\d') cmd_end = ":" @property def exec_str(self): return self.nickname + ':' @abstract def command(self, source, command, args): """ dispatch for commands """ pass noop = when(command, 'True')(BaseBot.noop) def action_msg(self, cxn, msg): cxn.privmsg(self.channel, '%sACTION %s ' % (chr(1), msg)) @when(command, cmd_is % 'dance') def shake_booty(self, source, command, args): user, address = source.split('!') if user.startswith('doug'): self.broadcast("/me refuses to dance for %s" % user) else: self.broadcast("/me shakes it's metal booty for %s" % user) @when(command, cmd_is % 'svn') def svnls(self, source, command, args): """ dbot: svnls: tree/path """ user, handle = source.split('!') if args == '': return self.broadcast( "%s: you have to give me a path to work with..." % user) return self.enqueue(qtasks.svn_ls, args) def _prep_release(self, source, args): """ Does some basic error checking and data preparation to be used by commands doing a release. """ user, handle = source.split('!') if args == '': return self.broadcast( "%s: you must give a python package to release" % user) pkgv = args.strip() self.broadcast("/me queues %s for release for %s." % (pkgv, user)) parts = pkgv.split('@') branch = None if len(parts) == 2: pkgv, branch = parts tokens = pkgv.split('/') return pkgv, branch, tokens, user @when(command, cmd_is % 'relsvn') def svn_release(self, source, command, args): """ dbot: relsvn: [tree_other_than_py]pkg-0.9.8rc2[@branch] """ pkgv, branch, tokens, user = self._prep_release(source, args) svntree = self.default_svntree if len(tokens) == 2: svntree, pkgv = tokens svnprefix = utils.urljoin(self.svnprefix, svntree) return self.enqueue(pypkg.pyrelease_svn_task, pkgv, branch, svnprefix, user) @when(command, cmd_is % 'relgit') def git_release(self, source, command, args): """ dbot: relgit: [user_or_group/]pkg-0.1.1[@branch] (from git) """ pkgv, branch, tokens, user = self._prep_release(source, args) ghuser = self.default_ghuser if len(tokens) == 2: ghuser, pkgv = tokens return self.enqueue(pypkg.pyrelease_git_task, pkgv, branch, ghuser, user) javasrc = set(('billingdal', 'userdal')) @when(command, cmd_is % 'reljava') def release_java(self, source, command, args): """ doula: reljava: {billingdal|userdal}-1.0rc2@branchname """ user, handle = source.split('!') if args == '': return self.broadcast( "%s: you must give a java sourcetree (Billing or UserAccount) to release" % user) pkgv = args.strip() self.broadcast("/me queues %s for release for %s." % (pkgv, user)) parts = pkgv.split('@') branch = None if len(parts) == 2: pkgv, branch = parts pv = pkgv.split('-') assert len(pv) == 2, "You must include a src tree and a version" assert pv[0] in self.javasrc, "%s not in available srctrees: %s" % ( pv[0], self.javasrc) return self.enqueue(java.DALRelease, pkgv, branch) @when(command, cmd_is % 'help') def help(self, source, command, args): for name in sorted([ 'svnls', 'current_version', 'git_release', 'svn_release', 'versions', 'push', 'cycle', 'release_java' ]): method = getattr(self, name) self.broadcast(method.__doc__.strip()) @when(command, cmd_is % 'cycle') def cycle(self, source, command, args, task=qtasks.cycle2): """ doula:cycle: bill*@mt1 | billweb:8100@mt2 """ user, o = source.split('!') args = [x.strip() for x in args.split('@')] if len(args) != 2: self.broadcast("%s: wrong format for cycle" % user) self.broadcast('help for cycle: cycle: someapp@mt1') app, mt = args self.broadcast('/me queues cycle for %s on %s' % (app, mt)) self.enqueue(task, app, mt, user) @when(command, ' or '.join([cmd_is % 'push', cmd_is % 'push2'])) def push(self, source, command, args, task=pushmod.push2): """ doula:push: howler-0.9.8rc2 -> billweb@mt2,billweb@mt2 """ user, o = source.split('!') pkgv, mts = [x.strip() for x in args.split('->')] mts = [x.strip() for x in mts.split(',')] for mt in mts: self.broadcast('/me queues push to %s of %s for %s' % (mt, pkgv, user)) self.enqueue(task, pkgv, mt, user) def _fetch_versions(self, pkg): root = html.parse("%s/%s" % (self.index_url, pkg.strip())).getroot() return (x.text for x in root.cssselect('a')) @when(command, cmd_is % 'v') def versions(self, source, command, args): """ doula:v:smlib.billing (lists all available releases) """ pkg = args versions = self.sorted_versions(self._fetch_versions(pkg)) for version in versions: sleep(0.5) self.broadcast(version) @staticmethod def get_distro(url): return next(distros_for_url(url)) def sorted_versions(self, raw_vs, reverse=False): distros = (self.get_distro(url) for url in raw_vs) distros = sorted(distros, reverse=reverse) for dist in distros: yield "-".join(dist.egg_name().rsplit('-')[:-1]) @when(command, cmd_is % 'cv') def current_version(self, source, command, args): """ doula:cv:smlib.billing (shows current version by best guess) """ pkg = args try: vs = self._fetch_versions(pkg) except IOError: return self.broadcast("/me could not find %s" % pkg) if vs: versions = self.sorted_versions(vs, reverse=True) self.broadcast(next(versions))