Back to index

moin  1.9.0~rc2
driver.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 """
00003 MoinMoin wiki project -> Google Project Hosting converter
00004 
00005 full of evil antipatterns, incl. Exception exceptions
00006 
00007 @copyright: 2007 MoinMoin:AlexanderSchremmer
00008 @license: GPL v2
00009 
00010 """
00011 import sys
00012 import re
00013 import urllib2
00014 from urllib import quote
00015 import xmlrpclib
00016 
00017 sys.path.append("/home/alexander/dev/python/ghopimport")
00018 #sys.path.append("/srv/moin_tw/moin-1.6/contrib")
00019 
00020 from googleimport import googlepush
00021 
00022 
00023 class DataNotFoundException(Exception): pass
00024 
00025 
00026 class Task(object):
00027     def __init__(self, summary, desc, label):
00028         self.summary = summary
00029         self.desc = desc
00030         self.label = label
00031 
00032     def __repr__(self):
00033         return (u"<Task summary=%r label=%r desc='''%s'''>" % (self.summary, self.label,  self.desc[:100] )).encode("utf-8")
00034 
00035 
00036 def find_dict_entry(name, text):
00037     m = re.search(r"^ %s:: (.*)$" % (name, ), text, re.M | re.U)
00038     if not m:
00039         raise DataNotFoundException("%s not found" % (name, ))
00040     return m.groups()[0]
00041 
00042 desc_pattern = r"""== Short Description ==
00043 ([\s\S]*?)
00044 (= |$)"""
00045 
00046 bugpage_pattern = r"""= Description =
00047 ([\s\S]*?)
00048 ="""
00049 
00050 already_pushed_pages = set([x.strip() for x in """
00051 EasyToDo/ExtendFormsOfAdvancedSearch
00052 EasyToDo/ResearchMacOSXPluginSupport
00053 EasyToDo/Research_Python_code_usable_for_filters
00054 EasyToDo/Code_vCard_hCard_Support_For_Wikihomepages
00055 EasyToDo/UserPreferredLanguageStatistics
00056 EasyToDo/CloneWikiPagesByPackagePages
00057 EasyToDo/ResearchLinuxPluginSupport
00058 EasyToDo/ConvertMacrosToNewSyntax
00059 EasyToDo/CaseStudy
00060 EasyToDo/InstallMoinMoinForYourFriends
00061 EasyToDo/JabberBotRefactoring
00062 EasyToDo/ProofreadEnglishDocumentation
00063 EasyToDo/ImplementXEPEntityCapabilities 1
00064 EasyToDo/ImplementXEPEntityCapabilities 3
00065 EasyToDo/ImplementXEPEntityCapabilities 2
00066 EasyToDo/TestInstallDocs
00067 EasyToDo/DesignAMoinMoinTheme
00068 EasyToDo/ImproveStyleOfModernTheme
00069 EasyToDo/ThinkingAloudUsabilityTest
00070 EasyToDo/MakeAScreencast
00071 EasyToDo/IntroduceMoinMoinToYourFriends
00072 EasyToDo/RunJabberBotOnWindows
00073 EasyToDo/ResearchWindowsPluginSupport
00074 EasyToDo/DesignNewIconset
00075 EasyToDo/CreateAPoster
00076 EasyToDo/GermanWikiKurs
00077 EasyToDo/Firefox3CompatibilityCheck
00078 EasyToDo/SearchForMoinMoinIntegration
00079 EasyToDo/AddUsageInfoToMoinCommand
00080 EasyToDo/DumpPagesIntoZip
00081 EasyToDo/ShowAclIndicator
00082 """.split("\n")])
00083 
00084 already_pushed_bugs = set([x.strip() for x in """
00085 1.6devFAT32TroubleWithUnderlayFileNames
00086 1.6devMissingRightsI18n
00087 AclBlockMoinDump
00088 ArbitraryInjectionOfErrorMessage
00089 CannotUpdateCreateDrawings
00090 GuiEditorExcelPasteExpatErrorUnboundPrefix
00091 MailAccountDataGivesError
00092 MakeIconLinkLosesAltTitle
00093 ModPyConnectionErrors
00094 MoinDumpTheme
00095 NavigationMacroMultipleRepeat
00096 RenamingUserAllowsOldUsernameToLogin
00097 SubscribeAndUnsubscribeShareSameUrl
00098 TWikiDrawOnDebian
00099 TrivialChangeEasyAccess
00100 WrongAlignedAttachment
00101 XmlRpcPutPageAllowsEmptyPageName
00102 """.split("\n")])
00103 
00104 gatherers = []
00105 
00106 
00107 class Collector(object):
00108     def is_gatherer(function):
00109         gatherers.append(function)
00110         return function
00111 
00112     def __init__(self, url):
00113         self.url = url
00114         self.server = xmlrpclib.ServerProxy(url + "?action=xmlrpc2")
00115 
00116     def collect_tasks(self):
00117         tasks = []
00118         for gatherer in gatherers:
00119             new = list(gatherer(self))
00120             tasks.extend(new)
00121 
00122         return tasks
00123 
00124     @is_gatherer
00125     def easytodo_pages(self):
00126         pages = self.server.getAllPagesEx(dict(prefix="EasyToDo/"))
00127         for page in pages:
00128             if page in already_pushed_pages:
00129                 continue
00130             page_contents = self.server.getPage(page)
00131             try:
00132                 summary = find_dict_entry("Summary", page_contents)
00133                 count = int(find_dict_entry("Count", page_contents))
00134                 label = find_dict_entry("Label", page_contents)
00135             except DataNotFoundException, e:
00136                 print "Could not import %r because of %r" % (page, e)
00137                 continue
00138             desc_m = re.search(desc_pattern, page_contents)
00139             if not desc_m:
00140                 raise Exception("Desc not found")
00141             desc = desc_m.groups()[0]
00142             for i in range(1, count + 1):
00143                 print page
00144                 text = desc
00145                 new_summary = summary
00146                 text += "\n\nA more detailed description of this issue is available at the MoinMoin wiki: %s" % (self.url + quote(page.encode("utf-8")), )
00147                 if count > 1:
00148                     text += "\n\nThis issue is available multiple times. This one is %i of %i." % (i, count)
00149                     new_summary += " %i/%i" % (i, count)
00150                 yield Task(new_summary, text, label)
00151 
00152     @is_gatherer
00153     def moin_bugs(self):
00154         pages = [pagename for pagename, contents in self.server.searchPages(r"t:MoinMoinBugs/ r:CategoryEasy\b")]
00155         for page in pages:
00156             bug_name = page.replace("MoinMoinBugs/", "")
00157             if bug_name in already_pushed_bugs:
00158                 continue
00159             page_contents = self.server.getPage(page)
00160             m = re.search(bugpage_pattern, page_contents)
00161             if not m:
00162                 raise Exception("bug desc not found")
00163             desc = m.groups()[0]
00164             desc = "A user filed a bug report at the MoinMoin site. Here is a short description about the issue. A more detailed description is available at the MoinMoin wiki: %s\n\n" % (self.url + quote(page.encode("utf-8")), ) + desc
00165             yield Task(bug_name, desc, "Code")
00166 
00167     #@is_gatherer
00168     def translation_items(self):
00169         #languages = self.server.getPage(u"EasyToDoTranslation/Languages").strip().splitlines()
00170         #languages = ["Lithuanian (lt)"]
00171         languages = []
00172         for language in languages:
00173             page = u"EasyToDoTranslation"
00174             page_contents = self.server.getPage(page)
00175             page_contents = page_contents.replace("LANG", language)
00176             summary = find_dict_entry("Summary", page_contents)
00177             count = int(find_dict_entry("Count", page_contents))
00178             desc_m = re.search(desc_pattern, page_contents)
00179             if not desc_m:
00180                 raise Exception("Desc not found")
00181             desc = desc_m.groups()[0]
00182             for i in range(1, count + 1):
00183                 text = desc
00184                 new_summary = summary
00185                 text += "\n\nA more detailed description of this task is available at the MoinMoin wiki: %s" % (self.url + quote(page.encode("utf-8")), )
00186                 if count > 1:
00187                     text += "\n\nThis task is available multiple times. This one is %i of %i." % (i, count)
00188                     new_summary += " %i/%i" % (i, count)
00189                 yield Task(new_summary, text, "Translation")
00190 
00191 
00192 def pull_and_push():
00193     #project_name = "google-highly-open-participation-moinmoin" # PRODUCTION IMPORT
00194     project_name = "moin-sandbox" # TEST RUN
00195     summary_prefix = "" # EMPTY FOR PRODUCTION IMPORT!
00196     if summary_prefix:
00197         tmin, tmax = 0, None
00198     else:
00199         tmin, tmax = 0, None
00200     print "Collecting tasks ..."
00201     tasks = Collector("http://moinmo.in/").collect_tasks()
00202     print "Importing %i tasks ..." % (len(tasks), )
00203     print "\n".join(repr(task) for task in tasks)
00204     argc = len(sys.argv)
00205     if not (2 <= argc <= 3):
00206         raise SystemExit("you must supply your username (and optionally your password) as argument(s) to this program")
00207     user = sys.argv[1]
00208     if argc == 2:
00209         password = raw_input("Password for %s:" % user)
00210     else:
00211         password = sys.argv[2]
00212 
00213 
00214     try:
00215         googlepush.login(user, password)
00216     except urllib2.URLError, e:
00217         print "Ignored exception %r" % (e, )
00218 
00219     i = 0
00220     for task in tasks[tmin:tmax]:
00221         i += 1
00222         print i, repr(task.summary)
00223         googlepush.push_item(project_name, summary_prefix + task.summary, task.desc, "Open", task.label)
00224 
00225 
00226 if __name__ == "__main__":
00227     pull_and_push()
00228