John Vandenberg has uploaded a new change for review. https://gerrit.wikimedia.org/r/237989
Change subject: Convert image & template to AutomaticTWSummaryBot ...................................................................... Convert image & template to AutomaticTWSummaryBot And thus convert replace to ExistingPageBot, MultipleSitesBot. Change-Id: If137fd2b8e57ac3981ac3800ed2eb7880c010ba1 --- M pywikibot/bot.py M scripts/image.py M scripts/replace.py M scripts/template.py 4 files changed, 133 insertions(+), 118 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/pywikibot/core refs/changes/89/237989/1 diff --git a/pywikibot/bot.py b/pywikibot/bot.py index 6c334b6..d5b5f05 100644 --- a/pywikibot/bot.py +++ b/pywikibot/bot.py @@ -1881,7 +1881,7 @@ def put_current(self, *args, **kwargs): """Defining a summary if not already defined and then call original.""" - if 'summary' not in kwargs: + if 'summary' not in kwargs or kwargs['summary'] is None: from pywikibot import i18n if self.summary_key is None: raise ValueError('The summary_key must be set.') diff --git a/scripts/image.py b/scripts/image.py index f780856..9020bd3 100755 --- a/scripts/image.py +++ b/scripts/image.py @@ -49,60 +49,24 @@ import pywikibot -from pywikibot import i18n, pagegenerators, Bot +from pywikibot import i18n, pagegenerators + +from pywikibot.bot import AutomaticTWSummaryBot +from pywikibot.page import Page +from pywikibot.tools import deprecated_args, issue_deprecation_warning from scripts.replace import ReplaceRobot as ReplaceBot +from scripts.replace import Replacement -class ImageRobot(ReplaceBot): +class ImageRobot(AutomaticTWSummaryBot, ReplaceBot): """This bot will replace or remove all occurrences of an old image.""" - # Summary messages for replacing images - msg_replace = { - 'ar': u'روبوت - استبدال الصورة %s مع %s', - 'de': u'Bot: Ersetze Bild %s durch %s', - 'en': u'Bot: Replacing image %s with %s', - 'es': u'Robot - Reemplazando imagen %s por %s', - 'fa': u'ربات: جایگزین کردن تصویر %s با %s', - 'fr': u'Bot: Remplace image %s par %s', - 'he': u'בוט: מחליף את התמונה %s בתמונה %s', - 'it': u"Bot: Sostituisco l'immagine %s con %s", - 'ja': u'ロボットによる:画像置き換え %s から %s へ', - 'ko': u'로봇 - 그림 %s을 %s로 치환', - 'lt': u'robotas: vaizdas %s keičiamas į %s', - 'nn': u'robot: erstatta biletet %s med %s', - 'no': u'robot: erstatter bildet %s med %s', - 'nl': u'Bot: afbeelding %s vervangen door %s', - 'pl': u'Robot zamienia obraz %s na %s', - 'pt': u'Bot: Alterando imagem %s para %s', - 'ru': u'Бот: Замена файла %s на %s', - 'zh': u'機器人:取代圖像 %s 至 %s', - } - - # Summary messages for removing images - msg_remove = { - 'ar': u'روبوت - إزالة الصورة %s', - 'de': u'Bot: Entferne Bild %s', - 'en': u'Robot: Removing image %s', - 'es': u'Robot - Retirando imagen %s', - 'fa': u'ربات: برداشتن تصویر %s', - 'fr': u'Bot: Enleve image %s', - 'he': u'בוט: מסיר את התמונה %s', - 'it': u"Bot: Rimuovo l'immagine %s", - 'ja': u'ロボットによる:画像削除 %s', - 'ko': u'로봇 - %s 그림을 제거', - 'lt': u'robotas: Šalinamas vaizdas %s', - 'nl': u'Bot: afbeelding %s verwijderd', - 'no': u'robot: fjerner bildet %s', - 'nn': u'robot: fjerna biletet %s', - 'pl': u'Robot usuwa obraz %s', - 'pt': u'Bot: Alterando imagem %s', - 'ru': u'Бот: удалил файл %s', - 'zh': u'機器人:移除圖像 %s', - } - - def __init__(self, generator, old_image, new_image=None, **kwargs): + @deprecated_args(oldImage='old_image_page', old_image='old_image_page', + newImage='new_image') + def __init__(self, generator, old_image_page, new_image=None, summary='', + always=False, loose=False, **kwargs): """ Constructor. @@ -119,17 +83,34 @@ 'loose': False, }) - Bot.__init__(self, generator=generator, **kwargs) + if not isinstance(old_image_page, pywikibot.Page): + issue_deprecation_warn( + 'old_image as a string', + 'old_image_page as Page', + 2) + old_image = old_image_page + site = pywibot.Site() + old_image_page = Page(site, old_image) + else: + old_image = old_image_page.title(withNamespace=False) + + print('hmm', old_image) + + self.old_image_page = old_image_page self.old_image = old_image self.new_image = new_image - if not self.getOption('summary'): - self.options['summary'] = i18n.translate( - self.site, self.msg_replace, - (self.old_image, self.new_image) if self.new_image - else self.old_image, - fallback=True) + if self.new_image: + self.summary_key = 'image-replace' + else: + self.summary_key = 'image-remove' + + super(ImageRobot, self).__init__(generator, replacements=[], + always=always, + summary=summary, + loose=loose, + **kwargs) # regular expression to find the original template. # {{vfd}} does the same thing as {{Vfd}}, so both will be found. @@ -139,7 +120,7 @@ replacements = [] - namespace = self.site.namespaces[6] + namespace = old_image_page.site.namespaces.FILE if namespace.case == 'first-letter': case = re.escape(self.old_image[0].upper() + self.old_image[0].lower()) @@ -160,16 +141,28 @@ if not self.getOption('loose'): replacements.append((image_regex, u'[[%s:%s\\g<parameters>]]' - % (self.site.namespaces.FILE, + % (namespace.canonical_name, self.new_image))) else: replacements.append((image_regex, self.new_image)) else: replacements.append((image_regex, '')) - super(ImageRobot, self).__init__(self.generator, replacements, - always=self.getOption('always'), - summary=self.getOption('summary')) + self.replacements = [Replacement.from_compiled(a, b) + for (a, b) in replacements] + + @property + def summary_parameters(self): + """Provide TWN parameters.""" + if self.new_image: + return { + 'old': self.old_image, + 'new': self.new_image, + } + else: + return { + 'file': self.old_image, + } def main(*args): @@ -205,7 +198,7 @@ old_imagepage = pywikibot.FilePage(site, old_image) gen = pagegenerators.FileLinksGenerator(old_imagepage) preloadingGen = pagegenerators.PreloadingGenerator(gen) - bot = ImageRobot(preloadingGen, old_image, new_image, **options) + bot = ImageRobot(preloadingGen, old_imagepage, new_image, **options) bot.run() return True else: diff --git a/scripts/replace.py b/scripts/replace.py index aa3b6ed..2b374f7 100755 --- a/scripts/replace.py +++ b/scripts/replace.py @@ -141,7 +141,6 @@ import collections import re import time -import sys import warnings import pywikibot @@ -151,10 +150,16 @@ # Imports predefined replacements tasks from fixes.py from pywikibot import fixes +from pywikibot.tools import chars -from pywikibot.tools import chars, deprecated_args +from pywikibot.bot import ( + AutomaticTWSummaryBot, + ExistingPageBot, + MultipleSitesBot, +) +from pywikibot.tools import PY2, deprecated_args, issue_deprecation_warning -if sys.version_info[0] > 2: +if not PY2: basestring = (str, ) # This is required for the text that is shown when you run this script @@ -465,14 +470,15 @@ return False -class ReplaceRobot(Bot): +class ReplaceRobot(ExistingPageBot, MultipleSitesBot): """A bot that can do text replacements.""" - @deprecated_args(acceptall='always') + @deprecated_args(acceptall='always', editSummary='summary', + articles=None, exctitles=None) def __init__(self, generator, replacements, exceptions={}, always=False, allowoverlap=False, recursive=False, - addedCat=None, sleep=None, summary='', site=None, **kwargs): + addedCat=None, sleep=None, summary='', **kwargs): """ Constructor. @@ -513,7 +519,6 @@ """ super(ReplaceRobot, self).__init__(generator=generator, always=always, - site=site, **kwargs) for i, replacement in enumerate(replacements): @@ -535,7 +540,12 @@ if isinstance(addedCat, pywikibot.Category): self.addedCat = addedCat else: - self.addedCat = pywikibot.Category(self.site, addedCat) + if not site: + issue_deprecation_warning('addedCat of type str', + 'type Page', + depth=2) + site = pywikibot.Site() + self.addedCat = pywikibot.Category(site, addedCat) self.sleep = sleep self.summary = summary @@ -612,7 +622,7 @@ new_text = textlib.replaceExcept( new_text, replacement.old_regex, replacement.new, exceptions + get_exceptions(replacement.exceptions or {}), - allowoverlap=self.allowoverlap, site=self.site) + allowoverlap=self.allowoverlap, site=page.site) if old_text != new_text: applied.add(replacement) @@ -635,8 +645,24 @@ if not isinstance(err, Exception): self.changed_pages += 1 + @property + def summary_parameters(self): + """ + Dummy AutomaticTWSummaryBot hook. + + @raises: NotImplementedError + """ + raise NotImplementedError( + 'AutomaticTWSummaryBot hook summary_parameters not implemented ' + 'by {0}'.format(self.__class__)) + def generate_summary(self, applied_replacements): """Generate a summary message for the replacements.""" + # If this is a AutomaticTWSummaryBot, the summary will be + # provided by TWN, in conjunction with summary_parameters + if isinstance(self, AutomaticTWSummaryBot) and not self.summary: + return None + # all replacements which are merged into the default message default_summaries = set() # all message parts @@ -662,26 +688,25 @@ semicolon = self.site.mediawiki_message('semicolon-separator') return semicolon.join(summary_messages) - def run(self): - """Start the bot.""" - # Run the generator which will yield Pages which might need to be - # changed. - for page in self.generator: + def treat_page(self): + """Treat a page.""" + page = self.current_page + if True: if self.isTitleExcepted(page.title()): pywikibot.output( u'Skipping %s because the title is on the exceptions list.' % page.title(asLink=True)) - continue + return try: # Load the page's text from the wiki original_text = page.get(get_redirect=True) if not page.canBeEdited(): pywikibot.output(u"You can't edit page %s" % page.title(asLink=True)) - continue + return except pywikibot.NoPage: pywikibot.output(u'Page %s not found' % page.title(asLink=True)) - continue + return applied = set() new_text = original_text while True: @@ -742,26 +767,13 @@ if choice == 'a': self.options['always'] = True if choice == 'y': - page.put_async(new_text, self.generate_summary(applied), - callback=self.count_changes) + self.put_current(new_text, self.generate_summary(applied), + callback=self.count_changes, async=True) # choice must be 'N' break if self.getOption('always') and new_text != original_text: - try: - page.put(new_text, self.generate_summary(applied), callback=self.count_changes) - except pywikibot.EditConflict: - pywikibot.output(u'Skipping %s because of edit conflict' - % (page.title(),)) - except pywikibot.SpamfilterError as e: - pywikibot.output( - u'Cannot change %s because of blacklist entry %s' - % (page.title(), e.url)) - except pywikibot.LockedPage: - pywikibot.output(u'Skipping %s (locked page)' - % (page.title(),)) - except pywikibot.PageNotSaved as error: - pywikibot.output(u'Error putting page: %s' - % (error.args,)) + self.put_current(new_text, self.generate_summary(applied), + callback=self.count_changes) def prepareRegexForMySQL(pattern): diff --git a/scripts/template.py b/scripts/template.py index ca35b61..b69037b 100755 --- a/scripts/template.py +++ b/scripts/template.py @@ -118,8 +118,12 @@ import pywikibot -from pywikibot import i18n, pagegenerators, xmlreader, Bot +from pywikibot import i18n, pagegenerators, xmlreader + +from pywikibot.bot import AutomaticTWSummaryBot from pywikibot.exceptions import ArgumentDeprecationWarning +from pywikibot.tools import deprecated_args, issue_deprecation_warning + from scripts.replace import ReplaceRobot as ReplaceBot @@ -170,11 +174,13 @@ yield page -class TemplateRobot(ReplaceBot): +class TemplateRobot(AutomaticTWSummaryBot, ReplaceBot): """This bot will replace, remove or subst all occurrences of a template.""" - def __init__(self, generator, templates, **kwargs): + @deprecated_args(editSummary='summary', acceptAll='always') + def __init__(self, generator, templates, subst=False, remove=False, + summary='', always=False, addedCat=None): """ Constructor. @@ -192,27 +198,26 @@ 'addedCat': None, }) - Bot.__init__(self, generator=generator, **kwargs) + super(TemplateRobot, self).__init__( + generator, replacements, exceptions, + always=always, + addedCat=addedCat, + summary=summary, + subst=subst, + remove=remove) self.templates = templates + site = pywikibot.Site() + # get edit summary message if it's empty if not self.getOption('summary'): - comma = self.site.mediawiki_message('comma-separator') - params = {'list': comma.join(self.templates.keys()), - 'num': len(self.templates)} - - site = self.site - if self.getOption('remove'): - self.options['summary'] = i18n.twntranslate( - site, 'template-removing', params) + self.summary_key = 'template-removing' elif self.getOption('subst'): - self.options['summary'] = i18n.twntranslate( - site, 'template-substituting', params) + self.summary_key = 'template-substituting' else: - self.options['summary'] = i18n.twntranslate( - site, 'template-changing', params) + self.summary_key = 'template-changing' # regular expression to find the original template. # {{vfd}} does the same thing as {{Vfd}}, so both will be found. @@ -222,7 +227,7 @@ replacements = [] exceptions = {} - namespace = self.site.namespaces[10] + namespace = site.namespaces.TEMPLATE for old, new in self.templates.items(): if namespace.case == 'first-letter': pattern = '[' + \ @@ -248,7 +253,7 @@ elif self.getOption('remove'): replacements.append((templateRegex, '')) else: - template = pywikibot.Page(self.site, new, ns=10) + template = pywikibot.Page(site, new, ns=10) if not template.exists(): pywikibot.warning(u'Template "%s" does not exist.' % new) if not pywikibot.input_yn('Do you want to proceed anyway?', @@ -257,11 +262,16 @@ replacements.append((templateRegex, r'{{%s\g<parameters>}}' % new)) - super(TemplateRobot, self).__init__( - generator, replacements, exceptions, - always=self.getOption('always'), - addedCat=self.getOption('addedCat'), - summary=self.getOption('summary')) + self.replacements = [Replacement.from_compiled(a, b) + for (a, b) in replacements] + self.exceptions = exceptions + + @property + def summary_parameters(self): + """Provide TWN parameters.""" + comma = self.site.mediawiki_message('comma-separator') + params = {'list': comma.join(self.templates.keys()), + 'num': len(self.templates)} def main(*args): -- To view, visit https://gerrit.wikimedia.org/r/237989 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: If137fd2b8e57ac3981ac3800ed2eb7880c010ba1 Gerrit-PatchSet: 1 Gerrit-Project: pywikibot/core Gerrit-Branch: master Gerrit-Owner: John Vandenberg <jay...@gmail.com> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits