http://www.mediawiki.org/wiki/Special:Code/pywikipedia/9545
Revision: 9545
Author: xqt
Date: 2011-09-25 10:41:04 +0000 (Sun, 25 Sep 2011)
Log Message:
-----------
udate from trunk r9544 (UserEditFilterGenerator, i18n-support, templateRegex, bugfix for
editSummary)
Modified Paths:
--------------
branches/rewrite/scripts/template.py
Modified: branches/rewrite/scripts/template.py
===================================================================
--- branches/rewrite/scripts/template.py 2011-09-25 10:38:14 UTC (rev 9544)
+++ branches/rewrite/scripts/template.py 2011-09-25 10:41:04 UTC (rev 9545)
@@ -25,6 +25,16 @@
-namespace: Only process templates in the given namespace number (may be used
multiple times).
+-user: Only process pages edited by a given user
+
+-skipuser: Only process pages not edited by a given user
+
+-timestamp: (With -user or -skipuser). Only check for a user where his edit is
+ not older than the given timestamp. Timestamp must be writen in
+ MediaWiki timestamp format which is "%Y%m%d%H%M%S"
+ If this parameter is missed, all edits are checked but this is
+ restricted to the last 100 edits.
+
-summary: Lets you pick a custom edit summary. Use quotes if edit summary
contains spaces.
@@ -88,6 +98,8 @@
#
# (C) Daniel Herding, 2004
# (C) Rob W.W. Hooft, 2003
+# (C) xqt, 2009-2011
+# (C) Pywikipedia team, 2004-2010
#
# Distributed under the terms of the MIT license.
#
@@ -95,10 +107,39 @@
#
import re, sys, string
import pywikibot
+from pywikibot import i18n
from pywikibot import config, pagegenerators, catlib
from scripts import replace
+def UserEditFilterGenerator(generator, username, timestamp=None, skip=False):
+ """
+ Generator which will yield Pages depending of user:username is an Author of
+ that page (only looks at the last 100 editors).
+ If timestamp is set in MediaWiki format JJJJMMDDhhmmss, older edits are
+ ignored
+ If skip is set, pages edited by the given user are ignored otherwise only
+ pages edited by this user are given back
+ """
+ if timestamp:
+ ts = pywikibot.Timestamp.fromtimestampformat(timestamp)
+ for page in generator:
+ editors = page.getLatestEditors(limit=100)
+ found = False
+ for ed in editors:
+ uts = pywikibot.Timestamp.fromISOformat(ed['timestamp'])
+ if not timestamp or uts>=ts:
+ if username == ed['user']:
+ found = True
+ break
+ else:
+ break
+ if found and not skip or not found and skip:
+ yield page
+ else:
+ pywikibot.output(u'Skipping %s' % page.title(asLink=True))
+
+
class XmlDumpTemplatePageGenerator:
"""
Generator which will yield Pages to pages that might contain the chosen
@@ -141,161 +182,13 @@
page = pywikibot.Page(mysite, entry.title)
yield page
+
class TemplateRobot:
"""
This robot will load all pages yielded by a page generator and replace or
remove all occurences of the old template, or substitute them with the
template's text.
"""
- # Summary messages for replacing templates
- msg_change={
- 'ar':u'روبوت: تغيير القالب: %s',
- 'da':u'Bot: Erstatter skabelon: %s',
- 'de':u'Bot: Ändere Vorlage: %s',
- 'en':u'Robot: Changing template: %s',
- 'es':u'Robot: Cambiada la plantilla: %s',
- 'fa':u'ربات:تغییر الگو: %s',
- 'fi':u'Botti korvasi mallineen: %s',
- 'fr':u'Robot : Change modèle: %s',
- 'he':u'בוט: משנה תבנית: %s',
- 'hu':u'Robot: Sablon csere: %s',
- 'ia':u'Robot: Modification del template: %s',
- 'kk':u'Бот: Мына үлгі өзгертілді: %s',
- 'lt':u'robotas: Keičiamas šablonas: %s',
- 'nds':u'Bot: Vörlaag utwesselt: %s',
- 'ja':u'ロボットによるテンプレートの張り替え : %s',
- 'nl':u'Bot: vervangen sjabloon: %s',
- 'no':u'bot: Endrer mal: %s',
- 'pl':u'Robot zmienia szablon: %s',
- 'pt':u'Bot: Alterando predefinição: %s',
- 'ru':u'Робот: замена шаблона: %s',
- 'sr':u'Бот: Измена шаблона: %s',
- 'uk':u'Робот: заміна шаблону: %s',
- 'zh':u'機器人: 更改模板 %s',
- }
-
- #Needs more translations!
- msgs_change={
- 'ar':u'روبوت: تغيير القوالب: %s',
- 'da':u'Bot: Erstatter skabeloner: %s',
- 'de':u'Bot: Ändere Vorlagen: %s',
- 'en':u'Robot: Changing templates: %s',
- 'es':u'Robot: Cambiando las plantillas: %s',
- 'fa':u'ربات:تغییر الگوها: %s',
- 'fi':u'Botti korvasi mallineet: %s',
- 'fr':u'Robot : Modifie modèles %s',
- 'he':u'בוט: משנה תבניות: %s',
- 'kk':u'Бот: Мына үлгілер өзгертілді: %s',
- 'lt':u'robotas: Keičiami šablonai: %s',
- 'nds':u'Bot: Vörlagen utwesselt: %s',
- 'ja':u'ロボットによるテンプレートの張り替え : %s',
- 'nl':u'Bot: vervangen sjablonen: %s',
- 'no':u'bot: Endrer maler: %s',
- 'pl':u'Robot zmienia szablony: %s',
- 'pt':u'Bot: Alterando predefinição: %s',
- 'ru':u'Робот: замена шаблонов: %s',
- 'uk':u'Робот: заміна шаблонів: %s',
- 'zh':u'機器人: 更改模板 %s',
- }
-
- # Summary messages for removing templates
- msg_remove={
- 'ar':u'روبوت: إزالة القالب: %s',
- 'da':u'Bot: Fjerner skabelon: %s',
- 'de':u'Bot: Entferne Vorlage: %s',
- 'en':u'Robot: Removing template: %s',
- 'es':u'Robot: Retirando la plantilla: %s',
- 'fa':u'ربات:حذف الگو: %s',
- 'fi':u'Botti poisti mallineen: %s',
- 'fr':u'Robot : Enlève le modèle: %s',
- 'he':u'בוט: מסיר תבנית: %s',
- 'hu':u'Robot: Sablon eltávolítása: %s',
- 'kk':u'Бот: Мына үлгі аластатылды: %s',
- 'ia':u'Robot: Elimination del template: %s',
- 'lt':u'robotas: Šalinamas šablonas: %s',
- 'nds':u'Bot: Vörlaag rut: %s',
- 'ja':u'ロボットによるテンプレートの除去 : %s',
- 'nl':u'Bot: verwijderen sjabloon: %s',
- 'no':u'bot: Fjerner mal: %s',
- 'pl':u'Robot usuwa szablon: %s',
- 'pt':u'Bot: Removendo predefinição: %s',
- 'ru':u'Робот: удаление шаблона: %s',
- 'sr':u'Бот: Уклањање шаблона: %s',
- 'uk':u'Робот: видалення шаблону: %s',
- 'zh':u'機器人: 移除模板 %s',
- }
-
- #Needs more translations!
- msgs_remove={
- 'ar':u'روبوت: إزالة القوالب: %s',
- 'da':u'Bot: Fjerner skabeloner: %s',
- 'de':u'Bot: Entferne Vorlagen: %s',
- 'en':u'Robot: Removing templates: %s',
- 'es':u'Robot: Retirando las plantillas: %s',
- 'fa':u'ربات:حذف الگوها: %s',
- 'fi':u'Botti poisti mallineet: %s',
- 'he':u'בוט: מסיר תבניות: %s',
- 'fr':u'Robot : Enlève modèles : %s',
- 'kk':u'Бот: Мына үлгілер аластатылды: %s',
- 'lt':u'robotas: Šalinami šablonai: %s',
- 'nds':u'Bot: Vörlagen rut: %s',
- 'ja':u'ロボットによるテンプレートの除去 : %s',
- 'nl':u'Bot: verwijderen sjablonen: %s',
- 'no':u'bot: Fjerner maler: %s',
- 'pl':u'Robot usuwa szablony: %s',
- 'ru':u'Робот: удаление шаблонов: %s',
- 'pt':u'Bot: Removendo predefinição: %s',
- 'uk':u'Робот: видалення шаблонів: %s',
- 'zh':u'機器人: 移除模板 %s',
- }
-
- # Summary messages for substituting templates
- #Needs more translations!
- msg_subst={
- 'ar':u'روبوت: نسخ القالب: %s',
- 'da':u'Bot: Substituerer skabelon: %s',
- 'de':u'Bot: Umgehe Vorlage: %s',
- 'en':u'Robot: Substituting template: %s',
- 'es':u'Robot: Sustituyendo la plantilla: %s',
- 'fa':u'ربات: جایگزینی الگو: %s',
- 'fi':u'Botti substasi mallineen: %s',
- 'fr':u'Robot : Remplace modèle : %s',
- 'he':u'בוט: מכליל תבנית בקוד הדף: %s',
- 'kk':u'Бот: Мына үлгі бәделдірленді: %s',
- 'nds':u'Bot: Vörlaag in Text övernahmen: %s',
- 'ja':u'ロボットによるテンプレートの置換 : %s',
- 'nl':u'Bot: substitueren sjabloon: %s',
- 'no':u'bot: Erstatter mal: %s',
- 'pl':u'Robot podmienia szablon: %s',
- 'pt':u'Bot: Substituindo predefinição: %s',
- 'ru':u'Робот: подстановка шаблона: %s',
- 'uk':u'Робот: підстановка шаблону: %s',
- 'zh':u'機器人: 更換模板 %s',
- }
-
- #Needs more translations!
- msgs_subst={
- 'ar':u'روبوت: نسخ القوالب: %s',
- 'da':u'Bot: Substituerer skabeloner: %s',
- 'de':u'Bot: Umgehe Vorlagen: %s',
- 'en':u'Robot: Substituting templates: %s',
- 'es':u'Robot: Sustituyendo las plantillas: %s',
- 'fa':u'ربات: جایگزینی الگوها: %s',
- 'fi':u'Botti substasi mallineet: %s',
- 'fr':u'Robot : Remplace modèles : %s',
- 'he':u'בוט: מכליל תבניות בקוד הדף: %s',
- 'kk':u'Бот: Мына үлгілер бәделдірленді: %s',
- 'nds':u'Bot: Vörlagen in Text övernahmen: %s',
- 'ja':u'ロボットによるテンプレートの置換 : %s',
- 'nl':u'Bot: substitueren sjablonen: %s',
- 'no':u'bot: Erstatter maler: %s',
- 'pl':u'Robot podmienia szablony: %s',
- 'pt':u'Bot: Substituindo predefinição: %s',
- 'ru':u'Робот: подстановка шаблонов: %s',
- 'uk':u'Робот: підстановка шаблонів: %s',
- 'zh':u'機器人: 更換模板 %s',
- }
-
def __init__(self, generator, templates, subst = False, remove = False,
editSummary = '', acceptAll = False, addedCat = None):
"""
@@ -315,35 +208,24 @@
self.editSummary = editSummary
self.acceptAll = acceptAll
self.addedCat = addedCat
- s = pywikibot.Site()
+ site = pywikibot.Site()
if self.addedCat:
- self.addedCat = pywikibot.Category(s,
- s.namespace(14) + ':' + self.addedCat)
+ self.addedCat = pywikibot.Category(
+ site, u'%s:%s' % (site.namespace(14), self.addedCat))
# get edit summary message if it's empty
if (self.editSummary==''):
- oldTemplateNames = (', ').join(self.templates.keys())
+ Param = {'list': (', ').join(self.templates.keys()),
+ 'num' : len(self.templates)}
if self.remove:
- if len(self.templates) > 1:
- self.editSummary = pywikibot.translate(s, self.msgs_remove) \
- % oldTemplateNames
- else:
- self.editSummary = pywikibot.translate(s, self.msg_remove) \
- % oldTemplateNames
+ self.editSummary = i18n.twntranslate(
+ site, 'template-removing', Param)
elif self.subst:
- if len(self.templates) > 1:
- self.editSummary = pywikibot.translate(s, self.msgs_subst) \
- % oldTemplateNames
- else:
- self.editSummary = pywikibot.translate(s, self.msg_subst) \
- % oldTemplateNames
+ self.editSummary = i18n.twntranslate(
+ site, 'template-substituting', Param)
else:
- if len(self.templates) > 1:
- self.editSummary = pywikibot.translate(s, self.msgs_change) \
- % oldTemplateNames
- else:
- self.editSummary = pywikibot.translate(s, self.msg_change) \
- % oldTemplateNames
+ self.editSummary = i18n.twntranslate(
+ site, 'template-changing', Param)
def run(self):
"""
@@ -357,35 +239,36 @@
replacements = []
exceptions = {}
- s = pywikibot.Site()
-
+ site = pywikibot.getSite()
for old, new in self.templates.iteritems():
- if not s.nocapitalize:
- pattern = '[' + re.escape(old[0].upper()) \
- + re.escape(old[0].lower()) + ']' \
- + re.escape(old[1:])
+ namespaces = list(site.namespace(10, all=True))
+ if not site.nocapitalize:
+ pattern = '[' + \
+ re.escape(old[0].upper()) + \
+ re.escape(old[0].lower()) + \
+ ']' + re.escape(old[1:])
else:
pattern = re.escape(old)
pattern = re.sub(r'_|\\ ', r'[_ ]', pattern)
- templateRegex = re.compile(r'\{\{ *([Tt]emplate:|[mM][sS][gG]:)?'
- + pattern
- + r'(?P<parameters>\s*\|.+?|)
*}}',
+ templateRegex = re.compile(r'\{\{ *(' + ':|'.join(namespaces)
+ \
+ r':|[mM][sS][gG]:)?' + pattern + \
+ r'(?P<parameters>\s*\|.+?|) *}}',
re.DOTALL)
if self.remove:
replacements.append((templateRegex, ''))
elif self.subst:
replacements.append((templateRegex,
- '{{subst:' + old +
'\g<parameters>}}'))
- exceptions['inside-tags']=['ref']
+ '{{subst:%s\g<parameters>}}' % old))
+ exceptions['inside-tags']=['ref', 'gallery']
else:
replacements.append((templateRegex,
- '{{' + new +
'\g<parameters>}}'))
+ '{{%s\g<parameters>}}' % new))
replaceBot = replace.ReplaceRobot(self.generator, replacements,
- exceptions, acceptall=self.acceptAll,
- addedCat=self.addedCat,
- summary=self.editSummary)
+ exceptions, acceptall=self.acceptAll,
+ addedCat=self.addedCat,
+ editSummary=self.editSummary)
replaceBot.run()
def main(*args):
@@ -400,6 +283,9 @@
genFactory = pagegenerators.GeneratorFactory()
# If xmlfilename is None, references will be loaded from the live wiki.
xmlfilename = None
+ user = None
+ skip = False
+ timestamp = None
# read command line parameters
for arg in pywikibot.handleArgs(*args):
if arg == '-remove':
@@ -410,7 +296,8 @@
acceptAll = True
elif arg.startswith('-xml'):
if len(arg) == 4:
- xmlfilename = pywikibot.input(u'Please enter the XML dump\'s
filename: ')
+ xmlfilename = pywikibot.input(
+ u'Please enter the XML dump\'s filename: ')
else:
xmlfilename = arg[5:]
elif arg.startswith('-namespace:'):
@@ -422,11 +309,18 @@
addedCat = arg[len('-category:'):]
elif arg.startswith('-summary:'):
editSummary = arg[len('-summary:'):]
+ elif arg.startswith('-user:'):
+ user = arg[len('-user:'):]
+ elif arg.startswith('-skipuser:'):
+ user = arg[len('-skipuser:'):]
+ skip = True
+ elif arg.startswith('-timestamp:'):
+ timestamp = arg[len('-timestamp:'):]
else:
if not genFactory.handleArg(arg):
templateNames.append(
- pywikibot.Page(pywikibot.Site(), arg, ns=10
- ).title(withNamespace=False))
+ pywikibot.Page(pywikibot.Site(), arg,
+ ns=10).title(withNamespace=False))
if subst or remove:
for templateName in templateNames:
@@ -452,14 +346,15 @@
gen = genFactory.getCombinedGenerator()
if not gen:
gens = []
- gens = [pagegenerators.ReferringPageGenerator(t,
- onlyTemplateInclusion = True) for t in oldTemplates]
+ gens = [pagegenerators.ReferringPageGenerator(
+ t, onlyTemplateInclusion=True) for t in oldTemplates]
gen = pagegenerators.CombinedPageGenerator(gens)
gen = pagegenerators.DuplicateFilterPageGenerator(gen)
if namespaces:
gen = pagegenerators.NamespaceFilterPageGenerator(gen, namespaces)
-
+ if user:
+ gen = UserEditFilterGenerator(gen, user, timestamp, skip)
preloadingGen = pagegenerators.PreloadingGenerator(gen)
bot = TemplateRobot(preloadingGen, templates, subst, remove, editSummary,