josh-gmail-backup 0.104

Sign up to get free protection for your applications and to get access to all the features.
@@ -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()