def treat(self, page): for name,params in textlib.extract_templates_and_params(page.get()): if name != u"Wikimedia CEE Spring 2016": continue country = params[u"țară"] break page = page.toggleTalkPage() words = self.getWordCount(page.get()) author = page.oldest_revision.user if author not in self.points: self.points[author] = 0 self.poland[author] = 0 self.czech[author] = 0 self.countries[author] = {} if words < 200: #not acceptable print u"Articol descalificat: " + page.title() return #TODO creation date self.points[author] += 1 if country not in [u"Albania", u"Estonia", u"Bașchiria", u"Bașkiria", u"Austria", u"Rusia", u"Republika Srpska", u"Republica Srpska", u"Slovacia", u"Ucraina", u"Lituania", u"Macedonia", u"Bulgaria", u"Croația", u"Azerbaidjan", u"Polonia", u"Kazahstan", u"Grecia", u"Belarus", u"Iacuția", u"Iacutia", u"Serbia", u"Letonia", u"Kosovo", u"Armenia", u"Cehia", u"Republica Cehă", u"Bosnia și Herțegovina", u"Georgia", u"Esperanto", u"Turcia", u"Ungaria"]: print u"Țară greșită: " + country else: self.points[author] += 0.2 self.countries[author][country] = 0 if country in [u"Polonia"]: self.poland[author] += 1.2 if country in [u"Cehia", u"Republica Cehă"]: self.czech[author] += 1.2 print page.title() print author print words print country
def generate(self): with open(self.filename, "w+") as file: for resp in self.site.query( prop='revisions', rvprop='content', redirects='no', generator='transcludedin', gtishow='!redirect', gtilimit='50', titles='Template:Tag', ): result = defaultdict(int) if 'pages' not in resp: continue for page in resp['pages']: if 'revisions' in page and len( page['revisions'] ) == 1 and 'content' in page['revisions'][0]: content = page['revisions'][0]['content'] for template in textlib.extract_templates_and_params( content, True, True): for key, value in parse_tag( template, page['title']): result[(key, value)] += 1 for k, count in result.items(): print(f'{k[0]}\t{k[1]}\t{count}', file=file) # Consolidate duplicates data = self.load() with open(self.filename, "w+") as file: for key, vv in sorted(data.items(), key=lambda v: sum(v[1].values()), reverse=True): for value, count in sorted(vv.items(), key=lambda v: v[0]): print(f'{key}\t{value}\t{count}', file=file)
def analyse_section(self, section, template_title = None): """ Analyse une section et retourne un dictionnaire contenant la date et le statut de la section (retourne : {'date': (string), 'statut': (string)}). Par défaut, le titre du modèle à analyser est celui du modèle correspondant à la page de requête associée à la classe (self.template_title). """ if not template_title: template_title = self.template_title date = None statut = None templates = textlib.extract_templates_and_params(section) # templates est du type : # [(u'RA début', {u'date': u'27 février 2011 à 14:56 (CET)' # , u'statut': u'oui'}), (u'RA fin', {})] # avec éventuellement d'autres modèles, utilisés dans la requête par # les contributeurs, et se trouvant entre le {{RA début}} et le {{RA fin}} for template in templates: # Si le modèle est celui qui annonce le début de la section. if template[0] == template_title: #modifié (todo A-1) # On extrait les paramètres utiles (statut et date) try: statut = template[1]['statut'] date = template[1]['date'] except: pywikibot.output(u"Erreur ! Les paramètres 'statut' et 'date' ne semblent pas exister !") return None # On arrête d'analyser les modèles, étant donné qu'on a trouvé # celui qui nous intéresse. break return {'date': date, 'statut': statut}
def get_infobox_params(self, tplnames, pagetext): infobox = {} #pywikibot.output(tplnames) counter = 0 for template, fielddict in textlib.extract_templates_and_params( pagetext, remove_disabled_parts=False, strip=True): #pywikibot.output(template) tplname = template.lower().strip().replace('_', ' ') #pywikibot.output(tplname) counter += 1 if counter == 50: break if tplname in tplnames: pywikibot.output(tplname) infobox = { f[0]: f[1].strip() for f in fielddict.items() if f[1].strip() != '' } #fileobj.write(str(thisrow)) #if len(parsed) % 25 == 0: # print(len(parsed)) #pywikibot.output(infobox) break return infobox
def treat(self, page): """Process a single page.""" if willstop: raise KeyboardInterrupt self.current_page = page pagetext = page.get() templates = textlib.extract_templates_and_params(pagetext) for (template, fielddict) in templates: # Clean up template try: template = pywikibot.Page(self.site, template, ns=10).title(withNamespace=False) except (pywikibot.exceptions.InvalidTitle, LookupError): pywikibot.error( "Failed parsing template; '%s' should be the template name." % template) continue # We found the template we were looking for if template in self.templateTitles: values = [None] * len(self.parameters) for param, value in fielddict.items(): param = param.strip() value = value.strip() if param in self.parameters: values[self.parameters.index(param)] = value else: self.parameters.append(param) values.append(value) self.output(page, fielddict) # Write in file self.write_file('%s\t%s\n' % (page.title(), '\t'.join([ x.replace('\n', '\\n') if x is not None else '' for x in values ])))
def replacement(self, match): if match.group('unhandled_depth'): return match.group() for template, fielddict in textlib.extract_templates_and_params( match.group(), remove_disabled_parts=False, strip=False): if template.strip() == match.group('name'): changed = False name_part = match.group().split('|', 1)[0] space_before = re.match(r'\{\{(\s*)', name_part).group(1) space_after = re.search(r'(\s*)$', name_part).group(1) new_template = '{{' + space_before + template + space_after for param, value in fielddict.items(): new_value = self.regex.sub(r'\g<after>', value) if new_value != value: changed = True if param.isdigit(): return match.group() else: new_template += '|%s=%s' % (param, new_value) if changed: return new_template + '}}' return match.group()
def treat(self, page): pywikibot.output(page) talktext = page.get() templates = textlib.extract_templates_and_params(talktext) for (template, fields) in templates: try: template = pywikibot.Page(self.site, template, ns=10).title(withNamespace=False) except (pywikibot.exceptions.InvalidTitle, LookupError): pywikibot.error('Invalid template name: %s' % template) continue if AssessmentTemplate(self.site, template) not in self.templates: continue params = {} for name, value in fields.items(): name = name.strip() value = value.strip() params[name] = value if template == self.multiAssessmentTemplate: for name in params: rem = re.match((r'%s(\d+)' % self.userParam), name) if rem and self.isSearchedUser(params[name]): self.found(page, params, rem.group(1)) elif self.userParam in params and self.isSearchedUser( params[self.userParam]): self.found(page, params)
def loadTypos(self): pywikibot.output('Loading typo rules') self.typoRules = [] if self.typos_page_name is None: self.typos_page_name = 'Wikipedie:WPCleaner/Typo' typos_page = pywikibot.Page(self.site, self.typos_page_name) if not typos_page.exists(): # todo: feedback return content = typos_page.get() load_all = self.load_all is True for template, fielddict in textlib.extract_templates_and_params( content, remove_disabled_parts=False, strip=False): if template.lower() == 'typo': try: rule = TypoRule.newFromParameters(fielddict, self.site) except IncompleteTypoRuleException as exc: pywikibot.warning(exc.message) # pwb.exception? except InvalidExpressionException as exc: if 'fixed-width' not in exc.message: pywikibot.warning('Invalid %s %s: %s' % ( exc.aspect, fielddict['1'], exc.message)) else: rule.id = self.top_id self.top_id += 1 if load_all or not rule.needsDecision(): self.typoRules.append(rule) pywikibot.output('%s typo rules loaded' % len(self.typoRules)) return self.typoRules
def loadTypos(self): pywikibot.output('Loading typo rules') self.typoRules = [] if self.typos_page_name is None: self.typos_page_name = 'Wikipedie:WPCleaner/Typo' typos_page = pywikibot.Page(self.site, self.typos_page_name) if not typos_page.exists(): # todo: feedback return text = textlib.removeDisabledParts( typos_page.text, include=['nowiki'], site=self.site) load_all = self.load_all is True for template, fielddict in textlib.extract_templates_and_params( text, remove_disabled_parts=False, strip=False): if template.lower() == 'typo': try: rule = TypoRule.newFromParameters(fielddict, self.site) except IncompleteTypoRuleException as exc: pywikibot.warning(exc.message) # pwb.exception? except InvalidExpressionException as exc: if 'fixed-width' not in exc.message: pywikibot.warning('Invalid %s %s: %s' % ( exc.aspect, fielddict['1'], exc.message)) else: rule.id = self.top_id # fixme: cvar or ivar? self.top_id += 1 if load_all or not rule.needs_decision(): self.typoRules.append(rule) pywikibot.output('%d typo rules loaded' % len(self.typoRules)) return self.typoRules
def find_add(self, page): """ Returns (user, oldid, timestamp) where * user is the user who added the {{Mort récente}} template (pywikibot.User) * oldid is the oldid of the revision of this add (int) * timestamp """ death_found = True history = page.getVersionHistory() if len(history) == 1: [(id, timestamp, user, comment)] = history return (pywikibot.User(self.site, user), id) oldid = None requester = None timestamp = None previous_timestamp = None for (id, timestamp, user, comment) in history: pywikibot.output("Analyzing id %i: timestamp is %s and user is %s" % (id, timestamp, user)) text = page.getOldVersion(id) templates_params_list = textlib.extract_templates_and_params(text) death_found = False for (template_name, dict_param) in templates_params_list: try: template_page = pywikibot.Page(pywikibot.Link(template_name, self.site, defaultNamespace=10), self.site) # TODO : auto-finding redirections if template_page.title(withNamespace=False) in [u"Mort récente", u"Décès récent"]: death_found = True break except Exception, myexception: pywikibot.output(u'An error occurred while analyzing template %s' % template_name) pywikibot.output(u'%s %s'% (type(myexception), myexception.args)) if oldid: print("id is %i ; oldid is %i" % (id, oldid)) else: print("id is %i ; no oldid" % id) if not death_found: if id == oldid: pywikibot.output("Last revision does not contain any {{Mort récente}} template!") return None else: pywikibot.output(u"-------------------------------------") triplet = (requester, oldid, previous_timestamp) pywikibot.output(u"Found it: user is %s; oldid is %i and timestamp is %s" % triplet) return triplet else: requester = pywikibot.User(self.site, user) oldid = id previous_timestamp = timestamp
def extractDisscussionData(pagetext): for template, fielddict in textlib.extract_templates_and_params( pagetext, remove_disabled_parts=False, strip=True): tplname = template.lower().strip().replace('_', ' ') if tplname not in ['cee spring 2021']: continue fielditems = [[k[0], k[1]] for k in fielddict.items()] return fielditems return None
def getList(self): input_requests = textlib.extract_templates_and_params(self.translationPage.text) for row in input_requests: if row[0] == templateName: dicoTrans = {} for p in self.translationParam: try: #print row[1] dicoTrans[p] = u"" + row[1][p] except KeyError: dicoTrans[p] = '' self.translateList.append(dicoTrans) return self.translateList
def run(self, page, text): templates = findtemplates(text) for template in templates: try: ext_temp = textlib.extract_templates_and_params(template)[0] except IndexError: continue if ext_temp[0] == "Eurohockey" or ext_temp[0] == "eurohockey": ext_temp = self.fixParam(ext_temp) text = text.replace(template, self.createTemplate(ext_temp)) self.error_count += 1 return text, self.error_count
def run(self, page, text): target_template = "Jalkapalloseura" templates = findtemplates(text) for template in templates: ntemplate = textlib.extract_templates_and_params(template) for tem in ntemplate: temx = template.split("\n") if tem[0].lower() == target_template.lower(): text = text.replace(template, self.glue_template_and_params(tem)) self.error_count += 1 return text, self.error_count
def analyse_section(self, section, template_title=None): """ Analyse une section et retourne un dictionnaire contenant la date et le statut de la section (retourne : {'date': (string), 'traitée': (boolean), 'attendre': (boolean)}). Par défaut, le titre du modèle à analyser est celui du modèle correspondant à la page de requête associée à la classe (template_title). """ if not template_title: template_title = self.template_title date = None traitee = False wait = False found = False templates = textlib.extract_templates_and_params(section) # templates est du type : # [(u'RA début', {u'date': u'27 février 2011 à 14:56 (CET)' # , u'traitée': u'oui'}), (u'RA fin', {})] # avec éventuellement d'autres modèles, utilisés dans la requête par # les contributeurs, et se trouvant entre le {{RA début}} et le {{RA fin}} for template in templates: # Si le modèle est celui qui annonce le début de la section. if template[0] == template_title: # On extrait les paramètres utiles (statut et date) try: date = template[1]['date'] if template[1][u'traitée'].strip() == 'oui': traitee = True elif template[1][u'traitée'].strip() in ('attente', 'encours'): wait = True except: pywikibot.output( u"Erreur ! Les paramètres 'date' et 'traitée' ne semblent pas exister !" ) return None # On arrête d'analyser les modèles, étant donné qu'on a trouvé # celui qui nous intéresse. found = True break if found: return {'date': date, 'traitée': traitee, 'attente': wait} else: pywikibot.output(u"Aucun modèle de début trouvé !") return None
def parse_page(self, page): if self.ignore_title(page.ns, page.title): return if 'revisions' in page and len(page.revisions) == 1 and 'content' in page.revisions[0]: found = False for (t, p) in textlib.extract_templates_and_params(page.revisions[0].content, True, True): if t.lower() in self.filters: found = True yield { 'ns': page.ns, 'title': page.title, 'template': t, 'params': p, } if not found and 'redirect' in page and not page.redirect: print(f'Unable to find relevant templates in {page.title}')
def get_infobox_params(pagetext): tplnames = ['dzēst', 'delete', 'dzēst attēlu'] infobox = {} for template, fielddict in textlib.extract_templates_and_params( pagetext, remove_disabled_parts=False, strip=True): tplname = template.lower().strip().replace('_', ' ') if tplname in tplnames: infobox = {f[0]: f[1] for f in fielddict.items()} #fileobj.write(str(thisrow)) #if len(parsed) % 25 == 0: # print(len(parsed)) #pywikibot.output(infobox) break return infobox
def analyse_section(self, section, template_title = None): """ Analyse une section et retourne un dictionnaire contenant la date et le statut de la section (retourne : {'date': (string), 'traitée': (boolean), 'attendre': (boolean)}). Par défaut, le titre du modèle à analyser est celui du modèle correspondant à la page de requête associée à la classe (template_title). """ if not template_title: template_title = self.template_title date = None traitee = False wait = False found = False templates = textlib.extract_templates_and_params(section) # templates est du type : # [(u'RA début', {u'date': u'27 février 2011 à 14:56 (CET)' # , u'traitée': u'oui'}), (u'RA fin', {})] # avec éventuellement d'autres modèles, utilisés dans la requête par # les contributeurs, et se trouvant entre le {{RA début}} et le {{RA fin}} for template in templates: # Si le modèle est celui qui annonce le début de la section. if template[0] == template_title: # On extrait les paramètres utiles (statut et date) try: date = template[1]['date'] if template[1][u'traitée'].strip() == 'oui': traitee = True elif template[1][u'traitée'].strip() in ('attente', 'encours'): wait = True except: pywikibot.output(u"Erreur ! Les paramètres 'date' et 'traitée' ne semblent pas exister !") return None # On arrête d'analyser les modèles, étant donné qu'on a trouvé # celui qui nous intéresse. found = True break if found: return {'date': date, 'traitée': traitee, 'attente': wait} else: pywikibot.output(u"Aucun modèle de début trouvé !") return None
def parse_members(line, printer, info): vals = {} for vt in textlib.extract_templates_and_params(line, True, True): name, params = vt m = re_lang_template.match(name) if m: name = m[1] name = name.lower() if name == 'iconnode' or (name == 'icon' and '1' in params and params['1'] == 'node'): vals['onnode'] = 'yes' elif name == 'iconway' or (name == 'icon' and '1' in params and params['1'] == 'way'): vals['onway'] = 'yes' elif name == 'iconrelation' or (name == 'icon' and '1' in params and params['1'] == 'relation'): vals['onrelation'] = 'yes' elif name == 'iconarea' or (name == 'icon' and '1' in params and params['1'] == 'area'): vals['onarea'] = 'yes' elif name == 'iconclosedway' or (name == 'icon' and '1' in params and params['1'] == 'closedway'): vals['onclosedway'] = 'yes' elif name == 'value': if list(params.keys()) == ['1']: vals['value'] = params['1'] vals['value'] = params['1'] elif len(params.keys()) == 0: vals['value'] = '' else: printer(f"Unknown value param pattern in '{line}'") elif name == 'icon': if list(params.keys()) == ['1']: p = params['1'].lower() if p == 'n' or p == 'node': vals['onnode'] = 'yes' elif p == 'w' or p == 'way': vals['onway'] = 'yes' elif p == 'r' or p == 'relation': vals['onrelation'] = 'yes' else: printer(f"Unknown value param pattern in '{line}'") else: info(f"Unknown template {name} in '{line}'") return vals
def parse_combinations(self, tkey, tval): items = [] for template in textlib.extract_templates_and_params(tval, True, True): for k, v in self.parse_tag(template): if v: items.append(('Tag', f'{k}={v}')) else: items.append(('Key', k)) # Parse free text links like [[ (Key) : (lanes) | (lanes) ]] for link in re_tag_link.findall(tval): dummy, typ, lnk, freetext = link typ = typ.lower() if typ == 'relation': items.append(('Relation', lnk)) else: self.info( f'Parsed link in {tkey} is unrecognized: {typ}:{lnk} | {freetext}' ) return items
def _retrieve_from_wiki(filename, alignment_template): """Retrieve a metadata mapping from a given wikipage on disk. Iterate over the given alignment template occurences, retrieve and return the mapping values. """ wiki_file = os.path.join('wiki', filename.replace("/", "")) try: with codecs.open(wiki_file, mode='r', encoding='utf-8') as f: all_templates = textlib.extract_templates_and_params(f.read()) field_mapper = dict() for x in all_templates: if x[0] == alignment_template: categories = x[1]['categories'].split(']]')[0].split(':')[-1] field_mapper[x[1]['item']] = (x[1]['value'], categories) return field_mapper except Exception, e: print e
def treat(self, page): global i i+=1 print(i) code = None for name,params in textlib.extract_templates_and_params(page.get()): if name != u"Monument istoric": continue code = params[u"1"] #print(code) break if code == None: print(page.title()) return author = page.oldest_revision.user if author in organizers: #if "Țetcu" not in author: return if author not in self.users: self.users[author] = set() self.users[author].add(code)
def check_open_section(username): already_warned = False text = get_text() match = u"== Demande de déblocage de %s ==" % username try: if (match in text) or debug: # if debug: # text = u"""== Demande de déblocage de Toto Azéro == #{{RA début|traitée=|date=29 mars 2013 à 17:36 (CET)}} #Test #{{RA fin}} #""" text = text[text.index(match):] text = text[:text.index(u"{{RA fin}}")] templates = textlib.extract_templates_and_params(text) for template in templates: if template[0] == u"RA début": if template[1][u'traitée'] != u'oui': already_warned = True except Exception, myexception: pywikibot.output('WARNING: error while looking for any request already posted!') pywikibot.output(u'%s %s'% (type(myexception), myexception.args))
def check_open_section(username): already_warned = False text = get_text() match = u"== Demande de déblocage de %s ==" % username try: if (match in text) or debug: if debug: text = u"""== Demande de déblocage de Toto Azéro == {{RA début|traitée=|date=29 mars 2013 à 17:36 (CET)}} Test {{RA fin}} """ text = text[text.index(match):] text = text[:text.index(u"{{RA fin}}")] templates = textlib.extract_templates_and_params(text) for template in templates: if template[0] == u"RA début": if template[1][u'traitée'] != u'oui': already_warned = True except Exception, myexception: pywikibot.output('WARNING: error while looking for any request already posted!') pywikibot.output(u'%s %s'% (type(myexception), myexception.args))
def retrieve_from_wiki(self, filename, alignment_template): """Retrieve the metadata mapping from a given wikipage on disk. Iterate over the given alignment template occurences, retrieve and return the mapping values. """ #TODO get wikipage from website? print "retrieve_from_wiki " + filename wiki_file = os.path.join('wikiin', filename) try: with codecs.open(wiki_file, mode='r', encoding='utf-8') as f: all_templates = textlib.extract_templates_and_params(f.read()) field_mapper = dict() for x in all_templates: if x[0] == alignment_template: categories = x[1]['categories'].split(']]')[0].split( ':')[-1] field_mapper[x[1]['item']] = (x[1]['value'], categories) return field_mapper except Exception, e: print e
def treat(self, page): pywikibot.output(page) talktext = page.get() templates = textlib.extract_templates_and_params(talktext) for (template, fields) in templates: try: template = pywikibot.Page(self.site, template, ns=10).title(withNamespace=False) except (pywikibot.exceptions.InvalidTitle, LookupError): pywikibot.error('Invalid template name: %s' % template) continue if AssessmentTemplate(self.site, template) not in self.templates: continue params = {} for name, value in fields.items(): name = name.strip() value = value.strip() params[name] = value if template == self.multiAssessmentTemplate: for name in params: rem = re.match((r'%s(\d+)' % self.userParam), name) if rem and self.isSearchedUser(params[name]): self.found(page, params, rem.group(1)) elif self.userParam in params and self.isSearchedUser(params[self.userParam]): self.found(page, params)
def analyse_section(self, section, template_title=None): """ Analyse une section et retourne un dictionnaire contenant la date et le statut de la section (retourne : {'date': (string), 'statut': (string)}). Par défaut, le titre du modèle à analyser est celui du modèle correspondant à la page de requête associée à la classe (self.template_title). """ if not template_title: template_title = self.template_title date = None statut = None templates = textlib.extract_templates_and_params(section) # templates est du type : # [(u'RA début', {u'date': u'27 février 2011 à 14:56 (CET)' # , u'statut': u'oui'}), (u'RA fin', {})] # avec éventuellement d'autres modèles, utilisés dans la requête par # les contributeurs, et se trouvant entre le {{RA début}} et le {{RA fin}} for template in templates: # Si le modèle est celui qui annonce le début de la section. if template[0] == template_title: #modifié (todo A-1) # On extrait les paramètres utiles (statut et date) try: statut = template[1]['statut'] date = template[1]['date'] except: pywikibot.output( u"Erreur ! Les paramètres 'statut' et 'date' ne semblent pas exister !" ) return None # On arrête d'analyser les modèles, étant donné qu'on a trouvé # celui qui nous intéresse. break return {'date': date, 'statut': statut}
def find_add(page): """ Returns (user, oldid) where * user is the user thatwho added the {{Déblocage}} template (pywikibot.User) * oldid is the oldid of the revision of this add (int) """ site = pywikibot.Site() unblock_found = True history = page.getVersionHistory() if len(history) == 1: [(id, timestamp, user, comment)] = history return (pywikibot.User(site, user), id) oldid = None requester = None for (id, timestamp, user, comment) in history: pywikibot.output("Analyzing id %i: timestamp is %s and user is %s" % (id, timestamp, user)) text = page.getOldVersion(id) templates_params_list = textlib.extract_templates_and_params(text) unblock_found = False for (template_name, dict_param) in templates_params_list: #pywikibot.output((template_name, dict_param)) try: print 0 template_page = pywikibot.Page(pywikibot.Link(template_name, site, defaultNamespace=10), site) print 1 pywikibot.output(template_page) pywikibot.output(template_page.title(withNamespace=False)) # TODO : auto-finding redirections if template_page.title(withNamespace=False) in [u"Déblocage", u"Unblock"]: # le modèle {{déblocage}} peut ne plus être actif print 2 if ((not dict_param.has_key('nocat')) or (dict_param.has_key('nocat') and dict_param['nocat'] in ["non", ''])) and not (dict_param.has_key('1') and dict_param['1'] in ['nocat', 'oui', 'non', u'traité', u'traité', u'traitée', u'traitée']): pywikibot.output('Found unblock request') pywikibot.output((template_name, dict_param)) unblock_found = True print 3 break except Exception, myexception: pywikibot.output(u'An error occurred while analyzing template %s' % template_name) pywikibot.output(u'%s %s'% (type(myexception), myexception.args)) print("id is %i" % id) if oldid: print("oldid is %i" % oldid) else: print "no oldid" if not unblock_found: if id == oldid: pywikibot.output("Last revision does not contain any {{Déblocage}} template!") return None else: return (requester, oldid) else: requester = pywikibot.User(site, user) oldid = id
start = int(raw_input("Start: ")) end = int(raw_input("End: ") or start) for i in xrange(start, end + 1): item = pywikibot.PropertyPage(repo, u'P%s' % i) pywikibot.output(u'Looking up for "%s"' % item.title()) if not item.exists(): pywikibot.output(u'"%s" doesn\'t exist, skipping to the next one' % item.title()) continue page = pywikibot.Page(site, 'P%s' % i, 121) if not page.exists(): pywikibot.output(u'"%s" doesn\'t exist, skipping to the next one' % page.title()) continue templates = textlib.extract_templates_and_params(page.get()) fields = None for template, fielddict in templates: if template.lower() == template_metadata: fields = fielddict break if fields is None: pywikibot.output(u'Template "%s" not found' % template_metadata) continue item.get() if item.type in ['commonsMedia', 'external-id', 'string', 'url']: for template, fielddict in templates: if template.lower() == template_regex:
def find_and_replace(self, text, init): new_params = [] old_params = [] unknown_params = [] removed_params = [] changed = False for template, fielddict in textlib.extract_templates_and_params( text, remove_disabled_parts=False, strip=False): if self.normalize(template) not in (self.template, self.new_template): continue changed = self.normalize(template) != self.new_template start_match = re.search(r'\{\{\s*((%s)\s*:\s*)?%s\s*' % ( '|'.join(self.site.namespaces[10]), re.escape(template)), text) if not start_match: if not init: pywikibot.error("Couldn't find the template") return text, 0 start = start_match.start() if len(fielddict) > 0: end = text.index('|', start) else: end = text.index('}}', start) unnamed = {} for name, value in chain(fielddict.items(), IterUnnamed(unnamed)): end += len('|%s=%s' % (name, value)) name = name.strip() value = (value .replace('\n<!-- Zastaralé parametry -->', '') .replace('\n<!-- Neznámé parametry -->', '') .strip()) try: new_name = self.handle_param(name) except OldParamException: if textlib.removeDisabledParts(value, ['comments']).strip(): old_params.append( (name, value) ) except RemoveParamException: changed = True if textlib.removeDisabledParts(value, ['comments']).strip(): removed_params.append( (name, value) ) except UnknownParamException: if textlib.removeDisabledParts(value, ['comments']).strip(): unknown_params.append( (name, value) ) except AssertionError: pywikibot.error('Couldn\'t handle parameter "%s"' % name) return text, 0 except UnnamedParamException: unnamed[value] = '' else: new_params.append( (new_name, value) ) if new_name != name: changed = True end += len('}}') while text[start:end].count('{{') < text[start:end].count('}}'): end = text[:end].rindex('}}') + len('}}') if text[start:end].count('{{') > text[start:end].count('}}'): ballance = 1 end = start while ballance > 0: next_close = text.index('}}', end) ballance += text[end:next_close].count('{{') - 1 end = next_close + len('}}') if not text[start:end].endswith('}}'): # elif? end = text[:end].rindex('}}') + len('}}') if (end < start or not text[start:end].endswith('}}') or text[start:end].count('{{') != text[start:end].count('}}')): pywikibot.error("Couldn't parse the template") return text, 0 break else: pywikibot.error("Couldn't parse the template") return text, 0 if not changed: pywikibot.output('No parameters changed') return text, 0 while end < len(text) and text[end].isspace(): # todo: also before end += 1 lines = [] nested = 0 for line in text[start:end].splitlines(): if nested == 1 and re.match(' *\|', line): lines.append(line) nested += line.count('{{') - line.count('}}') space_before = '' if len(lines) > 0 and choice(lines).startswith(' '): space_before = ' ' self.handle_params(new_params, old_params, removed_params, unknown_params) self.deduplicate(new_params) new_params.sort(key=self.key_for_sort) new_template = '{{%s' % self.new_template if len(new_params) > 0: new_template += '\n' for param, value in new_params: new_template += '%s| %s = %s\n' % (space_before, param, value) if len(old_params) > 0: new_template += '<!-- Zastaralé parametry -->\n' for param, value in old_params: new_template += '%s| %s = %s\n' % (space_before, param, value) if len(unknown_params) > 0: new_template += '<!-- Neznámé parametry -->\n' for param, value in unknown_params: new_template += '%s| %s = %s\n' % (space_before, param, value) new_template += '}}\n' return text[:start] + new_template + text[end:], end
def archivage(self): """ Archivage ou suppression des requêtes classées (suivant le paramétrage du dictionnaire principal self.dict), dès lors qu'elles satisfaisent le délai configuré (self.dict['delai']['archivage'] et self.dict['delai']['suppression']). Les requêtes archivées sont transférée vers une sous-page de la page principale (self.main_page), en rajoutant le suffixe '/Archives%i' avec %i un integer. Le bot détecte automatiquement la page d'archives en cours, et crée une nouvelle page dès que le nombre de 250 sections est atteint. TODO (D): - mettre à jour la page principale d'archives lorsqu'une nouvelle page d'archives est créée. - vérifier l.475 (new_text = archive_page.get() + '\\n' + text_to_archive) """ to_do = ['acceptees', 'refusees'] for type in to_do: if type == 'acceptees': page_en_cours = self.accepted_page #text = self.accepted_page.get() elif type == 'refusees': page_en_cours = self.refused_page #text = self.refused_page.get() pywikibot.output(page_en_cours) text = page_en_cours.get() if not text: pywikibot.output(u"Aucun texte dans la page !") continue titres = complements.extract_titles(text, beginning = "", match_title = self.match_titre_requete) sections = complements.extract_sections(text, titres) text_to_archive = u"" requests_to_archive = [] requests_to_delete = [] # Début de la boucle d'analyse de chacune des sections, au cas par cas. for numero_section in sections: pywikibot.output('--------------------------------') pywikibot.output(titres[numero_section]) analyse = self.analyse_section(sections[numero_section]) if analyse == None: # Une erreur a eu lieu continue date = analyse['date'] statut = analyse['statut'] if not date: pywikibot.output(u'erreur : pas de date !') continue try: date = self.match_date.search(date) pywikibot.output(date.group('month')) # Il est préférable de reformater la date, toujours au format string # avant de la parser avec la commande datetime.strptime. # Ici, la date est normalisée suivant le format suivant : # jour mois année heures:minutes (tout en chiffres) # ex : 13 02 2012 23:34 # On préfèrera utiliser exclusivement des chiffres pour éviter # des problèmes liés aux accents sur le nom de certains mois, # tels février, décembre et août. text_date = u"%s %s %s %s:%s" % (date.group('day'), self.les_mois[date.group('month')], date.group('year'), date.group('hours'), date.group('minutes')) date = datetime.strptime(text_date, u"%d %m %Y %H:%M") pywikibot.output("date is: %s" % date) except: pywikibot.output(u'erreur: problème avec la date') continue now = datetime.now() #pywikibot.output(now) pywikibot.output(u"délai classement : %i heures" % self.dict['delai']['classement']) #pywikibot.output((now-date)) pywikibot.output("from then to now: %s, that is %i hours" % ((now-date), ((now-date).seconds/3600) + (now-date).days*24)) if self.dict['archiver'][type]: # Si l'archivage des requêtes est activé. if self.dict['delai']['archivage'] <= ((now-date).seconds/3600 + (now-date).days*24): pywikibot.output(u'=> archivage') text_to_archive += sections[numero_section] requests_to_archive.append(sections[numero_section]) text = text.replace(sections[numero_section], '') else: pywikibot.output(u'=> pas d\'archivage') elif self.dict['supprimer'][type]: # Sinon, si leur suppression est activée. if self.dict['delai']['suppression'] <= ((now-date).seconds/3600 + (now-date).days*24): pywikibot.output(u'=> suppression') text = text.replace(sections[numero_section], '') requests_to_delete.append(sections[numero_section]) else: pywikibot.output(u'=> pas de suppression') # Fin de la boucle traitant les sections au cas par cas. # # La variable text_to_archive contient désormais la totalité des requêtes # à archiver (texte), si l'archivage est activé pour le type de requêtes en # cours de traitement. # # La variable requests_to_archive contient désormais la liste des requêtes # à archiver, si l'archivage est activé pour le type de requêtes en # cours de traitement. if self.dict['archiver'][type]: if not text_to_archive: # Si rien n'est à archiver, on passe directement # au traitement suivant (de l'autre type de requêtes). continue # Trouver le numéro de la page d'archive en cours archiveNumber=1 archive_page = None while True: previous_archive_page = archive_page archive_page = pywikibot.Page(self.site, self.main_page.title(asLink = False) + "/%s%i" % (self.archivePrefix, archiveNumber)) if not archive_page.exists(): break archiveNumber += 1 if previous_archive_page != None: archiveNumber -= 1 archive_page = previous_archive_page pywikibot.output(archive_page) #pywikibot.output(text_to_archive) # La variable archiveNumber contient à présent le numéro # de la page d'archive en cours. # Si la page d'archive existe (si elle n'existe pas, c'est qu'aucune page # d'archive n'a été trouvée par le bot. if archive_page.exists(): # On compte le nombre de requêtes déjà présentes dans # la page d'archive en cours. # Pour cela, on remplace chaque titre de section par '{[$REQUETE$]}' # et on compte le nombre de '{[$REQUETE$]}'. nombre_de_sections = re.sub(self.match_titre_requete, '{[$REQUETE$]}', archive_page.get()).count('{[$REQUETE$]}') #print re.sub(self.match_titre_requete, '{[$REQUETE$]}', text) pywikibot.output('nombre_de_sections = %i' % nombre_de_sections) if nombre_de_sections > 250: old_archiveNumber = archiveNumber old_archive_page = archive_page # On récupère la dernière requête pour donner la dernière date # de la page d'archive. text_temp = old_archive_page.get() old_archives = complements.extract_sections(text_temp, complements.extract_titles(text_temp, "", self.match_titre_requete)) last_archive = old_archives[len(old_archives) - 1] templates = textlib.extract_templates_and_params(last_archive) for template in templates: pywikibot.output(template) if template[0] == self.template_title:#u'RA début': #modifié (todo A-1) statut = template[1]['statut'] date = template[1]['date'] pywikibot.output(date) # On arrête d'analyser les modèles, étant donné qu'on a trouvé # celui qui nous intéresse. break if date: try: pywikibot.output(date) last_date = self.match_date.search(date) pywikibot.output(last_date) last_date = u"%s %s %s" % (last_date.group('day'), last_date.group('month'), last_date.group('year')) pywikibot.output(last_date) except Exception, myexception: pywikibot.output(u'%s %s' % (type(myexception), myexception.args)) pywikibot.output(u'erreur: problème avec la date') else: pywikibot.output(u'erreur : pas de date !') # La variable last_date contient désormais la date de la dernière # requête de la page d'archives. archiveNumber += 1 archive_page = pywikibot.Page(self.site, self.main_page.title(asLink = False) + "/%s%i" % (self.archivePrefix, archiveNumber)) new_text = text_to_archive pywikibot.output(u"Plus de 250 requêtes archivées -> création d'une nouvelle page d'archive (n°%i)" % archiveNumber) # Mise à jour de la page d'archives principale main_archive_page = pywikibot.Page(self.site, self.main_page.title() + u"/Archives") text_temp = main_archive_page.get() text_temp = re.sub(u"(\# *\[\[%s\]\]) *" % old_archive_page.title(asLink = False), u"\\1 (jusqu'au %s)\n# %s" % (last_date, archive_page.title(asLink = True)), text_temp) main_archive_page.put(text_temp, comment = u"Création d'une nouvelle page d'archives") else: pywikibot.output(u"Moins de 250 requêtes archivées -> page d'archive actuelle (n°%i)" % archiveNumber) new_text = archive_page.get() while new_text[-2:] != '\n\n': # Pour rajouter des sauts de lignes si nécessaire. new_text += '\n' new_text += text_to_archive else: # Aucune page d'archive n'a été trouvée par le bot. pywikibot.output(u"1ère page d'archive ! Aucune ne semble exister actuellement…") new_text = text_to_archive # Mise à jour de la page de classement en cours de traitement # ainsi que de la apge d'archive comment = (u"Archivage de %i requêtes" % len(requests_to_archive)) try: # pwb_error pywikibot.showDiff(page_en_cours.get(), text) pywikibot.output('******************************************************') # pwb_error if archive_page.exists(): # pwb_error pywikibot.showDiff(archive_page.get(), new_text) page_en_cours.put(text, comment = (comment + u" vers %s" % archive_page.title(asLink = True))) archive_page.put(new_text, comment = comment) except Exception, myexception: pywikibot.output("erreur type 2")
part_type, role, parent, mod = save_read(template, "type"), save_read(template, "role"), save_read(template, "parent"), save_read(template, "mod") # part_type = None if part_type and part_type not in TYPES: print("Part type '{}' is not recognised.".format(part_type)) old_part_type = part_type part_type = None else: old_part_type = None if not part_type and (bool(role) is not (bool(parent) or bool(mod))): #inconsitent: no type and only role xor parent failures += [(save_read(template, "file", ""), page.title(), "Inconsistent parameters.", [])] valid_guesses = None elif page.title() in manual_type: valid_guesses = [manual_type[page.title()]] successes += [(save_read(template, "file", ""), page.title(), "Updated because the type was manually defined in the [[User:BobBot/Types]] table", valid_guesses)] elif not part_type and not role: #no data at all: can guess more_templates = textlib.extract_templates_and_params(save_read(template, "more", "")) sub_templates = [] for more_template in more_templates: sub_template = more_template[0][len("Infobox/Part/"):] if sub_template in WATCHED: sub_templates += [(sub_template, more_template[1])] valid_guesses = [] for type_name, type_tuple in TYPES.iteritems(): # all in required must be in sub_template required = len(type_tuple[0]) > 0 other_templates = [] for e in type_tuple[0]: for sub_template in sub_templates: if matches(type_name, e, sub_template): break
def get_params(self): text = self.main_page.get() templates = textlib.extract_templates_and_params(text) template_in_use = None for tuple in templates: if tuple[0] == modele.title(asLink=False): template_in_use = tuple[1] break if not template_in_use: pywikibot.output(u"Aucun modèle {{%s}} détecté sur la page %s" % (modele.title(asLink=False), main_page.title())) return False titre_categorie = check_and_return_parameter(template_in_use, u'catégorie') if not titre_categorie: return False self.cat = pywikibot.Category(site, titre_categorie) if not self.cat.exists(): pywikibot.output(u"Erreur : la catégorie n'existe pas") return False self.nbMax = check_and_return_parameter(template_in_use, 'nbMax', -1) try: self.nbMax = int(self.nbMax) except: pywikibot.output(u'Erreur : nbMax incorrect') return False self.minimum = check_and_return_parameter(template_in_use, 'minimum', '10') try: self.minimum = int(self.minimum) except: pywikibot.output(u'Erreur : minimum incorrect') return False self.actions = check_and_return_parameter(template_in_use, 'actions', '0,1,3') try: [int(k) for k in self.actions.split(',')] except: pywikibot.output(u'Erreur : des actions spécifiées ne sont pas des entiers') return False self.delai = check_and_return_parameter(template_in_use, u'délai', '7') try: self.delai = int(self.delai) if self.delai <= 0: pywikibot.output(u'Erreur : délai négatif') return False except: pywikibot.output(u'Erreur : délai incorrect') return False self.orange = check_and_return_parameter(template_in_use, 'limite_orange', '20') try: self.orange = int(self.orange) except: pywikibot.output(u'Erreur : orange incorrect') return False self.rouge = check_and_return_parameter(template_in_use, 'limite_rouge', '40') try: self.rouge = int(self.rouge) except: pywikibot.output(u'Erreur : rouge incorrect') return False self.mineures = check_and_return_parameter(template_in_use, 'mineures', '0') try: self.mineures = int(self.mineures) except: pywikibot.output(u'Erreur : mineures incorrect') return False self.contributeurs = check_and_return_parameter(template_in_use, 'contributeurs', '0') try: self.contributeurs = int(self.contributeurs) except: pywikibot.output(u'Erreur : contributeurs incorrect') return False self.minimum_contributeurs = check_and_return_parameter(template_in_use, 'minimum_contributeurs', '1') try: self.minimum_contributeurs = int(self.minimum_contributeurs) except: pywikibot.output(u'Erreur : minimum_contributeurs incorrect') return False self.bots_inclus = check_and_return_parameter(template_in_use, 'bots_inclus', '1') try: self.bots_inclus = int(self.bots_inclus) except: pywikibot.output(u'Erreur : bots_inclus incorrect') return False self.bots_inclus_str = '' if self.bots_inclus == 0: # ne pas prendre les bots en compte # rc_bot indique une modification faite par un bot self.bots_inclus_str = 'AND rc_bot = 0' self.transclusion = check_and_return_parameter(template_in_use, 'transclusion', '0') try: self.transclusion = int(self.transclusion) except: pywikibot.output(u'Erreur : transclusion incorrect') return False self.diff = check_and_return_parameter(template_in_use, 'diff', '0') try: self.diff = int(self.diff) except: pywikibot.output(u'Erreur : diff incorrect') return False self.lien_historique = check_and_return_parameter(template_in_use, 'lien_historique', '0') try: self.lien_historique = int(self.lien_historique) except: pywikibot.output(u'Erreur : diff incorrect') return False return True
def processPage(self, page): """Process a single page.""" item = pywikibot.ItemPage.fromPage(page) self.current_page = page if not item.exists(): pywikibot.output('%s doesn\'t have a wikidata item :(' % page) #TODO FIXME: We should provide an option to create the page return item.get() if set(self.fields.values()) <= set(item.claims.keys()): pywikibot.output(u'%s item %s has claims for all properties. Skipping' % (page, item.title())) else: pagetext = page.get() templates = textlib.extract_templates_and_params(pagetext) for (template, fielddict) in templates: # Clean up template try: template = pywikibot.Page(page.site, template, ns=10).title(withNamespace=False) except pywikibot.exceptions.InvalidTitle: pywikibot.error(u"Failed parsing template; '%s' should be the template name." % template) continue # We found the template we were looking for if template in self.templateTitles: for field, value in fielddict.items(): field = field.strip() value = value.strip() if not field or not value: continue # This field contains something useful for us if field in self.fields: # Check if the property isn't already set claim = pywikibot.Claim(self.repo, self.fields[field]) if claim.getID() in item.get().get('claims'): pywikibot.output( u'A claim for %s already exists. Skipping' % claim.getID()) # TODO: Implement smarter approach to merging # harvested values with existing claims esp. # without overwriting humans unintentionally. else: if claim.type == 'wikibase-item': # Try to extract a valid page match = re.search(pywikibot.link_regex, value) if not match: pywikibot.output(u'%s field %s value %s isnt a wikilink. Skipping' % (claim.getID(), field, value)) continue link_text = match.group(1) linked_item = self._template_link_target(item, link_text) if not linked_item: continue claim.setTarget(linked_item) elif claim.type == 'string': claim.setTarget(value.strip()) elif claim.type == 'commonsMedia': commonssite = pywikibot.Site("commons", "commons") imagelink = pywikibot.Link(value, source=commonssite, defaultNamespace=6) image = pywikibot.FilePage(imagelink) if image.isRedirectPage(): image = pywikibot.FilePage(image.getRedirectTarget()) if not image.exists(): pywikibot.output('[[%s]] doesn\'t exist so I can\'t link to it' % (image.title(),)) continue claim.setTarget(image) else: pywikibot.output("%s is not a supported datatype." % claim.type) continue pywikibot.output('Adding %s --> %s' % (claim.getID(), claim.getTarget())) item.addClaim(claim) # A generator might yield pages from multiple sites source = self.getSource(page.site) if source: claim.addSource(source, bot=True)
def find_add(self, page, modele): """ modele is a pywikibot.Page """ site = pywikibot.Site() unblock_found = True history = page.getVersionHistory() pywikibot.output(u"Analysing page %s" % page.title()) if len(history) == 1: [(id, timestamp, user, comment)] = history return (timestamp, id) oldid = None requester = None timestamp_add = None look_back_count = 2 look_back = look_back_count for (id, timestamp, user, comment) in history: pywikibot.output( "Analyzing id %i: timestamp is %s and user is %s" % (id, timestamp, user + (" (lookback)" if look_back < look_back_count else ""))) if not user: pywikibot.output( "User's missing (hidden?), skipping this version...") continue text = page.getOldVersion(id) if not text: pywikibot.output( u"Can't get rev text (hidden?), skipping this version...") continue # text might be too long, if so textlib.extract_templates_and_params won't # proceed and will skip some templates #if u"{{déblocage" in text.lower(): # text = text[max(0,text.lower().index(u"{{déblocage")-12):] templates_params_list = textlib.extract_templates_and_params(text) unblock_found = False for (template_name, dict_param) in templates_params_list: try: template_page = pywikibot.Page( pywikibot.Link(template_name, site, defaultNamespace=10), site) # TODO : auto-finding redirections if template_page == modele: #pywikibot.output((template_name, dict_param)) unblock_found = True look_back = look_back_count break except Exception, myexception: pywikibot.output( u'An error occurred while analyzing template %s' % template_name) pywikibot.output(u'%s %s' % (type(myexception), myexception.args)) #if oldid: # print("oldid is %i" % oldid) #else: # print "no oldid" if (not unblock_found and id == oldid): # We did not find the model we were looking for # in the most recent revision: abort pywikibot.output( "Last revision does not contain any {{modele}} template!") return None elif not unblock_found: # We did not find the model we are looking for # in some old revision, but it was present in # more recent ones. # We will snap back at look_back revisions, to check # whether the model was truly added in the current # revision or if it dates back to some older revision # and was simply removed heer due to eg. vandalism if look_back > 0: pywikibot.output( "Template was added in oldid https://fr.wikipedia.org/w/index.php?oldid=%i" % oldid) return (timestamp_add, oldid) else: # Look back another time, but don't change # the future value returned (requested, oldid # timestamp_add) look_back -= 1 else: requester = pywikibot.User(site, user) oldid = id timestamp_add = timestamp
import re from pywikibot import textlib site = pywikibot.getSite() data_template = re.compile("^.*/(Data|Box|RefFrame|Param)$") yes_all = False for arg in pywikibot.handleArgs(): if arg in ["--all", "-a"]: yes_all = True for page in site.allpages(): match = data_template.search(page.title()) if match: if not page.isRedirectPage(): content = page.text templates = textlib.extract_templates_and_params(content) for template in templates: if template[0] == "Data template used": print("Already contain template in '{}'. Skipped.".format( page.title())) break else: # for didn't find page.text = "<noinclude>{{Data template used}}</noinclude>" + content if not yes_all: answer = pywikibot.inputChoice( "Add template to '{}'?".format(page.title()), ['Yes', 'No', 'All'], ['y', 'n', 'a'], 'n') if answer == 'a': yes_all = True if yes_all or answer != 'n':
def treat_page(self): # todo: treat_page_and_item page = self.current_page item = page.data_item() item.get() if 'P373' in item.claims.keys(): self.addCallback(page.touch, botflag=True) pywikibot.output('Already has a category on Commons') return cat_name = None has_param = False for template, fielddict in textlib.extract_templates_and_params( page.text, remove_disabled_parts=True, strip=True): # todo: l10n if template.lower() in ['commonscat', 'commons category']: cat_name = page.title(with_ns=False) if '1' in fielddict: value = fielddict['1'].strip() if value: has_param = True cat_name = value break if cat_name is None: pywikibot.warning('Template not found') return commons_cat = pywikibot.Category(self.commons, cat_name) exists = commons_cat.exists() if not exists: if not commons_cat.isEmptyCategory(): if self.getOption('createnew') is True: exists = self.doWithCallback( self.userPut, commons_cat, '', '{{Uncategorized}}', asynchronous=False) else: pywikibot.warning('%s is not empty' % commons_cat.title()) return if not exists: if self.getOption('noclean') is True: pywikibot.output('Category doesn\'t exist on Commons, ' 'cleanup restricted') return regex = r'(?:[\n\r]?|^)(?:\* *)?\{\{ *[Cc]ommons(?:cat|[_ ]?category) *' if has_param: regex += r'\| *' + re.escape(cat_name) regex += r'[^\}]*\}\}' page_replaced_text = re.sub(regex, '', page.text, flags=re.M | re.U, count=1) if page_replaced_text != page.text: # todo: l10n etc. templates = ( '|'.join(map(re.escape, page.site.getmagicwords('defaultsort'))), '[Pp]ahýl', '[Pp]osloupnost', '[Aa]utoritní data', '[Pp]ortály') page_replaced_text = re.sub( r'\s*==+ ?Externí odkazy ?==+ *$\s*^(==|\{\{' '(?:' + '|'.join(templates) + ')' r'|\[\[(?:%s):)' % '|'.join(page.site.namespaces[14]), r'\n\n\1', page_replaced_text, flags=re.M | re.U, count=1) # fixme self.doWithCallback( self.put_current, page_replaced_text, summary=i18n.translate(page.site, save_summary)) else: if self.getOption('noimport') is True: pywikibot.output('Category exists on Commons, import restricted') return claim = pywikibot.Claim(self.repo, 'P373') claim.setTarget(cat_name) pywikibot.output('Category missing on Wikidata') self.user_add_claim(item, claim, page.site, asynchronous=True) self.addCallback(page.touch, botflag=True)
import re from pywikibot import textlib site = pywikibot.getSite() data_template = re.compile("^.*/(Data|Box|RefFrame|Param)$") yes_all = False for arg in pywikibot.handleArgs(): if arg in ["--all", "-a"]: yes_all = True for page in site.allpages(): match = data_template.search(page.title()) if match: if not page.isRedirectPage(): content = page.text templates = textlib.extract_templates_and_params(content) for template in templates: if template[0] == "Data template used": print("Already contain template in '{}'. Skipped.".format(page.title())) break else: # for didn't find page.text = "<noinclude>{{Data template used}}</noinclude>" + content if not yes_all: answer = pywikibot.inputChoice("Add template to '{}'?".format(page.title()), ['Yes', 'No', 'All'], ['y', 'n', 'a'], 'n') if answer == 'a': yes_all = True if yes_all or answer != 'n': page.save(comment="+add 'data template used' template;") print("Edited page '{}'.".format(page.title())) else:
genFactory = pagegenerators.GeneratorFactory(site=site) for ns in (0, 14, 100): if family != 'wikisource' and ns == 100: # fixme: cswikiquote continue if family == 'wikisource' and ns == 0: continue genFactory.handleArg('-ns:%i' % ns) genFactory.handleArg('-unconnectedpages') generator = genFactory.getCombinedGenerator(preload=True) for page in generator: if page.namespace() != 14 and page.isDisambig(): continue for template, fields in textlib.extract_templates_and_params(page.text): if first_lower(template) not in tp_map[project].keys(): continue params = tp_map[project][first_lower(template)] for key in fields.keys(): if key not in params.keys(): continue title = fields[key].strip() if not title: continue target_lang = lang target_family = family if isinstance(params[key], dict):
def treat(self, page, item): """Process a single page/item.""" if willstop: raise KeyboardInterrupt self.current_page = page item.get() titre = page.title() clubs = [] teams = [] years = [] stats = [] value_stat = "" #param -b if self.param_first is not None: if self.param_first in titre: self.param_first = None else: pywikibot.output('Skipping') return pagetext = page.get(False, True) # on met de côté les tableaux entraîneur et junior if self.param_debug: pywikibot.output( 'self.fields %s' % self.fields) templates = textlib.extract_templates_and_params(pagetext) if self.param_debug: pywikibot.log( 'templates : %s' % templates) for (template, fielddict) in templates: # Clean up template try: template = pywikibot.Page(page.site, template, ns=10).title(withNamespace=False) except pywikibot.exceptions.InvalidTitle: pywikibot.error( "Failed parsing template; '%s' should be the template name." % template) continue # We found the template we were looking for if template in self.templateTitles: #nettoyage du fielddict for field, value in fielddict.items(): field_stripd = field.strip() value_stripd = value.strip() del fielddict[field] fielddict[field_stripd] = value_stripd if self.param_debug: pywikibot.output( 'hastings-test-wp0 %s' % fielddict) if fielddict.get("vereine") is not None : if self.param_debug: pywikibot.output( 'hastings-test-wp0 clubs %s -> years %s & stats %s' % (fielddict.get("vereine"), fielddict.get("jahre"), fielddict.get("spiele (tore)"))) clubs = re.split("< *br *\/?>", fielddict.get("vereine")) if fielddict.get("jahre") is not None : years = re.split("< *br *\/?>", fielddict.get("jahre")) if fielddict.get("spiele (tore)") is not None : spiele = fielddict.get("spiele (tore)").replace("{{0}}", "") stats = re.split("< *br *\/?>", spiele) if (len(clubs)==len(years)): if self.param_debug: pywikibot.output( '%s %s %s' % (clubs, years, stats)) for i in range(0, len(clubs)): if (i<len(stats)): value_stat = stats[i] if self.param_debug: pywikibot.output( '%s %s %s %s' % (i, clubs[i], years[i], value_stat)) self.adding(item, clubs[i], years[i], value_stat, page) else: break if fielddict.get("nationalmannschaft") is not None : if self.param_debug: pywikibot.output( 'hastings-test-wp0 teams %s -> years %s & stats %s' % (fielddict.get("nationalmannschaft"), fielddict.get("nationaljahre"), fielddict.get("länderspiele (tore)"))) teams = re.split("< *br *\/?>", fielddict.get("nationalmannschaft")) if fielddict.get("nationaljahre") is not None : years = re.split("< *br *\/?>", fielddict.get("nationaljahre")) if fielddict.get("länderspiele (tore)") is not None : spiele = fielddict.get("länderspiele (tore)").replace("{{0}}", "") stats = re.split("< *br *\/?>", spiele) if (len(teams)==len(years)): for i in range(0, len(teams)): if (i<len(stats)): value_stat = stats[i] if self.param_debug: pywikibot.output( '%s %s %s %s' % (i, teams[i], years[i], value_stat)) self.adding(item, teams[i], years[i], value_stat, page) else: break
def treat_page(self): """Load the given page, do some changes, and save it.""" refR = re.compile(r'(?P<all><ref.*?</ref>)') # clenaupR = re.compile(r'(?i){{dopracować.*?}}') text = self.current_page.text links = { 'links': 0, 'cat': 0, 'template': 0, 'infobox': 0, 'refs': 0, 'dopracować': False } # cleanupTmpl = False summary = [] if self.current_page.isRedirectPage(): pywikibot.output(u'Page %s is REDIRECT!' % self.current_page.title()) return elif self.current_page.isDisambig(): pywikibot.output(u'Page %s is DISAMBIG!' % self.current_page.title()) return else: if self.opt.test: pywikibot.output(u'Title:%s' % self.current_page.title()) pywikibot.output(u'Depth:%s' % self.current_page.depth) for l in self.current_page.linkedPages(namespaces=0): if self.opt.test: pywikibot.output(u'Links to:[[%s]]' % l.title()) links['links'] += 1 # pywikibot.output(u'Links:%s' % len(list(self.current_page.linkedPages(namespaces=0)))) for t, p in textlib.extract_templates_and_params( text, remove_disabled_parts=True): if self.opt.test: pywikibot.output('Template:[[%s]]' % t) links['template'] += 1 if 'infobox' in t: links['infobox'] += 1 if 'dopracować' in t.lower(): links['dopracować'] = True if t.lower( ) in tmplcat: # check for category adding templates links['cat'] += 1 if self.opt.test: pywikibot.output('Current cat#%i' % links['cat']) # cleanupTmpl = (t, p) # if 'rok w' in t or 'Rok w' in t: # links['cat'] += 1 for c in textlib.getCategoryLinks(text): if self.opt.test: pywikibot.output('Category:%s' % c) links['cat'] += 1 if self.opt.test: pywikibot.output('Current cat#%i' % links['cat']) for r in refR.finditer(text): if self.opt.test: pywikibot.output('Ref:%s' % r.group('all')) links['refs'] += 1 if self.opt.test: pywikibot.output('Links=%s' % links) # pywikibot.output('Cleanup=%s' % re.sub('\n','',textlib.glue_template_and_params(cleanupTmpl))) if links['dopracować']: if self.opt.test: pywikibot.output('Cleanup Tmpl FOUND') else: # add {{Dopracować}} t = 'Dopracować' # template title p = {} # template params today = datetime.now() datestr = today.strftime('%Y-%m') if self.opt.test: pywikibot.output('Date:%s' % datestr) if not (links['links'] and links['cat']): if not links['links']: p['linki'] = datestr summary.append('linki') if not links['cat']: p['kategoria'] = datestr summary.append('kategorie') # if not links['refs']: # p['przypisy'] = datestr # summary.append('przypisy') cleanupTmpl = (t, p) if not p: if self.opt.test: pywikibot.output('Nothing to add') return if self.opt.test: pywikibot.output('Cleanup Tmpl TO ADD') pywikibot.output('summary:%s' % summary) pywikibot.output('params:%s' % p) text = re.sub( '\n', '', textlib.glue_template_and_params(cleanupTmpl)) + '\n' + text # if summary option is None, it takes the default i18n summary from # i18n subdirectory with summary_key as summary key. self.put_current( text, summary= 'Sprawdzanie nowych stron, w artykule należy dopracować: %s' % ','.join(summary))
def traitement(self): pageTraitees = pywikibot.Page( self.site, u"Wikipédia:Demande de restauration de page/Traitées") pageRefusees = pywikibot.Page( self.site, u"Wikipédia:Demande de restauration de page/Refusées") pageSanssuite = pywikibot.Page( self.site, u"Wikipédia:Demande de restauration de page/Sans suite") list = [(self.main_page, u'Requêtes à traiter'), (self.main_page, u"Requêtes en cours d'examen"), (pageTraitees, None), (pageRefusees, None), (pageSanssuite, None)] for couple in list: dict = self.analyse_une_section(page=couple[0], match_debut=couple[1]) sections = dict['sections'] if not sections: continue for numero_section in sections: pywikibot.output('\n') titre_section = dict['titres'][numero_section] section = sections[numero_section] templates = textlib.extract_templates_and_params(section) # templates est du type : # [(u'DRP début', {u'date': u'27 février 2010 à 14:56 (CEC)' # , u'statut': u'oui'}), (u'DRP fin', {})] PaS = False found_full_template = False for template in templates: if template[0] == u'DRP début': if not ('statut' in template[1]): pywikibot.output( u"pas de paramètre 'statut' trouvé") continue elif not ('date' in template[1]): pywikibot.output(u"pas de paramètre 'date' trouvé") continue found_full_template = True statut_actuel = template[1]['statut'] date = template[1]['date'] if template[1].has_key(u'PàS'): pywikibot.output('phase try 0') pywikibot.output(template[1][u'PàS']) if template[1][u'PàS'] == 'oui': pywikibot.output('phase try 1') PaS = True page_PaS = None elif template[1][u'PàS'] != '': pywikibot.output('phase try 2') PaS = True page_PaS = pywikibot.Page( self.site, u"%s/Suppression" % template[1][u'PàS']).toggleTalkPage() pywikibot.output(u'found_full_template = %s' % found_full_template) if not found_full_template: pywikibot.output( 'Fully fulfilled template was not found, skipping to next section.' ) continue pywikibot.output(u"PaS = %s" % PaS) if PaS: try: pywikibot.output(u"page_PaS = %s" % page_PaS) except: pywikibot.output(u"no page_PaS") # Pour enlever les == et les éventuels espaces # du titre de la section puis les [[…]] qui sont # supprimés de l'URL par MediaWiki. titre_section = titre_section[2:-2] titre_section = titre_section.strip() titre_section_SQL = titre_section titre_section_MediaWiki = titre_section titre_section_MediaWiki = titre_section_MediaWiki.replace( "[[", "") titre_section_MediaWiki = titre_section_MediaWiki.replace( "]]", "") pywikibot.output(u"=== %s ===" % titre_section) pywikibot.output(u"statut_actuel = %s" % statut_actuel) pywikibot.output(u"date = %s" % date) if statut_actuel not in self.status_knonw: # Si le demande de restauration ne possède pas un de ces statuts, # il est inutile d'aller plus loin car seuls ceux-ci nécessitent # de laisser un message au demandeur. continue # Vérifier si la requête a déjà été analysée par le bot. self.database.query( 'SELECT * FROM drp WHERE titre_section = "%s"' % titre_section_SQL.replace('"', '\\"').encode('utf-8')) results = self.database.store_result() result = results.fetch_row(maxrows=0) if result: # Si oui, et si le statut est toujours le même, il n'y a rien à faire statut_traite = result[0][1] pywikibot.output(statut_traite) # La vérification d'un éventuel lancement d'une PàS technique # pour la restauration n'est faite que par la suite, le statut # 'oui_PaS' ne peut donc pas encore être le statut_actuel, # même si une PàS a été lancée ! # On remplace donc l'éventuel statut traité 'oui_PaS' par un # simple 'oui'. if statut_traite == 'oui_PaS': statut_traite = 'oui' if statut_traite.decode('utf-8') == statut_actuel: # Si le statut actuel est le même que celui qui a déjà été # traité, il n'y a rien d'autre à faire : le demandeur # a déjà été averti. pywikibot.output(u'DRP déjà traitée !') continue else: pywikibot.output( u'DRP déjà traitée mais statut différent…') # Supprimer la requête de la base de donnée SQL pour éviter # qu'elle ne se retrouve en double avec deux statuts # différents. self.database.query( 'DELETE FROM drp WHERE titre_section = "%s"' % titre_section_SQL.replace('"', '\\"').encode('utf-8')) #print section # Si on arrive ici, c'est que le demandeur n'a pas été averti du # statut actuel m1 = re.search( u"[dD]emandée? par .*\[ *\[ *([uU]tilisateur:|[uU]ser:|[sS]p[eé]cial:[cC]ontributions/)(?P<nom_demandeur>[^|\]]+)(\|| *\] *\])", section) m2 = re.search( u"[dD]emandée? par {{u'?\|(?P<nom_demandeur>[^|]+?)}}", section) m3 = re.search( u"[dD]emandée? par (?P<nom_demandeur>[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)", section) if m1: nom_demandeur = m1.group('nom_demandeur') #print 'm1' elif m2: nom_demandeur = m2.group('nom_demandeur') #print 'm2' elif m3: nom_demandeur = m3.group('nom_demandeur') #print 'm3' else: pywikibot.output(u'nom du demandeur introuvable !') continue #print nom_demandeur demandeur = pywikibot.User(self.site, nom_demandeur) if u'autopatrolled' in demandeur.groups(): pywikibot.output( u'demandeur autopatrolled : inutile de laisser un message' ) continue elif demandeur in self.whitelist: pywikibot.output(u"l'utilisateur est sur la whitelist") continue page_discussion_demandeur = demandeur.getUserTalkPage() pywikibot.output(page_discussion_demandeur) m = re.findall(u"\[ *\[ *(?P<titre_page>.*?) *\] *\]", titre_section) if not m: pywikibot.output( u'Titre de la page concernée introuvable !') continue titre_page_concernee = m[ 0] # Si plusieurs titres sont présents, vérifier arbitrairement que le premier titre_pages_concernees = u']], [['.join(m) pywikibot.output(titre_page_concernee) # Vérifier si une PàS technique pour la restauration a été # lancée ou non. if statut_actuel == 'oui': if PaS: statut_actuel = 'oui_PaS' pywikibot.output('oui_PaS') if not page_PaS or not page_PaS.exists(): try: page_PaS = pywikibot.Page( self.site, titre_page_concernee + "/Suppression" ).toggleTalkPage( ) #pywikibot.Page(self.site, u"Discussion:%s/Suppression" % titre_page_concernee) page_PaS.get() except: pywikibot.output( u'erreur : la PàS technique ne semble pas exister ou n\'est pas normalisée !' ) statut_actuel = 'oui_PaS_mais_introuvable' if page_PaS: # La PàS peut avoir été renommée if page_PaS.isRedirectPage(): page_PaS = page_PaS.getRedirectTarget() if re.search( u"[pP]roposé *par.* ([0-9]{1,2}.*20[01][0-9]) à [0-9]{2}:[0-9]{2}", page_PaS.get()): date_debut_PaS = re.search( u"[pP]roposé *par.* ([0-9]{1,2}.*20[01][0-9]) à [0-9]{2}:[0-9]{2}", page_PaS.get()).group(1) else: # Si la date n'est pas formatée comme attendue sur la PàS, le bot # cherche sa date de création en remontant l'historique, puis l'exprime # sous la forme attendue. date_creation = page_PaS.getVersionHistory( )[-1][1] date_debut_PaS = date_creation.strftime( "%d %B %Y") message = self.messages[statut_actuel] # La fonction urllib.quote() permet d'encoder une URL. # Ici, seul le titre de la section a besoin d'être encodé. # Cependant, MediaWiki remplace les espaces par des tirets bas ('_') # et les % dans l'encodage par des points ('.'). lien_drp = u"%s#%s" % ( self.main_page.title(asLink=False), urllib.quote(titre_section_MediaWiki.encode('utf-8'), safe=" /").replace(" ", "_").replace( "%", ".")) #pywikibot.output(u'lien_drp = %s' % lien_drp) if statut_actuel in [ 'non', 'oui', 'oui_PaS_mais_introuvable', 'sanssuite' ]: message = message % { 'titre_page': titre_page_concernee, 'lien_drp': lien_drp, 'date_debut_lien_valide': date } elif statut_actuel == 'oui_PaS': if not type(date_debut_PaS) == unicode: pywikibot.output(u"Formattage de date_debut_PaS") date_debut_PaS = date_debut_PaS.decode('utf-8') message = message % { 'titre_page': titre_page_concernee, 'lien_drp': lien_drp, 'date_debut_lien_valide': date, 'titre_PaS': page_PaS.title(asLink=False), 'date_debut_PaS': date_debut_PaS } elif statut_actuel in ['attente', 'autre', 'autreavis']: message = message % { 'titre_page': titre_page_concernee, 'lien_drp': lien_drp } else: pywikibot.output(u'statut inconnu : %s' % statut_actuel) continue # # Mauvaise gestion des IPv6 par pywikibot # Les caractères doivent être en majuscules # pattern_ipv6 = "Discussion utilisateur:(([0-9a-zA-Z]{,4}:){7}[0-9a-zA-Z]{,4})" if re.search(pattern_ipv6, page_discussion_demandeur.title()): ipv6 = re.search( pattern_ipv6, page_discussion_demandeur.title()).group(1) ipv6 = ipv6.upper() page_discussion_demandeur = pywikibot.Page( pywikibot.Site(), u"Discussion utilisateur:" + ipv6) # while page_discussion_demandeur.isRedirectPage(): page_discussion_demandeur = page_discussion_demandeur.getRedirectTarget( ) titre = self.titre_message % { 'titre_page': titre_pages_concernees } if page_discussion_demandeur.isFlowPage(): board = pywikibot.flow.Board( self.site, page_discussion_demandeur.title()) board.new_topic(titre, message) else: if page_discussion_demandeur.text: page_discussion_demandeur.text += '\n\n' if message in page_discussion_demandeur.text: pywikibot.output( u'BUG #13: le message a déjà été posté sur %s !' % page_discussion_demandeur.title(asLink=True)) continue page_discussion_demandeur.text += u"== %s ==" % titre + '\n' + message + u'\n\nDistribué par [[Utilisateur:ZéroBot|ZéroBot]], le ~~~~~' comment = self.resume % { 'titre_page': titre_pages_concernees } pywikibot.output(comment) try: page_discussion_demandeur.save(comment=comment, minorEdit=False) except: pywikibot.output( u'erreur lors de la publication du message !') continue # Enregistrer la requête comme analysée par le bot self.database.query( 'INSERT INTO drp VALUES ("%s", "%s", CURRENT_TIMESTAMP)' % (titre_section_SQL.replace('"', '\\"').encode('utf-8'), statut_actuel.encode('utf-8')))
def put_cats(page, new_cats, summary=None, always=False): line_sep = pywikibot.config.line_separator if not summary: summary = "Adding categories using catfiles" oldtext = page.get() old_cats = textlib.getCategoryLinks(oldtext) old_templates = textlib.extract_templates_and_params(oldtext) old_template_titles = [i[0].lower() for i in old_templates] templates, cats = [], [] for val in new_cats: if val.lower().startswith('category:'): tmp_cat = pywikibot.Category(pywikibot.Link(val, page.site)) if tmp_cat not in old_cats: cats.append(tmp_cat) elif val.lower().startswith('{{'): tmp_templates = textlib.extract_templates_and_params(val) if len(tmp_templates) != 1: logging.warn("There was an error when parsing the template " "'{0}'. Contact the developer, skipping it for " "now.".format(val)) tmp_template = tmp_templates[0] if tmp_template[0].lower() not in old_template_titles: templates.append(val) # Add templates to the top, and the categories to the bottom. newtext = oldtext if len(templates) > 0: newtext = line_sep.join(templates) + line_sep + newtext if len(cats) > 0: newtext = (newtext + line_sep + line_sep.join(c.title(asLink=True, underscore=False) for c in cats)) if oldtext == newtext: pywikibot.output("No changes to the page need to be made.") return while True: # Show the diff that has been created pywikibot.output(color_format( '\n\n>>> {lightpurple}{0}{default} <<<', page.title(underscore=False))) pywikibot.showDiff(oldtext, newtext) if always: choice = 'y' else: # Ask user whether to accept choice = pywikibot.input_choice( 'Do you want to accept these changes?', [('Yes', 'y'), ('No', 'n'), ('Edit', 'e'), ('Open browser', 'b')], 'n', automatic_quit=False) # Apply the choice from above if choice == 'n': break elif choice == 'b': pywikibot.bot.open_webbrowser(page) elif choice == 'e': editor = pywikibot.editor.TextEditor() as_edited = editor.edit(newtext) if as_edited and as_edited != newtext: newtext = as_edited elif choice == 'y': try: page.put_async(newtext, summary) except pywikibot.EditConflict: pywikibot.output('Edit conflict! Skipping') except pywikibot.ServerError: pywikibot.output('Server Error! Skipping') except pywikibot.SpamfilterError as e: pywikibot.output( 'Cannot change %s because of blacklist entry %s' % (page.title(), e.url)) except pywikibot.LockedPage: pywikibot.output('Skipping %s (locked page)' % page.title()) except pywikibot.PageNotSaved as error: pywikibot.output('Error putting page: %s' % error.args) break
def main(): config.use_mwparserfromhell = False locale.setlocale(locale.LC_ALL, "fr_FR.utf-8") db = False global test global dry dry = False # À activer seulement pour les tests test = False # À activer seulement pour tester le script sur une seule page ns_test = False recurse_test = False for arg in pywikibot.handleArgs(): if arg == "-dry": dry = True pywikibot.output(u"(dry is ON)") elif arg[0:6] == "-test:": test = True titre_page_test = arg[6:] elif arg[0:4] == "-ns:": ns_test = True namespaces_test_value = [int(i) for i in arg[4:].split(",")] elif arg[0:9] == "-recurse:": recurse_test = True recurse_test_value = bool(arg[9:]) comment_modele = ( u"%(nombre_articles)i articles) (Bot: Mise à jour de la liste des articles récents (%(precision_pages)s)" ) site = pywikibot.Site() titre_modele = u"Articles récents" modele = pywikibot.Page(site, titre_modele, ns=10) gen = pagegenerators.ReferringPageGenerator(modele, onlyTemplateInclusion=True) matchDebut1 = u"<!-- Ce tableau est créé automatiquement par un robot. Articles Récents DEBUT -->" matchFin1 = u"\n<!-- Ce tableau est créé automatiquement par un robot. Articles Récents FIN -->" matchDebut2 = u"<!-- Ce tableau est créé automatiquement par un robot. Articles Récents Liste DEBUT -->" matchFin2 = u"\n<!-- Ce tableau est créé automatiquement par un robot. Articles Récents Liste FIN -->" if test: pywikibot.output(u"(test is ON)") gen = [pywikibot.Page(site, titre_page_test)] if ns_test: pywikibot.output(u"(ns_test is ON)") for main_page in gen: try: comment = comment_modele pywikibot.output( u"\n========================\nTraitement de %s\n========================" % main_page.title() ) text = main_page.get() ##################### ### Récupération des informations sur la page ##################### templates = textlib.extract_templates_and_params(text) template_in_use = None for tuple in templates: if tuple[0] != u"Articles récents": continue else: template_in_use = tuple[1] break if not template_in_use: pywikibot.output(u"Aucun modèle {{Articles récents}} détecté sur la page %s" % main_page.title()) continue titre_categorie = check_and_return_parameter(template_in_use, u"catégorie") if not titre_categorie: continue cat = pywikibot.Category(site, titre_categorie) nbMax = check_and_return_parameter(template_in_use, "nbMax", 10) try: nbMax = int(nbMax) except: pywikibot.output(u"Erreur : nbMax incorrect") continue namespaces = check_and_return_parameter(template_in_use, "namespaces", "0") namespaces = namespaces.split(",") try: namespaces = [int(k) for k in namespaces] except: pywikibot.output(u"Erreur : des namespaces spécifiés ne sont pas des entiers") continue recurse = check_and_return_parameter(template_in_use, "recurse", "0") if recurse.lower().strip() in ("oui", "1"): recurse = True else: recurse = False delai_creation = check_and_return_parameter(template_in_use, "delai", "0") try: delai_creation = int(delai_creation) except: pywikibot.output(u"Erreur : delai incorrect") continue format_date = check_and_return_parameter(template_in_use, u"date") or None if format_date: try: test_date = datetime.datetime.now() test_date.strftime(format_date) except: format_date = None pywikibot.output(u"Erreur : format de date incorrect") puce = check_and_return_parameter(template_in_use, "puces", "#") listeRecents = text[(text.index(matchDebut1) + len(matchDebut1)) : text.index(matchFin1)] # Permet d'enlever le premier élément (vide) de la liste listeRecents = listeRecents.split("\n%s " % puce)[1:] listeRecents_old = [page for page in listeRecents] listeRecents = list() dico_dates_presentes = {} for recent in listeRecents_old: r = re.search(u"(\[\[.*\]\]) ?(\(.+\))?", recent) if r: listeRecents.append(r.group(1)) if r.group(2): dico_dates_presentes[r.group(1)] = r.group(2)[1:-1] else: pass text = re.sub( re.compile(u"%s.*%s" % (matchDebut2, matchFin2), re.S), u"%s%s" % (matchDebut2, matchFin2), text ) ##################### # Au cas où il n'y aurait aucune nouvelle page mais # une ou des pages ayant été supprimée(s) exception_maj = False # Pour préciser le résumé d'édition precisions_comment = u"" pywikibot.output("stade 0") ##################### ### Vérification des pages récentes actuelles (en cas de suppression) ##################### for titre_article in listeRecents: try: page = pywikibot.Page( site, re.sub(u"\[\[(.*)\]\]", "\\1", titre_article) ) # Pour enlever les crochets : [[…]]. # Si la page existe toujours et n'est pas une # redirection, on la laisse dans la liste… page.get() if format_date and not dico_dates_presentes.has_key(titre_article) and find_date(page, cat): # Date trouvée alors qu'elle n'y était pas. exception_maj = True dico_dates_presentes[titre_article] = find_date(page, cat).strftime(format_date) except pywikibot.NoPage: pywikibot.output(u"La page %s n'existe plus." % page.title(asLink=True)) pywikibot.output(u"Suppression de la page %s de la liste listeRecents" % page.title(asLink=True)) precisions_comment += u"; - %s" % titre_article listeRecents.remove(titre_article) # On force la mise à jour de la page, même si aucun nouvel article # récent n'est trouvé. exception_maj = True except pywikibot.IsRedirectPage: pywikibot.output(u"La page %s n'est plus qu'une redirection." % page.title(asLink=True)) try: nouvelle_page = page.getRedirectTarget() pywikibot.output( u"Modification du titre la page %s (renommée en %s)" % (page.title(asLink=True), nouvelle_page.title(asLink=True, withSection=False)) ) precisions_comment += u"; - %s ; + %s" % ( titre_article, nouvelle_page.title(asLink=True, withSection=False), ) if not nouvelle_page.title(asLink=True, withSection=False) in listeRecents: listeRecents[listeRecents.index(titre_article)] = nouvelle_page.title( asLink=True, withSection=False ) else: pywikibot.output(u"La page destination était déjà présente dans la liste") listeRecents.pop(listeRecents.index(titre_article)) # On force la mise à jour de la page, même si aucun nouvel article # récent n'est trouvé. exception_maj = True except: pywikibot.output(u"an error occured (CircularRedirect?)") # except KeyboardInterrupt: # pywikibot.stopme() except: try: pywikibot.output(u"Erreur inconnue lors du traitement de la page %s" % page.title(asLink=True)) except: pywikibot.output(u"Erreur inconnue lors du traitement d'une page") else: # Si pas d'erreur : on passe à la page suivante continue if precisions_comment: precisions_comment = precisions_comment[2:] # Pour supprimer le '; ' ##################### ##################### ### Recherches des articles nouveaux ##################### precisions_comment2 = u"" # Récupération de la dernière mise à jour de la page par le bot db = _mysql.connect( host="tools-db", db="s51245__totoazero", read_default_file="/data/project/totoazero/replica.my.cnf" ) results = db.query( 'SELECT last FROM maj_articles_recents WHERE page="%s"' % main_page.title().replace('"', '\\"').encode("utf-8") ) results = db.store_result() result = results.fetch_row(maxrows=0) pywikibot.output(("last check was " + str(result))) if result: first_passage = False t = result[0][0] timestamp = pywikibot.Timestamp.strptime(t, "%Y-%m-%d %H:%M:%S") # Permet de ne générer que la liste des articles ajoutés à la # catégorie après la dernière modification de la page # contenant le modèle {{Articles récents}}. # list_new.extend([page for page in site.categorymembers(cat, starttime=timestamp, sortby='timestamp', namespaces=[0])]) list_new = [ page for page in cat.articles( starttime=timestamp, sortby="timestamp", namespaces=namespaces, recurse=recurse ) ] list_new.reverse() else: # nouvelle page, premier passage du bot first_passage = True timestamp = main_page.editTime() if delai_creation > 0: timestamp -= datetime.timedelta(hours=delai_creation) # Génération de la première liste, pour éviter si possible de # laisser la page vide. list_new = [page for page in cat.newest_pages(total=nbMax)] # TODO : mieux ? # list_new = [page for page in cat.articles(sortby='timestamp', namespaces=namespaces, recurse=recurse)] pywikibot.output("stade 2") now = datetime.datetime.now() # NB : exception_maj peut être passer à True si un article # a été supprimé de la catégorie. if len(list_new) == 0 and not exception_maj: # Inutile d'aller plus loin s'il n'y a aucun nouvel article. end_page(main_page, now, first_passage) continue # Liste des pages pour requête SQL sur base frwiki_p list_new_str = '("' list_new_str += '", "'.join( [page.title(asLink=False, underscore=True).replace('"', '\\"') for page in list_new] ) list_new_str += '")' pywikibot.output(list_new_str) # Fonctionne uniquement avec les pages du ns 0 pour le moment frwiki_p = _mysql.connect( host="frwiki.labsdb", db="frwiki_p", read_default_file="/data/project/totoazero/replica.my.cnf" ) pywikibot.output( "SELECT page_title, page_id FROM page where page_title IN %s AND page_namespace=0" % list_new_str.encode("utf-8") ) results = frwiki_p.query( "SELECT page_title, page_id FROM page where page_title IN %s AND page_namespace=0" % list_new_str.encode("utf-8") ) results = frwiki_p.store_result() result = results.fetch_row(maxrows=0) pywikibot.output(result) dico_result = {} for tuple in result: title = tuple[0] id = tuple[1] dico_result[title] = id pywikibot.output(dico_result) dico_timestamp = {} pywikibot.output("stade 3") frwiki_p = _mysql.connect( host="frwiki.labsdb", db="frwiki_p", read_default_file="/data/project/totoazero/replica.my.cnf" ) for key in dico_result: id = dico_result[key] pywikibot.output( 'SELECT cl_from, cl_timestamp FROM categorylinks WHERE cl_from = %s AND cl_to = "%s"' % ( id.encode("utf-8"), cat.title(asLink=False, underscore=True, withNamespace=False).encode("utf-8"), ) ) results = frwiki_p.query( 'SELECT cl_from, cl_timestamp FROM categorylinks WHERE cl_from = %s AND cl_to = "%s"' % ( id.encode("utf-8"), cat.title(asLink=False, underscore=True, withNamespace=False).encode("utf-8"), ) ) results = frwiki_p.store_result() result = results.fetch_row(maxrows=0) if result: dico_timestamp[key.decode("utf-8")] = pywikibot.Timestamp.strptime( result[0][1], "%Y-%m-%d %H:%M:%S" ) else: pywikibot.output(u"pas de date trouvée pour %s" % key.decode("utf-8")) pywikibot.output(dico_timestamp) # Permet de mettre les nouvelles pages comme des titres : # nécessaires plus loin ! list_new = [page.title(asLink=True) for page in list_new] # Permet de récupérer des infos sur la catégorie. # NB : Si ralentit le script, l'item cat_info['pages'] # correspondant au nombre de pages contenues # dans la catégorie doit pouvoir être remplacé # par len(listeCategorie) + len(list_new). cat_info = site.categoryinfo(cat) pywikibot.output(cat_info) pywikibot.output("stade 4") list_new_old = list() list_new_old.extend(list_new) pywikibot.output("delai_creation is %s" % delai_creation) # for titre_page in list_new_old: # print titre_page for titre_page in list_new_old: # NB : titre_page est du type [[Nom de la page]] pywikibot.output("----------") pywikibot.output(u"Page récemment ajoutée : %s" % titre_page) if not titre_page in listeRecents: if delai_creation: # Délai imposé (en heures) depuis la création de l'article, # au-delà duquel l'article récemment ajouté à la catégorie # ne doit pas figurer dans la liste. # Exemple : delai_creation = 24 # => le bot liste uniquement les articles créés il y # a moins de 24h. page = pywikibot.Page(site, titre_page[2:-2]) # NB : date_creation et date_plus_petite_requise # sont du type pywikibot.Timestamp date_creation = page.getVersionHistory()[-1][1] pywikibot.output(date_creation) if delai_creation > 0: date_plus_petite_requise = pywikibot.Timestamp.now() - datetime.timedelta( hours=delai_creation ) elif delai_creation == -1: # 'timestamp' a été défini plus haut comme étant la date de dernière # édition du bot sur la page. date_plus_petite_requise = timestamp pywikibot.output(date_plus_petite_requise) if date_plus_petite_requise > date_creation: pywikibot.output(u"Vérification du délai : Non") pywikibot.output(u"La page ne satisfait pas le délai depuis la création imposé.") list_new.remove(titre_page) continue else: pywikibot.output(u"Vérification du délai : OK") precisions_comment2 += u"; + %s" % titre_page else: # Si l'article se trouve déjà dans la liste listeRecents # il est inutile de le rajouter à nouveau. list_new.remove(titre_page) pywikibot.output(u"L'article était déjà présent sur la page.") # Re-vérification pour voir si list_new contient toujours # au moins une page. if len(list_new) == 0 and not exception_maj: # Inutile d'aller plus loin s'il n'y a aucun nouvel article. pywikibot.output("Nothing left.") continue # Re-vérification pour voir si list_new contient toujours # au moins une page. if len(list_new) == 0 and not exception_maj: # Inutile d'aller plus loin s'il n'y a aucun nouvel article. end_page(main_page, now, first_passage) continue if precisions_comment: # Si precisions_comment contient déjà des infos (suppression de pages) precisions_comment += precisions_comment2 else: precisions_comment = precisions_comment2[2:] # Pour supprimer le '; ' pywikibot.output("stade 5") # Pour compléter le résumé d'édition comment = comment % {"nombre_articles": cat_info["pages"], "precision_pages": precisions_comment} ##################### ### Création de la liste des articles récents ##################### liste_nouveaux_recents = list() liste_nouveaux_recents.extend(list_new) # Si le nombre d'articles nouveaux est strictement au nombre maximum # d'articles récents qui doivent figurer. if len(liste_nouveaux_recents) < nbMax: i = 0 while len(liste_nouveaux_recents) != nbMax: if len(listeRecents) < i + 1: # Dans le cas où la liste listeRecents ne contiendrait pas # assez d'éléments. break liste_nouveaux_recents.append(listeRecents[i]) i += 1 if i == len(listeRecents): # Pourrait provoquer une erreur de longueur break elif len(liste_nouveaux_recents) > nbMax: liste_nouveaux_recents = liste_nouveaux_recents[0 : (nbMax - 1)] # La liste liste_nouveaux_recents contient désormais # nbMax articles récents exactement pywikibot.output("stade 6") liste_nouveaux_recents_string = ( u"<!-- Ce tableau est créé automatiquement par un robot. Articles Récents DEBUT -->" ) for titre_article in liste_nouveaux_recents: liste_nouveaux_recents_string += u"\n%s %s" % (puce, titre_article) if format_date and dico_timestamp.has_key(titre_article[2:-2].replace(" ", "_")): pywikibot.output("stade 6-1") pywikibot.output(dico_timestamp[titre_article[2:-2].replace(" ", "_")].strftime(format_date)) try: liste_nouveaux_recents_string += ( " (" + dico_timestamp[titre_article[2:-2].replace(" ", "_")] .strftime(format_date) .decode("utf-8") + ")" ) except: try: liste_nouveaux_recents_string += ( " (" + dico_timestamp[titre_article[2:-2].replace(" ", "_")].strftime(format_date) + ")" ) except: raise "erreur au stade 6-1" elif dico_dates_presentes.has_key(titre_article): pywikibot.output("stade 6-2") pywikibot.output(dico_dates_presentes[titre_article]) try: liste_nouveaux_recents_string += " (" + dico_dates_presentes[titre_article] + ")" except: # UnicodeEncodeError: try: liste_nouveaux_recents_string += ( " (" + dico_dates_presentes[titre_article].decode("utf-8") + ")" ) except: raise "erreur au stade 6-2" liste_nouveaux_recents_string += ( u"\n<!-- Ce tableau est créé automatiquement par un robot. Articles Récents FIN -->" ) ##################### ##################### ### Mise à jour du contenu de la page ##################### new_text = text pywikibot.output("stade 7") # Mise à jour de la liste des articles récents (listeRecents) new_text = re.sub( re.compile(u"%s.*%s" % (matchDebut1, matchFin1), re.S), liste_nouveaux_recents_string, new_text ) pywikibot.output(new_text) pywikibot.output(u"Commentaire: %s" % comment) if not dry: main_page.put(new_text, comment=comment) end_page(main_page, now, first_passage) else: pywikibot.showDiff(main_page.get(), new_text) ##################### except Exception, myexception: pywikibot.output("Erreur lors du traitement de la page %s" % main_page.title(asLink=True)) almalog2.error( u"maj_articles_recents", u"traitement de %s : %s %s" % (main_page.title(asLink=True), type(myexception), myexception.args), )
def find_add(self, page): """ Returns (user, oldid, timestamp) where * user is the user who added the {{Mort récente}} template (pywikibot.User) * oldid is the oldid of the revision of this add (int) * timestamp """ death_found = True history = page.getVersionHistory() if len(history) == 1: [(id, timestamp, user, comment)] = history return (pywikibot.User(self.site, user), id) oldid = None requester = None timestamp = None previous_timestamp = None for (id, timestamp, user, comment) in history: pywikibot.output( "Analyzing id %i: timestamp is %s and user is %s" % (id, timestamp, user)) text = page.getOldVersion(id) templates_params_list = textlib.extract_templates_and_params(text) death_found = False for (template_name, dict_param) in templates_params_list: try: template_page = pywikibot.Page( pywikibot.Link(template_name, self.site, defaultNamespace=10), self.site) # TODO : auto-finding redirections if template_page.title(withNamespace=False) in [ u"Mort récente", u"Décès récent" ]: death_found = True break except Exception, myexception: pywikibot.output( u'An error occurred while analyzing template %s' % template_name) pywikibot.output(u'%s %s' % (type(myexception), myexception.args)) if oldid: print("id is %i ; oldid is %i" % (id, oldid)) else: print("id is %i ; no oldid" % id) if not death_found: if id == oldid: pywikibot.output( "Last revision does not contain any {{Mort récente}} template!" ) return None else: pywikibot.output(u"-------------------------------------") triplet = (requester, oldid, previous_timestamp) pywikibot.output( u"Found it: user is %s; oldid is %i and timestamp is %s" % triplet) return triplet else: requester = pywikibot.User(self.site, user) oldid = id previous_timestamp = timestamp
genFactory = pagegenerators.GeneratorFactory(site=site) for ns in (0, 14, 100): if family != 'wikisource' and ns == 100: # fixme: cswikiquote continue if family == 'wikisource' and ns == 0: continue genFactory.handleArg('-ns:%i' % ns) genFactory.handleArg('-unconnectedpages') generator = genFactory.getCombinedGenerator(preload=True) for page in generator: if page.namespace() != 14 and page.isDisambig(): continue for template, fields in textlib.extract_templates_and_params(page.text): if first_lower(template) not in tp_map[project]: continue params = tp_map[project][first_lower(template)] for key in fields: if key not in params: continue title = fields[key].strip() if not title: continue target_lang = lang target_family = family if isinstance(params[key], dict):
def get_params(self): text = self.main_page.get() templates = textlib.extract_templates_and_params(text) template_in_use = None for tuple in templates: if tuple[0] == modele.title(asLink=False): template_in_use = tuple[1] break if not template_in_use: pywikibot.output(u"Aucun modèle {{%s}} détecté sur la page %s" % (modele.title(asLink=False), main_page.title())) return False titre_categorie = check_and_return_parameter(template_in_use, u'catégorie') if not titre_categorie: return False self.cat = pywikibot.Category(site, titre_categorie) if not self.cat.exists(): pywikibot.output(u"Erreur : la catégorie n'existe pas") return False self.nbMax = check_and_return_parameter(template_in_use, 'nbMax', -1) try: self.nbMax = int(self.nbMax) except: pywikibot.output(u'Erreur : nbMax incorrect') return False self.minimum = check_and_return_parameter(template_in_use, 'minimum', '10') try: self.minimum = int(self.minimum) except: pywikibot.output(u'Erreur : minimum incorrect') return False self.actions = check_and_return_parameter(template_in_use, 'actions', '0,1,3') try: [int(k) for k in self.actions.split(',')] except: pywikibot.output( u'Erreur : des actions spécifiées ne sont pas des entiers') return False self.delai = check_and_return_parameter(template_in_use, u'délai', '7') try: self.delai = int(self.delai) if self.delai <= 0: pywikibot.output(u'Erreur : délai négatif') return False except: pywikibot.output(u'Erreur : délai incorrect') return False self.orange = check_and_return_parameter(template_in_use, 'limite_orange', '20') try: self.orange = int(self.orange) except: pywikibot.output(u'Erreur : orange incorrect') return False self.rouge = check_and_return_parameter(template_in_use, 'limite_rouge', '40') try: self.rouge = int(self.rouge) except: pywikibot.output(u'Erreur : rouge incorrect') return False self.mineures = check_and_return_parameter(template_in_use, 'mineures', '0') try: self.mineures = int(self.mineures) except: pywikibot.output(u'Erreur : mineures incorrect') return False self.contributeurs = check_and_return_parameter( template_in_use, 'contributeurs', '0') try: self.contributeurs = int(self.contributeurs) except: pywikibot.output(u'Erreur : contributeurs incorrect') return False self.minimum_contributeurs = check_and_return_parameter( template_in_use, 'minimum_contributeurs', '1') try: self.minimum_contributeurs = int(self.minimum_contributeurs) except: pywikibot.output(u'Erreur : minimum_contributeurs incorrect') return False self.bots_inclus = check_and_return_parameter(template_in_use, 'bots_inclus', '1') try: self.bots_inclus = int(self.bots_inclus) except: pywikibot.output(u'Erreur : bots_inclus incorrect') return False self.bots_inclus_str = '' if self.bots_inclus == 0: # ne pas prendre les bots en compte # rc_bot indique une modification faite par un bot self.bots_inclus_str = 'AND rc_bot = 0' self.transclusion = check_and_return_parameter(template_in_use, 'transclusion', '0') try: self.transclusion = int(self.transclusion) except: pywikibot.output(u'Erreur : transclusion incorrect') return False self.diff = check_and_return_parameter(template_in_use, 'diff', '0') try: self.diff = int(self.diff) except: pywikibot.output(u'Erreur : diff incorrect') return False self.lien_historique = check_and_return_parameter( template_in_use, 'lien_historique', '0') try: self.lien_historique = int(self.lien_historique) except: pywikibot.output(u'Erreur : diff incorrect') return False return True
def find_add(self, page, modele): """ modele is a pywikibot.Page """ site = pywikibot.Site() unblock_found = True history = page.getVersionHistory() pywikibot.output(u"Analysing page %s" % page.title()) if len(history) == 1: [(id, timestamp, user, comment)] = history return (timestamp, id) oldid = None requester = None timestamp_add = None look_back_count = 2 look_back = look_back_count for (id, timestamp, user, comment) in history: pywikibot.output("Analyzing id %i: timestamp is %s and user is %s" % (id, timestamp, user+(" (lookback)" if look_back < look_back_count else ""))) if not user: pywikibot.output("User's missing (hidden?), skipping this version...") continue text = page.getOldVersion(id) if not text: pywikibot.output(u"Can't get rev text (hidden?), skipping this version...") continue # text might be too long, if so textlib.extract_templates_and_params won't # proceed and will skip some templates #if u"{{déblocage" in text.lower(): # text = text[max(0,text.lower().index(u"{{déblocage")-12):] templates_params_list = textlib.extract_templates_and_params(text) unblock_found = False for (template_name, dict_param) in templates_params_list: try: template_page = pywikibot.Page(pywikibot.Link(template_name, site, defaultNamespace=10), site) # TODO : auto-finding redirections if template_page == modele: #pywikibot.output((template_name, dict_param)) unblock_found = True look_back = look_back_count break except Exception, myexception: pywikibot.output(u'An error occurred while analyzing template %s' % template_name) pywikibot.output(u'%s %s'% (type(myexception), myexception.args)) #if oldid: # print("oldid is %i" % oldid) #else: # print "no oldid" if (not unblock_found and id == oldid): # We did not find the model we were looking for # in the most recent revision: abort pywikibot.output("Last revision does not contain any {{modele}} template!") return None elif not unblock_found: # We did not find the model we are looking for # in some old revision, but it was present in # more recent ones. # We will snap back at look_back revisions, to check # whether the model was truly added in the current # revision or if it dates back to some older revision # and was simply removed heer due to eg. vandalism if look_back > 0: pywikibot.output("Template was added in oldid https://fr.wikipedia.org/w/index.php?oldid=%i" % oldid) return (timestamp_add, oldid) else: # Look back another time, but don't change # the future value returned (requested, oldid # timestamp_add) look_back -= 1 else: requester = pywikibot.User(site, user) oldid = id timestamp_add = timestamp
def archivage(self): """ Archivage ou suppression des requêtes classées (suivant le paramétrage du dictionnaire principal self.dict), dès lors qu'elles satisfaisent le délai configuré (self.dict['delai']['archivage'] et self.dict['delai']['suppression']). Les requêtes archivées sont transférée vers une sous-page de la page principale (self.main_page), en rajoutant le suffixe '/Archives%i' avec %i un integer. Le bot détecte automatiquement la page d'archives en cours, et crée une nouvelle page dès que le nombre de 250 sections est atteint. TODO (D): - mettre à jour la page principale d'archives lorsqu'une nouvelle page d'archives est créée. - vérifier l.475 (new_text = archive_page.get() + '\\n' + text_to_archive) """ to_do = ['acceptees', 'refusees'] for type in to_do: if type == 'acceptees': page_en_cours = self.accepted_page #text = self.accepted_page.get() elif type == 'refusees': page_en_cours = self.refused_page #text = self.refused_page.get() pywikibot.output(page_en_cours) text = page_en_cours.get() if not text: pywikibot.output(u"Aucun texte dans la page !") continue titres = complements.extract_titles( text, beginning="", match_title=self.match_titre_requete) sections = complements.extract_sections(text, titres) text_to_archive = u"" requests_to_archive = [] requests_to_delete = [] # Début de la boucle d'analyse de chacune des sections, au cas par cas. for numero_section in sections: pywikibot.output('--------------------------------') pywikibot.output(titres[numero_section]) analyse = self.analyse_section(sections[numero_section]) if analyse == None: # Une erreur a eu lieu continue date = analyse['date'] statut = analyse['statut'] if not date: pywikibot.output(u'erreur : pas de date !') continue try: date = self.match_date.search(date) pywikibot.output(date.group('month')) # Il est préférable de reformater la date, toujours au format string # avant de la parser avec la commande datetime.strptime. # Ici, la date est normalisée suivant le format suivant : # jour mois année heures:minutes (tout en chiffres) # ex : 13 02 2012 23:34 # On préfèrera utiliser exclusivement des chiffres pour éviter # des problèmes liés aux accents sur le nom de certains mois, # tels février, décembre et août. text_date = u"%s %s %s %s:%s" % ( date.group('day'), self.les_mois[date.group('month')], date.group('year'), date.group('hours'), date.group('minutes')) date = datetime.strptime(text_date, u"%d %m %Y %H:%M") pywikibot.output("date is: %s" % date) except: pywikibot.output(u'erreur: problème avec la date') continue now = datetime.now() #pywikibot.output(now) pywikibot.output(u"délai classement : %i heures" % self.dict['delai']['classement']) #pywikibot.output((now-date)) pywikibot.output("from then to now: %s, that is %i hours" % ((now - date), ((now - date).seconds / 3600) + (now - date).days * 24)) if self.dict['archiver'][type]: # Si l'archivage des requêtes est activé. if self.dict['delai']['archivage'] <= ( (now - date).seconds / 3600 + (now - date).days * 24): pywikibot.output(u'=> archivage') text_to_archive += sections[numero_section] requests_to_archive.append(sections[numero_section]) text = text.replace(sections[numero_section], '') else: pywikibot.output(u'=> pas d\'archivage') elif self.dict['supprimer'][type]: # Sinon, si leur suppression est activée. if self.dict['delai']['suppression'] <= ( (now - date).seconds / 3600 + (now - date).days * 24): pywikibot.output(u'=> suppression') text = text.replace(sections[numero_section], '') requests_to_delete.append(sections[numero_section]) else: pywikibot.output(u'=> pas de suppression') # Fin de la boucle traitant les sections au cas par cas. # # La variable text_to_archive contient désormais la totalité des requêtes # à archiver (texte), si l'archivage est activé pour le type de requêtes en # cours de traitement. # # La variable requests_to_archive contient désormais la liste des requêtes # à archiver, si l'archivage est activé pour le type de requêtes en # cours de traitement. if self.dict['archiver'][type]: if not text_to_archive: # Si rien n'est à archiver, on passe directement # au traitement suivant (de l'autre type de requêtes). continue # Trouver le numéro de la page d'archive en cours archiveNumber = 1 archive_page = None while True: previous_archive_page = archive_page archive_page = pywikibot.Page( self.site, self.main_page.title(asLink=False) + "/%s%i" % (self.archivePrefix, archiveNumber)) if not archive_page.exists(): break archiveNumber += 1 if previous_archive_page != None: archiveNumber -= 1 archive_page = previous_archive_page pywikibot.output(archive_page) #pywikibot.output(text_to_archive) # La variable archiveNumber contient à présent le numéro # de la page d'archive en cours. # Si la page d'archive existe (si elle n'existe pas, c'est qu'aucune page # d'archive n'a été trouvée par le bot. if archive_page.exists(): # On compte le nombre de requêtes déjà présentes dans # la page d'archive en cours. # Pour cela, on remplace chaque titre de section par '{[$REQUETE$]}' # et on compte le nombre de '{[$REQUETE$]}'. nombre_de_sections = re.sub( self.match_titre_requete, '{[$REQUETE$]}', archive_page.get()).count('{[$REQUETE$]}') #print re.sub(self.match_titre_requete, '{[$REQUETE$]}', text) pywikibot.output('nombre_de_sections = %i' % nombre_de_sections) if nombre_de_sections > 250: old_archiveNumber = archiveNumber old_archive_page = archive_page # On récupère la dernière requête pour donner la dernière date # de la page d'archive. text_temp = old_archive_page.get() old_archives = complements.extract_sections( text_temp, complements.extract_titles( text_temp, "", self.match_titre_requete)) last_archive = old_archives[len(old_archives) - 1] templates = textlib.extract_templates_and_params( last_archive) for template in templates: pywikibot.output(template) if template[ 0] == self.template_title: #u'RA début': #modifié (todo A-1) statut = template[1]['statut'] date = template[1]['date'] pywikibot.output(date) # On arrête d'analyser les modèles, étant donné qu'on a trouvé # celui qui nous intéresse. break if date: try: pywikibot.output(date) last_date = self.match_date.search(date) pywikibot.output(last_date) last_date = u"%s %s %s" % ( last_date.group('day'), last_date.group('month'), last_date.group('year')) pywikibot.output(last_date) except Exception, myexception: pywikibot.output( u'%s %s' % (type(myexception), myexception.args)) pywikibot.output( u'erreur: problème avec la date') else: pywikibot.output(u'erreur : pas de date !') # La variable last_date contient désormais la date de la dernière # requête de la page d'archives. archiveNumber += 1 archive_page = pywikibot.Page( self.site, self.main_page.title(asLink=False) + "/%s%i" % (self.archivePrefix, archiveNumber)) new_text = text_to_archive pywikibot.output( u"Plus de 250 requêtes archivées -> création d'une nouvelle page d'archive (n°%i)" % archiveNumber) # Mise à jour de la page d'archives principale main_archive_page = pywikibot.Page( self.site, self.main_page.title() + u"/Archives") text_temp = main_archive_page.get() text_temp = re.sub( u"(\# *\[\[%s\]\]) *" % old_archive_page.title(asLink=False), u"\\1 (jusqu'au %s)\n# %s" % (last_date, archive_page.title(asLink=True)), text_temp) main_archive_page.put( text_temp, comment=u"Création d'une nouvelle page d'archives") else: pywikibot.output( u"Moins de 250 requêtes archivées -> page d'archive actuelle (n°%i)" % archiveNumber) new_text = archive_page.get() while new_text[ -2:] != '\n\n': # Pour rajouter des sauts de lignes si nécessaire. new_text += '\n' new_text += text_to_archive else: # Aucune page d'archive n'a été trouvée par le bot. pywikibot.output( u"1ère page d'archive ! Aucune ne semble exister actuellement…" ) new_text = text_to_archive # Mise à jour de la page de classement en cours de traitement # ainsi que de la apge d'archive comment = (u"Archivage de %i requêtes" % len(requests_to_archive)) try: # pwb_error pywikibot.showDiff(page_en_cours.get(), text) pywikibot.output( '******************************************************' ) # pwb_error if archive_page.exists(): # pwb_error pywikibot.showDiff(archive_page.get(), new_text) page_en_cours.put( text, comment=( comment + u" vers %s" % archive_page.title(asLink=True))) archive_page.put(new_text, comment=comment) except Exception, myexception: pywikibot.output("erreur type 2")
def treat(self, page, item): """Process a single page/item.""" if willstop: raise KeyboardInterrupt self.current_page = page item.get() if set(self.fields.values()) <= set(item.claims.keys()): pywikibot.output('%s item %s has claims for all properties. ' 'Skipping.' % (page, item.title())) return pagetext = page.get() templates = textlib.extract_templates_and_params(pagetext) for (template, fielddict) in templates: # Clean up template try: template = pywikibot.Page(page.site, template, ns=10).title(withNamespace=False) except pywikibot.exceptions.InvalidTitle: pywikibot.error( "Failed parsing template; '%s' should be the template name." % template) continue # We found the template we were looking for if template in self.templateTitles: for field, value in fielddict.items(): field = field.strip() value = value.strip() if not field or not value: continue # This field contains something useful for us if field in self.fields: # Check if the property isn't already set claim = pywikibot.Claim(self.repo, self.fields[field]) if claim.getID() in item.get().get('claims'): pywikibot.output( 'A claim for %s already exists. Skipping.' % claim.getID()) # TODO: Implement smarter approach to merging # harvested values with existing claims esp. # without overwriting humans unintentionally. else: if claim.type == 'wikibase-item': # Try to extract a valid page match = re.search(pywikibot.link_regex, value) if not match: pywikibot.output( '%s field %s value %s is not a ' 'wikilink. Skipping.' % (claim.getID(), field, value)) continue link_text = match.group(1) linked_item = self._template_link_target(item, link_text) if not linked_item: continue claim.setTarget(linked_item) elif claim.type == 'string': claim.setTarget(value.strip()) elif claim.type == 'commonsMedia': commonssite = pywikibot.Site("commons", "commons") imagelink = pywikibot.Link(value, source=commonssite, defaultNamespace=6) image = pywikibot.FilePage(imagelink) if image.isRedirectPage(): image = pywikibot.FilePage(image.getRedirectTarget()) if not image.exists(): pywikibot.output( '[[%s]] doesn\'t exist so I can\'t link to it' % (image.title(),)) continue claim.setTarget(image) else: pywikibot.output( '%s is not a supported datatype.' % claim.type) continue pywikibot.output('Adding %s --> %s' % (claim.getID(), claim.getTarget())) item.addClaim(claim) # A generator might yield pages from multiple sites source = self.getSource(page.site) if source: claim.addSource(source, bot=True)
diff = list(set(articles) - set(articles_alreadsy)) print(len(diff)) tplnames_en = ['cee spring 2020'] fsdf = [] for article in diff: page = pywikibot.Page(site, "Diskusija:{}".format(article)) pagetext = page.get() #wikicode = mwparserfromhell.parse(pagetext) #templates = wikicode.filter_templates() for template, fielddict in textlib.extract_templates_and_params( pagetext, remove_disabled_parts=False, strip=True): tplname = template.lower().strip().replace('_', ' ') if tplname not in tplnames_en: continue fielditems = [[k[0], k[1]] for k in fielddict.items()] fsdf.append([article, fielditems]) break # #pywikibot.output(fsdf) fileconts.extend(fsdf) with open('cee2dfgfdfgdfgdfgdgdfgd-2-final.txt', 'w', encoding='utf-8') as filetowrite1:
def traitement(self): pageTraitees = pywikibot.Page(self.site, u"Wikipédia:Demande de restauration de page/Traitées") pageRefusees = pywikibot.Page(self.site, u"Wikipédia:Demande de restauration de page/Refusées") list = [(self.main_page, u'Requêtes à traiter'), (self.main_page, u'Requêtes en cours d\'examen'), (pageTraitees, None), (pageRefusees, None)] for couple in list: dict = self.analyse_une_section(page = couple[0], match_debut = couple[1]) sections = dict['sections'] if not sections: continue for numero_section in sections: pywikibot.output('\n') titre_section = dict['titres'][numero_section] section = sections[numero_section] templates = textlib.extract_templates_and_params(section) # templates est du type : # [(u'DRP début', {u'date': u'27 février 2010 à 14:56 (CEC)' # , u'statut': u'oui'}), (u'DRP fin', {})] PaS = False found_full_template = False for template in templates: if template[0] == u'DRP début': if not ('statut' in template[1]): pywikibot.output(u"pas de paramètre 'statut' trouvé") continue elif not ('date' in template[1]): pywikibot.output(u"pas de paramètre 'date' trouvé") continue found_full_template = True statut_actuel = template[1]['statut'] date = template[1]['date'] if template[1].has_key(u'PàS'): pywikibot.output('phase try 0') pywikibot.output(template[1][u'PàS']) if template[1][u'PàS'] == 'oui': pywikibot.output('phase try 1') PaS = True page_PaS = None elif template[1][u'PàS'] != '': pywikibot.output('phase try 2') PaS = True page_PaS = pywikibot.Page(self.site, u"%s/Suppression" % template[1][u'PàS']).toggleTalkPage() pywikibot.output(u'found_full_template = %s' % found_full_template) if not found_full_template: pywikibot.output('Fully fulfilled template was not found, skipping to next section.') continue pywikibot.output(u"PaS = %s" % PaS) if PaS: try: pywikibot.output(u"page_PaS = %s" % page_PaS) except: pywikibot.output(u"no page_PaS") # Pour enlever les == et les éventuels espaces # du titre de la section puis les [[…]] qui sont # supprimés de l'URL par MediaWiki. titre_section = titre_section[2:-2] titre_section = titre_section.strip() titre_section_SQL = titre_section titre_section_MediaWiki = titre_section titre_section_MediaWiki = titre_section_MediaWiki.replace("[[", "") titre_section_MediaWiki = titre_section_MediaWiki.replace("]]", "") pywikibot.output(u"=== %s ===" % titre_section) pywikibot.output(u"statut_actuel = %s" % statut_actuel) pywikibot.output(u"date = %s" % date) if statut_actuel not in self.status_knonw: # Si le demande de restauration ne possède pas un de ces statuts, # il est inutile d'aller plus loin car seuls ceux-ci nécessitent # de laisser un message au demandeur. continue # Vérifier si la requête a déjà été analysée par le bot. self.database.query('SELECT * FROM drp WHERE titre_section = "%s"' % titre_section_SQL.replace('"', '\\"').encode('utf-8')) results=self.database.store_result() result=results.fetch_row(maxrows=0) if result: # Si oui, et si le statut est toujours le même, il n'y a rien à faire statut_traite = result[0][1] pywikibot.output(statut_traite) # La vérification d'un éventuel lancement d'une PàS technique # pour la restauration n'est faite que par la suite, le statut # 'oui_PaS' ne peut donc pas encore être le statut_actuel, # même si une PàS a été lancée ! # On remplace donc l'éventuel statut traité 'oui_PaS' par un # simple 'oui'. if statut_traite == 'oui_PaS': statut_traite = 'oui' if statut_traite.decode('utf-8') == statut_actuel: # Si le statut actuel est le même que celui qui a déjà été # traité, il n'y a rien d'autre à faire : le demandeur # a déjà été averti. pywikibot.output(u'DRP déjà traitée !') continue else: pywikibot.output(u'DRP déjà traitée mais statut différent…') # Supprimer la requête de la base de donnée SQL pour éviter # qu'elle ne se retrouve en double avec deux statuts # différents. self.database.query('DELETE FROM drp WHERE titre_section = "%s"' % titre_section_SQL.replace('"', '\\"').encode('utf-8')) #print section # Si on arrive ici, c'est que le demandeur n'a pas été averti du # statut actuel m1 = re.search(u"[dD]emandée? par .*\[ *\[ *([uU]tilisateur:|[uU]ser:|[sS]p[eé]cial:[cC]ontributions/)(?P<nom_demandeur>[^|\]]+)(\|| *\] *\])", section) m2 = re.search(u"[dD]emandée? par {{u'?\|(?P<nom_demandeur>[^|]+)}}", section) m3 = re.search(u"[dD]emandée? par (?P<nom_demandeur>[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)", section) if m1: nom_demandeur = m1.group('nom_demandeur') #print 'm1' elif m2: nom_demandeur = m2.group('nom_demandeur') #print 'm2' elif m3: nom_demandeur = m3.group('nom_demandeur') #print 'm3' else: pywikibot.output(u'nom du demandeur introuvable !') continue #print nom_demandeur demandeur = pywikibot.User(self.site, nom_demandeur) if u'autopatrolled' in demandeur.groups(): pywikibot.output(u'demandeur autopatrolled : inutile de laisser un message') continue elif demandeur in self.whitelist: pywikibot.output(u"l'utilisateur est sur la whitelist") continue page_discussion_demandeur = demandeur.getUserTalkPage() pywikibot.output(page_discussion_demandeur) m = re.search(u"\[ *\[ *(?P<titre_page>.*) *\] *\]", titre_section) if not m: pywikibot.output(u'Titre de la page concernée introuvable !') continue titre_page_concernee = m.group('titre_page').strip() pywikibot.output(titre_page_concernee) # Vérifier si une PàS technique pour la restauration a été # lancée ou non. if statut_actuel == 'oui': if PaS: statut_actuel = 'oui_PaS' pywikibot.output('oui_PaS') if not page_PaS or page_PaS.exists(): try: page_PaS = pywikibot.Page(self.site, titre_page_concernee + "/Suppression").toggleTalkPage() #pywikibot.Page(self.site, u"Discussion:%s/Suppression" % titre_page_concernee) page_PaS.get() except: pywikibot.output(u'erreur : la PàS technique ne semble pas exister ou n\'est pas normalisée !') statut_actuel = 'oui_PaS_mais_introuvable' if page_PaS: # La PàS peut avoir été renommée if page_PaS.isRedirectPage(): page_PaS = page_PaS.getRedirectTarget() if re.search(u"[pP]roposé *par.* ([0-9]{1,2}.*20[01][0-9]) à [0-9]{2}:[0-9]{2}", page_PaS.get()): date_debut_PaS = re.search(u"[pP]roposé *par.* ([0-9]{1,2}.*20[01][0-9]) à [0-9]{2}:[0-9]{2}", page_PaS.get()).group(1) else: # Si la date n'est pas formatée comme attendue sur la PàS, le bot # cherche sa date de création en remontant l'historique, puis l'exprime # sous la forme attendue. date_creation = page_PaS.getVersionHistory()[-1][1] date_debut_PaS = date_creation.strftime("%d %B %Y") message = self.messages[statut_actuel] # La fonction urllib.quote() permet d'encoder une URL. # Ici, seul le titre de la section a besoin d'être encodé. # Cependant, MediaWiki remplace les espaces par des tirets bas ('_') # et les % dans l'encodage par des points ('.'). lien_drp = u"%s#%s" % (self.main_page.title(asLink = False), urllib.quote(titre_section_MediaWiki.encode('utf-8'), safe=" /").replace(" ", "_").replace("%", ".")) #pywikibot.output(u'lien_drp = %s' % lien_drp) if statut_actuel == 'non' or statut_actuel == 'oui' or statut_actuel == 'oui_PaS_mais_introuvable': message = message % {'titre_page':titre_page_concernee, 'lien_drp':lien_drp, 'date_debut_lien_valide':date} elif statut_actuel == 'oui_PaS': if not type(date_debut_PaS) == unicode: pywikibot.output(u"Formattage de date_debut_PaS") date_debut_PaS = date_debut_PaS.decode('utf-8') message = message % {'titre_page':titre_page_concernee, 'lien_drp':lien_drp, 'date_debut_lien_valide':date, 'titre_PaS':page_PaS.title(asLink = False), 'date_debut_PaS':date_debut_PaS} elif statut_actuel in ['attente', 'autre', 'autreavis']: message = message % {'titre_page':titre_page_concernee, 'lien_drp':lien_drp} else: pywikibot.output(u'statut inconnu : %s' % statut_actuel) continue # # Mauvaise gestion des IPv6 par pywikibot # Les caractères doivent être en majuscules # pattern_ipv6 = "Discussion utilisateur:(([0-9a-zA-Z]{,4}:){7}[0-9a-zA-Z]{,4})" if re.search(pattern_ipv6, page_discussion_demandeur.title()): ipv6 = re.search(pattern_ipv6, page_discussion_demandeur.title()).group(1) ipv6 = ipv6.upper() page_discussion_demandeur = pywikibot.Page(pywikibot.Site(), u"Discussion utilisateur:"+ipv6) # if page_discussion_demandeur.exists(): while page_discussion_demandeur.isRedirectPage(): page_discussion_demandeur = page_discussion_demandeur.getRedirectTarget() text = page_discussion_demandeur.get() newtext = text newtext += '\n\n' newtext += u"== %s ==" % self.titre_message % {'titre_page': titre_page_concernee} newtext += '\n' newtext += message # pwb_error pywikibot.showDiff(page_discussion_demandeur.get(), newtext) else: newtext = u"== %s ==" % self.titre_message % {'titre_page': titre_page_concernee} newtext += '\n' newtext += message pywikibot.output(newtext) comment = self.resume % {'titre_page': titre_page_concernee} pywikibot.output(comment) try: page_discussion_demandeur.put(newtext, comment=comment, minorEdit=False) except: pywikibot.output(u'erreur lors de la publication du message !') continue # Enregistrer la requête comme analysée par le bot self.database.query('INSERT INTO drp VALUES ("%s", "%s", CURRENT_TIMESTAMP)' % (titre_section_SQL.replace('"', '\\"').encode('utf-8'), statut_actuel.encode('utf-8')))
def get_params(self): text = self.main_page.get() templates = textlib.extract_templates_and_params(text) template_in_use = None for tuple in templates: if tuple[0] == modele.title(asLink=False): template_in_use = tuple[1] break if not template_in_use: _errorhandler.message(u"Aucun modèle {{%s}} détecté sur la page" % modele.title(asLink=False), addtags={'page': self.main_page}) return False titre_categorie = check_and_return_parameter(template_in_use, u'catégorie') if not titre_categorie: return False self.cat = pywikibot.Category(site, titre_categorie) if not self.cat.exists(): _errorhandler.message(u"Erreur : la catégorie n'existe pas", addtags={'page': self.main_page}) return False self.nbMax = check_and_return_parameter(template_in_use, 'nbMax', -1) try: self.nbMax = int(self.nbMax) except: _errorhandler.message(u'Erreur : nbMax incorrect', addtags={'page': self.main_page}) return False self.minimum = check_and_return_parameter(template_in_use, 'minimum', '10') try: self.minimum = int(self.minimum) except: _errorhandler.message(u'Erreur : minimum incorrect', addtags={'page': self.main_page}) return False self.actions = check_and_return_parameter(template_in_use, 'actions', '0,1,3') try: [int(k) for k in self.actions.split(',')] except: _errorhandler.message( u'Erreur : des actions spécifiées ne sont pas des entiers', addtags={'page': self.main_page}) return False self.delai = check_and_return_parameter(template_in_use, u'délai', '7') try: self.delai = int(self.delai) if self.delai <= 0: _errorhandler.message(u'Erreur : délai négatif', addtags={'page': self.main_page}) return False except: _errorhandler.message(u'Erreur : délai incorrect', addtags={'page': self.main_page}) return False self.orange = check_and_return_parameter(template_in_use, 'limite_orange', '20') try: self.orange = int(self.orange) except: _errorhandler.message(u'Erreur : orange incorrect', addtags={'page': self.main_page}) return False self.rouge = check_and_return_parameter(template_in_use, 'limite_rouge', '40') try: self.rouge = int(self.rouge) except: _errorhandler.message(u'Erreur : rouge incorrect', addtags={'page': self.main_page}) return False self.mineures = check_and_return_parameter(template_in_use, 'mineures', '0') try: self.mineures = int(self.mineures) except: _errorhandler.message(u'Erreur : mineures incorrect', addtags={'page': self.main_page}) return False self.contributeurs = check_and_return_parameter( template_in_use, 'contributeurs', '0') try: self.contributeurs = int(self.contributeurs) except: _errorhandler.message(u'Erreur : contributeurs incorrect', addtags={'page': self.main_page}) return False self.minimum_contributeurs = check_and_return_parameter( template_in_use, 'minimum_contributeurs', '1') try: self.minimum_contributeurs = int(self.minimum_contributeurs) except: _errorhandler.message(u'Erreur : minimum_contributeurs incorrect', addtags={'page': self.main_page}) return False self.bots_inclus = check_and_return_parameter(template_in_use, 'bots_inclus', '1') try: self.bots_inclus = int(self.bots_inclus) except: _errorhandler.message(u'Erreur : bots_inclus incorrect', addtags={'page': self.main_page}) return False self.bots_inclus_str = '' if self.bots_inclus == 0: # ne pas prendre les bots en compte # rc_bot indique une modification faite par un bot self.bots_inclus_str = 'AND rc_bot = 0' self.transclusion = check_and_return_parameter(template_in_use, 'transclusion', '0') try: self.transclusion = int(self.transclusion) except: _errorhandler.message(u'Erreur : transclusion incorrect', addtags={'page': self.main_page}) return False self.diff = check_and_return_parameter(template_in_use, 'diff', '0') try: self.diff = int(self.diff) except: _errorhandler.message(u'Erreur : diff incorrect', addtags={'page': self.main_page}) return False self.lien_historique = check_and_return_parameter( template_in_use, 'lien_historique', '0') try: self.lien_historique = int(self.lien_historique) except: _errorhandler.message(u'Erreur : diff incorrect', addtags={'page': self.main_page}) return False self.namespaces = check_and_return_parameter(template_in_use, 'namespaces', '0') print self.namespaces try: # Check namespaces specified are actually numbers, # and preformat them for the SQL request self.namespaces = "(" + ",".join( [str(int(k)) for k in self.namespaces.split(",")]) + ")" except: _errorhandler.message(u'Erreur : namespaces incorrect', addtags={'page': self.main_page}) return False return True