def set_task_priority(source: CommandSource, titles: str, priority: Optional[int] = None): GlobalVariables.task_manager.set_priority(TitleList(titles), priority) info_task(source, titles, headline_override=tr('priority_set')) GlobalVariables.log( f"{source_name(source)} set task {titles} priority to {priority}")
def on_load(server: PluginServerInterface, prev_module): if prev_module is not None: pass GlobalVariables.set_config(Config.load(server)) GlobalVariables.setup_task_manager(TaskManager.load()) register_cmd_tree(server) server.register_help_message(PREFIX, server.tr("mcd_task.mcdr_help"))
def set_task_deadline(source: CommandSource, titles: str, ddl: str) -> None: deadline = float(time.time()) + float(ddl) * 3600 * 24 GlobalVariables.task_manager.set_deadline(TitleList(titles), deadline) info_task(source, titles, headline_override=tr("ddl_set")) GlobalVariables.log( f"{source_name(source)} set task {titles} deadline to {formatted_time(deadline, locale='en_us')}" )
def load(cls): if not os.path.isfile(TASK_PATH): cls.get_default().save() with open(TASK_PATH, 'r', encoding='utf8') as fp: js = json.load(fp) manager = cls.deserialize(js) GlobalVariables.debug(manager.serialize()) manager.responsible_manager.load() return manager
def add_task(source: CommandSource, titles: str, desc: str = ''): titles = TitleList(titles) titles_for_text = titles.copy() GlobalVariables.task_manager.add_task(titles, desc=desc) info_task(source, title=str(titles_for_text), headline_override=tr("new_task_created")) GlobalVariables.log( f"{source_name(source)} created new task named {str(titles_for_text)}")
def inherit_responsible(info: Info, old_name: str, new_name: str, debug=False): manager = GlobalVariables.task_manager.responsible_manager if old_name in manager.player_work.keys(): manager.rename_player(old_name, new_name) num = len(manager[new_name]) info.get_server().tell(new_name, tr("mcd_task.on_player_renamed", num)) GlobalVariables.logger.debug(tr("mcd_task.on_player_renamed", num), no_check=debug) GlobalVariables.log( f"Detected player rename {old_name} -> {new_name}. Inherited {num} task(s)" )
def seek_for_item_with_priority(self, sort=True, with_done=False): result = [] for item in self.sub_tasks: if isinstance(item.priority, int): if with_done or not item.is_done: result.append(item) GlobalVariables.debug( f'Priority task found: {item.full_path()}') result += item.seek_for_item_with_priority(sort=False) return sorted(result, key=lambda task: task.priority, reverse=True) if sort else result
def deserialize(cls, data: dict, **kwargs): GlobalVariables.debug(data) sub_tasks = copy(data.get(SUB_TASKS, [])) if not isinstance(sub_tasks, list): raise TypeError( 'Unsupported input type: expected class "{}" but found data with class "{}"' .format(list.__name__, type(data).__name__)) data[SUB_TASKS] = [] this_task = deserialize(data=data, cls=cls, **kwargs) this_task.create_sub_tasks_from_serialized_data(sub_tasks) return this_task
def rename_task(source: CommandSource, old_titles: str, new_title: str) -> None: if '.' in list(new_title): source.reply(tr("mcd_task.illegal_title_with_dot", new_title)) return GlobalVariables.task_manager.rename_task(TitleList(old_titles), new_title) new_titles = TitleList(old_titles) new_titles.pop_tail() new_titles.append(new_title) info_task(source, title=str(new_titles), headline_override=tr("mcd_task.task_renamed", old_titles)) GlobalVariables.log( f"{source_name(source)} renamed {old_titles} to {str(new_titles)}")
def seek_for_item_with_deadline_approaching(self, sort=True, with_done=False): result = [] for item in self.sub_tasks: if item.deadline != 0 and item.deadline - \ time.time() < 3600 * 24 * GlobalVariables.config.overview_deadline_warning_threshold: if with_done or not item.is_done: result.append(item) GlobalVariables.debug( f'Deadline task found: {item.full_path()}') result += item.seek_for_item_with_deadline_approaching(sort=False) return sorted(result, key=lambda task: task.deadline, reverse=False) if sort else result
def set_responsible(source: CommandSource, titles: str, players: Optional[str] = None) -> None: if players is None: if isinstance(source, PlayerCommandSource): players = source.player else: illegal_call(source) return players = players.split(' ') num = GlobalVariables.task_manager.set_responsible(TitleList(titles), *players) info_task(source, titles, headline_override=tr("mcd_task.added_responsibles_title", num)) GlobalVariables.log( f"{source_name(source)} added responsibles for task {str(titles)}: {str(players)}" )
def task_overview(source: CommandSource): GlobalVariables.debug('Running overview...') headline = tr('overview_headline').set_styles(RStyle.bold).set_color( RColor.green) + ' ' + add_task_button() # Get task instances deadline_approaching = GlobalVariables.task_manager.seek_for_item_with_deadline_approaching( ) GlobalVariables.debug(deadline_approaching) max_length = GlobalVariables.config.overview_maximum_task_amount priority_amount = max_length - len(deadline_approaching) with_priorities = [] if priority_amount > 0: with_priorities = GlobalVariables.task_manager.seek_for_item_with_priority( ) # Found no matched task handle if len(deadline_approaching) == 0 and len(with_priorities) == 0: task_text = tr('no_priority').set_color(RColor.yellow) # Organize task texts else: task_texts = {} for task in deadline_approaching: if len(task_texts ) >= GlobalVariables.config.overview_maximum_task_amount: break task_texts[task.titles] = RText('[!] ', RColor.red).h( tr('date_approaching', formatted_time( task.deadline))) + title_text(task, display_full_path=True) for task in with_priorities: if len(task_texts ) >= GlobalVariables.config.overview_maximum_task_amount: break if task.title not in task_texts.keys(): task_texts[task.titles] = RText('[!] ', RColor.gold).h( tr('has_a_high_priority', task.priority)) + title_text( task, display_full_path=True) task_text = RTextBase.join('\n', task_texts.values()) help_message = tr('overview_help', PREFIX).set_translator(GlobalVariables.htr) source.reply(RTextBase.join('\n', [headline, task_text, help_message]))
def on_info(server: PluginServerInterface, info: Info): if info.is_from_server and GlobalVariables.config["detect_player_rename"]: psd = parse(PLAYER_RENAMED, info.content) if psd is not None: inherit_responsible(info, **psd.named) if info.is_user and DEBUG_MODE: if info.content.startswith('!!task debug '): info.cancel_send_to_server() args = info.content.split(' ') if args[2] == 'base-title': info.get_command_source().reply('Manager title is {}'.format( GlobalVariables.task_manager.title)) elif args[2] == 'full-path' and len(args) == 4: info.get_command_source().reply( GlobalVariables.task_manager[args[3]].titles) elif args[2] == 'player-join': on_player_joined(server, info.player, info) elif args[2] == 'player-renamed' and len(args) == 5: inherit_responsible(info, old_name=args[3], new_name=args[4], debug=True) elif args[2] == 'taskmgr-data' and len(args) == 3: GlobalVariables.debug( str(GlobalVariables.task_manager.serialize())) elif args[2] == 'seek-no-father' and len(args) == 3: GlobalVariables.debug( str(GlobalVariables.task_manager.seek_no_father_nodes())) elif args[2] == 'detail' and len(args) == 4: GlobalVariables.debug( str(GlobalVariables.task_manager[args[3]].titles))
def register_cmd_tree(server: PluginServerInterface): def permed_literal(*literal: str) -> Literal: lvl = GlobalVariables.config.get_permission(literal[0]) lvl = lvl if isinstance(lvl, int) else 0 return Literal(literal).requires(lambda src: src.has_permission(lvl), failure_message_getter=lambda: server. rtr('mcd_task.perm_denied', lvl)) def ensure_task_exist_quotable_text(title: str = 'title'): return QuotableText(title).requires( lambda src, ctx: GlobalVariables.task_manager.exists( TitleList(ctx[title])), lambda: tr("mcd_task.task_not_found"). h(tr("mcd_task.task_not_found_hover", PREFIX)).c( RAction.run_command, f'{PREFIX} list').set_color(RColor.red)) def ensure_task_not_exist_quotable_text(title: str = 'title'): def ensure_not_exist(source: CommandSource, context: CommandContext): return not GlobalVariables.task_manager.exists( TitleList(context[title])) return QuotableText(title).requires( ensure_not_exist, lambda: tr("mcd_task.task_already_exist"). h(tr("mcd_task.task_not_found_hover", PREFIX)).c( RAction.run_command, f'{PREFIX} list').set_color(RColor.red)) root_func = task_overview if GlobalVariables.config.default_overview_instead_of_list else list_task root_node = Literal(PREFIX).runs(lambda src: root_func(src)) nodes = [ permed_literal('overview').runs(lambda src: task_overview(src)), permed_literal('list').runs(lambda src: list_task(src)), permed_literal('help').runs(lambda src: show_help(src)), permed_literal('detail').then(ensure_task_exist_quotable_text().runs( lambda src, ctx: info_task(src, title=ctx['title']))), permed_literal('list-all').runs(lambda src: all_tasks_detail(src)), permed_literal('add').then(ensure_task_not_exist_quotable_text().runs( lambda src, ctx: add_task(src, ctx['title'])).then( GreedyText('description').runs(lambda src, ctx: add_task( src, ctx['title'], ctx['description'])))), permed_literal('remove', 'rm', 'delete', 'del').then(ensure_task_exist_quotable_text().runs( lambda src, ctx: remove_task(src, ctx['title']))), permed_literal('rename').then( ensure_task_exist_quotable_text('old_titles').then( QuotableText('new_title').runs(lambda src, ctx: rename_task( src, ctx['old_titles'], ctx['new_title'])))), permed_literal('change').then(ensure_task_exist_quotable_text().then( GreedyText('description').runs(lambda src, ctx: edit_desc( src, ctx['title'], ctx['description'])))), permed_literal('done').then(ensure_task_exist_quotable_text().runs( lambda src, ctx: set_done(src, ctx['title']))), permed_literal('undone').then(ensure_task_exist_quotable_text().runs( lambda src, ctx: set_undone(src, ctx['title']))), permed_literal('deadline').then(ensure_task_exist_quotable_text().then( Literal('clear').runs( lambda src, ctx: clear_task_deadline(src, ctx['title']))).then( Number('days').runs(lambda src, ctx: set_task_deadline( src, ctx['title'], ctx['days'])))), permed_literal('player').then( QuotableText('name').runs( lambda src, ctx: info_player(src, ctx['name']))), permed_literal("responsible", "res").then( ensure_task_exist_quotable_text( ).runs(lambda src, ctx: set_responsible(src, ctx['title'])).then( GreedyText("players").runs(lambda src, ctx: set_responsible( src, ctx['title'], ctx['players'])))), permed_literal("unresponsible", "unres").then( ensure_task_exist_quotable_text().runs( lambda src, ctx: rm_responsible(src, ctx['title'])).then( Literal('-all').runs(lambda src, ctx: rm_all_responsible( src, ctx['title']))).then( GreedyText("players").runs( lambda src, ctx: rm_responsible( src, ctx['title'], ctx['players'])))), permed_literal('priority').then(ensure_task_exist_quotable_text().then( Literal('clear') .runs(lambda src, ctx: set_task_priority(src, ctx['title']))).then( Integer('priority').runs(lambda src, ctx: set_task_priority( src, ctx['title'], ctx['priority'])))), permed_literal('reload').runs(lambda src: reload_self(src)) ] for node in nodes: GlobalVariables.debug( f'Registered cmd "{PREFIX} {list(node.literals)[0]}"') root_node.then(node) server.register_command(root_node)
def save(self): data = json.dumps(self.serialize(), indent=4, ensure_ascii=False) GlobalVariables.debug(f'Saving data: {data}') with open(TASK_PATH, 'w', encoding='utf8') as fp: fp.write(data)
def clear_task_deadline(source: CommandSource, titles: str): GlobalVariables.task_manager.set_deadline(TitleList(titles), 0) info_task(source, titles, headline_override=tr('ddl_cleared')) GlobalVariables.log( f"{source_name(source)} removed task {titles} deadline")
def remove_task(source: CommandSource, titles: str): GlobalVariables.task_manager.delete_task(TitleList(titles)) source.reply(tr("mcd_task.deleted_task", "§e{}§r".format(titles))) GlobalVariables.log(f"{source_name(source)} deleted task {titles}")
def tr(key: str, *args, **kwargs): return GlobalVariables.tr(key, *args, **kwargs)
def edit_desc(source: CommandSource, titles: str, desc: str) -> None: GlobalVariables.task_manager.edit_desc(TitleList(titles), desc) info_task(source, title=titles, headline_override='changed_desc_title') GlobalVariables.log( f"{source_name(source)} changed task {titles} description to {desc}")
def set_undone(source: CommandSource, titles: str) -> None: GlobalVariables.task_manager.undone_task(TitleList(titles)) info_task(source, title=titles, headline_override='undone_task_title') GlobalVariables.log( f"{source_name(source)} marked task {titles} as undone")