[PATCH] mbox feature implemented

Rafael Cunha de Almeida rafael at kontesti.me
Sun Dec 5 15:32:18 UTC 2010


---
 bin/querybts             |   14 ++++++--
 bin/reportbug            |   11 +++++--
 reportbug/ui/gtk2_ui.py  |    3 +-
 reportbug/ui/text_ui.py  |   69 +++++++++++++++++++++++++++++++++++++--------
 reportbug/ui/urwid_ui.py |    3 +-
 reportbug/utils.py       |   31 +++++++++++++++++++-
 6 files changed, 107 insertions(+), 24 deletions(-)

diff --git a/bin/querybts b/bin/querybts
index c3744d5..314ef95 100755
--- a/bin/querybts
+++ b/bin/querybts
@@ -53,12 +53,14 @@ def main():
     defaults = dict(system = 'debian', archived = False,
                     http_proxy = '', interface = 'text',
                     use_browser = False, source = False,
-                    mirrors = None, mbox = False,  buglist = False)
+                    mirrors = None, mbox = False,  buglist = False,
+                    mbox_reader_cmd = None)
 
     # parse config file to update default options
     args = utils.parse_config_files()
     for option, arg in args.items():
-        if option in ('system', 'mirrors', 'interface', 'http_proxy'):
+        if option in ('system', 'mirrors', 'interface', 'http_proxy',
+                      'mbox_reader_cmd'):
             defaults[option] = arg
 
     # define the cli options parser
@@ -90,6 +92,8 @@ def main():
                       help='Specify the user interface to use; available values: %s ' % ', '.join(AVAILABLE_UIS.keys()))
     parser.add_option('-w', '--web', action='store_true', dest='use_browser',
                       help='Use a web browser instead of the internal interface.')
+    parser.add_option('--mbox-reader-cmd', dest='mbox_reader_cmd',
+                      help="Specify the program to open the reports' mbox.")
 
 
     # parse cli options
@@ -201,7 +205,8 @@ def main():
                                           options.http_proxy, options.timeout,
                                           queryonly=True,
                                           title=VERSION,
-                                          archived=options.archived)
+                                          archived=options.archived,
+                                          mbox_reader_cmd=options.mbox_reader_cmd)
                     ui.long_message('This option is not available while using querybts alone.\n')
                     x = ui.select_options('What do you want to do now?', 'Qb',
                                           {'q': 'Exit querybts.',
@@ -213,7 +218,8 @@ def main():
         while 1:
             ui.handle_bts_query(package, options.system, options.timeout, options.mirrors, options.http_proxy,
                                 queryonly=True, title=VERSION, archived=options.archived,
-                                source=options.source, buglist=options.buglist)
+                                source=options.source, buglist=options.buglist,
+                                mbox_reader_cmd=options.mbox_reader_cmd)
             ui.long_message('This option is not available while using querybts alone.\n')
             x = ui.select_options('What do you want to do now?', 'Qb',
                                   {'q': 'Exit querybts.',
diff --git a/bin/reportbug b/bin/reportbug
index f827334..1a8545b 100755
--- a/bin/reportbug
+++ b/bin/reportbug
@@ -749,7 +749,7 @@ def main():
                     editor='', offline=False, verify=True, check_uid=True,
                     testmode=False, attachments=[], keyid='', body=None,
                     bodyfile=None, smtptls=False, smtpuser='', smtppasswd='',
-                    paranoid=False)
+                    paranoid=False, mbox_reader_cmd=None)
 
     # Convention: consider `option.foo' names read-only; they always contain
     # the original value as determined by the cascade of command-line options
@@ -952,6 +952,8 @@ def main():
     parser.add_option('--no-tags-menu', dest="tagsmenu", default=True,
                       action='store_false',
                       help='don\'t show tags menu')
+    parser.add_option('--mbox-reader-cmd', dest='mbox_reader_cmd',
+                      help="Specify the program to open the reports' mbox.")
 
     (options, args) = parser.parse_args()
 
@@ -1309,7 +1311,8 @@ class UI(object):
                     exinfo = ui.show_report(report, 'debian', self.options.mirrors,
                                           self.options.http_proxy, self.options.timeout, queryonly=True,
                                           title=VERSION,
-                                          archived=False)
+                                          archived=False,
+                                          mbox_reader_cmd=self.options.mbox_reader_cmd)
                     if foundpackage:
                         package = foundpackage
                     if not exinfo:
@@ -1626,7 +1629,9 @@ class UI(object):
                                              self.options.http_proxy,
                                              source=src,
                                              queryonly=self.options.queryonly,
