diff --git a/red.py b/red.py index 3d398f4..d9bda88 100644 --- a/red.py +++ b/red.py @@ -34,7 +34,235 @@ from pywikibot import pagegenerators import jogobot -def main(*args): # noqa (temp) +def active(task_slug): + """ + Checks up if bot with given task_slug is active via jogobot.framework + + @param task_slug Task slug to check + @type task_slug str + + @return True if active, otherwise False + @rtype bool + """ + + try: + # Will throw Exception if disabled/blocked + # jogobot.is_active( task_slug ) + pass + + except jogobot.jogobot.Blocked: + (type, value, traceback) = sys.exc_info() + jogobot.output( "\03{lightpurple} %s (%s)" % (value, type ), + "CRITICAL" ) + return False + + except jogobot.jogobot.Disabled: + (type, value, traceback) = sys.exc_info() + jogobot.output( "\03{red} %s (%s)" % (value, type ), + "ERROR" ) + return False + + # Bot/Task is active + else: + return True + + +def parse_local_args( local_args ): + """ + Parses local cmd args which are not parsed by pywikibot + + @param local_args Local args returned by pywikibot.handle_args(args) + @type iterable + + @returns The following tuple + @return 1 Slug of given subtask (Arg "-task") + @rtype str + @return 2 GenFactory with parsed pagegenerator args + @rtype pagegenerators.GeneratorFactory + @return 3 Additional args for subtasks + @rtype dict + @rtype tuple + """ + + # This factory is responsible for processing command line arguments + # that are also used by other scripts and that determine on which pages + # to work on. + genFactory = pagegenerators.GeneratorFactory() + + # If always is True, bot won't ask for confirmation of edit (automode) + # always = False + + # If force_reload is True, bot will always parse Countrylist regardless + # if parsing is needed or not + # force_reload = False + + # Subtask selects the specific bot to run + # Default is reddiscparser + subtask = None + + # kwargs are passed to selected bot as **kwargs + kwargs = dict() + + # Parse command line arguments + for arg in local_args: + + # Split args + arg, sep, value = arg.partition(':') + + if arg.startswith("-always"): + # always = True + pass + elif arg.startswith("-task"): + subtask = value + else: + genFactory.handleArg(arg) + + # Return Tuple + return ( subtask, genFactory, kwargs ) + + +def prepare_bot( task_slug, subtask, genFactory, subtask_args ): + """ + Handles importing subtask Bot class and prepares specific args + + Throws exception if bot not exists + + @param task_slug Task slug, needed for logging + @type task_slug str + @param subtask Slug of given subtask + @type subtask str + @param genFactory GenFactory with parsed pagegenerator args + @type genFactory pagegenerators.GeneratorFactory + @param subtask_args Additional args for subtasks + @type subtask_args dict\ + + @returns The following tuple + @return 1 Subtask slug (replaced None for default) + @rtype str + @return 2 Botclass of given subtask (Arg "-task") + @rtype Class + @return 3 GenFactory with parsed pagegenerator args + @rtype pagegenerators.GeneratorFactory + @return 4 Additional args for subtasks + @rtype dict + @rtype tuple + """ + # kwargs are passed to selected bot as **kwargs + kwargs = dict() + + if not subtask or subtask == "discparser": + # Default case: discparser + subtask = "discparser" + + # Import related bot + from bots.reddiscparser import DiscussionParserBot as Bot + + # Subtask error + else: + jogobot.output( ( + "\03{{red}} Given subtask \"{subtask} \"" + + "is not existing!" ).format( subtask=subtask ), "ERROR" ) + raise Exception + + return ( subtask, Bot, genFactory, kwargs ) + + +def init_bot( task_slug, subtask, Bot, genFactory, **kwargs ): + """ + Initiates Bot-Object with Class given in Bot and passes params genFactory + and kwargs to it + + Passes through exception generated by Bot.__init__() after logging. + + @param task_slug Task slug, needed for logging + @type task_slug str + @param subtask Slug of given subtask + @type subtask str + @param Bot Bot class to build bot-object from + @type Class + @param genFactory GenFactory with parsed pagegenerator args + @type genFactory pagegenerators.GeneratorFactory + @param **kwargs Additional args for Bot() + @type **kwargs dict + + @returns bot-object + @type type(Bot()) + """ + # Bot gets prepared genFactory as first param and possible kwargs dict + # It has to threw an exception if something does not work properly + try: + # Init bot with genFactory and **kwargs + bot = Bot( genFactory, **kwargs ) + + except: + # Catch Errors while initiation + jogobot.output( ( + "\03{{red}} Error while trying to init " + + "subtask \"{task_slug}-{subtask}\"!" ). + format( task_slug=task_slug, subtask=subtask ), "ERROR" ) + raise + else: + # Init successfull + jogobot.output( ( + "Subtask \"{task_slug}-{subtask}\" was " + + "initiated successfully" ). + format(task_slug=task_slug, subtask=subtask) ) + return bot + + +def run_bot( task_slug, subtask, bot ): + """ + Calls the run()-method of bot-object + + Passes through exceptions generated by Bot.__init__() after logging. + Catches Errors caused by missing run(0-method. + + @param task_slug Task slug, needed for logging + @type task_slug str + @param subtask Slug of given subtask + @type subtask str + @param bot Bot object to call run()-method on + @type object with method run + """ + + # Fire up Bot + # Bot must have implemented a run()-method + # It has to threw an exception if something does not work properly + try: + # Call run method on Bot + bot.run() + + # Special event on AttributeError to catch missing run()-method + except AttributeError: + (type, value, traceback) = sys.exc_info() + + # Catch missing run()-method + if "has no attribute 'run'" in value: + jogobot.output( ( + "\03{{red}} Error while trying to run " + + "subtask \"{task_slug}-{subtask} \": +" + "Run-method is missing! "). + format( task_slug=task_slug, subtask=subtask ), "ERROR" ) + + # Pass through other AttributeError + else: + raise + + except: + jogobot.output( ( + "\03{{red}} Error while trying to run " + + "subtask \"{task_slug}-{subtask} \"!" ). + format( task_slug=task_slug, subtask=subtask ), "ERROR" ) + raise + + else: + # Run successfull + jogobot.output( ( + "Subtask \"{task_slug}-{subtask}\" was finished successfully"). + format(task_slug=task_slug, subtask=subtask) ) + + +def main(*args): """ Process command line arguments and invoke bot. @@ -51,126 +279,21 @@ def main(*args): # noqa (temp) task_slug = os.path.basename(__file__)[:-len(".py")] # Before run, we need to check wether we are currently active or not - try: - # Will throw Exception if disabled/blocked - # jogobot.is_active( task_slug ) - pass + if not active( task_slug ): + return - except jogobot.jogobot.Blocked: - (type, value, traceback) = sys.exc_info() - jogobot.output( "\03{lightpurple} %s (%s)" % (value, type ), - "CRITICAL" ) + # Parse local Args to get information about subtask + ( subtask, genFactory, subtask_args ) = parse_local_args( local_args ) - except jogobot.jogobot.Disabled: - (type, value, traceback) = sys.exc_info() - jogobot.output( "\03{red} %s (%s)" % (value, type ), - "ERROR" ) + # select subtask and prepare args + ( subtask, Bot, genFactory, kwargs ) = prepare_bot( + task_slug, subtask, genFactory, subtask_args ) - # Bot/Task is active - else: + # Init Bot + bot = init_bot( task_slug, subtask, Bot, genFactory, **kwargs) - # This factory is responsible for processing command line arguments - # that are also used by other scripts and that determine on which pages - # to work on. - genFactory = pagegenerators.GeneratorFactory() - - # If always is True, bot won't ask for confirmation of edit (automode) - # always = False - - # If force_reload is True, bot will always parse Countrylist regardless - # if parsing is needed or not - # force_reload = False - - # Subtask selects the specific bot to run - # Default is reddiscparser - subtask = None - - # kwargs are passed to selected bot as **kwargs - kwargs = dict() - - # Parse command line arguments - for arg in local_args: - - # Split args - arg, sep, value = arg.partition(':') - - if arg.startswith("-always"): - # always = True - pass - elif arg.startswith("-task"): - subtask = value - else: - genFactory.handleArg(arg) - - # After parsing args we can select bot to run - if not subtask or subtask == "discparser": - # Default case: discparser - subtask = "discparser" - - # Import related bot - from bots.reddiscparser import DiscussionParserBot as Bot - - # - else: - jogobot.output( ( - "\03{{red}} Given subtask \"{subtask} \"" + - "is not existing!" ).format( subtask=subtask ), "ERROR" ) - - # Bot gets prepared genFactory as first param and possible kwargs dict - # It has to threw an exception if something does not work properly - try: - # Init bot with genFactory and **kwargs - bot = Bot( genFactory, **kwargs ) - - except: - # Catch Errors while initiation - jogobot.output( ( - "\03{{red}} Error while trying to init " + - "subtask \"{task_slug}-{subtask} \"!" ). - format( task_slug=task_slug, subtask=subtask ), "ERROR" ) - raise - else: - # Init successfull - jogobot.output( ( - "Subtask \"{task_slug}-{subtask}\" was" + - "initiated successfully" ). - format(task_slug=task_slug, subtask=subtask) ) - - # Fire up Bot - # Bot must have implemented a run()-method - # It has to threw an exception if something does not work properly - try: - # Call run method on Bot - bot.run() - - # Special event on AttributeError to catch missing run()-method - except AttributeError: - (type, value, traceback) = sys.exc_info() - - # Catch missing run()-method - if "has no attribute 'run'" in value: - jogobot.output( ( - "\03{{red}} Error while trying to run " + - "subtask \"{task_slug}-{subtask} \": +" - "Run-method is missing! "). - format( task_slug=task_slug, subtask=subtask ), "ERROR" ) - - # Pass through other AttributeError - else: - raise - - except: - jogobot.output( ( - "\03{{red}} Error while trying to run " + - "subtask \"{task_slug}-{subtask} \"!" ). - format( task_slug=task_slug, subtask=subtask ), "ERROR" ) - raise - - else: - # Run successfull - jogobot.output( ( - "Subtask \"{task_slug}-{subtask}\" was finished successfully"). - format(task_slug=task_slug, subtask=subtask) ) + # Run bot + run_bot( task_slug, subtask, bot ) if( __name__ == "__main__" ):