1import mimetypes
2import os
3import re
4import sys
5import tempfile
6
7try:
8    import readline
9except ImportError:
10    readline = None
11
12BUGZ_COMMENT_TEMPLATE = """
13BUGZ: ---------------------------------------------------
14%s
15BUGZ: Any line beginning with 'BUGZ:' will be ignored.
16BUGZ: ---------------------------------------------------
17"""
18
19DEFAULT_NUM_COLS = 80
20
21#
22# Auxiliary functions
23#
24
25
26def get_content_type(filename):
27    return mimetypes.guess_type(filename)[0] or 'application/octet-stream'
28
29
30def raw_input_block():
31    """ Allows multiple line input until a Ctrl+D is detected.
32
33    @rtype: string
34    """
35    target = ''
36    while True:
37        try:
38            line = input()
39            target += line + '\n'
40        except EOFError:
41            return target
42
43#
44# This function was lifted from Bazaar 1.9.
45#
46
47
48def terminal_width():
49    """Return estimated terminal width."""
50    if sys.platform == 'win32':
51        return win32utils.get_console_size()[0]
52    width = DEFAULT_NUM_COLS
53    try:
54        import struct
55        import fcntl
56        import termios
57        s = struct.pack('HHHH', 0, 0, 0, 0)
58        x = fcntl.ioctl(1, termios.TIOCGWINSZ, s)
59        width = struct.unpack('HHHH', x)[1]
60    except IOError:
61        pass
62
63    if width <= 0:
64        try:
65            width = int(os.environ['COLUMNS'])
66        except:
67            pass
68
69    if width <= 0:
70        width = DEFAULT_NUM_COLS
71
72    return width
73
74
75def launch_editor(initial_text, comment_from='', comment_prefix='BUGZ:'):
76    """Launch an editor with some default text.
77
78    Lifted from Mercurial 0.9.
79    @rtype: string
80    """
81    (fd, name) = tempfile.mkstemp("bugz")
82    f = os.fdopen(fd, "w")
83    f.write(comment_from)
84    f.write(initial_text)
85    f.close()
86
87    editor = (os.environ.get("BUGZ_EDITOR") or os.environ.get("EDITOR"))
88    if editor:
89        result = os.system("%s \"%s\"" % (editor, name))
90        if result != 0:
91            raise RuntimeError('Unable to launch editor: %s' % editor)
92
93        new_text = open(name).read()
94        new_text = re.sub('(?m)^%s.*\n' % comment_prefix, '', new_text)
95        os.unlink(name)
96        return new_text
97
98    return ''
99
100
101def block_edit(comment, comment_from=''):
102    editor = (os.environ.get('BUGZ_EDITOR') or os.environ.get('EDITOR'))
103
104    if not editor:
105        print(comment + ': (Press Ctrl+D to end)')
106        new_text = raw_input_block()
107        return new_text
108
109    initial_text = '\n'.join(['BUGZ: %s' % line
110                              for line in comment.splitlines()])
111    new_text = launch_editor(BUGZ_COMMENT_TEMPLATE % initial_text,
112                             comment_from)
113
114    if new_text.strip():
115        return new_text
116    else:
117        return ''
118