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.
@@ -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()