Back to index

moin  1.9.0~rc2
mkpagepacks.py
Go to the documentation of this file.
00001 # -*- coding: iso-8859-1 -*-
00002 """
00003 MoinMoin - Package Generator
00004 
00005 @copyright: 2005 Alexander Schremmer,
00006             2006-2009 MoinMoin:ThomasWaldmann
00007 @license: GNU GPL, see COPYING for details.
00008 """
00009 
00010 import os
00011 import zipfile
00012 from datetime import datetime
00013 
00014 from MoinMoin.support.python_compatibility import set
00015 from MoinMoin import wikiutil
00016 from MoinMoin.action.AttachFile import _get_files
00017 from MoinMoin.Page import Page
00018 from MoinMoin.action import AttachFile
00019 from MoinMoin.packages import packLine, MOIN_PACKAGE_FILE
00020 from MoinMoin.script import MoinScript
00021 from MoinMoin import i18n
00022 from MoinMoin.i18n import strings
00023 i18n.strings = strings
00024 
00025 
00026 COMPRESSION_LEVEL = zipfile.ZIP_STORED
00027 
00028 class PluginScript(MoinScript):
00029     """\
00030 Purpose:
00031 ========
00032 This tool generates a set of packages from all the pages in a wiki.
00033 
00034 Detailed Instructions:
00035 ======================
00036 General syntax: moin [options] maint mkpagepacks [mkpagepacks-options]
00037 
00038 [options] usually should be:
00039     --config-dir=/path/to/my/cfg/ --wiki-url=wiki.example.org/
00040 
00041 [mkpagepacks-options] see below:
00042     0. THIS SCRIPT SHOULD NEVER BE RUN ON ANYTHING OTHER THAN A TEST WIKI!
00043 
00044     1. This script takes no command line arguments.
00045 """
00046 
00047     def __init__(self, argv, def_values):
00048         MoinScript.__init__(self, argv, def_values)
00049 
00050     def buildPageSets(self):
00051         """ Calculates which pages should go into which package. """
00052         request = self.request
00053 
00054         all_pages = set(request.rootpage.getPageList())
00055         packaged_pages = set()
00056 
00057         languages = i18n.wikiLanguages()
00058         pageset_names = i18n.strings.pagesets
00059         pageSets = {}
00060         for lang in languages:
00061             def trans(text, request=request, lang=lang, **kw):
00062                 return i18n.getText(text, request, lang, **kw)
00063 
00064             try:
00065                 lang_long = languages[lang]['x-language-in-english']
00066                 lang_long = lang_long.replace('/', '_').replace(' ', '_')
00067             except KeyError:
00068                 lang_long = lang
00069 
00070             for pageset_name in pageset_names:
00071                 pageset_orig = set(getattr(i18n.strings, pageset_name))
00072                 pageset_trans = set([trans(pn) for pn in pageset_orig])
00073                 key = u"%s_%s" % (lang_long, pageset_name)
00074                 pageset = pageset_trans
00075                 if lang != 'en':
00076                     pageset -= pageset_orig
00077                 if pageset:
00078                     print key, len(pageset)
00079                     pageSets[key] = pageset
00080                     packaged_pages |= pageset
00081 
00082         not_packaged_pages = all_pages - packaged_pages
00083         pageSets['00_needs_fixing'] = not_packaged_pages
00084         return pageSets
00085 
00086     def packagePages(self, pagelist, filename, function):
00087         """ Puts pages from pagelist into filename and calls function on them on installation. """
00088         request = self.request
00089         try:
00090             os.remove(filename)
00091         except OSError:
00092             pass
00093         # page LanguageSetup needs no packing!
00094         existing_pages = [pagename for pagename in pagelist if Page(request, pagename).exists() and pagename != 'LanguageSetup']
00095         if not existing_pages:
00096             return
00097 
00098         zf = zipfile.ZipFile(filename, "w", COMPRESSION_LEVEL)
00099 
00100         script = [packLine(['MoinMoinPackage', '1']), ]
00101 
00102         cnt = 0
00103         for pagename in existing_pages:
00104             pagename = pagename.strip()
00105             page = Page(request, pagename)
00106             files = _get_files(request, pagename)
00107             for attname in files:
00108                 cnt += 1
00109                 zipname = "%d" % cnt
00110                 script.append(packLine(["ReplaceUnderlayAttachment", zipname, attname, pagename]))
00111                 attpath = AttachFile.getFilename(request, pagename, attname)
00112                 zf.write(attpath, zipname)
00113 
00114             cnt += 1
00115             zipname = "%d" % cnt
00116             script.append(packLine([function, zipname, pagename]))
00117             timestamp = wikiutil.version2timestamp(page.mtime_usecs())
00118             zi = zipfile.ZipInfo(filename=zipname, date_time=datetime.fromtimestamp(timestamp).timetuple()[:6])
00119             zi.compress_type = COMPRESSION_LEVEL
00120             zf.writestr(zi, page.get_raw_body().encode("utf-8"))
00121 
00122         script += [packLine(['Print', 'Installed MoinMaster page bundle %s.' % os.path.basename(filename)])]
00123 
00124         zf.writestr(MOIN_PACKAGE_FILE, u"\n".join(script).encode("utf-8"))
00125         zf.close()
00126 
00127     def removePages(self, pagelist):
00128         """ Pages from pagelist get removed from the underlay directory. """
00129         request = self.request
00130         import shutil
00131         for pagename in pagelist:
00132             pagename = pagename.strip()
00133             page = Page(request, pagename)
00134             try:
00135                 underlay, path = page.getPageBasePath(-1)
00136                 shutil.rmtree(path)
00137             except:
00138                 pass
00139 
00140     def mainloop(self):
00141         # self.options.wiki_url = 'localhost/'
00142         if self.options.wiki_url and '.' in self.options.wiki_url:
00143             print "NEVER EVER RUN THIS ON A REAL WIKI!!! This must be run on a local testwiki."
00144             return
00145 
00146         self.init_request() # this request will work on a test wiki in tests/wiki/ directory
00147                             # we assume that there are current moinmaster pages there
00148         request = self.request
00149 
00150         if not ('tests/wiki' in request.cfg.data_dir.replace("\\", "/") and 'tests/wiki' in request.cfg.data_underlay_dir.replace("\\", "/")):
00151             import sys
00152             print sys.path
00153             print "NEVER EVER RUN THIS ON A REAL WIKI!!! This must be run on a local testwiki."
00154             return
00155 
00156         print "Building page sets ..."
00157         pageSets = self.buildPageSets()
00158 
00159         print "Creating packages ..."
00160         package_path = os.path.join('tests', 'wiki', 'underlay', 'pages', 'LanguageSetup', 'attachments')
00161         try:
00162             # create attachment dir in case it is not there:
00163             os.mkdir(package_path)
00164         except OSError:
00165             pass
00166         generate_filename = lambda name: os.path.join(package_path, '%s.zip' % name)
00167         [self.packagePages(list(pages), generate_filename(name), "ReplaceUnderlay") for name, pages in pageSets.items()]
00168 
00169         print "Removing pagedirs of packaged pages ..."
00170         dontkill = set(['LanguageSetup'])
00171         [self.removePages(list(pages - dontkill)) for name, pages in pageSets.items()]
00172 
00173         print "Finished."
00174