-                                             version=pkgversion)
+                                             version=pkgversion,
+                                             mbox_reader_cmd=
+                                                 self.options.mbox_reader_cmd)
             except UINotImplemented:
                 exinfo = None
             except NoNetwork:
diff --git a/reportbug/ui/gtk2_ui.py b/reportbug/ui/gtk2_ui.py
index 056ef0a..ab9679f 100644
--- a/reportbug/ui/gtk2_ui.py
+++ b/reportbug/ui/gtk2_ui.py
@@ -864,7 +864,8 @@ class HandleBTSQueryPage (TreePage):
     value_column = 0
 
     def sync_pre_operation (self, package, bts, timeout, mirrors=None, http_proxy="", queryonly=False, screen=None,
-                            archived='no', source=False, title=None, version=None, buglist=None):
+                            archived='no', source=False, title=None,
+                            version=None, buglist=None, mbox_reader_cmd=None):
         self.bts = bts
         self.mirrors = mirrors
         self.http_proxy = http_proxy
diff --git a/reportbug/ui/text_ui.py b/reportbug/ui/text_ui.py
index 4bfcda6..b54c3af 100644
--- a/reportbug/ui/text_ui.py
+++ b/reportbug/ui/text_ui.py
@@ -43,6 +43,7 @@ from reportbug.exceptions import (
     InvalidRegex,
     )
 from reportbug.urlutils import launch_browser
+import reportbug.utils
 
 ISATTY = sys.stdin.isatty()
 charset = 'us-ascii'
@@ -105,6 +106,20 @@ if readline is not None:
     except:
         pass
 
+def _launch_mbox_reader(mbox_reader_cmd, bts, bugs, number, mirrors, archived,
+                        mbox, http_proxy, timeout):
+    try:
+        number = int(number)
+        if number not in bugs and 1 <= number <= len(bugs):
+            number = bugs[number-1]
+        reportbug.utils.launch_mbox_reader(mbox_reader_cmd,
+            debianbts.get_report_url(
+                bts, number, mirrors, archived, mbox), http_proxy,
+            timeout)
+    except ValueError:
+        ewrite('Invalid report number: %s\n',
+               number)
+
 class our_completer(object):
     def __init__(self, completions=None):
         self.completions = None
@@ -389,7 +404,7 @@ def menu(par, options, prompt, default=None, title=None, any_ok=False,
 # Things that are very UI dependent go here
 def show_report(number, system, mirrors,
                 http_proxy, timeout, screen=None, queryonly=False, title='',
-                archived='no'):
+                archived='no', mbox_reader_cmd=None):
     sysinfo = debianbts.SYSTEMS[system]
     ewrite('Retrieving report #%d from %s bug tracking system...\n',
            number, sysinfo['name'])
