diff --git a/earwigbot/tasks/wikiproject_tagger.py b/earwigbot/tasks/wikiproject_tagger.py index edff8aa..6fdee44 100644 --- a/earwigbot/tasks/wikiproject_tagger.py +++ b/earwigbot/tasks/wikiproject_tagger.py @@ -39,7 +39,7 @@ class WikiProjectTagger(Task): ``--banner BANNER`` the page name of the banner to add, without a namespace (unless the namespace is something other than ``Template``) so - ``--banner WikiProject Biography`` for ``{{WikiProject Biography}}`` + ``--banner "WikiProject Biography"`` for ``{{WikiProject Biography}}`` ``--category CAT`` or ``--file FILE`` determines which pages to tag; either all pages in a category (to include subcategories as well, see ``--recursive``) or all @@ -67,6 +67,9 @@ class WikiProjectTagger(Task): ``--recursive NUM`` recursively go through subcategories up to a maximum depth of ``NUM``, or if ``NUM`` isn't provided, go infinitely (this can be dangerous) + ``--tag-categories`` + also tag category pages; will autoassess with ``|class=category`` if + ``--autoassess`` is given ``--genfixes`` apply general fixes to the page if already making other changes ``--site SITE`` @@ -134,6 +137,7 @@ class WikiProjectTagger(Task): ow_banner = kwargs.get("only-with") nocreate = kwargs.get("nocreate", False) recursive = kwargs.get("recursive", 0) + tag_categories = kwargs.get("tag-categories", False) genfixes = kwargs.get("genfixes", False) dry_run = kwargs.get("dry-run", False) banner, names = self.get_names(site, banner) @@ -148,7 +152,8 @@ class WikiProjectTagger(Task): job = _Job(banner=banner, names=names, summary=summary, update=update, append=append, autoassess=autoassess, only_with=only_with, - nocreate=nocreate, genfixes=genfixes, dry_run=dry_run) + nocreate=nocreate, tag_categories=tag_categories, + genfixes=genfixes, dry_run=dry_run) try: self.run_job(kwargs, site, job, recursive) @@ -218,6 +223,8 @@ class WikiProjectTagger(Task): self.logger.info(u"Processing category: [[%s]]", page.title) for member in page.get_members(): if member.namespace == constants.NS_CATEGORY: + if job.tag_categories: + self.process_page(member, job, is_category=True) if recursive is True: self.process_category(member, job, True) elif recursive > 0: @@ -225,7 +232,7 @@ class WikiProjectTagger(Task): else: self.process_page(member, job) - def process_page(self, page, job): + def process_page(self, page, job, is_category=False): """Try to tag a specific *page* using the *job* description.""" if job.counter % 10 == 0: # Do a shutoff check every ten pages if self.shutoff_enabled(page.site): @@ -264,7 +271,7 @@ class WikiProjectTagger(Task): if is_update: old_banner = unicode(banner) - self.update_banner(banner, job, code) + self.update_banner(banner, job, code, is_category=is_category) if banner == old_banner: log = u"Skipping page: [[%s]]; already tagged and no updates" self.logger.info(log, page.title) @@ -273,7 +280,7 @@ class WikiProjectTagger(Task): banner = banner.encode("utf8") else: self.logger.info(u"Tagging page: [[%s]]", page.title) - banner = self.make_banner(job, code) + banner = self.make_banner(job, code, is_category=is_category) shell = self.get_banner_shell(code) if shell: if shell.has_param(1): @@ -306,34 +313,44 @@ class WikiProjectTagger(Task): summary = job.summary.replace("$3", banner) page.edit(text, self.make_summary(summary), minor=True) - def make_banner(self, job, code=None): + def make_banner(self, job, code=None, is_category=False): """Return banner text to add based on a *job* and a page's *code*.""" banner = job.banner if code is not None and job.autoassess is not False: - assessment = self.get_autoassessment(code, job.autoassess) - if assessment: - banner += "|class=" + assessment + assess, reason = self.get_autoassessment( + code, job.autoassess, is_category=is_category) + if assess: + banner += "|class=" + assess + if reason: + banner += "|auto=" + reason if job.append: banner += "|" + "|".join(job.append.split(",")) return "{{" + banner + "}}" - def update_banner(self, banner, job, code): + def update_banner(self, banner, job, code, is_category=False): """Update an existing *banner* based on a *job* and a page's *code*.""" has = lambda key: (banner.has(key) and banner.get(key).value.strip() not in ("", "?")) if job.autoassess is not False: if not has("class"): - assessment = self.get_autoassessment(code, job.autoassess) - if assessment: - banner.add("class", assessment) + assess, reason = self.get_autoassessment( + code, job.autoassess, is_category=is_category) + if assess: + banner.add("class", assess) + if reason: + banner.add("auto", reason) if job.append: for param in job.append.split(","): key, value = param.split("=", 1) if not has(key): banner.add(key, value) - def get_autoassessment(self, code, only_classes=None): + def get_autoassessment(self, code, only_classes=None, is_category=False): + """Get an autoassessment for a page. + + Return (assessed class as a string or None, assessment reason or None). + """ if only_classes is None: classnames = ["a", "b", "book", "c", "category", "dab", "fa", "fl", "ga", "list", "redirect", "start", "stub", @@ -342,6 +359,9 @@ class WikiProjectTagger(Task): classnames = [klass.strip().lower() for klass in only_classes.split(",")] + if is_category: + return ("category" if "category" in classnames else None), None + classes = {klass: 0 for klass in classnames} for template in code.ifilter_templates(recursive=True): if template.has("class"): @@ -356,10 +376,10 @@ class WikiProjectTagger(Task): if confidence > 0.75: rank = tuple(classes.keys())[values.index(best)] if rank in ("fa", "fl", "ga"): - return rank.upper() + return rank.upper(), "inherit" else: - return self._upperfirst(rank) - return None + return self._upperfirst(rank), "inherit" + return None, None def get_banner_shell(self, code): """Return the banner shell template within *code*, else ``None``.""" @@ -410,6 +430,7 @@ class _Job(object): self.autoassess = kwargs["autoassess"] self.only_with = kwargs["only_with"] self.nocreate = kwargs["nocreate"] + self.tag_categories = kwargs["tag_categories"] self.genfixes = kwargs["genfixes"] self.dry_run = kwargs["dry_run"] self.counter = 0