jenkins-bot has submitted this change. ( https://gerrit.wikimedia.org/r/c/pywikibot/core/+/699413 )
Change subject: [IMPR] Use CurrentPageBot for add_text script ......................................................................
[IMPR] Use CurrentPageBot for add_text script
- use AutomaticTWSummaryBot and NoRedirectPageBot bot class - Update argument title and types to be usable with ConfigParserBot later - remove code duplication in parse function - get_text, put_text and add_text functions aren't used anymore any will be deprecated with a separate patch - update tests
Bug: T196851 Change-Id: I863a3bcaaaa57cc79cae605e80355ec8b012aa0a --- M scripts/add_text.py M tests/add_text_tests.py 2 files changed, 96 insertions(+), 44 deletions(-)
Approvals: Xqt: Looks good to me, approved jenkins-bot: Verified
diff --git a/scripts/add_text.py b/scripts/add_text.py index 6af8835..509a11c 100755 --- a/scripts/add_text.py +++ b/scripts/add_text.py @@ -55,14 +55,15 @@ # Distributed under the terms of the MIT license. # import codecs -import collections import re import sys from typing import Optional, Union
import pywikibot + from pywikibot import config, i18n, pagegenerators, textlib -from pywikibot.backports import Tuple +from pywikibot.backports import Dict, Tuple +from pywikibot.bot import AutomaticTWSummaryBot, NoRedirectPageBot from pywikibot.bot_choice import QuitKeyboardInterrupt from pywikibot.exceptions import ( EditConflictError, @@ -76,14 +77,14 @@ from pywikibot.tools.formatter import color_format
DEFAULT_ARGS = { - 'text': None, - 'text_file': None, - 'summary': None, + 'text': '', + 'textfile': '', + 'summary': '', 'up': False, 'always': False, 'talk_page': False, 'reorder': True, - 'regex_skip_url': None, + 'regex_skip_url': '', }
ARG_PROMPT = { @@ -289,6 +290,77 @@ error_count += 1
+class AddTextBot(AutomaticTWSummaryBot, NoRedirectPageBot): + + """A bot which adds a text to a page.""" + + summary_key = 'add_text-adding' + + def __init__(self, **kwargs): + """Initializer.""" + self.available_options.update(DEFAULT_ARGS) + super().__init__(**kwargs) + + @property + def summary_parameters(self): + """Return a dictionary of all parameters for i18n. + + Line breaks are replaced by dash. + """ + text = re.sub(r'\r?\n', ' - ', self.opt.text[:200]) + return {'adding': text} + + def setup(self): + """Read text to be added from file.""" + if self.opt.textfile: + with codecs.open(self.opt.textfile, 'r', + config.textfile_encoding) as f: + self.opt.text = f.read() + else: + # Translating the \n into binary \n if given from command line + self.opt.text = self.opt.text.replace('\n', '\n') + + if self.opt.talk_page: + self.generator = pagegenerators.PageWithTalkPageGenerator( + self.generator, return_talk_only=True) + + def skip_page(self, page): + """Skip if -exceptUrl matches or page does not exists.""" + if not page.exists(): + if not page.isTalkPage(): + pywikibot.warning('Page {page} does not exist on {page.site}.' + .format(page=page)) + return True + elif self.opt.regex_skip_url: + url = page.full_url() + result = re.findall(self.opt.regex_skip_url, page.site.getUrl(url)) + if result: + pywikibot.warning( + 'Regex (or word) used with -exceptUrl is in the page. ' + 'Skipping {page}\nMatch was: {result}' + .format(page=page, result=result)) + return True + + skipping = super().skip_page(page) + if not skipping and not page.exists(): + pywikibot.output("{} doesn't exist, creating it!".format(page)) + return skipping + + def treat_page(self): + """Add text to the page.""" + text = self.current_page.text + + if self.opt.up: + text = self.opt.text + '\n' + text + elif not self.opt.reorder: + text += '\n' + self.opt.text + else: + text = textlib.add_text(text, self.opt.text, + site=self.current_page.site) + + self.put_current(text, summary=self.opt.summary) + + def main(*argv: Tuple[str, ...]) -> None: """ Process command line arguments and invoke bot. @@ -300,35 +372,22 @@ generator_factory = pagegenerators.GeneratorFactory()
try: - args = parse(argv, generator_factory) + options = parse(argv, generator_factory) except ValueError as exc: pywikibot.bot.suggest_help(additional_text=str(exc)) return
- text = args.text - - if args.text_file: - with codecs.open(args.text_file, 'r', config.textfile_encoding) as f: - text = f.read() - generator = generator_factory.getCombinedGenerator() - if pywikibot.bot.suggest_help(missing_generator=not generator): return
- if args.talk_page: - generator = pagegenerators.PageWithTalkPageGenerator(generator, True) - - for page in generator: - add_text(page, text, args.summary, - regexSkipUrl=args.regex_skip_url, always=args.always, - up=args.up, reorderEnabled=args.reorder, - create=args.talk_page) + bot = AddTextBot(generator=generator, **options) + bot.run()
def parse(argv: Tuple[str, ...], generator_factory: pagegenerators.GeneratorFactory - ) -> collections.namedtuple: + ) -> Dict[str, str]: """ Parses our arguments and provide a named tuple with their values.
@@ -349,16 +408,10 @@ if not value and option in ARG_PROMPT: value = pywikibot.input(ARG_PROMPT[option])
- if option == '-text': - args['text'] = value - elif option == '-textfile': - args['text_file'] = value - elif option == '-summary': - args['summary'] = value - elif option == '-up': - args['up'] = True - elif option == '-always': - args['always'] = True + if option in ('-text', '-textfile', '-summary'): + args[option[1:]] = value + elif option in ('-up', '-always'): + args[option[1:]] = True elif option in ('-talk', '-talkpage'): args['talk_page'] = True elif option == '-noreorder': @@ -368,14 +421,13 @@ else: raise ValueError("Argument '{}' is unrecognized".format(option))
- if not args['text'] and not args['text_file']: + if not args['text'] and not args['textfile']: raise ValueError("Either the '-text' or '-textfile' is required")
- if args['text'] and args['text_file']: + if args['text'] and args['textfile']: raise ValueError("'-text' and '-textfile' cannot both be used")
- Args = collections.namedtuple('Args', args.keys()) - return Args(**args) + return args
if __name__ == '__main__': diff --git a/tests/add_text_tests.py b/tests/add_text_tests.py index f4e9232..7a15450 100644 --- a/tests/add_text_tests.py +++ b/tests/add_text_tests.py @@ -33,15 +33,15 @@ def test_parse(self): """Basic argument parsing.""" args = parse(['-text:"hello world"'], self.generator_factory) - self.assertEqual('"hello world"', args.text) - self.assertFalse(args.up) - self.assertTrue(args.reorder) + self.assertEqual('"hello world"', args['text']) + self.assertFalse(args['up']) + self.assertTrue(args['reorder'])
args = parse(['-text:hello', '-up', '-noreorder'], self.generator_factory) - self.assertEqual('hello', args.text) - self.assertTrue(args.up) - self.assertFalse(args.reorder) + self.assertEqual('hello', args['text']) + self.assertTrue(args['up']) + self.assertFalse(args['reorder'])
@patch('pywikibot.handle_args', Mock(side_effect=lambda args: args)) def test_unrecognized_argument(self): @@ -76,7 +76,7 @@ input_mock.return_value = 'hello world'
args = parse(['-text'], self.generator_factory) - self.assertEqual('hello world', args.text) + self.assertEqual('hello world', args['text']) input_mock.assert_called_with('What text do you want to add?')
def test_basic(self):