@@ -445,7 +460,7 @@ def show_report(number, system, mirrors,
                     raise
         skip_pager = False
 
-        options = 'xOrbq'
+        options = 'xOrbeq'
 
         if (current_message+1) < len(messages):
             options = 'N'+options.lower()
@@ -459,6 +474,7 @@ def show_report(number, system, mirrors,
                             'n' : 'Show next message (followup).',
                             'p' : 'Show previous message (followup).',
                             'r' : 'Redisplay this message.',
+                            'e' : 'Launch e-mail client to read full log.',
                             'b' : 'Launch web browser to read '
                             'full log.',
                             'q' : "I'm bored; quit please."},
@@ -471,6 +487,12 @@ def show_report(number, system, mirrors,
             launch_browser(debianbts.get_report_url(
                 system, number, mirrors, archived))
             skip_pager = True
+        elif x == 'e':
+            reportbug.utils.launch_mbox_reader(mbox_reader_cmd,
+                debianbts.get_report_url(
+                    system, number, mirrors, archived, True), http_proxy,
+                    timeout)
+            skip_pager = True
         elif x == 'o':
             break
         elif x == 'n':
@@ -481,7 +503,8 @@ def show_report(number, system, mirrors,
 
 def handle_bts_query(package, bts, timeout, mirrors=None, http_proxy="",
                      queryonly=False, title="", screen=None, archived='no',
-                     source=False, version=None, mbox=False, buglist=None):
+                     source=False, version=None, mbox=False, buglist=None,
+                     mbox_reader_cmd=None):
     root = debianbts.SYSTEMS[bts].get('btsroot')
     if not root:
         ewrite('%s bug tracking system has no web URL; bypassing query\n',
@@ -574,7 +597,8 @@ def handle_bts_query(package, bts, timeout, mirrors=None, http_proxy="",
             ewrite('%d bug reports found:\n\n', count)
 
         return browse_bugs(hierarchy, count, bugs, bts, queryonly,
-                           mirrors, http_proxy, timeout, screen, title, package)
+                           mirrors, http_proxy, timeout, screen, title, package,
+                           mbox_reader_cmd)
 
     except (IOError, NoNetwork):
         ewrite('Unable to connect to %s BTS; ', debianbts.SYSTEMS[bts]['name'])
@@ -585,7 +609,7 @@ def handle_bts_query(package, bts, timeout, mirrors=None, http_proxy="",
             raise NoNetwork
 
 def browse_bugs(hierarchy, count, bugs, bts, queryonly, mirrors,
-                http_proxy, timeout, screen, title, package):
+                http_proxy, timeout, screen, title, package, mbox_reader_cmd):
     try:
         output_encoding = locale.getpreferredencoding()
     except locale.Error, msg:
@@ -630,8 +654,8 @@ def browse_bugs(hierarchy, count, bugs, bts, queryonly, mirrors,
                 if endcount == count:
                     skipmsg = ''
 
-                options = 'yNbmrqsf'
-                if queryonly: options = 'Nbmrqf'
+                options = 'yNbmrqsfe'
+                if queryonly: options = 'Nbmrqfe'
 
                 rstr = "(%d-%d/%d) " % (startcount, endcount, count)
                 pstr = rstr + "Is the bug you found listed above"
@@ -651,6 +675,7 @@ def browse_bugs(hierarchy, count, bugs, bts, queryonly, mirrors,
                     'q' : "I'm bored; quit please.",
                     's' : 'Skip remaining problems; file a new '
                     'report immediately.',
+                    'e' : 'Open the report using an e-mail client.',
                     'f' : 'Filter bug list using a pattern.'}
                 if skipmsg:
                     helptext['n'] = helptext['n'][:-1]+' (skip to Next page).'
@@ -699,11 +724,19 @@ def browse_bugs(hierarchy, count, bugs, bts, queryonly, mirrors,
 		    elif x == 'f':
 			# Do filter. Recursive done.
 			retval = search_bugs(hierarchy,bts, queryonly, mirrors,
-                                             http_proxy, timeout, screen, title, package)
+                                             http_proxy, timeout, screen, title,
+                                             package, mbox_reader_cmd)
 			if retval in ["FilterEnd", "Top"]:
 			    continue
 			else:
 			    return retval
+                    elif x == 'e':
+                        number = our_raw_input('Please enter the number of the '
+                            'bug you would like to view: #',
+                            allowed)
+                        _launch_mbox_reader(mbox_reader_cmd, bts, bugs, number,
+                                            mirrors, 'no', True, http_proxy,
+                                            timeout)
                     else:
                         if x == 'm' or x == 'i':
                             if len(bugs) == 1:
@@ -728,7 +761,8 @@ def browse_bugs(hierarchy, count, bugs, bts, queryonly, mirrors,
                                                   http_proxy, timeout,
                                                   queryonly=queryonly,
                                                   screen=screen,
-                                                  title=title)
+                                                  title=title,
+                                                  mbox_reader_cmd=mbox_reader_cmd)
                                 if res:
                                     return res
                             except ValueError:
@@ -768,7 +802,7 @@ def proc_hierarchy(hierarchy):
     return count, bugs
 
 def search_bugs(hierarchyfull, bts, queryonly, mirrors,
-                http_proxy, timeout, screen, title, package):
+                http_proxy, timeout, screen, title, package, mbox_reader_cmd):
     """Search for the bug list using a pattern."""
     """Return string "FilterEnd" when we are done with search."""
 
@@ -838,8 +872,8 @@ def search_bugs(hierarchyfull, bts, queryonly, mirrors,
                 if endcount == count:
                     skipmsg = ''
 
-                options = 'yNbmrqsfut'
-                if queryonly: options = 'Nmbrqfut'
+                options = 'yNbmrqsfute'
+                if queryonly: options = 'Nmbrqfute'
 
                 rstr = "(%d-%d/%d) " % (startcount, endcount, count)
                 pstr = rstr + "Is the bug you found listed above"
@@ -861,6 +895,7 @@ def search_bugs(hierarchyfull, bts, queryonly, mirrors,
                     'report immediately.',
 		    'f' : 'Filter (search) bug list using a pattern.',
 		    'u' : 'Up one level of filter.',
+                    'e' : 'Open the report using an e-mail client.',
 		    't' : 'Top of the bug list (remove all filters).'}
                 if skipmsg:
                     helptext['n'] = helptext['n'][:-1]+' (skip to Next page).'
@@ -905,7 +940,8 @@ def search_bugs(hierarchyfull, bts, queryonly, mirrors,
 		    elif x == 'f':
 			# Do filter. Recursive done.
 			retval = search_bugs(hierarchy, bts, queryonly, mirrors,
-			    http_proxy, timeout, screen, title, package)
+			    http_proxy, timeout, screen, title, package,
+                            mbox_reader_cmd)
 			if retval == "FilterEnd":
 			    continue
 			else:
@@ -916,6 +952,13 @@ def search_bugs(hierarchyfull, bts, queryonly, mirrors,
 		    elif x == 't':
 			# go back to the Top level.
 			return "Top"
+                    elif x == 'e':
+                        number = our_raw_input('Please enter the number of the '
+                            'bug you would like to view: #',
+                            allowed)
+                        _launch_mbox_reader(mbox_reader_cmd, bts, bugs, number,
+                                            mirrors, 'no', True, http_proxy,
+                                            timeout)
                     else:
                         if x == 'm' or x == 'i':
                             number = our_raw_input(
diff --git a/reportbug/ui/urwid_ui.py b/reportbug/ui/urwid_ui.py
index baa94ee..c7215c2 100644
--- a/reportbug/ui/urwid_ui.py
+++ b/reportbug/ui/urwid_ui.py
@@ -532,7 +532,8 @@ def show_report(number, system, mirrors,
 
 def handle_bts_query(package, bts, timeout, mirrors=None, http_proxy="",
                      queryonly=False, screen=None, title="", archived='no',
-                     source=False, version=None, mbox=False, buglist=None):
+                     source=False, version=None, mbox=False, buglist=None,
+                     mbox_reader_cmd=None):
     from reportbug import debianbts
 
     sysinfo = debianbts.SYSTEMS[bts]
diff --git a/reportbug/utils.py b/reportbug/utils.py
index 9d241c6..a738027 100644
--- a/reportbug/utils.py
+++ b/reportbug/utils.py
@@ -43,6 +43,7 @@ import rfc822
 import socket
 import subprocess
 
+from urlutils import open_url
 from string import ascii_letters, digits
 
 # Paths for dpkg
@@ -784,7 +785,7 @@ CONFIG_ARGS = (
     'sign', 'nocc', 'nocompress', 'dontquery', 'noconf', 'mirrors', 'keyid',
     'headers', 'interface', 'template', 'mode', 'check_available', 'query_src',
     'printonly', 'offline', 'check_uid', 'smtptls', 'smtpuser', 'smtppasswd',
-    'paranoid')
+    'paranoid', 'mbox_reader_cmd')
 
 class Mua:
     command = ""
@@ -919,7 +920,8 @@ def parse_config_files():
                     args[token] = True
                 elif token in ('email', 'realname', 'replyto', 'http_proxy',
                                'smtphost', 'editor', 'mua', 'mta', 'smtpuser',
-                               'smtppasswd', 'justification', 'keyid'):
+                               'smtppasswd', 'justification', 'keyid',
+                               'mbox_reader_cmd'):
                     bit = lex.get_token()
                     args[token] = bit.decode('utf-8', 'replace')
                 elif token in ('no-smtptls', 'smtptls'):
@@ -1079,3 +1081,28 @@ def cleanup_msg(dmessage, headers, pseudos, type):
                 ph += ['%s: %s' % (header, ph2[header])]
 
     return message, newheaders, ph
+
+def launch_mbox_reader(cmd, url, http_proxy, timeout):
+    """Runs the command specified by cmd passing the mbox file
+    downloaded from url as a parameter. If cmd is None or fails, then
+    fallback to mail program."""
+    mbox = open_url(url, http_proxy, timeout)
+    if mbox is None:
+        return
+    (fd, fname) = TempFile()
+    try:
+        for line in mbox:
+            fd.write(line)
+        fd.close()
+        if cmd is not None:
+            try:
+                cmd = cmd % fname
+            except TypeError:
+                cmd = "%s %s" % (cmd, fname)
+            error = os.system(cmd)
+            if not error:
+                return
+        #fallback
+        os.system('mail -f ' + fname)
+    finally:
+        os.unlink(fname)
-- 
1.5.6.5


--DocE+STaALJfprDB
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="0002-Documentation-on-new-mbox-feature.patch"



More information about the Reportbug-maint mailing list