# -*- coding: utf-8 -*- # # Copyright (C) 2015 Ben Kurtovic # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. from __future__ import unicode_literals from earwigbot.tasks import Task from earwigbot.wiki import constants import mwparserfromhell class InfoboxStation(Task): """ A task to replace ``{{Infobox China station}}`` and ``{{Infobox Japan station}}`` with ``{{Infobox station}}``. """ name = "infobox_station" number = 20 def setup(self): self.site = self.bot.wiki.getsite() self._targets = { "China": ( ["Infobox China station", "Infobox china station"], "Infobox China station/sandbox", "Infobox China station/sandbox/cats", "Wikipedia:Templates for discussion/Log/2015 February 8#Template:Infobox China station" ), "Japan": ( ["Infobox Japan station", "Infobox japan station"], "Infobox Japan station/sandbox", "Infobox Japan station/sandbox/cats", "Wikipedia:Templates for discussion/Log/2015 May 9#Template:Infobox Japan station" ), } self._replacement = "{{Infobox station}}" self.summary = self.make_summary( "Replacing {source} with {dest} per [[{discussion}|TfD]].") def run(self, **kwargs): for name, args in self._targets.items(): if self.shutoff_enabled(): return self._replace(name, args) def _replace(self, name, args): """ Replace a template in all pages that transclude it. """ self.logger.info("Replacing {0} infobox template".format(name)) count = 0 for search in args[0]: for title in self._get_transclusions(search): count += 1 if count % 10 == 0 and self.shutoff_enabled(): return page = self.site.get_page(title) self._process_page(page, search, args) def _process_page(self, page, search, args): """ Process a single page to replace a template. """ self.logger.debug("Processing [[{0}]]".format(page.title)) if not page.check_exclusion(): self.logger.warn("Bot excluded from [[{0}]]".format(page.title)) return code = mwparserfromhell.parse(page.get(), skip_style_tags=True) for tmpl in code.filter_templates(): if tmpl.name.matches(search): tmpl.name = "subst:" + args[2] self._add_cats(code, unicode(tmpl)) tmpl.name = "subst:" + args[1] break if code == page.get(): msg = "Couldn't figure out what to edit in [[{0}]]" self.logger.warn(msg.format(page.title)) return summary = self.summary.format( source="{{" + search + "}}", dest="{{" + self._replacement + "}}", discussion=args[3]) page.edit(unicode(code), summary, minor=True) def _add_cats(self, code, cats): """Add category data (*cats*) to wikicode.""" for link in code.ifilter_wikilinks(): if link.title.lower().startswith("category:"): code.insert_before(link, cats + "\n") return for tmpl in code.filter_templates(): if tmpl.name.lower().endswith("stub"): prev = code.get(code.index(tmpl) - 1) if prev.endswith("\n\n"): code.replace(prev, prev[:-1]) code.insert_before(tmpl, cats + "\n\n") def _get_transclusions(self, title): """ Return a list of mainspace translusions of the given template. """ query = """SELECT page_title FROM templatelinks LEFT JOIN page ON tl_from = page_id WHERE tl_namespace = ? AND tl_title = ? AND tl_from_namespace = ?""" results = self.site.sql_query(query, ( constants.NS_TEMPLATE, title.replace(" ", "_"), constants.NS_MAIN)) return [title for (title,) in results]