root/branches/mbutscher/work/lib/pwiki/CmdLineAction.py @ 288

Revision 288, 15.4 kB (checked in by mbutscher, 3 years ago)

branches/mbutscher/work:
* Option to open link in new window (Ross' rep.:

517346f7e238022217c982b5c71ed92880e40249 and
7698dcedf92b4a7fedfe16cc5138c2b5ab99f437)

Line 
1import sys, os, getopt, traceback
2
3import wx
4
5from WikiExceptions import *
6
7from StringOps import mbcsDec, wikiUrlToPathWordAndAnchor
8
9import PluginManager
10
11
12class CmdLineAction:
13    """
14    This class parses command line options, provides necessary information
15    and performs actions
16    """
17   
18    def __init__(self, sargs):
19        """
20        sargs -- stripped args (normally sys.args[1:])
21        """
22        self.wikiToOpen = None  # Path to wiki to open
23                # (interpreted by PersonalWikiFrame)
24        self.wikiWordsToOpen = None  # Name of wiki words to open
25                # (interpreted by PersonalWikiFrame)
26        self.anchorToOpen = None   # Name of anchor to open in wiki word
27        self.exitFinally = False   # Exit WikidPad when done
28                # (interpreted by PersonalWikiFrame)
29        self.showHelp = False   # Show help text?
30        self.cmdLineError = False   # Command line couldn't be interpreted
31        self.exportWhat = None   # String identifying what to export
32        self.exportType = None   # Export into which type of data?
33        self.exportDest = None   # Destination path to dir/file
34        self.exportCompFn = False   # Export with compatible filenames?
35        self.exportSaved = None  # Name of saved export instead
36        self.continuousExportSaved = None  # Name of saved export to run as continuous export
37        self.rebuild = False # Rebuild the wiki
38        self.frameToOpen = 1  # Open wiki in new frame? (yet unrecognized)
39                # 1:New frame, 2:Already open frame, 0:Use config default
40        self.activeTabNo = -1  # Number of tab to activate
41                # (interpreted by PersonalWikiFrame)
42        self.lastTabsSubCtrls = None  # Corresponding list of subcontrol names
43                # for each wikiword to open
44        self.wikiWordsToCreate = None  # Words to create and open
45        self.noRecent = False  # Do not modify history of recently opened wikis
46
47        if len(sargs) == 0:
48            return
49           
50        if sargs[0][0] != "-":
51            # Old style, mainly used by the system
52
53            # mbcs decoding of parameters
54            sargs = [mbcsDec(a, "replace")[0] for a in sargs]
55            self.setWikiToOpen(sargs[0])
56
57            if len(sargs) > 1:
58                self.wikiWordsToOpen = (sargs[1],)
59
60            return
61
62        # New style
63        try:
64            opts, rargs = getopt.getopt(sargs, "hw:p:x",
65                    ["help", "wiki=", "page=", "new-page=", "exit",
66                    "export-what=", "export-type=", "export-dest=",
67                    "export-compfn", "export-saved=", "continuous-export-saved=",
68                    "anchor", "rebuild", "no-recent", "preview", "editor"])
69        except getopt.GetoptError:
70            self.cmdLineError = True
71            return
72
73        wikiWordsToOpen = []
74        wikiWordsToCreate = []
75
76        for o, a in opts:
77            if o in ("-h", "--help"):
78                self.showHelp = True
79            elif o in ("-w", "--wiki"):
80                self.wikiToOpen = mbcsDec(a, "replace")[0]
81            elif o in ("-p", "--page"):
82                wikiWordsToOpen.append(mbcsDec(a, "replace")[0])
83            elif o in ("--new-page"):
84                wikiWordsToCreate.append(mbcsDec(a, "replace")[0])
85            elif o == "--anchor":
86                self.anchorToOpen = mbcsDec(a, "replace")[0]
87            elif o in ("-x", "--exit"):
88                self.exitFinally = True
89            elif o == "--export-what":
90                self.exportWhat = mbcsDec(a, "replace")[0]
91            elif o == "--export-type":
92                self.exportType = mbcsDec(a, "replace")[0]
93            elif o == "--export-dest":
94                self.exportDest = mbcsDec(a, "replace")[0]
95            elif o == "--export-compfn":
96                self.exportCompFn = True
97            elif o == "--export-saved":
98                self.exportSaved = mbcsDec(a, "replace")[0]
99            elif o == "--continuous-export-saved":
100                self.continuousExportSaved = mbcsDec(a, "replace")[0]
101            elif o == "--rebuild":
102                self.rebuild = True
103            elif o == "--no-recent":               
104                self.noRecent = True
105            elif o == "--preview":
106                self._fillLastTabsSubCtrls(len(wikiWordsToOpen), "preview")
107            elif o == "--editor":
108                self._fillLastTabsSubCtrls(len(wikiWordsToOpen), "textedit")
109
110
111        if len(wikiWordsToOpen) > 0:
112            self.wikiWordsToOpen = tuple(wikiWordsToOpen)
113
114        if len(wikiWordsToCreate) > 0:
115            self.wikiWordsToCreate = tuple(wikiWordsToCreate)
116
117        self._fillLastTabsSubCtrls(len(wikiWordsToOpen))
118
119
120    def _fillLastTabsSubCtrls(self, wwoLen, newItem=None):
121        """
122        If self.lastTabsSubCtrls contains at least one item, fill it up
123        to length of wwoLen with last item. If newItem is not None, it is
124        appended.
125        If newItem is None (done by final call after collecting) self.lastTabsSubCtrls
126        shortened to length of wwoLen. If wwoLen is 0, the last item is preserved
127        to ensure that the setting "--preview" is processed when opening wiki
128        with previously opened words.
129        """
130        if not self.lastTabsSubCtrls:
131            if newItem is not None:
132                # Fill up already mentioned words with textedit subControl setting
133                self.lastTabsSubCtrls = ["textedit"] * wwoLen + [newItem]
134
135            return
136
137        if len(self.lastTabsSubCtrls) < wwoLen:
138                self.lastTabsSubCtrls += [self.lastTabsSubCtrls[-1]] * \
139                        (wwoLen - len(self.lastTabsSubCtrls))
140
141        if newItem is not None:
142            self.lastTabsSubCtrls.append(newItem)
143        else:
144            if wwoLen > 0:
145                self.lastTabsSubCtrls = self.lastTabsSubCtrls[:wwoLen]
146            else:
147                self.lastTabsSubCtrls = self.lastTabsSubCtrls[-1:]
148
149            if not self.lastTabsSubCtrls:
150                self.lastTabsSubCtrls = None
151
152
153    def setWikiToOpen(self, wto):
154        if wto.startswith("wiki:"):
155            self.wikiToOpen, wikiWordToOpen, self.anchorToOpen = \
156                    wikiUrlToPathWordAndAnchor(wto)
157
158            self.wikiWordsToOpen = (wikiWordToOpen,)
159#                 self.wikiToOpen = urllib.url2pathname(self.wikiToOpen)
160#                 self.wikiToOpen = self.wikiToOpen.replace("wiki:", "")
161        else:
162            self.wikiToOpen = wto
163
164
165    def inheritFrom(self, cmdline):
166        """
167        Inherits some settings from another commandline. Some special settings
168        should be persistent when opening one frame from another.
169        """
170        self.noRecent = cmdline.noRecent
171
172
173    def actionBeforeShow(self, pWiki):
174        """
175        Actions to do before the main frame is shown
176        """
177        self.rebuildAction(pWiki)
178        self.exportAction(pWiki)
179        self.continuousExportAction(pWiki)
180
181        if self.showHelp:
182            self.showCmdLineUsage(pWiki)
183
184
185    def rebuildAction(self, pWiki):
186        if self.rebuild:
187            pWiki.rebuildWiki(True)
188
189
190    def _runSavedExport(self, pWiki, savedExportName, continuousExport):
191        import Serialization, PluginManager, Exporters, SearchAndReplace
192
193        exportList = Exporters.retrieveSavedExportsList(pWiki,
194                pWiki.getWikiData(), continuousExport)
195        xmlNode = None
196        for exportName, xn in exportList:
197            if exportName == savedExportName:
198                xmlNode = xn
199                break
200
201        if xmlNode is None:
202            self.showCmdLineUsage(pWiki,
203                    _(u"Saved export '%s' is unknown.") % savedExportName + u"\n\n")
204            return
205
206
207        # TODO: Refactor, it is based on AdditionalDialogs.ExportDialog._showExportProfile
208        try:
209            etypeProfile = Serialization.serFromXmlUnicode(xmlNode,
210                    u"exportTypeName")
211
212            try: 
213                exporter, etype, desc, panel = PluginManager.getSupportedExportTypes(
214                        pWiki, None, continuousExport)[etypeProfile]
215            except KeyError:
216                self.showCmdLineUsage(pWiki,
217                        _(u"Export type '%s' of saved export is not supported") %
218                        etypeProfile + u"\n\n")
219                return
220
221            addOptXml = Serialization.findXmlElementFlat(xmlNode,
222                    u"additionalOptions")
223
224            addOptVersion = int(addOptXml.getAttribute(u"version"))
225
226            if addOptVersion != exporter.getAddOptVersion():
227                self.showCmdLineUsage(pWiki,
228                        _(u"Saved export uses different version for additional "
229                        "options than current export\nExport type: '%s'\n"
230                        "Saved export version: %i\nCurrent export version: %i") %
231                        (etypeProfile, addOptVersion, exporter.getAddOptVersion()) +
232                        u"\n\n")
233                return
234
235            if addOptXml.getAttribute(u"type") != u"simpleTuple":
236                self.showCmdLineUsage(pWiki,
237                        _(u"Type of additional option storage ('%s') is unknown") %
238                        addOptXml.getAttribute(u"type") + u"\n\n")
239                return
240
241            pageSetXml = Serialization.findXmlElementFlat(xmlNode, u"pageSet")
242
243            sarOp = SearchAndReplace.SearchReplaceOperation()
244            sarOp.serializeFromXml(pageSetXml)
245           
246           
247            addOpt = Serialization.convertTupleFromXml(addOptXml)
248
249#                 self.ctrls.chSelectedSet.SetSelection(3)
250#                 self.ctrls.chExportTo.SetSelection(sel)
251#                 exporter.setAddOpt(addOpt, panel)
252
253            exportDest = Serialization.serFromXmlUnicode(xmlNode,
254                    u"destinationPath")
255
256#                 self._refreshForEtype()
257
258        except SerializationException, e:
259            self.showCmdLineUsage(pWiki, _(u"Error during retrieving "
260                    "saved export: ") + e.message + u"\n\n")
261
262
263        if not continuousExport:
264            wordList = pWiki.getWikiDocument().searchWiki(sarOp,
265                    True)
266            try:
267                exporter.export(pWiki.getWikiDocument(), wordList,
268                        etype, exportDest, self.exportCompFn, addOpt, None)
269            except (IOError, WindowsError), e:
270                traceback.print_exc()
271                # unicode(e) returns different result for IOError
272                self.showCmdLineUsage(pWiki, str(e) + u"\n\n")
273                return
274        else:
275            exporter.startContinuousExport(pWiki.getWikiDocument(),
276                    sarOp, etype, exportDest, self.exportCompFn, addOpt,
277                    None)
278            pWiki.continuousExporter = exporter
279
280
281
282    def exportAction(self, pWiki):
283        if not (self.exportWhat or self.exportType or self.exportDest or
284                self.exportSaved):
285            return # No export
286
287        if self.exportSaved:
288            if self.exportWhat or self.exportType or self.exportDest:
289                self.showCmdLineUsage(pWiki,
290                        _(u"If saved export is given, 'what', 'type' and 'dest' aren't allowed.") +
291                        u"\n\n")
292                return
293
294            self._runSavedExport(pWiki, self.exportSaved, False)
295            return
296
297
298        if not (self.exportWhat and self.exportType and self.exportDest):
299            # but at least one of the necessary options is missing
300            self.showCmdLineUsage(pWiki,
301                    _(u"To export, all three export options ('what', 'type' and 'dest') must be set.") +
302                    u"\n\n")
303            return
304
305        # Handle self.exportWhat
306        wordList = None
307        if self.exportWhat in (u"page", u"word"):
308            # single pages
309            wordList = list(self.wikiWordsToOpen)
310        elif self.exportWhat == u"subtree":
311            # subtree
312            wordList = pWiki.getWikiData().getAllSubWords(
313                    list(self.wikiWordsToOpen))
314        elif self.exportWhat == u"wiki":
315            # whole wiki
316            wordList = pWiki.getWikiData().getAllDefinedWikiPageNames()
317        else:
318            self.showCmdLineUsage(pWiki,
319                    _(u"Value for --export-what can be 'page', 'subtree' or 'wiki'.") + u"\n\n")
320            return
321
322#             # custom list
323#             wordList = pWiki.getWikiData().search(self.listPagesOperation, True)
324
325        # Handle self.exportType
326        exporterList = []
327        for obtp in PluginManager.getSupportedExportTypes(
328                mainControl, None).values():
329            exporterList.append((obtp[0], obtp[1]))
330           
331        mainControl.getCollator().sortByItem(exporterList, 1)
332
333        exporter = None
334        for ei in exporterList:
335            if ei[1] == self.exportType:
336                exporter = ei[0]
337                break
338               
339        if exporter is None:
340            exList = ", ".join([ei[1] for ei in exporterList])
341           
342            self.showCmdLineUsage(pWiki,
343                    _(u"Value for --export-type can be one of:\n%s") % exList) + u"\n\n"
344            return
345
346        try:
347            exporter.export(pWiki.getWikiDocument(), wordList,
348                    self.exportType, self.exportDest,
349                    self.exportCompFn, exporter.getAddOpt(None), None)
350        except (IOError, WindowsError), e:
351            traceback.print_exc()
352            # unicode(e) returns different result for IOError
353            self.showCmdLineUsage(pWiki, str(e) + u"\n\n")
354            return
355
356
357
358    def continuousExportAction(self, pWiki):
359        if not self.continuousExportSaved:
360            return
361       
362        if self.exitFinally:
363            self.showCmdLineUsage(pWiki,
364                    _(u"Combination of --exit and --continuous-export-saved isn't allowed") + u"\n\n")
365            return
366       
367        self._runSavedExport(pWiki, self.continuousExportSaved, True)
368           
369
370
371    USAGE = \
372N_(u"""Options:
373
374    -h, --help: Show this message box
375    -w, --wiki  <wiki path>: set the wiki to open on startup
376    -p, --page  <page name>: set the page to open on startup
377    -x, --exit: exit immediately after performing command line actions
378    --export-what <what>: choose if you want to export page, subtree or wiki
379    --export-type <type>: tag of the export type
380    --export-dest <destination path>: path of destination directory for export
381    --export-saved <name of saved export>: alternatively name of saved export to run
382    --export-compfn: Use compatible filenames on export
383    --continuous-export-saved <name of saved export>: continuous export to start with
384    --rebuild: rebuild the Wiki database
385    --no-recent: Do not record opened wikis in recently opened wikis list
386    --preview: If no pages are given, all opened pages from previous session
387               are opened in preview mode. Otherwise all pages given after that
388               option are opened in preview mode.
389    --editor: Same as --preview but opens in text editor mode.
390
391""")
392
393    def showCmdLineUsage(self, pWiki, addRemark=u""):
394        """
395        Show dialog with addRemark and command line usage information.
396        """
397        wx.MessageBox(addRemark + _(self.USAGE), _(u"Usage information"),
398                style=wx.OK, parent=None)
399
400
401
402
403
Note: See TracBrowser for help on using the browser.