Files
jogobot-red/red.py
GOLDERWEB – Jonathan Golder 3540cc2a7d Move functional sections to functions in main()
To make main() function less complicated functional sections are moved
to dedicated functions

Related Task: [https://fs.golderweb.de/index.php?do=details&task_id=82 FS#82]
2016-08-27 15:40:09 +02:00

301 lines
8.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# reddiscparser.py
#
# Copyright 2016 GOLDERWEB Jonathan Golder <jonathan@golderweb.de>
#
# 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()