def testMultipleNonNumbers(self): """Test error handling for multiple non-numbers.""" with self.assertRaisesRegex(ValueError, "invalid literal for int\(\) with base 10: 'drei'"): i18n.twntranslate('de', 'test-multiple-plurals', ["drei", "1", 1]) with self.assertRaisesRegex(ValueError, "invalid literal for int\(\) with base 10: 'elf'"): i18n.twntranslate('de', 'test-multiple-plurals', {'action': u'Ändere', 'line': "elf", 'page': 2})
def __init__(self, generator, templates, subst=False, remove=False, editSummary="", acceptAll=False, addedCat=None): """ Arguments: * generator - A page generator. * replacements - A dictionary which maps old template names to their replacements. If remove or subst is True, it maps the names of the templates that should be removed/resolved to None. * remove - True if the template should be removed. * subst - True if the template should be resolved. """ self.generator = generator self.templates = templates self.subst = subst self.remove = remove self.editSummary = editSummary self.acceptAll = acceptAll self.addedCat = addedCat site = pywikibot.getSite() if self.addedCat: self.addedCat = catlib.Category(site, u"%s:%s" % (site.namespace(14), self.addedCat)) comma = site.mediawiki_message("comma-separator") # get edit summary message if it's empty if not self.editSummary: Param = {"list": comma.join(self.templates.keys()), "num": len(self.templates)} if self.remove: self.editSummary = i18n.twntranslate(site, "template-removing", Param) elif self.subst: self.editSummary = i18n.twntranslate(site, "template-substituting", Param) else: self.editSummary = i18n.twntranslate(site, "template-changing", Param)
def __init__(self, generator, templates, **kwargs): """ Constructor. @param generator: the pages to work on @type generator: iterable @param templates: a dictionary which maps old template names to their replacements. If remove or subst is True, it maps the names of the templates that should be removed/resolved to None. @type templates: dict """ self.availableOptions.update({"subst": False, "remove": False, "summary": None, "addedCat": None}) super(TemplateRobot, self).__init__(**kwargs) self.generator = generator self.templates = templates site = pywikibot.Site() if self.getOption("addedCat"): self.options["addedCat"] = pywikibot.Category(site, self.getOption("addedCat")) comma = site.mediawiki_message("comma-separator") # get edit summary message if it's empty if not self.getOption("summary"): params = {"list": comma.join(self.templates.keys()), "num": len(self.templates)} if self.getOption("remove"): self.options["summary"] = i18n.twntranslate(site, "template-removing", params) elif self.getOption("subst"): self.options["summary"] = i18n.twntranslate(site, "template-substituting", params) else: self.options["summary"] = i18n.twntranslate(site, "template-changing", params)
def run(self): if not self.Page.Page.botMayEdit(Site.username): return whys = self.analyzePage() if self.archivedThreads < int(self.get('minthreadstoarchive',2)): # We might not want to archive a measly few threads # (lowers edit frequency) return if whys: #Save the archives first (so that bugs don't cause a loss of data) for a in sorted(self.archives.keys()): self.commentParams['count'] = self.archives[a].archivedThreads comment = i18n.twntranslate(language, 'archivebot-archive-summary', self.commentParams) self.archives[a].update(comment) #Save the page itself rx = re.compile('{{'+self.tpl+'\n.*?\n}}',re.DOTALL) self.Page.header = rx.sub(self.attr2text(),self.Page.header) self.commentParams['count'] = self.archivedThreads self.commentParams['archives'] \ = ', '.join(['[['+a.title+']]' for a in self.archives.values()]) if not self.commentParams['archives']: self.commentParams['archives'] = '/dev/null' self.commentParams['why'] = ', '.join(whys) comment = i18n.twntranslate(language, 'archivebot-page-summary', self.commentParams) self.Page.update(comment)
def run(self): if not self.Page.botMayEdit(Site.username): return whys = self.analyzePage() if self.archivedThreads < int(self.get("minthreadstoarchive", 2)): # We might not want to archive a measly few threads # (lowers edit frequency) pywikibot.output(u"There are only %d Threads. Skipping" % self.archivedThreads) return if whys: pywikibot.output(u"Archiving %d thread(s)." % self.archivedThreads) # Save the archives first (so that bugs don't cause a loss of data) for a in sorted(self.archives.keys()): self.commentParams["count"] = self.archives[a].archivedThreads comment = i18n.twntranslate(language, "archivebot-archive-summary", self.commentParams) self.archives[a].update(comment) # Save the page itself rx = re.compile("{{" + self.tpl + "\n.*?\n}}", re.DOTALL) self.Page.header = rx.sub(self.attr2text(), self.Page.header) self.commentParams["count"] = self.archivedThreads self.commentParams["archives"] = ", ".join(["[[" + a.title() + "]]" for a in self.archives.values()]) if not self.commentParams["archives"]: self.commentParams["archives"] = "/dev/null" self.commentParams["why"] = ", ".join(whys) comment = i18n.twntranslate(language, "archivebot-page-summary", self.commentParams) self.Page.update(comment)
def run(self): if not self.page.botMayEdit(): return whys = self.analyze_page() mintoarchive = int(self.get_attr('minthreadstoarchive', 2)) if self.archived_threads < mintoarchive: # We might not want to archive a measly few threads # (lowers edit frequency) pywikibot.output(u'Only %d (< %d) threads are old enough. Skipping' % (self.archived_threads, mintoarchive)) return if whys: pywikibot.output(u'Archiving %d thread(s).' % self.archived_threads) # Save the archives first (so that bugs don't cause a loss of data) for a in sorted(self.archives.keys()): self.comment_params['count'] = self.archives[a].archived_threads comment = i18n.twntranslate(self.site.code, 'archivebot-archive-summary', self.comment_params) self.archives[a].update(comment) # Save the page itself rx = re.compile('{{' + self.tpl + '\n.*?\n}}', re.DOTALL) self.page.header = rx.sub(self.attr2text(), self.page.header) self.comment_params['count'] = self.archived_threads self.comment_params['archives'] \ = ', '.join(['[[' + a.title() + ']]' for a in self.archives.values()]) if not self.comment_params['archives']: self.comment_params['archives'] = '/dev/null' self.comment_params['why'] = ', '.join(whys) comment = i18n.twntranslate(self.site.code, 'archivebot-page-summary', self.comment_params) self.page.update(comment)
def run(self): if not self.Page.botMayEdit(Site.username): return whys = self.analyzePage() if self.archivedThreads < int(self.get('minthreadstoarchive', 2)): # We might not want to archive a measly few threads # (lowers edit frequency) pywikibot.output(u'There are only %d Threads. Skipping' % self.archivedThreads) return if whys: pywikibot.output(u'Archiving %d thread(s).' % self.archivedThreads) # Save the archives first (so that bugs don't cause a loss of data) for a in sorted(self.archives.keys()): self.commentParams['count'] = self.archives[a].archivedThreads comment = i18n.twntranslate(language, 'archivebot-archive-summary', self.commentParams) self.archives[a].update(comment) # Save the page itself rx = re.compile('{{' + self.tpl + '\n.*?\n}}', re.DOTALL) self.Page.header = rx.sub(self.attr2text(), self.Page.header) self.commentParams['count'] = self.archivedThreads self.commentParams['archives'] \ = ', '.join(['[[' + a.title() + ']]' for a in self.archives.values()]) if not self.commentParams['archives']: self.commentParams['archives'] = '/dev/null' self.commentParams['why'] = ', '.join(whys) comment = i18n.twntranslate(language, 'archivebot-page-summary', self.commentParams) self.Page.update(comment)
def testMultipleWrongParameterLength(self): """Test wrong parameter length.""" err_msg = 'Length of parameter does not match PLURAL occurrences' with self.assertRaisesRegex(ValueError, err_msg): i18n.twntranslate('de', 'test-multiple-plurals', (1, 2)) with self.assertRaisesRegex(ValueError, err_msg): i18n.twntranslate('de', 'test-multiple-plurals', ["321"])
def testMultipleWrongParameterLength(self): """Test wrong parameter length.""" err_msg = 'Length of parameter does not match PLURAL occurrences' with self.assertRaisesRegex(ValueError, err_msg): i18n.twntranslate('de', 'test-multiple-plurals', (1, 2)) with self.assertRaisesRegex(ValueError, err_msg): i18n.twntranslate('de', 'test-multiple-plurals', ['321'])
def testMultiple(self): """Test using multiple plural entries.""" self.assertEqual( i18n.twntranslate('de', 'test-multiple-plurals', 1) % { 'action': u'Ändere', 'line': u'eine' }, u'Bot: Ändere eine Zeile von einer Seite.') self.assertEqual( i18n.twntranslate('de', 'test-multiple-plurals', 2) % { 'action': u'Ändere', 'line': u'zwei' }, u'Bot: Ändere zwei Zeilen von mehreren Seiten.') self.assertEqual( i18n.twntranslate('de', 'test-multiple-plurals', 3) % { 'action': u'Ändere', 'line': u'drei' }, u'Bot: Ändere drei Zeilen von mehreren Seiten.') self.assertEqual( i18n.twntranslate('de', 'test-multiple-plurals', (1, 2, 2)) % { 'action': u'Ändere', 'line': u'eine' }, u'Bot: Ändere eine Zeile von mehreren Seiten.') self.assertEqual( i18n.twntranslate('de', 'test-multiple-plurals', [3, 1, 1]) % { 'action': u'Ändere', 'line': u'drei' }, u'Bot: Ändere drei Zeilen von einer Seite.') self.assertEqual( i18n.twntranslate('de', 'test-multiple-plurals', ["3", 1, 1]) % { 'action': u'Ändere', 'line': u'drei' }, u'Bot: Ändere drei Zeilen von einer Seite.') self.assertEqual( i18n.twntranslate('de', 'test-multiple-plurals', "321") % { 'action': u'Ändere', 'line': u'dreihunderteinundzwanzig' }, u'Bot: Ändere dreihunderteinundzwanzig Zeilen von mehreren Seiten.' ) self.assertEqual( i18n.twntranslate('de', 'test-multiple-plurals', { 'action': u'Ändere', 'line': 1, 'page': 1 }), u'Bot: Ändere 1 Zeile von einer Seite.') self.assertEqual( i18n.twntranslate('de', 'test-multiple-plurals', { 'action': u'Ändere', 'line': 1, 'page': 2 }), u'Bot: Ändere 1 Zeile von mehreren Seiten.') self.assertEqual( i18n.twntranslate('de', 'test-multiple-plurals', { 'action': u'Ändere', 'line': "11", 'page': 2 }), u'Bot: Ändere 11 Zeilen von mehreren Seiten.')
def testAllParametersExist(self): """Test that all parameters are required when using a dict.""" with self.assertRaisesRegex(KeyError, repr(u'line')): # all parameters must be inside twntranslate i18n.twntranslate('de', 'test-multiple-plurals', { 'line': 1, 'page': 1 }) % { 'action': u'Ändere' }
def testMultipleNonNumbers(self): """Test error handling for multiple non-numbers.""" with self.assertRaisesRegex(ValueError, "invalid literal for int\(\) with base 10: 'drei'"): self.assertEqual( i18n.twntranslate('de', 'test-multiple-plurals', ["drei", "1", 1]) % {'action': u'Ändere', 'line': u'drei'}, u'Bot: Ändere drei Zeilen von einer Seite.') with self.assertRaisesRegex(ValueError, "invalid literal for int\(\) with base 10: 'elf'"): self.assertEqual( i18n.twntranslate('de', 'test-multiple-plurals', {'action': u'Ändere', 'line': "elf", 'page': 2}), u'Bot: Ändere elf Zeilen von mehreren Seiten.')
def testMultipleWrongParameterLength(self): """Test wrong parameter length.""" with self.assertRaisesRegex(ValueError, "Length of parameter does not match PLURAL occurrences"): self.assertEqual( i18n.twntranslate('de', 'test-multiple-plurals', (1, 2)) % {'action': u'Ändere', 'line': u'drei'}, u'Bot: Ändere drei Zeilen von mehreren Seiten.') with self.assertRaisesRegex(ValueError, "Length of parameter does not match PLURAL occurrences"): self.assertEqual( i18n.twntranslate('de', 'test-multiple-plurals', ["321"]) % {'action': u'Ändere', 'line': u'dreihunderteinundzwanzig'}, u'Bot: Ändere dreihunderteinundzwanzig Zeilen von mehreren Seiten.')
def testNumber(self): """Use a number.""" self.assertEqual( i18n.twntranslate('de', 'test-plural', 0) % {'num': 0}, u'Bot: Ändere 0 Seiten.') self.assertEqual( i18n.twntranslate('de', 'test-plural', 1) % {'num': 1}, u'Bot: Ändere 1 Seite.') self.assertEqual( i18n.twntranslate('de', 'test-plural', 2) % {'num': 2}, u'Bot: Ändere 2 Seiten.') self.assertEqual( i18n.twntranslate('de', 'test-plural', 3) % {'num': 3}, u'Bot: Ändere 3 Seiten.') self.assertEqual( i18n.twntranslate('en', 'test-plural', 0) % {'num': 'no'}, u'Bot: Changing no pages.') self.assertEqual( i18n.twntranslate('en', 'test-plural', 1) % {'num': 'one'}, u'Bot: Changing one page.') self.assertEqual( i18n.twntranslate('en', 'test-plural', 2) % {'num': 'two'}, u'Bot: Changing two pages.') self.assertEqual( i18n.twntranslate('en', 'test-plural', 3) % {'num': 'three'}, u'Bot: Changing three pages.')
def __init__(self, generator, templates, subst=False, remove=False, editSummary='', acceptAll=False, addedCat=None): """ Arguments: * generator - A page generator. * replacements - A dictionary which maps old template names to their replacements. If remove or subst is True, it maps the names of the templates that should be removed/resolved to None. * remove - True if the template should be removed. * subst - True if the template should be resolved. """ self.generator = generator self.templates = templates self.subst = subst self.remove = remove self.editSummary = editSummary self.acceptAll = acceptAll self.addedCat = addedCat site = pywikibot.Site() if self.addedCat: self.addedCat = pywikibot.Category( site, u'%s:%s' % (site.namespace(14), self.addedCat)) comma = site.mediawiki_message('comma-separator') # get edit summary message if it's empty if not self.editSummary: Param = { 'list': comma.join(self.templates.keys()), 'num': len(self.templates) } if self.remove: self.editSummary = i18n.twntranslate(site, 'template-removing', Param) elif self.subst: self.editSummary = i18n.twntranslate(site, 'template-substituting', Param) else: self.editSummary = i18n.twntranslate(site, 'template-changing', Param)
def run(self): listOfArticles = self.cat.articlesList(recurse=self.recurse) if self.subCats: listOfArticles += self.cat.subcategoriesList() if not self.editSummary: self.editSummary = i18n.twntranslate( self.site, 'category-listifying', { 'fromcat': self.cat.title(), 'num': len(listOfArticles) }) listString = "" for article in listOfArticles: if (not article.isImage() or self.showImages) and not article.isCategory(): if self.talkPages and not article.isTalkPage(): listString += "*[[%s]] -- [[%s|talk]]\n" \ % (article.title(), article.toggleTalkPage().title()) else: listString += "*[[%s]]\n" % article.title() else: if self.talkPages and not article.isTalkPage(): listString += "*[[:%s]] -- [[%s|talk]]\n" \ % (article.title(), article.toggleTalkPage().title()) else: listString += "*[[:%s]]\n" % article.title() if self.list.exists() and not self.overwrite: pywikibot.output(u'Page %s already exists, aborting.' % self.list.title()) else: self.list.put(listString, comment=self.editSummary)
def __init__(self, djvu, index, pages=None, **kwargs): """ Constructor. @param djvu: djvu from where to fetch the text layer @type djvu: DjVuFile object @param index: index page in the Index: namespace @type index: Page object @param pages: page interval to upload (start, end) @type pages: tuple """ self.availableOptions.update({'force': False, 'summary': None}) super(DjVuTextBot, self).__init__(site=index.site, **kwargs) self._djvu = djvu self._index = index self._prefix = self._index.title(withNamespace=False) if not pages: self._pages = (1, self._djvu.number_of_images()) else: self._pages = pages self.generator = self.gen() # Get edit summary message if it's empty. if not self.getOption('summary'): self.options['summary'] = i18n.twntranslate( self._index.site, 'djvutext-creating')
def run(self): """Start bot.""" setOfArticles = set(self.cat.articles(recurse=self.recurse)) if self.subCats: setOfArticles = setOfArticles.union(set(self.cat.subcategories())) if not self.editSummary: self.editSummary = i18n.twntranslate( self.site, "category-listifying", {"fromcat": self.cat.title(), "num": len(setOfArticles)} ) listString = "" for article in setOfArticles: if (not article.isImage() or self.showImages) and not article.isCategory(): if self.talkPages and not article.isTalkPage(): listString += "*[[%s]] -- [[%s|talk]]\n" % (article.title(), article.toggleTalkPage().title()) else: listString += "*[[%s]]\n" % article.title() else: if self.talkPages and not article.isTalkPage(): listString += "*[[:%s]] -- [[%s|talk]]\n" % (article.title(), article.toggleTalkPage().title()) else: listString += "*[[:%s]]\n" % article.title() if self.list.exists() and not self.overwrite: pywikibot.output("Page %s already exists, aborting." % self.list.title()) else: self.list.put(listString, summary=self.editSummary)
def __init__(self, djvu, index, pages=None, **kwargs): """ Constructor. @param djvu: djvu from where to fetch the text layer @type djvu: DjVuFile object @param index: index page in the Index: namespace @type index: Page object @param pages: page interval to upload (start, end) @type pages: tuple """ self.availableOptions.update({ 'force': False, 'summary': None }) super(DjVuTextBot, self).__init__(site=index.site, **kwargs) self._djvu = djvu self._index = index self._prefix = self._index.title(withNamespace=False) if not pages: self._pages = (1, self._djvu.number_of_images()) else: self._pages = pages self.generator = self.gen() # Get edit summary message if it's empty. if not self.getOption('summary'): self.options['summary'] = i18n.twntranslate( self._index.site, 'djvutext-creating')
def run(self): listOfArticles = self.cat.articlesList(recurse=self.recurse) if self.subCats: listOfArticles += self.cat.subcategoriesList() if not self.editSummary: self.editSummary = i18n.twntranslate( self.site, 'category-listifying', { 'fromcat': self.cat.title(), 'num': len(listOfArticles) }) listString = "" for article in listOfArticles: if (not article.isImage() or self.showImages) and not article.isCategory(): if self.talkPages and not article.isTalkPage(): listString = listString + article.title() + '\n' else: listString = listString + article.title() + '\n' else: if self.talkPages and not article.isTalkPage(): listString = listString + article.title() + '\n' else: listString = listString + article.title() + '\n' if self.list.exists() and not self.overwrite: return listString else: return listString
def run(self): listOfArticles = self.cat.articlesList(recurse = self.recurse) if self.subCats: listOfArticles += self.cat.subcategoriesList() if not self.editSummary: self.editSummary = i18n.twntranslate(self.site, 'category-listifying', {'fromcat': self.cat.title(), 'num': len(listOfArticles)}) listString = "" for article in listOfArticles: if (not article.isImage() or self.showImages) and not article.isCategory(): if self.talkPages and not article.isTalkPage(): listString = listString + article.title() +'\n' else: listString = listString + article.title()+'\n' else: if self.talkPages and not article.isTalkPage(): listString = listString + article.title()+'\n' else: listString = listString + article.title()+'\n' if self.list.exists() and not self.overwrite: return listString else: return listString
def run(self): listOfArticles = self.cat.articlesList(recurse=self.recurse) if self.subCats: listOfArticles += self.cat.subcategoriesList() if not self.editSummary: self.editSummary = i18n.twntranslate(self.site, 'category-listifying', {'fromcat': self.cat.title(), 'num': len(listOfArticles)}) listString = "" for article in listOfArticles: if (not article.isImage() or self.showImages) and not article.isCategory(): if self.talkPages and not article.isTalkPage(): listString += "*[[%s]] -- [[%s|talk]]\n" \ % (article.title(), article.toggleTalkPage().title()) else: listString += "*[[%s]]\n" % article.title() else: if self.talkPages and not article.isTalkPage(): listString += "*[[:%s]] -- [[%s|talk]]\n" \ % (article.title(), article.toggleTalkPage().title()) else: listString += "*[[:%s]]\n" % article.title() if self.list.exists() and not self.overwrite: pywikibot.output(u'Page %s already exists, aborting.' % self.list.title()) else: self.list.put(listString, comment=self.editSummary)
def testExtended(self): """Use additional format strings.""" self.assertEqual( i18n.twntranslate('fr', 'test-plural', { 'num': 1, 'descr': 'seulement' }), 'Robot: Changer seulement une page.')
def testAllParametersExist(self): with self.assertRaisesRegex(KeyError, repr(u'line')): # all parameters must be inside twntranslate self.assertEqual( i18n.twntranslate('de', 'test-multiple-plurals', {'line': 1, 'page': 1}) % {'action': u'Ändere'}, u'Bot: Ändere 1 Zeile von einer Seite.')
def testAllParametersExist(self): """Test that all parameters are required when using a dict.""" # all parameters must be inside twntranslate self.assertEqual( i18n.twntranslate('de', 'test-multiple-plurals', { 'line': 1, 'page': 1 }), 'Bot: %(action)s %(line)s Zeile von einer Seite.')
def run(self): if not self.page.botMayEdit(): return whys = self.analyze_page() mintoarchive = int(self.get_attr('minthreadstoarchive', 2)) if self.archived_threads < mintoarchive: # We might not want to archive a measly few threads # (lowers edit frequency) pywikibot.output( u'Only %d (< %d) threads are old enough. Skipping' % (self.archived_threads, mintoarchive)) return if whys: # Search for the marker template rx = re.compile( r'\{\{%s\s*?\n.*?\n\}\}' % (template_title_regex(self.tpl).pattern), re.DOTALL) if not rx.search(self.page.header): raise MalformedConfigError( "Couldn't find the template in the header") pywikibot.output(u'Archiving %d thread(s).' % self.archived_threads) # Save the archives first (so that bugs don't cause a loss of data) for a in sorted(self.archives.keys()): self.comment_params['count'] = self.archives[ a].archived_threads comment = i18n.twntranslate(self.site.code, 'archivebot-archive-summary', self.comment_params) self.archives[a].update(comment) # Save the page itself self.page.header = rx.sub(self.attr2text(), self.page.header) self.comment_params['count'] = self.archived_threads comma = self.site.mediawiki_message('comma-separator') self.comment_params['archives'] \ = comma.join(a.title(asLink=True) for a in self.archives.values()) self.comment_params['why'] = comma.join(whys) comment = i18n.twntranslate(self.site.code, 'archivebot-page-summary', self.comment_params) self.page.update(comment)
def test_fallback_lang(self): """ Test that twntranslate uses the translation's language. twntranslate calls _twtranslate which might return the translation for a different language and then the plural rules from that language need to be applied. """ # co has fr as altlang but has no plural rules defined (otherwise this # test might not catch problems) so it's using the plural variant for 0 # although French uses the plural variant for numbers > 1 (so not 0) assert('co' not in plural.plural_rules) assert(plural.plural_rules['fr']['plural'](0) is False) self.assertEqual( i18n.twntranslate('co', 'test-plural', {'num': 0, 'descr': 'seulement'}), u'Robot: Changer seulement une page.') self.assertEqual( i18n.twntranslate('co', 'test-plural', {'num': 1, 'descr': 'seulement'}), u'Robot: Changer seulement une page.')
def __init__(self, generator, templates, **kwargs): """ Constructor. @param generator: the pages to work on @type generator: iterable @param templates: a dictionary which maps old template names to their replacements. If remove or subst is True, it maps the names of the templates that should be removed/resolved to None. @type templates: dict """ self.availableOptions.update({ 'subst': False, 'remove': False, 'summary': None, 'addedCat': None, }) super(TemplateRobot, self).__init__(**kwargs) self.generator = generator self.templates = templates site = pywikibot.Site() if self.getOption('addedCat'): self.options['addedCat'] = pywikibot.Category( site, self.getOption('addedCat')) comma = site.mediawiki_message('comma-separator') # get edit summary message if it's empty if not self.getOption('summary'): params = { 'list': comma.join(self.templates.keys()), 'num': len(self.templates) } if self.getOption('remove'): self.options['summary'] = i18n.twntranslate( site, 'template-removing', params) elif self.getOption('subst'): self.options['summary'] = i18n.twntranslate( site, 'template-substituting', params) else: self.options['summary'] = i18n.twntranslate( site, 'template-changing', params)
def testMultiple(self): """Test using multiple plural entries.""" self.assertEqual( i18n.twntranslate('de', 'test-multiple-plurals', 1) % {'action': u'Ändere', 'line': u'eine'}, u'Bot: Ändere eine Zeile von einer Seite.') self.assertEqual( i18n.twntranslate('de', 'test-multiple-plurals', 2) % {'action': u'Ändere', 'line': u'zwei'}, u'Bot: Ändere zwei Zeilen von mehreren Seiten.') self.assertEqual( i18n.twntranslate('de', 'test-multiple-plurals', 3) % {'action': u'Ändere', 'line': u'drei'}, u'Bot: Ändere drei Zeilen von mehreren Seiten.') self.assertEqual( i18n.twntranslate('de', 'test-multiple-plurals', (1, 2, 2)) % {'action': u'Ändere', 'line': u'eine'}, u'Bot: Ändere eine Zeile von mehreren Seiten.') self.assertEqual( i18n.twntranslate('de', 'test-multiple-plurals', [3, 1, 1]) % {'action': u'Ändere', 'line': u'drei'}, u'Bot: Ändere drei Zeilen von einer Seite.') self.assertEqual( i18n.twntranslate('de', 'test-multiple-plurals', ["3", 1, 1]) % {'action': u'Ändere', 'line': u'drei'}, u'Bot: Ändere drei Zeilen von einer Seite.') self.assertEqual( i18n.twntranslate('de', 'test-multiple-plurals', "321") % {'action': u'Ändere', 'line': u'dreihunderteinundzwanzig'}, u'Bot: Ändere dreihunderteinundzwanzig Zeilen von mehreren Seiten.') self.assertEqual( i18n.twntranslate('de', 'test-multiple-plurals', {'action': u'Ändere', 'line': 1, 'page': 1}), u'Bot: Ändere 1 Zeile von einer Seite.') self.assertEqual( i18n.twntranslate('de', 'test-multiple-plurals', {'action': u'Ändere', 'line': 1, 'page': 2}), u'Bot: Ändere 1 Zeile von mehreren Seiten.') self.assertEqual( i18n.twntranslate('de', 'test-multiple-plurals', {'action': u'Ändere', 'line': "11", 'page': 2}), u'Bot: Ändere 11 Zeilen von mehreren Seiten.')
def run(self): if not self.page.botMayEdit(): return whys = self.analyze_page() mintoarchive = int(self.get_attr('minthreadstoarchive', 2)) if self.archived_threads < mintoarchive: # We might not want to archive a measly few threads # (lowers edit frequency) pywikibot.output(u'Only %d (< %d) threads are old enough. Skipping' % (self.archived_threads, mintoarchive)) return if whys: # Search for the marker template rx = re.compile(r'\{\{%s\s*?\n.*?\n\}\}' % (template_title_regex(self.tpl).pattern), re.DOTALL) if not rx.search(self.page.header): raise MalformedConfigError( "Couldn't find the template in the header" ) pywikibot.output(u'Archiving %d thread(s).' % self.archived_threads) # Save the archives first (so that bugs don't cause a loss of data) for a in sorted(self.archives.keys()): self.comment_params['count'] = self.archives[a].archived_threads comment = i18n.twntranslate(self.site.code, 'archivebot-archive-summary', self.comment_params) self.archives[a].update(comment) # Save the page itself self.page.header = rx.sub(self.attr2text(), self.page.header) self.comment_params['count'] = self.archived_threads comma = self.site.mediawiki_message('comma-separator') self.comment_params['archives'] \ = comma.join(a.title(asLink=True) for a in self.archives.values()) self.comment_params['why'] = comma.join(whys) comment = i18n.twntranslate(self.site.code, 'archivebot-page-summary', self.comment_params) self.page.update(comment)
def __init__(self, generator, templates, **kwargs): """ Constructor. @param generator: the pages to work on @type generator: iterable @param replacements: a dictionary which maps old template names to their replacements. If remove or subst is True, it maps the names of the templates that should be removed/resolved to None. @type replacements: dict """ self.availableOptions.update({ 'subst': False, 'remove': False, 'summary': None, 'addedCat': None, }) super(TemplateRobot, self).__init__(**kwargs) self.generator = generator self.templates = templates site = pywikibot.Site() if self.getOption('addedCat'): self.options['addedCat'] = pywikibot.Category(site, self.getOption('addedCat')) comma = site.mediawiki_message('comma-separator') # get edit summary message if it's empty if not self.getOption('summary'): params = {'list': comma.join(self.templates.keys()), 'num': len(self.templates)} if self.getOption('remove'): self.options['summary'] = i18n.twntranslate( site, 'template-removing', params) elif self.getOption('subst'): self.options['summary'] = i18n.twntranslate( site, 'template-substituting', params) else: self.options['summary'] = i18n.twntranslate( site, 'template-changing', params)
def treat(self, page): """ Load a page, convert all HTML tables in its text to wiki syntax, and save the result. Returns True if the converted table was successfully saved, otherwise returns False. """ pywikibot.output(u'\n>>> %s <<<' % page.title()) site = page.site try: text = page.get() except pywikibot.NoPage: pywikibot.error(u"couldn't find %s" % page.title()) return False except pywikibot.IsRedirectPage: pywikibot.output(u'Skipping redirect %s' % page.title()) return False newText, convertedTables, warningSum = self.convertAllHTMLTables(text) # Check if there are any marked tags left markedTableTagR = re.compile("<##table##|</##table##>", re.IGNORECASE) if markedTableTagR.search(newText): pywikibot.error( u'not all marked table start or end tags processed!') return if convertedTables == 0: pywikibot.output(u"No changes were necessary.") else: if config.table2wikiAskOnlyWarnings and warningSum == 0: doUpload = True else: if config.table2wikiSkipWarnings: doUpload = True else: pywikibot.output( "There were %i replacement(s) that might lead to bad " "output." % warningSum) doUpload = (pywikibot.input( u'Do you want to change the page anyway? [y|N]') == "y" ) if doUpload: # get edit summary message if warningSum == 0: editSummaryMessage = i18n.twtranslate( site.code, 'table2wiki-no-warning') else: editSummaryMessage = i18n.twntranslate( site.code, 'table2wiki-warnings', {'count': warningSum}) page.put_async(newText, summary=editSummaryMessage)
def __init__(self, generator, templates, subst = False, remove = False, editSummary = '', acceptAll = False, addedCat = None): """ Arguments: * generator - A page generator. * replacements - A dictionary which maps old template names to their replacements. If remove or subst is True, it maps the names of the templates that should be removed/resolved to None. * remove - True if the template should be removed. * subst - True if the template should be resolved. """ self.generator = generator self.templates = templates self.subst = subst self.remove = remove self.editSummary = editSummary self.acceptAll = acceptAll self.addedCat = addedCat site = pywikibot.Site() if 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==''): Param = {'list': (', ').join(self.templates.keys()), 'num' : len(self.templates)} if self.remove: self.editSummary = i18n.twntranslate( site, 'template-removing', Param) elif self.subst: self.editSummary = i18n.twntranslate( site, 'template-substituting', Param) else: self.editSummary = i18n.twntranslate( site, 'template-changing', Param)
def treat(self, page): """ Load a page, convert all HTML tables in its text to wiki syntax, and save the result. Returns True if the converted table was successfully saved, otherwise returns False. """ pywikibot.output(u'\n>>> %s <<<' % page.title()) site = page.site try: text = page.get() except pywikibot.NoPage: pywikibot.error(u"couldn't find %s" % page.title()) return False except pywikibot.IsRedirectPage: pywikibot.output(u'Skipping redirect %s' % page.title()) return False newText, convertedTables, warningSum = self.convertAllHTMLTables(text) # Check if there are any marked tags left markedTableTagR = re.compile("<##table##|</##table##>", re.IGNORECASE) if markedTableTagR.search(newText): pywikibot.error( u'not all marked table start or end tags processed!') return if convertedTables == 0: pywikibot.output(u"No changes were necessary.") else: if config.table2wikiAskOnlyWarnings and warningSum == 0: doUpload = True else: if config.table2wikiSkipWarnings: doUpload = True else: pywikibot.output("There were %i replacement(s) that might lead to bad " "output." % warningSum) doUpload = (pywikibot.input( u'Do you want to change the page anyway? [y|N]') == "y") if doUpload: # get edit summary message if warningSum == 0: editSummaryMessage = i18n.twtranslate(site.code, 'table2wiki-no-warning') else: editSummaryMessage = i18n.twntranslate( site.code, 'table2wiki-warnings', {'count': warningSum} ) page.put_async(newText, summary=editSummaryMessage)
def __init__(self, generator, templates, subst = False, remove = False, editSummary = '', acceptAll = False, addedCat = None): """ Arguments: * generator - A page generator. * replacements - A dictionary which maps old template names to their replacements. If remove or subst is True, it maps the names of the templates that should be removed/resolved to None. * remove - True if the template should be removed. * subst - True if the template should be resolved. """ self.generator = generator self.templates = templates self.subst = subst self.remove = remove self.editSummary = editSummary self.acceptAll = acceptAll self.addedCat = addedCat if self.addedCat: self.addedCat = catlib.Category(pywikibot.getSite(), 'Category:' + self.addedCat) # get edit summary message if it's empty if (self.editSummary==''): Param = {'list': (', ').join(self.templates.keys()), 'num' : len(self.templates)} mysite = pywikibot.getSite() if self.remove: self.editSummary = i18n.twntranslate( mysite, 'template-removing', Param) elif self.subst: self.editSummary = i18n.twntranslate( mysite, 'template-substituting', Param) else: self.editSummary = i18n.twntranslate( mysite, 'template-changing', Param)
def treat_page(self): """Convert all HTML tables in text to wiki syntax and save it.""" text = self.current_page.text newText, convertedTables, warnings = self.convertAllHTMLTables(text) # Check if there are any marked tags left markedTableTagR = re.compile("<##table##|</##table##>", re.IGNORECASE) if markedTableTagR.search(newText): pywikibot.error( u'not all marked table start or end tags processed!') return if convertedTables == 0: pywikibot.output(u"No changes were necessary.") return if warnings: if self.getOption('always') and self.getOption('skipwarning'): pywikibot.output( 'There were %i replacements that might lead to bad ' 'output. Skipping.' % warnings) return if not self.getOption('always'): pywikibot.output( 'There were %i replacements that might lead to bad ' 'output.' % warnings) if not input_yn('Do you want to change the page anyway'): return # get edit summary message if warnings == 0: editSummaryMessage = i18n.twtranslate( self.site.code, 'table2wiki-no-warning') else: editSummaryMessage = i18n.twntranslate( self.site.code, 'table2wiki-warnings', {'count': warnings} ) self.put_current(newText, summary=editSummaryMessage, show_diff=not (self.getOption('quiet') and self.getOption('always')))
def treat(self, page): """ Loads a page, converts all HTML tables in its text to wiki syntax, and saves the converted text. Returns True if the converted table was successfully saved, otherwise returns False. """ pywikibot.output(u"\n>>> %s <<<" % page.title()) site = page.site() try: text = page.get() except pywikibot.NoPage: pywikibot.output(u"ERROR: couldn't find %s" % page.title()) return False except pywikibot.IsRedirectPage: pywikibot.output(u"Skipping redirect %s" % page.title()) return False newText, convertedTables, warningSum = self.convertAllHTMLTables(text) # Check if there are any marked tags left markedTableTagR = re.compile("<##table##|</##table##>", re.IGNORECASE) if markedTableTagR.search(newText): pywikibot.output(u"ERROR: not all marked table start or end tags processed!") return if convertedTables == 0: pywikibot.output(u"No changes were necessary.") else: if config.table2wikiAskOnlyWarnings and warningSum == 0: doUpload = True else: if config.table2wikiSkipWarnings: doUpload = True else: print "There were %i replacement(s) that might lead to bad output." % warningSum doUpload = pywikibot.input(u"Do you want to change the page anyway? [y|N]") == "y" if doUpload: # get edit summary message if warningSum == 0: pywikibot.setAction(i18n.twtranslate(site.lang, "table2wiki-no-warning")) else: pywikibot.setAction(i18n.twntranslate(site.lang, "table2wiki-warnings", {"count": warningSum})) page.put_async(newText)
def treat_page(self): """Convert all HTML tables in text to wiki syntax and save it.""" text = self.current_page.text new_text, converted_tables, warnings = self.convertAllHTMLTables(text) # Check if there are any marked tags left if re.search('<##table##|</##table##>', new_text, re.IGNORECASE): pywikibot.error( 'not all marked table start or end tags processed!') return if converted_tables == 0: pywikibot.output('No changes were necessary.') return if warnings: if self.opt.always and self.opt.skipwarning: pywikibot.output( 'There were {} replacements that might lead to bad ' 'output. Skipping.'.format(warnings)) return if not self.opt.always: pywikibot.output( 'There were {} replacements that might lead to bad ' 'output.'.format(warnings)) if not input_yn('Do you want to change the page anyway'): return # get edit summary message if warnings == 0: edit_summary = i18n.twtranslate( self.site.code, 'table2wiki-no-warning') else: edit_summary = i18n.twntranslate( self.site.code, 'table2wiki-warnings', {'count': warnings} ) self.put_current(new_text, summary=edit_summary, show_diff=not (self.opt.quiet and self.opt.always))
def test_basic(self): """Verify that real messages are able to be loaded.""" self.assertEqual(i18n.twntranslate('en', 'pywikibot-enter-new-text'), 'Please enter the new text:')
def __init__(self, generator, templates, **kwargs): """ Constructor. @param generator: the pages to work on @type generator: iterable @param templates: a dictionary which maps old template names to their replacements. If remove or subst is True, it maps the names of the templates that should be removed/resolved to None. @type templates: dict """ self.availableOptions.update({ 'subst': False, 'remove': False, 'summary': None, 'addedCat': None, }) Bot.__init__(self, generator=generator, **kwargs) self.templates = templates # 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) elif self.getOption('subst'): self.options['summary'] = i18n.twntranslate( site, 'template-substituting', params) else: self.options['summary'] = i18n.twntranslate( site, 'template-changing', params) # regular expression to find the original template. # {{vfd}} does the same thing as {{Vfd}}, so both will be found. # The old syntax, {{msg:vfd}}, will also be found. # The group 'parameters' will either match the parameters, or an # empty string if there are none. replacements = [] exceptions = {} namespace = self.site.namespaces[10] for old, new in self.templates.items(): if namespace.case == 'first-letter': 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'\{\{ *(' + ':|'.join(namespace) + r':|[mM][sS][gG]:)?' + pattern + r'(?P<parameters>\s*\|.+?|) *}}', re.DOTALL) if self.getOption('subst') and self.getOption('remove'): replacements.append( (templateRegex, r'{{subst:%s\g<parameters>}}' % new)) exceptions['inside-tags'] = ['ref', 'gallery'] elif self.getOption('subst'): replacements.append( (templateRegex, r'{{subst:%s\g<parameters>}}' % old)) exceptions['inside-tags'] = ['ref', 'gallery'] elif self.getOption('remove'): replacements.append((templateRegex, '')) else: template = pywikibot.Page(self.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?', default=False, automatic_quit=False): continue 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'))
def testExtendedOutside(self): """Use additional format strings also outside.""" self.assertEqual( i18n.twntranslate('fr', 'test-plural', 1) % {'descr': 'seulement'}, u'Robot: Changer seulement une page.')
def testExtended(self): """Use additional format strings.""" self.assertEqual( i18n.twntranslate('fr', 'test-plural', {'num': 1, 'descr': 'seulement'}), u'Robot: Changer seulement une page.')
def testDict(self): """Use a dictionary.""" self.assertEqual( i18n.twntranslate('en', 'test-plural', {'num': 2}), u'Bot: Changing 2 pages.')
def testString(self): """Use a string.""" self.assertEqual( i18n.twntranslate('en', 'test-plural', '1') % {'num': 'one'}, u'Bot: Changing one page.')
def test_missing(self): """Test a missing message from a real message bundle.""" with self.assertRaises(i18n.TranslationError): i18n.twntranslate('en', 'pywikibot-missing-key')
def testAllParametersExist(self): """Test that all parameters are required when using a dict.""" # all parameters must be inside twntranslate self.assertEqual(i18n.twntranslate('de', 'test-multiple-plurals', {'line': 1, 'page': 1}), 'Bot: %(action)s %(line)s Zeile von einer Seite.')
def __init__(self, generator, templates, **kwargs): """ Constructor. @param generator: the pages to work on @type generator: iterable @param templates: a dictionary which maps old template names to their replacements. If remove or subst is True, it maps the names of the templates that should be removed/resolved to None. @type templates: dict """ self.availableOptions.update({ 'subst': False, 'remove': False, 'summary': None, 'addedCat': None, }) Bot.__init__(self, generator=generator, **kwargs) self.templates = templates # 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) elif self.getOption('subst'): self.options['summary'] = i18n.twntranslate( site, 'template-substituting', params) else: self.options['summary'] = i18n.twntranslate( site, 'template-changing', params) # regular expression to find the original template. # {{vfd}} does the same thing as {{Vfd}}, so both will be found. # The old syntax, {{msg:vfd}}, will also be found. # The group 'parameters' will either match the parameters, or an # empty string if there are none. replacements = [] exceptions = {} namespace = self.site.namespaces[10] for old, new in self.templates.items(): if namespace.case == 'first-letter': 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'\{\{ *(' + ':|'.join(namespace) + r':|[mM][sS][gG]:)?' + pattern + r'(?P<parameters>\s*\|.+?|) *}}', re.DOTALL) if self.getOption('subst') and self.getOption('remove'): replacements.append((templateRegex, r'{{subst:%s\g<parameters>}}' % new)) exceptions['inside-tags'] = ['ref', 'gallery'] elif self.getOption('subst'): replacements.append((templateRegex, r'{{subst:%s\g<parameters>}}' % old)) exceptions['inside-tags'] = ['ref', 'gallery'] elif self.getOption('remove'): replacements.append((templateRegex, '')) else: template = pywikibot.Page(self.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?', default=False, automatic_quit=False): continue 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'))