def process(day): """ one day bot processing arguments: day -- python date format """ if params.verbose: print("processing Journal des recréations ({day})".format( day=format_date(day))) start = to_date(day) end = to_date(day + ONE_DAY) result = "\n\n== {} ==\n".format(format_date(day)) comment = [] for i, page in enumerate(creation_log(start, end), 1): gras = '' date = '' if params.verbose: print(i, page["timestamp"]) dl = deletelog(page["title"]) if dl: page_pas = Page(Site(), "Discussion:" + page["title"] + "/Suppression") if page_pas.isRedirectPage(): page_pas = page_pas.getRedirectTarget() if page_pas.exists() and re.search(r'article supprimé', page_pas.get(), re.I): if re.search( r'\{\{ ?article supprimé[^\}]*\d{1,2} (\S* \d{4}) à', page_pas.get(), re.I): date = u' de %s' % re.search( r'\{\{ ?article supprimé[^\}]*\d{1,2} (\S* \d{4}) à', page_pas.get(), re.I).group(1) comment.append(u'[[%s]] (malgré [[%s|PàS]]%s)' % (page["title"], page_pas.title(), date)) gras = "'''" r = ( u"* {g}{{{{a-court|{title}}}}} <small>([[{pas}|PàS]])</small> supprimé le {date} puis recréé par {{{{u|{user}}}}}{g} \n" .format(title=wiki_param(page["title"]), pas=page_pas.title(), user=wiki_param(page["user"]), date=format_date(from_date(dl["timestamp"])), g=gras)) if params.verbose: print(r) result += r page = Page(Site(), params.prefix + u'/' + format_date(day, skip_day=True)) try: result = page.get() + result except NoPage: result = u'{{mise à jour bot|Zérobot}}' + result if comment: comment.insert(0, '') page.put( result, comment="Journal des recréations ({day}) ".format(day=format_date(day)) + ' - '.join(comment))
def _add_category_page(self, title, categories): """Add a page with categories. Parameters ---------- title : str Title of the page. categories : list The categories to add to the page. """ page = Page(self._site, title, "Category") if page.exists() and not self._overwrite: logging.warning( "Category page '{}' already exists. It will not be created.". format(page.title()) # noqa: E501 ) else: page.text = "" for category in categories: if category != title: page.text += "[[Kategori:{}]]\n".format(category) logging.info("Writing to category page '{}'".format(page.title())) logging.debug(page.text) self._write_page(page)
def _add_page_from_template(self, namespace, title, template_name, template_parameters): """Add a page by substituting a template. Parameters ---------- namespace : str Namespace of the page. If None, the default namespace will be used. title : str The title of the page. template_name : str The name of the template to substitute to create the subpage. template_parameters : list or OrderedDict Parameters to pass to the template. """ if namespace is None: page = Page(self._site, title) else: page = Page(self._site, title, namespace) if page.exists() and not self._overwrite: logging.warning( "Page '{}' already exists. It will not be created.".format( page.title())) else: template = Template(template_name, True, template_parameters) page.text = template.multiline_string() logging.info("Writing to page '{}'.".format(page.title())) logging.debug(page.text) self._write_page(page)
def add_old_cfd( page: pywikibot.Page, cfd_page: CfdPage, action: str, result: str, summary: str, ) -> None: """Add {{Old CfD}} to the talk page.""" date = cfd_page.title(with_section=False).rpartition('/')[2] if page.exists(): wikicode = mwparserfromhell.parse(page.text, skip_style_tags=True) for tpl in wikicode.ifilter_templates(): try: template = pywikibot.Page(page.site, str(tpl.name), ns=10) if template not in TPL['old cfd'] or not tpl.has( 'date', ignore_empty=True): continue except pywikibot.InvalidTitle: continue if tpl.get('date').value.strip() == date: # Template already present. return old_cfd = Template('Old CfD') old_cfd.add('action', action) old_cfd.add('date', date) old_cfd.add('section', cfd_page.section()) old_cfd.add('result', result) page.text = str(old_cfd) + '\n' + page.text page.save(summary=summary)
def logGroup(self, page: pywikibot.Page, users: List[pywikibot.User]) -> None: text = page.get(force=True) if page.exists() else "" for user in users: newLine = f"\n* [[Benutzer:{user.username}|{user.username}]]" if not newLine in text: text += newLine page.text = text page.save(summary=f"Bot: Benutzerliste nach Botlauf aktualisiert.")
def skip_page(self, page: pywikibot.Page) -> bool: """Skip special/media pages""" if page.namespace() < 0: return True elif not page.exists(): return True elif page.isRedirectPage(): return True return super().skip_page(page)
def get_page_from_size(page: pywikibot.Page) -> pywikibot.Page: """Return a page based on the current page size.""" i = 1 title = page.title() while True: if not page.exists(): break if len(page.text) < 1e6: break i += 1 page = Page(page.site, f"{title} ({i:02d})") return page
def load_config(page: pywikibot.Page, **kwargs: Any) -> ConfigJSONObject: """Load JSON config from the page.""" if page.isRedirectPage(): pywikibot.log(f"{page!r} is a redirect.") page = page.getRedirectTarget() _empty = jsoncfg.loads_config("{}") if not page.exists(): pywikibot.log(f"{page!r} does not exist.") return _empty try: return jsoncfg.loads_config(page.get(**kwargs).strip()) except pywikibot.exceptions.PageRelatedError: return _empty
def get_wikidata_id(self, page: pywikibot.Page): if not page.exists(): return None # T256583, T87345 page.get(get_redirect=True) if page.isRedirectPage(): page = page.getRedirectTarget() page.get() item = pywikibot.ItemPage.fromPage(page) if not item or not item.exists(): return None return item.title()
def process(day): """ one day bot processing arguments: day -- python date format """ if params.verbose: print("processing Journal des recréations ({day})".format(day=format_date(day))) start = to_date(day) end = to_date(day+ONE_DAY) result = "\n\n== {} ==\n".format(format_date(day)) comment = [] for i,page in enumerate(creation_log(start,end),1): gras = '' date = '' if params.verbose: print (i,page["timestamp"]) dl = deletelog(page["title"]) if dl: page_pas = Page(Site(), "Discussion:" + page["title"] + "/Suppression") if page_pas.isRedirectPage(): page_pas = page_pas.getRedirectTarget() if page_pas.exists() and re.search(r'article supprimé', page_pas.get(), re.I): if re.search(r'\{\{ ?article supprimé[^\}]*\d{1,2} (\S* \d{4}) à', page_pas.get(), re.I): date = u' de %s' % re.search(r'\{\{ ?article supprimé[^\}]*\d{1,2} (\S* \d{4}) à', page_pas.get(), re.I).group(1) comment.append(u'[[%s]] (malgré [[%s|PàS]]%s)' % (page["title"], page_pas.title(), date)) gras = "'''" r = (u"* {g}{{{{a-court|{title}}}}} <small>([[{pas}|PàS]])</small> supprimé le {date} puis recréé par {{{{u|{user}}}}}{g} \n" .format(title = wiki_param(page["title"]), pas = page_pas.title(), user = wiki_param(page["user"]), date = format_date(from_date(dl["timestamp"])), g = gras)) if params.verbose: print(r) result += r page = Page(Site(), params.prefix + u'/' + format_date(day, skip_day=True)) try: result = page.get() + result except NoPage: result = u'{{mise à jour bot|Zérobot}}' + result if comment: comment.insert(0, '') page.put(result,comment="Journal des recréations ({day}) ".format(day=format_date(day)) + ' - '.join(comment))
def delete_page(page: pywikibot.Page, summary: str) -> None: """Delete the page and dependent pages.""" page.delete(reason=summary, prompt=False) if page.exists(): return page_link = page.title(as_link=True) for redirect in page.backlinks(filter_redirects=True): redirect.delete(reason=SUMMARIES['redirect'].format(page_link), prompt=False) talk_page = page.toggleTalkPage() if talk_page.exists(): talk_page.delete(reason=SUMMARIES['talk'].format(page_link), prompt=False) talk_link = talk_page.title(as_link=True) for redirect in talk_page.backlinks(filter_redirects=True): redirect.delete(reason=SUMMARIES['redirect'].format(talk_link), prompt=False)
def check_page(self, pagename): """Check one page.""" pywikibot.output('\nChecking ' + pagename) sys.stdout.flush() page1 = Page(self.original, pagename) txt1 = page1.text if self.options.dest_namespace: dest_ns = int(self.options.dest_namespace) else: dest_ns = None for site in self.sites: if dest_ns is not None: page2 = Page(site, page1.title(with_ns=False), dest_ns) pywikibot.output('\nCross namespace, new title: ' + page2.title()) else: page2 = Page(site, pagename) if page2.exists(): txt2 = page2.text else: txt2 = '' if str(site) in config.replicate_replace: txt_new = multiple_replace(txt1, config.replicate_replace[str(site)]) if txt1 != txt_new: pywikibot.output( 'NOTE: text replaced using config.sync_replace') pywikibot.output('{0} {1} {2}'.format(txt1, txt_new, txt2)) txt1 = txt_new if txt1 != txt2: pywikibot.output('\n {0} DIFFERS'.format(site)) self.differences[site].append(pagename) if self.options.replace: page2.text = txt1 page2.save(self.put_message(site)) else: sys.stdout.write('.') sys.stdout.flush()
def check_page(self, pagename): """Check one page.""" pywikibot.output("\nChecking %s" % pagename) sys.stdout.flush() page1 = Page(self.original, pagename) txt1 = page1.text if self.options.dest_namespace: dest_ns = int(self.options.dest_namespace) else: dest_ns = None for site in self.sites: if dest_ns is not None: page2 = Page(site, page1.title(withNamespace=False), dest_ns) pywikibot.output("\nCross namespace, new title: %s" % page2.title()) else: page2 = Page(site, pagename) if page2.exists(): txt2 = page2.text else: txt2 = '' if str(site) in config.replicate_replace: txt_new = multiple_replace(txt1, config.replicate_replace[str(site)]) if txt1 != txt_new: pywikibot.output( 'NOTE: text replaced using config.sync_replace') pywikibot.output('%s %s %s' % (txt1, txt_new, txt2)) txt1 = txt_new if txt1 != txt2: pywikibot.output("\n %s DIFFERS" % site) self.differences[site].append(pagename) if self.options.replace: page2.text = txt1 page2.save(self.put_message(site)) else: sys.stdout.write('.') sys.stdout.flush()
def check_page(self, pagename): """Check one page.""" pywikibot.output("\nChecking %s" % pagename) sys.stdout.flush() page1 = Page(self.original, pagename) txt1 = page1.text for site in self.sites: if self.options.dest_namespace: prefix = namespaces(site)[int(self.options.dest_namespace)] if prefix: prefix += ':' new_pagename = prefix + page1.titleWithoutNamespace() pywikibot.output("\nCross namespace, new title: %s" % new_pagename) else: new_pagename = pagename page2 = Page(site, new_pagename) if page2.exists(): txt2 = page2.text else: txt2 = '' if str(site) in config.replicate_replace: txt_new = multiple_replace(txt1, config.replicate_replace[str(site)]) if txt1 != txt_new: pywikibot.output( 'NOTE: text replaced using config.sync_replace') pywikibot.output('%s %s %s' % (txt1, txt_new, txt2)) txt1 = txt_new if txt1 != txt2: pywikibot.output("\n %s DIFFERS" % site) self.differences[site].append(pagename) if self.options.replace: page2.text = txt1 page2.save(self.put_message(site)) else: sys.stdout.write('.') sys.stdout.flush()
def process(day): """ one day bot processing arguments: day -- python date format """ if params.verbose: print("processing Journal des recréations ({day})".format(day=format_date(day))) start = to_date(day) end = to_date(day+ONE_DAY) result = "\n== {} ==\n".format(format_date(day)) comment = '' for i,page in enumerate(creation_log(start,end),1): gras = '' if params.verbose: print (i,page["timestamp"]) dl = deletelog(page["title"]) if dl: page_pas = Page(Site(), "Discussion:"+page["title"]+"/Suppression") if page_pas.exists() and re.search('\{\{\ ?Article supprimé', page_pas.get(), re.I): comment += u' - %s (malgré [[%s|PàS]])' % (page["title"], page_pas.title()) gras = "'''" r = ("* {g}{{{{a-court|{title}}}}} <small>([[{pas}|PàS]])</small> supprimé le {date} recréé par {{{{u|{user}}}}}{g} \n" .format(title = wiki_param(page["title"]) , pas = page_pas.title()), user = wiki_param(page["user"]), date = format_date(from_date(dl["timestamp"])), g = gras) if params.verbose: print(r) result += r page = Page(Site(), params.prefix+"/"+format_date(day,skip_day=True)) try: result = page.get()+result except NoPage: pass page.put(result,comment="Journal des recréations ({day})".format(day=format_date(day)) + comment)
def _create_current_projects_template(self): """Create a current projects template with the new projects.""" page_name = self._make_year_title( self._config["year_pages"]["current_projects_template"]) page = Page(self._site, page_name) if page.exists() and not self._overwrite: logging.warning( "Page '{}' already exists. It will not be created.".format( page.title())) return project_format = "[[{ns}:{{proj}}|{{proj}}]]".format( ns=self._config["project_namespace"]) delimiter = "''' · '''" template_data = {} for program in self._programs: projects = set() for strategy in program.get('strategies'): # projects sorted by id to get thematic grouping projects.update(strategy.get("projects")) template_data[program.get('name')] = delimiter.join([ project_format.format(proj=self._projects[project]) for project in sorted(projects) ]) template = Template("Aktuella projekt/layout") template.add_parameter("år", self._year) template.add_parameter("access", template_data["Tillgång"]) template.add_parameter("use", template_data["Användning"]) template.add_parameter("community", template_data["Gemenskapen"]) template.add_parameter("enabling", template_data["Möjliggörande"]) page.text = template.multiline_string() + \ "\n<noinclude>{{Dokumentation}}</noinclude>" logging.info("Writing to page '{}'.".format(page.title())) logging.debug(page.text) self._write_page(page)
def skip_page(self, page: pywikibot.Page) -> bool: if page.namespace() < 0: return True if not page.exists(): return True return super().skip_page(page)
def add_project_page(self, phab_id, phab_name, parameters, goals, goal_fulfillments): """Add the main project page. Parameters ---------- name : str The project name in Swedish. This will be used as title for the page. description : str Passed to template as parameter "beskrivning". partners : str Passed to template as parameter "samarbetspartners". """ name = parameters[self._project_columns["swedish_name"]] page = Page(self._site, name, self._config["project_namespace"]) if page.exists() and not self._overwrite: logging.warning( "Project page '{}' already exists. It will not be created.". format(page.title()) # noqa: E501 ) else: template = Template(self._config["project_template"], True) project_parameters = self._config["project_parameters"].items() for template_parameter, label in project_parameters: template.add_parameter( template_parameter, parameters[self._project_columns[label]]) template.add_parameter("year", self._year) template.add_parameter("phabricatorId", phab_id) template.add_parameter("phabricatorName", phab_name) template.add_parameter("bot", "ja") content = "{}".format(template) page.text = content logging.info("Writing to project page '{}'".format(page.title())) logging.debug(page.text) self._write_page(page) for subpage in self._config["subpages"]: subpage_parameters = { "år": self._year # always pass the year parameter } if "parameters" in subpage: for key, label in subpage["parameters"].items(): subpage_parameters[key] = parameters[ self._project_columns[label]] if "add_goals_parameters" in subpage: # Special case for goals parameters, as they are not # just copied. template_key = \ list(subpage["add_goals_parameters"].keys())[0] template_value = self._make_year_title( subpage["add_goals_parameters"][template_key]) subpage_parameters[template_key] = \ Template(template_value, parameters=goals) subpage_parameters["måluppfyllnad"] = \ self._create_goal_fulfillment_text( goals.keys(), goal_fulfillments ) # noqa:E123 self._add_subpage(name, subpage["title"], subpage["template_name"], subpage_parameters)
def process_list(type, formatter_class): """ Post notifications about a certain type of deletions @param type: Deletion type @type type: str @param formatter_class: Class to be used for formatting messages @type formatter_class: commonsbot.formatters.Formatter """ filename = 'lists/%s.txt' % type if not os.path.isfile(filename) or not os.path.exists(filename): return file = open(filename, 'r', encoding='utf8') lines = [s.strip() for s in file.readlines()] file.close() file_states = {} def load(store): nonlocal file_states (file_states, _) = store.load_state(lines, type) with_store(load) mapper = PerWikiMapper(NOTIFS_PER_WIKI) notified_files = set() for filename in lines: file = FilePage(commons, filename) if filename in file_states: state = file_states[filename] else: print('No deletion state found for %s, stubbing' % filename, file=sys.stderr) state = DeletionState(filename, type, 'new') file_states[filename] = state state.file_page = file if type == 'discussion': state.load_discussion_info(commons) page = Page(commons, state.discussion_page) if not page.exists(): print( "Discussion page %s doesn't exist, not notifying about this file" % page, file=sys.stderr) continue pageset = file.globalusage(MAX_GLOBALUSAGE) for page in pageset: wiki = page.site.dbName() if wiki not in config.wikis: continue if page.namespace() != Namespace.MAIN: continue talk_page = page.toggleTalkPage() if talk_page.isRedirectPage(): continue if not talk_page.botMayEdit(): continue if talk_page.exists() and not talk_page.canBeEdited(): continue mapper.add(filename, page) for page, files in mapper.files_per_page(): states = [] for filename in files: state = file_states[filename] states.append(state) try: spam_notifications(type, formatter_class, page.toggleTalkPage(), states) except: # Error - save state to avoid reposting and then rethrow failed = set(states) failed_only = failed - notified_files def save(store): store.set_failure(type, list(failed_only)) store.set_state(type, list(notified_files), 'notified') with_store(save) raise notified_files.update(states) with_store(lambda store: store.set_state(type, list(file_states.values()), 'notified'))