#!/usr/bin/env python3 # -*- coding: utf-8 -*- # # reddiscparser.py # # Copyright 2016 GOLDERWEB – Jonathan Golder # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, # MA 02110-1301, USA. # # """ Wrapper script to invoke all redundances bot tasks """ import os import sys import pywikibot from pywikibot import pagegenerators import jogobot 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. If args is an empty list, sys.argv is used. @param args: command line arguments @type args: list of unicode """ # Process global arguments to determine desired site local_args = pywikibot.handle_args(args) # Get the jogobot-task_slug (basename of current file without ending) task_slug = os.path.basename(__file__)[:-len(".py")] # Before run, we need to check wether we are currently active or not if not active( task_slug ): return # Parse local Args to get information about subtask ( subtask, genFactory, subtask_args ) = parse_local_args( local_args ) # select subtask and prepare args ( subtask, Bot, genFactory, kwargs ) = prepare_bot( task_slug, subtask, genFactory, subtask_args ) # Init Bot bot = init_bot( task_slug, subtask, Bot, genFactory, **kwargs) # Run bot run_bot( task_slug, subtask, bot ) if( __name__ == "__main__" ): main()