def command_FORCE(self, args, tquery=None, partial=None, **kwargs): """force a build""" try: forceschedulers = yield self.master.data.get(('forceschedulers',)) except AttributeError: forceschedulers = None else: forceschedulers = dict((s['name'], s) for s in forceschedulers) if not forceschedulers: raise UsageError("no force schedulers configured for use by /force") argv = self.splitArgs(args) try: sched = argv[0] except IndexError: if len(forceschedulers) == 1: sched = next(iter(forceschedulers)) else: keyboard = [ [self.query_button(s['label'], '/force {}'.format(s['name']))] for s in forceschedulers.values() ] self.send("Which force scheduler do you want to activate?", reply_markup={'inline_keyboard': keyboard}) return else: if sched in forceschedulers: del argv[0] elif len(forceschedulers) == 1: sched = next(iter(forceschedulers)) else: raise UsageError("Try '/force' and follow the instructions" " (no force scheduler {})".format(sched)) scheduler = forceschedulers[sched] try: task = argv.pop(0) except IndexError: task = 'config' if tquery and task != 'config': self.bot.edit_keyboard(self.chat_id, tquery['message']['message_id']) if not argv: keyboard = [ [self.query_button(b, '/force {} {} {}'.format(sched, task, b))] for b in scheduler['builder_names'] ] self.send("Which builder do you want to start?", reply_markup={'inline_keyboard': keyboard}) return if task == 'ask': try: what = argv.pop(0) except IndexError: raise UsageError("Try '/force' and follow the instructions") else: what = None # silence PyCharm warnings bldr = argv.pop(0) if bldr not in scheduler['builder_names']: raise UsageError(("Try '/force' and follow the instructions " "(`{}` not configured for _{}_ scheduler)" ).format(bldr, scheduler['label'])) try: params = dict(arg.split('=', 1) for arg in argv) except ValueError as err: raise UsageError("Try '/force' and follow the instructions ({})".format(err)) all_fields = list(collect_fields(scheduler['all_fields'])) required_params = [f['fullName'] for f in all_fields if f['required'] and f['fullName'] not in ('username', 'owner')] missing_params = [p for p in required_params if p not in params] if task == 'build': # TODO This should probably be moved to the upper class, # however, it will change the force command totally try: if missing_params: # raise UsageError task = 'config' else: params.update(dict( (f['fullName'], f['default']) for f in all_fields if f['type'] == 'fixed' and f['fullName'] not in ('username', 'owner') )) builder = yield self.bot.getBuilder(buildername=bldr) for scheduler in self.master.allSchedulers(): if scheduler.name == sched and isinstance(scheduler, ForceScheduler): break else: raise ValueError("There is no force scheduler '{}'".format(sched)) try: yield scheduler.force(builderid=builder['builderid'], owner=self.describeUser(), **params) except CollectedValidationError as err: raise ValueError(err.errors) else: self.send("Force build successfully requested.") return except (IndexError, ValueError) as err: raise UsageError("Try '/force' and follow the instructions ({})".format(err)) if task == 'config': msg = "{}, you are about to start a new build on `{}`!"\ .format(self.user_full_name, bldr) keyboard = [] args = ' '.join(shlex.quote("{}={}".format(*p)) for p in params.items()) fields = [f for f in all_fields if f['type'] != 'fixed' and f['fullName'] not in ('username', 'owner')] if fields: msg += "\n\nThe current build parameters are:" for field in fields: if field['type'] == 'nested': msg += "\n{}".format(field['label']) else: field_name = field['fullName'] value = params.get(field_name, field['default']).strip() msg += "\n {} `{}`".format(field['label'], value) if value: key = "Change " else: key = "Set " key += field_name.replace('_', ' ').title() if field_name in missing_params: key = "⚠️ " + key msg += " ⚠️" keyboard.append( [self.query_button(key, '/force {} ask {} {} {}' .format(sched, field_name, bldr, args))] ) msg += "\n\nWhat do you want to do?" if missing_params: msg += " You must set values for all parameters marked with ⚠️" if not missing_params: keyboard.append( [self.query_button("🚀 Start Build", '/force {} build {} {}' .format(sched, bldr, args))], ) self.send(msg, reply_markup={'inline_keyboard': keyboard}) elif task == 'ask': prompt = "enter the new value for the " + what.replace('_', ' ').lower() args = ' '.join(shlex.quote("{}={}".format(*p)) for p in params.items() if p[0] != what) self.template = '/force {} config {} {} {}={{}}'.format(sched, bldr, args, what) self.ask_for_reply(prompt, '') else: raise UsageError("Try '/force' and follow the instructions")
def command_LIST(self, args, **kwargs): args = self.splitArgs(args) if not args: keyboard = [ [self.query_button("👷️ Builders", '/list builders'), self.query_button("👷️ (including old ones)", '/list all builders')], [self.query_button("⚙ Workers", '/list workers'), self.query_button("⚙ (including old ones)", '/list all workers')], [self.query_button("📄 Changes (last 10)", '/list changes')], ] self.send("What do you want to list?", reply_markup={'inline_keyboard': keyboard}) return all = False num = 10 try: num = int(args[0]) del args[0] except ValueError: if args[0] == 'all': all = True del args[0] except IndexError: pass if not args: raise UsageError("Try '" + self.bot.commandPrefix + "list [all|N] builders|workers|changes'.") if args[0] == 'builders': bdicts = yield self.bot.getAllBuilders() online_builderids = yield self.bot.getOnlineBuilders() response = ["I found the following **builders**:"] for bdict in bdicts: if bdict['builderid'] in online_builderids: response.append("`{}`".format(bdict['name'])) elif all: response.append("`{}` ❌".format(bdict['name'])) self.send('\n'.join(response)) elif args[0] == 'workers': workers = yield self.master.data.get(('workers',)) response = ["I found the following **workers**:"] for worker in workers: if worker['configured_on']: response.append("`{}`".format(worker['name'])) if not worker['connected_to']: response[-1] += " ⚠️" elif all: response.append("`{}` ❌".format(worker['name'])) self.send('\n'.join(response)) elif args[0] == 'changes': wait_message = yield self.send("⏳ Getting your changes...") if all: changes = yield self.master.data.get(('changes',)) self.bot.delete_message(self.channel.id, wait_message['message_id']) num = len(changes) if num > 50: keyboard = [ [self.query_button("‼ Yes, flood me with all of them!", '/list {} changes'.format(num))], [self.query_button("✅ No, just show last 50", '/list 50 changes')] ] self.send("I found {} changes. Do you really want me " "to list them all?".format(num), reply_markup={'inline_keyboard': keyboard}) return else: changes = yield self.master.data.get(('changes',), order=['-changeid'], limit=num) self.bot.delete_message(self.channel.id, wait_message['message_id']) response = ["I found the following recent **changes**:\n"] for change in reversed(changes): change['comment'] = change['comments'].split('\n')[0] change['date'] = epoch2datetime(change['when_timestamp']).strftime('%Y-%m-%d %H:%M') response.append( "[{comment}]({revlink})\n" "_Author_: {author}\n" "_Date_: {date}\n" "_Repository_: {repository}\n" "_Branch_: {branch}\n" "_Revision_: {revision}\n".format(**change)) self.send('\n'.join(response))