josh-gmail-backup 0.104
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/bin/gmail-backup +6 -0
- data/bin/gmail-backup-gui +6 -0
- data/gmail-backup-gui.pyo +0 -0
- data/gmail-backup-gui.sh +2 -0
- data/gmail-backup.gemspec +36 -0
- data/gmail-backup.pyo +0 -0
- data/gmail-backup.sh +2 -0
- data/gmb.gif +0 -0
- data/gmb.ico +0 -0
- data/gmb.pyo +0 -0
- data/svc/LICENSE.TXT +12 -0
- data/svc/__init__.py +0 -0
- data/svc/egg.py +166 -0
- data/svc/map.py +123 -0
- data/svc/osutils.py +67 -0
- data/svc/registry.py +171 -0
- data/svc/retrans.py +225 -0
- data/svc/scripting/__init__.py +1461 -0
- data/svc/scripting/conversions.py +157 -0
- data/svc/scripting/externals.py +580 -0
- data/svc/scripting/extractors.py +361 -0
- data/svc/scripting/help.py +173 -0
- data/svc/template.py +76 -0
- data/svc/utils.py +261 -0
- metadata +77 -0
@@ -0,0 +1,361 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
# Copyright (C) 2008 Jan Svec and Filip Jurcicek
|
3
|
+
#
|
4
|
+
# YOU USE THIS TOOL ON YOUR OWN RISK!
|
5
|
+
#
|
6
|
+
# email: info@gmail-backup.com
|
7
|
+
#
|
8
|
+
#
|
9
|
+
# Disclaimer of Warranty
|
10
|
+
# ----------------------
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, licensor provides
|
13
|
+
# this tool (and each contributor provides its contributions) on an "AS IS"
|
14
|
+
# BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
15
|
+
# implied, including, without limitation, any warranties or conditions of
|
16
|
+
# TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR
|
17
|
+
# PURPOSE. You are solely responsible for determining the appropriateness of
|
18
|
+
# using this work and assume any risks associated with your exercise of
|
19
|
+
# permissions under this license.
|
20
|
+
|
21
|
+
"""Extraktory sloužící třídě `Script`
|
22
|
+
|
23
|
+
Všechny extraktory musí implementovat rozhraní `Extractor`. Je-li jim jako
|
24
|
+
zdroj pomocí `Extractor.setSource` předána hodnota ``None``, musí být použit
|
25
|
+
implicitní zdroj. Extraktory vytváří metoda `Script.createExtractors`, proto po
|
26
|
+
případném přidání extraktoru nezapomeňte tuto metodu modifikovat.
|
27
|
+
|
28
|
+
.. image:: ../uml6.png
|
29
|
+
"""
|
30
|
+
|
31
|
+
__docformat__ = 'restructuredtext cs'
|
32
|
+
|
33
|
+
import sys
|
34
|
+
from os.path import expanduser, isfile
|
35
|
+
import os
|
36
|
+
|
37
|
+
from svc.utils import issequence, seqIntoDict
|
38
|
+
from svc.scripting import Extractor, Multiple, EnvVar, JoinSources
|
39
|
+
from svc.scripting.conversions import Flag
|
40
|
+
from getopt import gnu_getopt as getopt
|
41
|
+
|
42
|
+
class CmdlineExtractor(Extractor):
|
43
|
+
def __init__(self, short_opts={}, pos_opts=[]):
|
44
|
+
self.setSource(None)
|
45
|
+
self.setPosOpts(pos_opts)
|
46
|
+
self.setShortOpts(short_opts)
|
47
|
+
|
48
|
+
def getPosOpts(self):
|
49
|
+
return self._posOpts
|
50
|
+
|
51
|
+
def setPosOpts(self, pos_opts):
|
52
|
+
seqIntoDict([], pos_opts)
|
53
|
+
self._posOpts = pos_opts
|
54
|
+
|
55
|
+
def getShortOpts(self):
|
56
|
+
return self._shortOpts
|
57
|
+
|
58
|
+
def setShortOpts(self, short_opts):
|
59
|
+
for key, value in short_opts.iteritems():
|
60
|
+
if len(key) != 1:
|
61
|
+
raise ValueError("Bad key in short_opts dictionary: %r" % key)
|
62
|
+
if value in self.posOpts:
|
63
|
+
raise ValueError("Positional option cannot have short form: %r" % key)
|
64
|
+
self._shortOpts = short_opts
|
65
|
+
|
66
|
+
def getSource(self):
|
67
|
+
return self._source
|
68
|
+
|
69
|
+
def setSource(self, source):
|
70
|
+
self._source = source
|
71
|
+
|
72
|
+
def getSourceName(self):
|
73
|
+
return 'argv'
|
74
|
+
|
75
|
+
def extract(self, state):
|
76
|
+
source = self.getSource()
|
77
|
+
if source is None:
|
78
|
+
source = sys.argv[1:]
|
79
|
+
|
80
|
+
short = self._getoptShort()
|
81
|
+
long = self._getoptLong()
|
82
|
+
|
83
|
+
options, positional = getopt(source, short, long)
|
84
|
+
|
85
|
+
self._extractGetoptOpt(state, options)
|
86
|
+
self._extractGetoptPos(state, positional)
|
87
|
+
|
88
|
+
def _extractGetoptOpt(self, state, options):
|
89
|
+
with_arg = self._optionsWithArg()
|
90
|
+
source_name = self.getSourceName()
|
91
|
+
for option, value in options:
|
92
|
+
if option.startswith('--'):
|
93
|
+
opt_name = option[2:]
|
94
|
+
else:
|
95
|
+
opt_name = self._shortOpts[option[1:]]
|
96
|
+
# Map back from the command-line form into underscored form
|
97
|
+
opt_name = opt_name.replace('-', '_')
|
98
|
+
if opt_name in with_arg:
|
99
|
+
state.append( (opt_name, value, source_name, option) )
|
100
|
+
else:
|
101
|
+
state.append( (opt_name, 'true', source_name, option) )
|
102
|
+
|
103
|
+
def _extractGetoptPos(self, state, positional):
|
104
|
+
source_name = self.getSourceName()
|
105
|
+
pos_opts = self.posOpts
|
106
|
+
d = seqIntoDict(positional, pos_opts)
|
107
|
+
state.addObjects(d, source_name, positional)
|
108
|
+
|
109
|
+
def setManager(self, manager):
|
110
|
+
self._manager = manager
|
111
|
+
|
112
|
+
def _optionsWithArg(self):
|
113
|
+
m = self._manager
|
114
|
+
return set(m.paramToOption(p) for p in m.params()
|
115
|
+
if m.conversion(p)[0] != Flag)
|
116
|
+
|
117
|
+
def _getoptShort(self):
|
118
|
+
with_arg = self._optionsWithArg()
|
119
|
+
ret = []
|
120
|
+
for short, long in self._shortOpts.iteritems():
|
121
|
+
if long in self.posOpts:
|
122
|
+
# Positional options cannot have short-option form
|
123
|
+
continue
|
124
|
+
ret.append(short)
|
125
|
+
if long in with_arg:
|
126
|
+
ret.append(':')
|
127
|
+
return ''.join(ret)
|
128
|
+
|
129
|
+
def _getoptLong(self):
|
130
|
+
with_arg = self._optionsWithArg()
|
131
|
+
ret = []
|
132
|
+
for o in self._manager.options():
|
133
|
+
if o in self.posOpts:
|
134
|
+
# Positional options don't have long-option form
|
135
|
+
continue
|
136
|
+
if o in with_arg:
|
137
|
+
o += '='
|
138
|
+
# Map into command-line form (tj. '_' maps to '-')
|
139
|
+
o = o.replace('_', '-')
|
140
|
+
ret.append(o)
|
141
|
+
return ret
|
142
|
+
|
143
|
+
def getHelpCmdline(self):
|
144
|
+
def mapEllipsis(item):
|
145
|
+
if item is not Ellipsis:
|
146
|
+
return str(item).title()
|
147
|
+
else:
|
148
|
+
return '...'
|
149
|
+
opts = self._posOpts
|
150
|
+
return ' '.join(mapEllipsis(i) for i in self._posOpts)
|
151
|
+
|
152
|
+
def getHelpForOptions(self):
|
153
|
+
ret = {}
|
154
|
+
reverse_short = dict((item, key) for (key, item) in self.shortOpts.iteritems())
|
155
|
+
for o in self._manager.options():
|
156
|
+
help = []
|
157
|
+
if o in reverse_short:
|
158
|
+
help.append('-%s, ' % reverse_short[o])
|
159
|
+
else:
|
160
|
+
help.append(' ')
|
161
|
+
if o in self._posOpts:
|
162
|
+
help.append(o.title())
|
163
|
+
else:
|
164
|
+
help.append('--%s' % o.replace('_', '-'))
|
165
|
+
ret[o] = ''.join(help)
|
166
|
+
return ret
|
167
|
+
|
168
|
+
|
169
|
+
class PyFileExtractor(Extractor):
|
170
|
+
def __init__(self, globals=None, app_source=None):
|
171
|
+
self.setSource(None)
|
172
|
+
self.setAppSource(app_source)
|
173
|
+
if globals is None:
|
174
|
+
globals = {}
|
175
|
+
self.setGlobals(globals)
|
176
|
+
self._processedFiles = set()
|
177
|
+
|
178
|
+
def getSource(self):
|
179
|
+
return self._source
|
180
|
+
|
181
|
+
def setSource(self, source):
|
182
|
+
self._source = source
|
183
|
+
|
184
|
+
def getAppSource(self):
|
185
|
+
return self._appSource
|
186
|
+
|
187
|
+
def setAppSource(self, source):
|
188
|
+
self._appSource = source
|
189
|
+
|
190
|
+
def getGlobals(self):
|
191
|
+
return self._globals
|
192
|
+
|
193
|
+
def setGlobals(self, globals):
|
194
|
+
self._globals = globals
|
195
|
+
|
196
|
+
def getSourceName(self):
|
197
|
+
return 'pyfiles'
|
198
|
+
|
199
|
+
def _prepareSource(self, source):
|
200
|
+
"""Předpřipraví zdroj `source`
|
201
|
+
|
202
|
+
Je-li `source` None, vrátí [], není-li `source` posloupnost, vrátí
|
203
|
+
``[source]``. Ve výsledku expanduje znak tilda ``~`` na domovský
|
204
|
+
adresář aktuálního uživatele. Z výsledku odstraní již zpracované
|
205
|
+
soubory podle `processedFiles`.
|
206
|
+
|
207
|
+
:See:
|
208
|
+
processedFiles
|
209
|
+
"""
|
210
|
+
if source is None:
|
211
|
+
source = []
|
212
|
+
elif not issequence(source):
|
213
|
+
source = [source]
|
214
|
+
source = [f for f in (expanduser(f) for f in source) if isfile(f)]
|
215
|
+
source = [f for f in source if f not in self.processedFiles]
|
216
|
+
return source
|
217
|
+
|
218
|
+
def _extractFromFile(self, pyfile):
|
219
|
+
globals = self.getGlobals()
|
220
|
+
locals = {}
|
221
|
+
self._processedFiles.add(pyfile)
|
222
|
+
execfile(pyfile, globals, locals)
|
223
|
+
ret = []
|
224
|
+
for opt_name, value in locals.iteritems():
|
225
|
+
if isinstance(value, (list, tuple)):
|
226
|
+
# If option has assigned the list- or tuple-value, insert
|
227
|
+
# distinct items from this sequence
|
228
|
+
for item in value:
|
229
|
+
ret.append( (opt_name, item, pyfile, '') )
|
230
|
+
else:
|
231
|
+
ret.append( (opt_name, value, pyfile, '') )
|
232
|
+
return ret
|
233
|
+
|
234
|
+
def extract(self, state):
|
235
|
+
self._processedFiles.clear()
|
236
|
+
|
237
|
+
while True:
|
238
|
+
source = self._prepareSource(self.getSource()) \
|
239
|
+
+ self._prepareSource(self.getAppSource())
|
240
|
+
if not source:
|
241
|
+
break
|
242
|
+
state.extend(self._extractFromFile(source[0]))
|
243
|
+
|
244
|
+
def getProcessedFiles(self):
|
245
|
+
return self._processedFiles
|
246
|
+
|
247
|
+
def setManager(self, manager):
|
248
|
+
self._manager = manager
|
249
|
+
|
250
|
+
|
251
|
+
class EnvironExtractor(Extractor):
|
252
|
+
def __init__(self, env_prefix=None, split_char=None):
|
253
|
+
self.setSource(None)
|
254
|
+
self.setEnvPrefix(env_prefix)
|
255
|
+
if split_char is None:
|
256
|
+
if os.name == 'nt':
|
257
|
+
self.setSplitChar(';')
|
258
|
+
else:
|
259
|
+
self.setSplitChar(':')
|
260
|
+
else:
|
261
|
+
self.setSplitChar(split_char)
|
262
|
+
|
263
|
+
def getSource(self):
|
264
|
+
return self._source
|
265
|
+
|
266
|
+
def setSource(self, source):
|
267
|
+
self._source = source
|
268
|
+
|
269
|
+
def getEnvPrefix(self):
|
270
|
+
return self._envPrefix
|
271
|
+
|
272
|
+
def setEnvPrefix(self, prefix):
|
273
|
+
self._envPrefix = prefix
|
274
|
+
|
275
|
+
def getSplitChar(self):
|
276
|
+
return self._splitChar
|
277
|
+
|
278
|
+
def setSplitChar(self, s_char):
|
279
|
+
self._splitChar = s_char
|
280
|
+
|
281
|
+
def getSourceName(self):
|
282
|
+
return 'env'
|
283
|
+
|
284
|
+
def setManager(self, manager):
|
285
|
+
self._manager = manager
|
286
|
+
|
287
|
+
def extract(self, state):
|
288
|
+
source = self._source
|
289
|
+
if source is None:
|
290
|
+
source = os.environ
|
291
|
+
env_vars = self._manager.optionsWithSpecifier(EnvVar)
|
292
|
+
multiple_vars = self._manager.optionsWithSpecifier(Multiple)
|
293
|
+
multiple_vars |= self._manager.optionsWithSpecifier(JoinSources) # Union of sets
|
294
|
+
prefix = self.getEnvPrefix()
|
295
|
+
if not issequence(prefix):
|
296
|
+
prefix = [prefix]
|
297
|
+
if not prefix:
|
298
|
+
prefix = [None]
|
299
|
+
prefix = [p or '' for p in prefix]
|
300
|
+
split_char = self.getSplitChar()
|
301
|
+
|
302
|
+
for p in prefix:
|
303
|
+
for var in env_vars:
|
304
|
+
whole_var = (p+var).upper()
|
305
|
+
if whole_var in source:
|
306
|
+
value = source[whole_var]
|
307
|
+
if var in multiple_vars:
|
308
|
+
for item in value.split(split_char):
|
309
|
+
state.append( (var, item, 'env:%s'%p, whole_var) )
|
310
|
+
else:
|
311
|
+
state.append( (var, value, 'env:%s'%p, whole_var) )
|
312
|
+
|
313
|
+
|
314
|
+
class CmdPosOptsExtractor(Extractor):
|
315
|
+
def __init__(self, exscript):
|
316
|
+
super(CmdPosOptsExtractor, self).__init__()
|
317
|
+
self._exscript = exscript
|
318
|
+
|
319
|
+
def getSource(self):
|
320
|
+
return None
|
321
|
+
|
322
|
+
def setSource(self, source):
|
323
|
+
pass
|
324
|
+
|
325
|
+
def getSourceName(self):
|
326
|
+
return 'cmdPosOpts'
|
327
|
+
|
328
|
+
def getPosOpts(self, state):
|
329
|
+
cmdPosOption = '__premain__._command_pos_opts'
|
330
|
+
enabled = state.enabled
|
331
|
+
try:
|
332
|
+
state.disableAll()
|
333
|
+
state.enable([cmdPosOption])
|
334
|
+
try:
|
335
|
+
objects = state.getObjects()
|
336
|
+
return objects['__premain__']['_command_pos_opts']
|
337
|
+
except KeyError:
|
338
|
+
return []
|
339
|
+
finally:
|
340
|
+
state.disableExcept(enabled)
|
341
|
+
|
342
|
+
def extract(self, state):
|
343
|
+
try:
|
344
|
+
command = self._exscript.getCommandValue().pop()
|
345
|
+
except ValueError:
|
346
|
+
# Command wasn't specified
|
347
|
+
return
|
348
|
+
if command in self._exscript.cmdPosOpts:
|
349
|
+
format = self._exscript.cmdPosOpts[command]
|
350
|
+
pos_opts = self.getPosOpts(state)
|
351
|
+
d = seqIntoDict(pos_opts, format)
|
352
|
+
self._exscript.state.addObjects(d, 'cmdPosOpts')
|
353
|
+
|
354
|
+
def setManager(self, manager):
|
355
|
+
pass
|
356
|
+
|
357
|
+
def getHelpForOptions(self):
|
358
|
+
return {}
|
359
|
+
|
360
|
+
def getHelpForExtractor(self):
|
361
|
+
return ''
|
@@ -0,0 +1,173 @@
|
|
1
|
+
# Copyright (C) 2008 Jan Svec and Filip Jurcicek
|
2
|
+
#
|
3
|
+
# YOU USE THIS TOOL ON YOUR OWN RISK!
|
4
|
+
#
|
5
|
+
# email: info@gmail-backup.com
|
6
|
+
#
|
7
|
+
#
|
8
|
+
# Disclaimer of Warranty
|
9
|
+
# ----------------------
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, licensor provides
|
12
|
+
# this tool (and each contributor provides its contributions) on an "AS IS"
|
13
|
+
# BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
14
|
+
# implied, including, without limitation, any warranties or conditions of
|
15
|
+
# TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR
|
16
|
+
# PURPOSE. You are solely responsible for determining the appropriateness of
|
17
|
+
# using this work and assume any risks associated with your exercise of
|
18
|
+
# permissions under this license.
|
19
|
+
|
20
|
+
import sys
|
21
|
+
import textwrap
|
22
|
+
|
23
|
+
from svc.egg import PythonEgg
|
24
|
+
from svc.utils import issequence
|
25
|
+
|
26
|
+
class HelpManager(PythonEgg):
|
27
|
+
def __init__(self, manager, extractors, screenWidth=80):
|
28
|
+
self._manager = manager
|
29
|
+
self._extractors = extractors
|
30
|
+
self._ex_help = [e.helpForOptions for e in extractors]
|
31
|
+
self._screenWidth = screenWidth
|
32
|
+
|
33
|
+
def _wrapParagraphs(self, str, width=70):
|
34
|
+
paragraphs = []
|
35
|
+
for line in str.splitlines(True):
|
36
|
+
line = line.lstrip()
|
37
|
+
if not line and paragraphs and paragraphs[-1]:
|
38
|
+
paragraphs.append('')
|
39
|
+
elif not paragraphs:
|
40
|
+
paragraphs.append(line)
|
41
|
+
else:
|
42
|
+
paragraphs[-1] += line
|
43
|
+
paragraphs = [textwrap.wrap(par, width) for par in paragraphs]
|
44
|
+
paragraphs = ['\n'.join(par) for par in paragraphs]
|
45
|
+
return '\n\n'.join(paragraphs)
|
46
|
+
|
47
|
+
|
48
|
+
def getHelpDict(self, screenWidth=None):
|
49
|
+
if screenWidth is None:
|
50
|
+
screenWidth = self._screenWidth
|
51
|
+
|
52
|
+
option_help = {}
|
53
|
+
|
54
|
+
for ehelp in self._ex_help:
|
55
|
+
if ehelp is None:
|
56
|
+
continue
|
57
|
+
for opt_name, opt_desc in ehelp.iteritems():
|
58
|
+
if opt_name not in option_help:
|
59
|
+
option_help[opt_name] = []
|
60
|
+
if not issequence(opt_desc):
|
61
|
+
opt_desc = [opt_desc]
|
62
|
+
option_help[opt_name].extend(opt_desc)
|
63
|
+
|
64
|
+
max_desc_width = 0
|
65
|
+
|
66
|
+
manager_help = self._manager.helpForOptions
|
67
|
+
|
68
|
+
for opt_name in option_help:
|
69
|
+
opt_doc = manager_help.get(opt_name, '')
|
70
|
+
opt_desc = option_help[opt_name]
|
71
|
+
opt_desc = ', '.join(opt_desc)
|
72
|
+
max_desc_width = max(max_desc_width, len(opt_desc))
|
73
|
+
option_help[opt_name] = (opt_desc, opt_doc)
|
74
|
+
|
75
|
+
padding = 2
|
76
|
+
|
77
|
+
template = '%%-%ds' % max_desc_width + ' '*padding
|
78
|
+
|
79
|
+
wrap_width = max(screenWidth - max_desc_width - padding, 30)
|
80
|
+
|
81
|
+
str_help = {}
|
82
|
+
for opt_name, (opt_desc, opt_doc) in option_help.iteritems():
|
83
|
+
par = []
|
84
|
+
lines = self._wrapParagraphs(opt_doc, wrap_width).splitlines() or ['']
|
85
|
+
for line in lines:
|
86
|
+
par.append(template % opt_desc + line)
|
87
|
+
opt_desc = ''
|
88
|
+
str_help[opt_name] = '\n'.join(par).rstrip()
|
89
|
+
return str_help
|
90
|
+
|
91
|
+
def getHelpDictOptions(self, options, screenWidth=None):
|
92
|
+
ret = self.getHelpDict(screenWidth)
|
93
|
+
new = {}
|
94
|
+
for opt_name in options:
|
95
|
+
if opt_name in ret:
|
96
|
+
new[opt_name] = ret[opt_name]
|
97
|
+
return new
|
98
|
+
|
99
|
+
def getFuncDoc(self, func, screenWidth=None):
|
100
|
+
if screenWidth is None:
|
101
|
+
screenWidth = self._screenWidth
|
102
|
+
|
103
|
+
doc = getattr(func, '__doc__')
|
104
|
+
if doc is None:
|
105
|
+
doc = ''
|
106
|
+
doc = doc.strip()
|
107
|
+
|
108
|
+
return self._wrapParagraphs(doc, screenWidth)
|
109
|
+
|
110
|
+
|
111
|
+
def printHelpDictOptions(self, options, screenWidth=None, stdout=None, newline=False):
|
112
|
+
if stdout is None:
|
113
|
+
stdout = sys.stdout
|
114
|
+
help = self.getHelpDictOptions(options, screenWidth)
|
115
|
+
help = [i[1] for i in sorted(help.items())]
|
116
|
+
if help:
|
117
|
+
stdout.write('\n'.join(help) + '\n')
|
118
|
+
if newline:
|
119
|
+
stdout.write('\n')
|
120
|
+
|
121
|
+
def printHelpDictOptionsHdr(self, options, header, screenWidth=None, stdout=None, newline=False):
|
122
|
+
self.printHeader(header, stdout)
|
123
|
+
self.printHelpDictOptions(options, screenWidth, stdout, newline)
|
124
|
+
|
125
|
+
def printFuncDoc(self, func, screenWidth=None, stdout=None, newline=False):
|
126
|
+
if stdout is None:
|
127
|
+
stdout = sys.stdout
|
128
|
+
help = self.getFuncDoc(func, screenWidth)
|
129
|
+
if help:
|
130
|
+
stdout.write(help + '\n')
|
131
|
+
if newline:
|
132
|
+
stdout.write('\n')
|
133
|
+
|
134
|
+
def printHeader(self, header, stdout=None, head_str='='):
|
135
|
+
if stdout is None:
|
136
|
+
stdout = sys.stdout
|
137
|
+
stdout.write(header + ':\n')
|
138
|
+
stdout.write(head_str * (len(header)+1) + '\n')
|
139
|
+
|
140
|
+
def printHelpForCommand(self, command, method, screenWidth=None, stdout=None):
|
141
|
+
if stdout is None:
|
142
|
+
stdout = sys.stdout
|
143
|
+
self.printHeader(command, stdout, head_str='~')
|
144
|
+
|
145
|
+
self.printFuncDoc(method, screenWidth, stdout, newline=True)
|
146
|
+
|
147
|
+
command_params = self._manager.paramsChildren(command)
|
148
|
+
command_options = [self._manager.paramToOption(p) for p in command_params]
|
149
|
+
if command_options:
|
150
|
+
self.printHelpDictOptions(command_options, screenWidth, stdout)
|
151
|
+
else:
|
152
|
+
stdout.write("No options available\n")
|
153
|
+
stdout.write('\n')
|
154
|
+
|
155
|
+
def printUsage(self, script_file, pos_opts, main_obj=None, screenWidth=None, stdout=None):
|
156
|
+
if stdout is None:
|
157
|
+
stdout = sys.stdout
|
158
|
+
|
159
|
+
pos_opts_str = []
|
160
|
+
for o in pos_opts:
|
161
|
+
if o == Ellipsis:
|
162
|
+
pos_opts_str.append('...')
|
163
|
+
elif isinstance(o, dict):
|
164
|
+
pos_opts_str.append('...')
|
165
|
+
else:
|
166
|
+
pos_opts_str.append(o.title())
|
167
|
+
pos_opts_str = ' '.join(pos_opts_str)
|
168
|
+
|
169
|
+
self.printHeader('Usage', stdout, head_str='=')
|
170
|
+
stdout.write(' %s [options] %s\n' % (script_file, pos_opts_str))
|
171
|
+
stdout.write('\n')
|
172
|
+
if main_obj is not None:
|
173
|
+
self.printFuncDoc(main_obj, screenWidth, stdout, newline=True)
|
data/svc/template.py
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
# Copyright (C) 2008 Jan Svec and Filip Jurcicek
|
2
|
+
#
|
3
|
+
# YOU USE THIS TOOL ON YOUR OWN RISK!
|
4
|
+
#
|
5
|
+
# email: info@gmail-backup.com
|
6
|
+
#
|
7
|
+
#
|
8
|
+
# Disclaimer of Warranty
|
9
|
+
# ----------------------
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, licensor provides
|
12
|
+
# this tool (and each contributor provides its contributions) on an "AS IS"
|
13
|
+
# BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
14
|
+
# implied, including, without limitation, any warranties or conditions of
|
15
|
+
# TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR
|
16
|
+
# PURPOSE. You are solely responsible for determining the appropriateness of
|
17
|
+
# using this work and assume any risks associated with your exercise of
|
18
|
+
# permissions under this license.
|
19
|
+
|
20
|
+
import re
|
21
|
+
from string import Template
|
22
|
+
|
23
|
+
class ExTemplate(Template):
|
24
|
+
places = {
|
25
|
+
'exact': r'^%s$',
|
26
|
+
'space': r'^\s*%s\s*$',
|
27
|
+
'space_start': r'^\s*%s$',
|
28
|
+
'space_end': r'^%s\s*$',
|
29
|
+
'ignore': r'^.*%s.*$',
|
30
|
+
'ignore_start': r'^.*%s$',
|
31
|
+
'ignore_end': r'^%s.*$',
|
32
|
+
}
|
33
|
+
def __init__(self, template, placing='exact'):
|
34
|
+
super(Template, self).__init__(template)
|
35
|
+
self._makeBlPattern(template, placing)
|
36
|
+
|
37
|
+
def _makeBlPattern(self, template, placing):
|
38
|
+
tesc = ''
|
39
|
+
from_ = 0
|
40
|
+
for match in self.pattern.finditer(template):
|
41
|
+
start, end = match.span()
|
42
|
+
tesc += re.escape(template[from_:start])
|
43
|
+
tesc += template[start:end]
|
44
|
+
from_ = end
|
45
|
+
else:
|
46
|
+
tesc += re.escape(template[from_:])
|
47
|
+
try:
|
48
|
+
place = self.places[placing]
|
49
|
+
except KeyError:
|
50
|
+
raise ValueError("Unknown placing: %r" % placing)
|
51
|
+
|
52
|
+
def bl_replace(match):
|
53
|
+
d = match.groupdict()
|
54
|
+
named = d['named']
|
55
|
+
braced = d['braced']
|
56
|
+
escaped = d['escaped']
|
57
|
+
invalid = d['invalid']
|
58
|
+
if named is not None:
|
59
|
+
ret = r'(?P<%s>.*)' % named
|
60
|
+
elif braced is not None:
|
61
|
+
ret = r'(?P<%s>.*)' % braced
|
62
|
+
elif invalid is not None:
|
63
|
+
raise ValueError("Invalid reference")
|
64
|
+
else:
|
65
|
+
ret = re.escape(escaped)
|
66
|
+
return ret
|
67
|
+
|
68
|
+
blpat = place % self.pattern.sub(bl_replace, tesc)
|
69
|
+
self.blpattern = re.compile(blpat)
|
70
|
+
|
71
|
+
def backload(self, s):
|
72
|
+
match = self.blpattern.search(s)
|
73
|
+
if match is None:
|
74
|
+
return None
|
75
|
+
else:
|
76
|
+
return match.groupdict()
|