[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