jenkins-bot has submitted this change and it was merged.
Change subject: [FEAT] Bot: Add Bot subclasses
......................................................................
[FEAT] Bot: Add Bot subclasses
This adds Bot subclasses which implement 'treat_page' and automatically
set 'current_page'. Five subclasses check that only certain types of
pages are treated.
Change-Id: I80164eaca587d2fc92c8eed6c71440f833412cac
---
M pywikibot/__init__.py
M pywikibot/bot.py
M scripts/capitalize_redirects.py
M scripts/cosmetic_changes.py
M scripts/create_categories.py
M scripts/delete.py
6 files changed, 179 insertions(+), 54 deletions(-)
Approvals:
John Vandenberg: Looks good to me, approved
jenkins-bot: Verified
diff --git a/pywikibot/__init__.py b/pywikibot/__init__.py
index 7fd7983..38ee92c 100644
--- a/pywikibot/__init__.py
+++ b/pywikibot/__init__.py
@@ -29,7 +29,7 @@
from pywikibot.bot import (
output, warning, error, critical, debug, stdout, exception,
input, input_choice, input_yn, inputChoice, handle_args, showHelp, ui, log,
- calledModuleName, Bot, WikidataBot, QuitKeyboardInterrupt,
+ calledModuleName, Bot, CurrentPageBot, WikidataBot, QuitKeyboardInterrupt,
# the following are flagged as deprecated on usage
handleArgs,
)
@@ -70,7 +70,7 @@
'stdout', 'output', 'warning', 'error',
'critical', 'debug',
'exception', 'input_choice', 'input',
'input_yn', 'inputChoice',
'handle_args', 'handleArgs', 'showHelp', 'ui',
'log',
- 'calledModuleName', 'Bot', 'WikidataBot',
+ 'calledModuleName', 'Bot', 'CurrentPageBot',
'WikidataBot',
'Error', 'InvalidTitle', 'BadTitle', 'NoPage',
'SectionError',
'SiteDefinitionError', 'NoSuchSite', 'UnknownSite',
'UnknownFamily',
'NoUsername', 'UserBlocked', 'UserActionRefuse',
diff --git a/pywikibot/bot.py b/pywikibot/bot.py
index ef9673b..1b4bb34 100644
--- a/pywikibot/bot.py
+++ b/pywikibot/bot.py
@@ -1149,6 +1149,135 @@
self.__class__.__name__)
+class CurrentPageBot(Bot):
+
+ """A bot which automatically sets 'current_page' on each
treat()."""
+
+ ignore_save_related_errors = True
+ ignore_server_errors = False
+
+ def treat_page(self):
+ """Process one page (Abstract method)."""
+ raise NotImplementedError('Method %s.treat_page() not implemented.'
+ % self.__class__.__name__)
+
+ def treat(self, page):
+ """Set page to current page and treat that
page."""
+ self.current_page = page
+ self.treat_page()
+
+ def put_current(self, new_text, ignore_save_related_errors=None,
+ ignore_server_errors=None, **kwargs):
+ """
+ Call L{Bot.userPut} but use the current page.
+
+ It compares the new_text to the current page text.
+
+ @param new_text: The new text
+ @type new_text: basestring
+ @param ignore_save_related_errors: Ignore save related errors and
+ automatically print a message. If None uses this instances default.
+ @type ignore_save_related_errors: bool or None
+ @param ignore_server_errors: Ignore server errors and automatically
+ print a message. If None uses this instances default.
+ @type ignore_server_errors: bool or None
+ @param kwargs: Additional parameters directly given to L{Bot.userPut}.
+ @type kwargs: dict
+ """
+ if ignore_save_related_errors is None:
+ ignore_save_related_errors = self.ignore_save_related_errors
+ if ignore_server_errors is None:
+ ignore_server_errors = self.ignore_server_errors
+ self.userPut(self.current_page, self.current_page.text, new_text,
+ ignore_save_related_errors=ignore_save_related_errors,
+ ignore_server_errors=ignore_server_errors,
+ **kwargs)
+
+
+class ExistingPageBot(CurrentPageBot):
+
+ """A CurrentPageBot class which only treats existing
pages."""
+
+ def treat(self, page):
+ """Treat page if it exists and handle NoPage from
it."""
+ if not page.exists():
+ pywikibot.warning('Page "{0}" does not exist on
{1}.'.format(
+ page.title(), page.site))
+ return
+ try:
+ super(ExistingPageBot, self).treat(page)
+ except pywikibot.NoPage as e:
+ if e.page != page:
+ raise
+ pywikibot.warning(
+ 'During handling of page "{0}" on {1} a NoPage exception
was '
+ 'raised.'.format(page.title(), page.site))
+
+
+class FollowRedirectPageBot(CurrentPageBot):
+
+ """A CurrentPageBot class which follows the
redirect."""
+
+ def treat(self, page):
+ """Treat target if page is redirect and the page
otherwise."""
+ if page.isRedirectPage():
+ page = page.getRedirectTarget()
+ super(FollowRedirectPageBot, self).treat(page)
+
+
+class CreatingPageBot(CurrentPageBot):
+
+ """A CurrentPageBot class which only treats not exisiting
pages."""
+
+ def treat(self, page):
+ """Treat page if doesn't exist."""
+ if page.exists():
+ pywikibot.warning('Page "{0}" does already exist on
{1}.'.format(
+ page.title(), page.site))
+ return
+ super(CreatingPageBot, self).treat(page)
+
+
+class RedirectPageBot(CurrentPageBot):
+
+ """A RedirectPageBot class which only treats
redirects."""
+
+ def treat(self, page):
+ """Treat only redirect pages and handle IsNotRedirectPage from
it."""
+ if not page.isRedirectPage():
+ pywikibot.warning('Page "{0}" on {1} is skipped because it is
not '
+ 'a redirect'.format(page.title(), page.site))
+ return
+ try:
+ super(RedirectPageBot, self).treat(page)
+ except pywikibot.IsNotRedirectPage as e:
+ if e.page != page:
+ raise
+ pywikibot.warning(
+ 'During handling of page "{0}" on {1} a IsNotRedirectPage
'
+ 'exception was raised.'.format(page.title(), page.site))
+
+
+class NoRedirectPageBot(CurrentPageBot):
+
+ """A NoRedirectPageBot class which only treats
non-redirects."""
+
+ def treat(self, page):
+ """Treat only non-redirect pages and handle IsRedirectPage from
it."""
+ if page.isRedirectPage():
+ pywikibot.warning('Page "{0}" on {1} is skipped because it is a
'
+ 'redirect'.format(page.title(), page.site))
+ return
+ try:
+ super(NoRedirectPageBot, self).treat(page)
+ except pywikibot.IsRedirectPage as e:
+ if e.page != page:
+ raise
+ pywikibot.warning(
+ 'During handling of page "{0}" on {1} a IsRedirectPage
'
+ 'exception was raised.'.format(page.title(), page.site))
+
+
class WikidataBot(Bot):
"""
diff --git a/scripts/capitalize_redirects.py b/scripts/capitalize_redirects.py
index 6c2422b..f0a27d7 100644
--- a/scripts/capitalize_redirects.py
+++ b/scripts/capitalize_redirects.py
@@ -33,14 +33,15 @@
#
import pywikibot
-from pywikibot import i18n, pagegenerators, Bot
+from pywikibot import i18n, pagegenerators
+from pywikibot.bot import FollowRedirectPageBot, ExistingPageBot
docuReplacements = {
'¶ms;': pagegenerators.parameterHelp
}
-class CapitalizeBot(Bot):
+class CapitalizeBot(FollowRedirectPageBot, ExistingPageBot):
"""Capitalization Bot."""
@@ -60,18 +61,14 @@
super(CapitalizeBot, self).__init__(**kwargs)
self.generator = generator
- def treat(self, page):
- """Load the given page and create capitalized
redirects."""
- if not page.exists():
- return
- if page.isRedirectPage():
- page = page.getRedirectTarget()
- page_t = page.title()
- self.current_page = page
+ def treat_page(self):
+ """Capitalize redirects of the current page."""
+ page_t = self.current_page.title()
+ site = self.current_page.site
if self.getOption('titlecase'):
- page_cap = pywikibot.Page(page.site, page_t.title())
+ page_cap = pywikibot.Page(site, page_t.title())
else:
- page_cap = pywikibot.Page(page.site, page_t.capitalize())
+ page_cap = pywikibot.Page(site, page_t.capitalize())
if page_cap.exists():
pywikibot.output(u'%s already exists, skipping...\n'
% page_cap.title(asLink=True))
@@ -86,12 +83,12 @@
self.options['always'] = True
if self.getOption('always') or choice == 'y':
comment = i18n.twtranslate(
- page.site,
+ site,
'capitalize_redirects-create-redirect',
{'to': page_t})
- page_cap.text = u"#%s %s" % (page.site.redirect(),
- page.title(asLink=True,
- textlink=True))
+ page_cap.text = u"#%s %s" % (site.redirect(),
+ self.current_page.title(
+ asLink=True, textlink=True))
try:
page_cap.save(comment)
except:
diff --git a/scripts/cosmetic_changes.py b/scripts/cosmetic_changes.py
index 5b90caa..3d5f5b2 100755
--- a/scripts/cosmetic_changes.py
+++ b/scripts/cosmetic_changes.py
@@ -77,7 +77,8 @@
from pywikibot.tools import MediaWikiVersion
import pywikibot
import isbn
-from pywikibot import config, i18n, textlib, pagegenerators, Bot
+from pywikibot import config, i18n, textlib, pagegenerators
+from pywikibot.bot import ExistingPageBot, NoRedirectPageBot
from pywikibot.page import url2unicode
from pywikibot.tools import deprecate_arg
@@ -194,6 +195,12 @@
self.fixArabicLetters,
)
+
+ @classmethod
+ def from_page(cls, page, diff, ignore):
+ """Create toolkit based on the page."""
+ return cls(page.site, diff=diff, namespace=page.namespace(),
+ pageTitle=page.title(), ignore=ignore)
def safe_execute(self, method, text):
"""Execute the method and catch exceptions if
enabled."""
@@ -891,7 +898,7 @@
return text
-class CosmeticChangesBot(Bot):
+class CosmeticChangesBot(ExistingPageBot, NoRedirectPageBot):
"""Cosmetic changes bot."""
@@ -905,29 +912,22 @@
self.generator = generator
- def treat(self, page):
+ def treat_page(self):
+ """Treat page with the cosmetic toolkit."""
try:
- self.current_page = page
- ccToolkit = CosmeticChangesToolkit(page.site, diff=False,
- namespace=page.namespace(),
- pageTitle=page.title(),
- ignore=self.getOption('ignore'))
- changedText = ccToolkit.change(page.get())
+ ccToolkit = CosmeticChangesToolkit.from_page(
+ self.current_page, True, self.getOption('ignore'))
+ changedText = ccToolkit.change(self.current_page.get())
if changedText is not False:
- self.userPut(page, page.text, changedText,
- comment=self.getOption('comment'),
- async=self.getOption('async'))
- except pywikibot.NoPage:
- pywikibot.output("Page %s does not exist?!"
- % page.title(asLink=True))
- except pywikibot.IsRedirectPage:
- pywikibot.output("Page %s is a redirect; skipping."
- % page.title(asLink=True))
+ self.put_current(newtext=changedText,
+ comment=self.getOption('comment'),
+ async=self.getOption('async'))
except pywikibot.LockedPage:
- pywikibot.output("Page %s is locked?!" % page.title(asLink=True))
+ pywikibot.output("Page %s is locked?!"
+ % self.current_page.title(asLink=True))
except pywikibot.EditConflict:
pywikibot.output("An edit conflict has occured at %s."
- % page.title(asLink=True))
+ % self.current_page.title(asLink=True))
def main(*args):
diff --git a/scripts/create_categories.py b/scripts/create_categories.py
index f6ef329..90f2536 100755
--- a/scripts/create_categories.py
+++ b/scripts/create_categories.py
@@ -47,7 +47,8 @@
self.basename = basename
self.comment = u'Creating new category'
- def create_category(self, page):
+ def treat(self, page):
+ """Create category in commons for that page."""
title = page.title(withNamespace=False)
newpage = pywikibot.Category(pywikibot.Site('commons',
'commons'),
@@ -69,10 +70,6 @@
else:
# FIXME: Add overwrite option
pywikibot.output(u'%s already exists, skipping' % newpage.title())
-
- def run(self):
- for page in self.generator:
- self.create_category(page)
def main(*args):
diff --git a/scripts/delete.py b/scripts/delete.py
index 93f6f8a..870fad3 100644
--- a/scripts/delete.py
+++ b/scripts/delete.py
@@ -34,7 +34,7 @@
#
import pywikibot
-from pywikibot import i18n, pagegenerators, Bot
+from pywikibot import i18n, pagegenerators, CurrentPageBot
# This is required for the text that is shown when you run this script
# with the parameter -help.
@@ -43,7 +43,7 @@
}
-class DeletionRobot(Bot):
+class DeletionRobot(CurrentPageBot):
""" This robot allows deletion of pages en masse. """
@@ -63,20 +63,22 @@
self.summary = summary
- def treat(self, page):
+ def treat_page(self):
"""Process one page from the generator."""
- self.current_page = page
if self.getOption('undelete'):
- if page.exists():
- pywikibot.output(u'Skipping: %s already exists.' % page)
+ if self.current_page.exists():
+ pywikibot.output(u'Skipping: {0} already exists.'.format(
+ self.current_page))
else:
- page.undelete(self.summary)
+ self.current_page.undelete(self.summary)
else:
- if page.exists():
- page.delete(self.summary, not self.getOption('always'),
- self.getOption('always'))
+ if self.current_page.exists():
+ self.current_page.delete(self.summary,
+ not self.getOption('always'),
+ self.getOption('always'))
else:
- pywikibot.output(u'Skipping: %s does not exist.' % page)
+ pywikibot.output(u'Skipping: {0} does not exist.'.format(
+ self.current_page))
def main(*args):
--
To view, visit
https://gerrit.wikimedia.org/r/171978
To unsubscribe, visit
https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I80164eaca587d2fc92c8eed6c71440f833412cac
Gerrit-PatchSet: 6
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Owner: XZise <CommodoreFabianus(a)gmx.de>
Gerrit-Reviewer: John Vandenberg <jayvdb(a)gmail.com>
Gerrit-Reviewer: Ladsgroup <ladsgroup(a)gmail.com>
Gerrit-Reviewer: Merlijn van Deen <valhallasw(a)arctus.nl>
Gerrit-Reviewer: XZise <CommodoreFabianus(a)gmx.de>
Gerrit-Reviewer: jenkins-bot <>