Browse Source

Basic stuff.

Bernd Zeimetz 6 years ago
commit
f63b1fa58a
2 changed files with 455 additions and 0 deletions
  1. 4
    0
      .gitignore
  2. 451
    0
      monkeystore.py

+ 4
- 0
.gitignore View File

@@ -0,0 +1,4 @@
1
+*.pyc
2
+*.shelve
3
+*.shelve.lock
4
+.*.swp

+ 451
- 0
monkeystore.py View File

@@ -0,0 +1,451 @@
1
+#!/usr/bin/python
2
+# Monkeystore client
3
+# 
4
+# Copyright (c) 2012 Bernd Zeimetz <b.zeimetz@conova.com>
5
+#
6
+# Parts taken from reportbug:
7
+#
8
+#   Written by Chris Lawrence <lawrencc@debian.org>
9
+#   (C) 2001-08 Chris Lawrence
10
+#   Copyright (C) 2008-2012 Sandro Tosi <morph@debian.org>
11
+#
12
+# This program is freely distributable per the following license:
13
+#
14
+##  Permission to use, copy, modify, and distribute this software and its
15
+##  documentation for any purpose and without fee is hereby granted,
16
+##  provided that the above copyright notice appears in all copies and that
17
+##  both that copyright notice and this permission notice appear in
18
+##  supporting documentation.
19
+##
20
+##  I DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
21
+##  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL I
22
+##  BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
23
+##  DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
24
+##  WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
25
+##  ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
26
+##  SOFTWARE.
27
+
28
+import sys
29
+import os
30
+import commands
31
+import re
32
+import math
33
+import string
34
+import errno
35
+import glob
36
+import getpass
37
+import textwrap
38
+import locale
39
+try:
40
+    import readline
41
+except ImportError:
42
+    readline = None
43
+
44
+ISATTY = sys.stdin.isatty()
45
+charset = 'us-ascii'
46
+
47
+try:
48
+    r, c = commands.getoutput('stty size').split()
49
+    rows, columns = int(r) or 24, int(c) or 79
50
+except:
51
+    rows, columns = 24, 79
52
+
53
+def ewrite(message, *args):
54
+    if not ISATTY:
55
+        return
56
+
57
+    if args:
58
+        message = message % args
59
+
60
+    if isinstance(message, unicode):
61
+        message = message.encode(charset, 'replace')
62
+
63
+    sys.stderr.write(message)
64
+    sys.stderr.flush()
65
+
66
+log_message = ewrite
67
+display_failure = ewrite
68
+
69
+def system(cmdline):
70
+    try:
71
+        x = os.getcwd()
72
+    except OSError:
73
+        os.chdir('/')
74
+    return os.system(cmdline)
75
+
76
+def indent_wrap_text(text, starttext='', indent=0, linelen=None):
77
+    """Wrapper for textwrap.fill to the existing API."""
78
+    if not linelen:
79
+        linelen = columns-1
80
+
81
+    if indent:
82
+        si = ' '*indent
83
+    else:
84
+        si = ''
85
+
86
+    text = ' '.join(text.split())
87
+    if not text:
88
+        return starttext+'\n'
89
+
90
+    output = textwrap.fill(text, width=linelen, initial_indent=starttext,
91
+                           subsequent_indent=si)
92
+    if output.endswith('\n'):
93
+        return output
94
+    return output + '\n'
95
+
96
+# Readline support, if available
97
+if readline is not None:
98
+    readline.parse_and_bind("tab: complete")
99
+    try:
100
+        # minimize the word delimeter list if possible
101
+        readline.set_completer_delims(' ')
102
+    except:
103
+        pass
104
+
105
+
106
+class our_completer(object):
107
+    def __init__(self, completions=None):
108
+        self.completions = None
109
+        if completions:
110
+            self.completions = tuple(map(str, completions))
111
+
112
+    def complete(self, text, i):
113
+        if not self.completions: return None
114
+
115
+        matching = [x for x in self.completions if x.startswith(text)]
116
+        if i < len(matching):
117
+            return matching[i]
118
+        else:
119
+            return None
120
+
121
+def our_raw_input(prompt = None, completions=None, completer=None):
122
+    istty = sys.stdout.isatty()
123
+    if not istty:
124
+        sys.stderr.write(prompt)
125
+    sys.stderr.flush()
126
+    if readline:
127
+        if completions and not completer:
128
+            completer = our_completer(completions).complete
129
+        if completer:
130
+            readline.set_completer(completer)
131
+
132
+    try:
133
+        if istty:
134
+            ret = raw_input(prompt)
135
+        else:
136
+            ret = raw_input()
137
+    except EOFError:
138
+        ewrite('\nUser interrupt (^D).\n')
139
+        raise SystemExit
140
+
141
+    if readline:
142
+        readline.set_completer(None)
143
+    return ret.strip()
144
+
145
+def select_options(msg, ok, help, allow_numbers=None, nowrap=False):
146
+    err_message = ''
147
+    for option in ok:
148
+        if option in string.ascii_uppercase:
149
+            default=option
150
+            break
151
+
152
+    if not help: help = {}
153
+
154
+    if '?' not in ok: ok = ok+'?'
155
+
156
+    if nowrap:
157
+        longmsg = msg+' ['+'|'.join(ok)+']?'+' '
158
+    else:
159
+        longmsg = indent_wrap_text(msg+' ['+'|'.join(ok)+']?').strip()+' '
160
+    ch = our_raw_input(longmsg, allow_numbers)
161
+    # Allow entry of a bug number here
162
+    if allow_numbers:
163
+        while ch and ch[0] == '#': ch = ch[1:]
164
+        if type(allow_numbers) == type(1):
165
+            try:
166
+                return str(int(ch))
167
+            except ValueError:
168
+                pass
169
+        else:
170
+            try:
171
+                number = int(ch)
172
+                if number in allow_numbers:
173
+                    return str(number)
174
+                else:
175
+                    nums = list(allow_numbers)
176
+                    nums.sort()
177
+                    err_message = 'Only the following entries are allowed: '+\
178
+                                  ', '.join(map(str, nums))
179
+            except (ValueError, TypeError):
180
+                pass
181
+
182
+    if not ch: ch = default
183
+    ch = ch[0]
184
+    if ch=='?':
185
+        help['?'] = 'Display this help.'
186
+        for ch in ok:
187
+            if ch in string.ascii_uppercase:
188
+                desc = '(default) '
189
+            else:
190
+                desc = ''
191
+            desc += help.get(ch, help.get(ch.lower(),
192
+                                          'No help for this option.'))
193
+            ewrite(indent_wrap_text(desc+'\n', '%s - '% ch, 4))
194
+        return select_options(msg, ok, help, allow_numbers, nowrap)
195
+    elif (ch.lower() in ok) or (ch.upper() in ok):
196
+        return ch.lower()
197
+    elif err_message:
198
+        ewrite(indent_wrap_text(err_message))
199
+    else:
200
+        ewrite('Invalid selection.\n')
201
+
202
+    return select_options(msg, ok, help, allow_numbers, nowrap)
203
+
204
+def yes_no(msg, yeshelp, nohelp, default=True, nowrap=False):
205
+    "Return True for yes, False for no."
206
+    if default:
207
+        ok = 'Ynq'
208
+    else:
209
+        ok = 'yNq'
210
+
211
+    res = select_options(msg, ok, {'y': yeshelp, 'n': nohelp, 'q' : 'Quit.'},
212
+                         nowrap=nowrap)
213
+    if res == 'q':
214
+        raise SystemExit
215
+    return (res == 'y')
216
+
217
+def long_message(text, *args):
218
+    if args:
219
+        ewrite(indent_wrap_text(text % args))
220
+    else:
221
+        ewrite(indent_wrap_text(text))
222
+
223
+final_message = long_message
224
+
225
+def get_string(prompt, options=None, title=None, empty_ok=False, force_prompt=False,
226
+               default='', completer=None):
227
+    if prompt and (len(prompt) < 2*columns/3) and not force_prompt:
228
+        if default:
229
+            prompt = '%s [%s]: ' % (prompt, default)
230
+            response = our_raw_input(prompt, options, completer) or default
231
+        else:
232
+            response = our_raw_input(prompt, options, completer)
233
+    else:
234
+        if prompt:
235
+            ewrite(indent_wrap_text(prompt))
236
+        if default:
237
+            response = our_raw_input('[%s]> ' % default, options, completer) or default
238
+        else:
239
+            response = our_raw_input('> ', options, completer)
240
+
241
+    # Translate the response into a Unicode string
242
+    if response is not None and not isinstance(response, unicode):
243
+        response = unicode(response, charset, 'replace')
244
+
245
+    return response
246
+
247
+def get_multiline(prompt):
248
+    ewrite('\n')
249
+    ewrite(indent_wrap_text(prompt + "  Press ENTER on a blank line to continue.\n"))
250
+    l = []
251
+    while 1:
252
+        entry = get_string('', force_prompt=True).strip()
253
+        if not entry:
254
+            break
255
+        l.append(entry)
256
+    ewrite('\n')
257
+    return l
258
+
259
+def get_password(prompt=None):
260
+    return getpass.getpass(prompt)
261
+
262
+def FilenameCompleter(text, i):
263
+    text = os.path.expanduser(text)
264
+    text = os.path.expandvars(text)
265
+    paths = glob.glob(text+'*')
266
+    if not paths: return None
267
+
268
+    if i < len(paths):
269
+        entry = paths[i]
270
+        if os.path.isdir(entry):
271
+            return entry+'/'
272
+        return entry
273
+    else:
274
+        return None
275
+
276
+def get_filename(prompt, title=None, force_prompt=False, default=''):
277
+    return get_string(prompt, title=title, force_prompt=force_prompt,
278
+                      default=default, completer=FilenameCompleter)
279
+
280
+def select_multiple(par, options, prompt, title=None, order=None, extras=None):
281
+    return menu(par, options, prompt, title=title, order=order, extras=extras,
282
+                multiple=True, empty_ok=False)
283
+
284
+def menu(par, options, prompt, default=None, title=None, any_ok=False,
285
+         order=None, extras=None, multiple=False, empty_ok=False):
286
+    selected = {}
287
+
288
+    if not extras:
289
+        extras = []
290
+    else:
291
+        extras = list(extras)
292
+
293
+    if title:
294
+        ewrite(title+'\n\n')
295
+
296
+    ewrite(indent_wrap_text(par, linelen=columns)+'\n')
297
+
298
+    if isinstance(options, dict):
299
+        options = options.copy()
300
+        # Convert to a list
301
+        if order:
302
+            olist = []
303
+            for key in order:
304
+                if options.has_key(key):
305
+                    olist.append( (key, options[key]) )
306
+                    del options[key]
307
+
308
+            # Append anything out of order
309
+            options = options.items()
310
+            options.sort()
311
+            for option in options:
312
+                olist.append( option )
313
+            options = olist
314
+        else:
315
+            options = options.items()
316
+            options.sort()
317
+
318
+    if multiple:
319
+        options.append( ('none', '') )
320
+        default = 'none'
321
+        extras += ['done']
322
+
323
+    allowed = map(lambda x: x[0], options)
324
+    allowed = allowed + extras
325
+
326
+    maxlen_name = min(max(map(len, allowed)), columns/3)
327
+    digits = int(math.ceil(math.log10(len(options)+1)))
328
+
329
+    i = 1
330
+    for name, desc in options:
331
+        text = indent_wrap_text(desc, indent=(maxlen_name+digits+3),
332
+                                starttext=('%*d %-*.*s  ' % (
333
+            digits, i, maxlen_name, maxlen_name, name)))
334
+        ewrite(text)
335
+        if len(options) < 5:
336
+            ewrite('\n')
337
+        i = i+1
338
+    if len(options) >= 5:
339
+        ewrite('\n')
340
+
341
+    if multiple:
342
+        prompt += '(one at a time) '
343
+
344
+    while 1:
345
+        if default:
346
+            aprompt = prompt + '[%s] ' % default
347
+        else:
348
+            aprompt = prompt
349
+
350
+        response = our_raw_input(aprompt, allowed)
351
+        if not response: response = default
352
+
353
+        try:
354
+            num = int(response)
355
+            if 1 <= num <= len(options):
356
+                response = options[num-1][0]
357
+        except (ValueError, TypeError):
358
+            pass
359
+
360
+        if response in allowed or (response == default and response):
361
+            if multiple:
362
+                if response == 'done':
363
+                    return selected.keys()
364
+                elif response == 'none':
365
+                    return []
366
+                elif selected.get(response):
367
+                    del selected[response]
368
+                else:
369
+                    selected[response]=1
370
+                ewrite('- selected: %s\n' % ', '.join(selected.keys()))
371
+                if len(selected):
372
+                    default = 'done'
373
+                else:
374
+                    default = 'none'
375
+                continue
376
+            else:
377
+                return response
378
+
379
+        if any_ok and response:
380
+            return response
381
+        elif empty_ok and not response:
382
+            return
383
+
384
+        ewrite('Invalid entry.\n')
385
+    return
386
+
387
+
388
+
389
+def initialize ():
390
+    return True
391
+
392
+def can_input():
393
+    return sys.stdin.isatty()
394
+
395
+
396
+import gnupg
397
+gpg=gnupg.GPG()
398
+
399
+def __encrypt_data__(data, keys, passphrase=None, symmetric=False):
400
+    gpg_data = gpg.encrypt(data, keys, passphrase=passphrase, symmetric=symmetric, always_trust=True)
401
+    if not gpg_data.ok:
402
+        raise Exception("Failed to encrypt: \n%s" %(gpg_data.stderr,))
403
+    return gpg_data.data
404
+
405
+def __decrypt_data__(gpg_data, passphrase=None):
406
+    data = gpg.decrypt(gpg_data, passphrase=passphrase, always_trust=True)
407
+    if not data.ok:
408
+        raise Exception("Failed to decrypt: \n%s" %(data.stderr,))
409
+    return data.data
410
+
411
+
412
+
413
+
414
+def __menu_category__():
415
+    categories = {
416
+        'l' : 'linux',
417
+        'w' : 'windows',
418
+        'n' : 'networking'
419
+    }
420
+    return categories[select_options('Hi! Please choose a category!',
421
+                                     ''.join(categories.keys()),
422
+                                     categories)]
423
+
424
+
425
+
426
+if __name__ == '__main__':
427
+    if sys.platform.startswith('linux'):
428
+        import pwd
429
+        user = pwd.getpwuid( os.getuid() )[ 0 ]
430
+    else:
431
+        import win32api
432
+        user = win32api.GetUserName()
433
+
434
+#    x = select_options('foo', 'abcd',
435
+#                              {'y': 'YESPLEASE',
436
+#                               'n': "Don't submit the bug report; instead, "
437
+#                               "save it in a temporary file (exits reportbug).",
438
+#                               'q': "Save it in a temporary file and quit.",
439
+#                               'a': "Attach a file.",
440
+#                               'd': "Detach an attachment file.",
441
+#                               'i': "Include a text file.",
442
+#                               'c': "Change editor and re-edit.",
443
+#                               'e': 'Re-edit the bug report.',
444
+#                               'l': 'Pipe the message through the pager.',
445
+#                               'p': 'print message to stdout.',
446
+#                               't': 'Add tags.',
447
+#                               's': 'Add a X-Debbugs-CC recipient (a CC but after BTS processing).',
448
+#                               'm': "Choose a mailer to edit the report."})
449
+
450
+    category = __menu_category__()
451
+    print category

Loading…
Cancel
Save