#!/usr/bin/python # -*- coding: utf-8 -*- __version__ = '$Id: ISS-Dockingbays.py$' import wikipedia, sys import pagegenerators import re, os, codecs, catlib, time # SETTING update_template = '{{update PALZ9000}}' data_page_name = 'Template:ISS-Dockingbays/Data' transl_data_page_name = 'Template:ISS-Dockingbays/Translation data' title_in_lang = { 'ru': u'User:ZxxZxxZ/sandbox', 'de': u'User:ZxxZxxZ/sandbox', 'ja': u'User:ZxxZxxZ/sandbox' } updating_comment_in_lang = { 'en': 'Bot: updating table', 'ru': u'Bot: updating table', 'de': u'Bot: updating table', 'ja': u'Bot: updating table' } tables_page_title = 'Template:ISS-Dockingbays/Tables' # the page in en.wikipedia which cantains all updated tables in all langs class issBot: def run(self): while True: page = wikipedia.Page(wikipedia.getSite('en'), data_page_name) text = self.load(page) if not update_template in text: time.sleep(3600*2) # sleep for two hours continue try: data = re.search(r'\[\s\n\r]*(.+?)[\s\n\r]*\<\/pre\>', text, re.S).group(1) except AttributeError: # Someone has removed our data, I must kill him target_user = page.getLatestEditors(limit=1) target_user_talk_page = wikipedia.Page(wikipedia.getSite('en'), 'User talk:'+target_user) target_user_text = self.load(target_user_talk_page) target_user_text += ''' == BOT: ALERT == Don't do that again. --~~~~ ''' if not self.save(target_user_text, target_user_talk_page, comment='Alert'): wikipedia.output('ERROR: Killing failed; page not saved.') self.error_report(error_text=u'The data has been {{diff|%s|%s|removed}} by %s.' % (page.title(), page.latestRevision(), target_user)) ### wikipedia.stopme() data = re.sub(r'[ \t]*\n[\s\n\r]*', r'\n', data) data = re.sub(r'[ \t]+', ' ', data) rows = re.split(r'\n', data) ### '\n'.split(data) raw_data = list() for row in rows: try: ref = re.search(r'(.*?)<\/ref>', row).group(1) row = row.replace(ref, '') except AttributeError: ref = '' row = re.sub(u'[\s\t ]*.*$', '', row) raw_data.append(list()) raw_data[-1] = re.split(' ', row) if raw_data[-1] < 5: # Less that 5 columns in this row self.error_report(error_text='Data in line #%d seems corrupt, take a look. There was only %d. I will skip that line.' % (len(raw_data), len(raw_data[-1]))) raw_data[-1] = [] transl_data_page = wikipedia.Page(wikipedia.getSite('en'), transl_data_page_name) transl_data = self.load(transl_data_page) for lang in title_in_lang.keys(): translated_data = list() wikipedia.output('INFO: working on %s.wikipedia' % lang) for i in range(0, len(raw_data)): translated_data.append(list()) for j in range(0, len(raw_data[i])): wikipedia.output('INFO: raw_data[%s][%s]: %s' % (i, j, raw_data[i][j])) ### v try: tr_section = re.search(ur'\<%s\>(.*?)\<\/%s\>' % (raw_data[i][j], raw_data[i][j]), transl_data, re.S).group(1) except AttributeError: if j == 0: # SPACECRAFT try: default_craft_name = re.search('(.+?)_', raw_data[i][j]).group(1) except AttributeError: wikipedia.output(u'ERROR: Cannot get default value for "%s".' % raw_data[i][j]) else: try: tr_section = re.search(ur'\<%s\>(.*?)\<\/%s\>' % (default_craft_name, default_craft_name), transl_data, re.S).group(1) except AttributeError: wikipedia.output(u'ERROR: Cannot fetch translation data for neither "%s" nor its default value "%s".' % (raw_data[i][j], default_craft_name)) else: wikipedia.output(u'INFO: Cannot fetch translation data for "%s".' % raw_data[i][j]) ##pageIW = wikipedia.Page(wikipedia.getSite('en'), data_page_name) translated_word = raw_data[i][j].replace('_', ' ') # use untranslated word else: try: translated_word = re.search(ur'\[\[ *:%s: *(.*?)\]\]' % lang, tr_section).group(1) except: wikipedia.output(u'ERROR: Cannot fetch translation data for "%s" in language "%s".' % (raw_data[i][j], lang)) translated_word = raw_data[i][j].replace('_', ' ') # use untranslated word translated_word = '[[%s]]' % translated_word translated_data[i].append(translated_word) wikipedia.output(u'Translating done. Trying to update the table in [[:%s:%s]]...' % (lang, title_in_lang[lang])) table = '{|' table2 = '{|' for i in range(0, len(translated_data)): table += '\n|-' table2 += '\n|-' for j in range(0, len(translated_data[i])): table += u'\n| %s' % translated_data[i][j] try: translated_data_linktitle = re.search(ur'(?:\[\[(?:.*?\||)|)(.*?)(?=\]\]|)', translated_data[i][j]).group(1) except AttributeError: wikipedia.output(u'ERROR: Cannot fetch link title from "%s".' % translated_data[i][j]) translated_data_linktitle = translated_data[i][j] table2 += u'\n| [[%s#%s|%s]]' % (tables_page_title, raw_data[i][j], translated_data_linktitle) table += '\n|}' table2 += '\n|}' page_in_lang = wikipedia.Page(wikipedia.getSite(lang), title_in_lang[lang]) text_in_lang = self.load(page_in_lang) text_in_lang = re.sub(ur'.*?(?=\)', table, text_in_lang, re.S) if not self.save(text_in_lang, page_in_lang, comment=updating_comment_in_lang[lang]): wikipedia.output('ERROR: Updating failed; page not saved.') self.error_report(error_text='ERROR: Can not update %s.' % page_in_lang.title(asLink=True)) else: tables_page = wikipedia.Page(wikipedia.getSite('en'), tables_page_title) tables_page_text = self.load(tables_page) tables_page_text = re.sub(ur'\n\=+ *%s *\=+\n(.*?)(?=\n\=+.*?\=+\n|$)' % lang, ur'\n== %s ==\n%s' % (lang, table2), tables_page_text, re.S) if not self.save(tables_page_text, tables_page, comment=updating_comment_in_lang['en']): self.error_report(error_text='ERROR: Can not update %s.' % tables_page.title(asLink=True)) def load(self, page): try: text = page.get() except wikipedia.NoPage: wikipedia.output(u'ERROR: Page %s does not exist.' % page.title(asLink=True)) wikipedia.stopme() except wikipedia.IsRedirectPage: wikipedia.output(u'ERROR: Page %s is a redirect.' % page.title(asLink=True)) else: return text return None def save(self, text, page, comment=''): try: page.put(text, comment=comment, minorEdit=True, botflag=True) except wikipedia.LockedPage: wikipedia.output(u'ERROR: Page %s is locked.' % page.title(asLink=True)) except wikipedia.EditConflict: wikipedia.output(u'ERROR: Skipping %s because of edit conflict' % page.title()) except wikipedia.SpamfilterError, error: wikipedia.output(u'ERROR: Cannot change %s because of spam blacklist entry %s' % (page.title(), error.url)) else: return True return False def error_report(self, error_title='Bot: error', error_text='something went wrong', comment='Bot: reporting error', user='ZxxZxxZ', site='en', user2='Penyulap', site2='en'): wikipedia.output(u'Reporting error, title: %s, text: %s' % (error_title, error_text)) talk_page = wikipedia.Page(wikipedia.getSite(site), user) text = self.load(talk_page) text += u''' == %s == Hi %s! %s. --~~~~ ''' % (error_title, user, error_text) if not self.save(text, talk_page, comment=comment): talk_page2 = wikipedia.Page(wikipedia.getSite(site2), user2) text2 = self.load(talk_page2) text2 += u''' == %s == Hi %s! %s --~~~~ ''' % (error_title, user2, error_text) if not self.save(text2, talk_page2, comment=comment): wikipedia.output('ERROR: Error reporting failed; pages not saved.') wikipedia.stopme() def main(): bot = issBot() bot.run() if __name__ == '__main__': try: main() finally: wikipedia.stopme()