On Wed, Jan 02, 2008 at 05:59:15AM -0800, Josh Triplett wrote:
> Package: reportbug
> Version: 3.39
> Severity: wishlist
>
> Using bts from devscripts, "bts show --mbox $BUGNUM" will download the
> mbox for $BUGNUM and show it in a mailer, defaulting to mutt ("mutt -f
> %s"). I'd love to have the same feature in querybts and reportbug, so
> that when viewing a bug, I could press a key (such as 'm', which looks
> available) to see the mbox.
I wrote a patch that implements that feature. I tried to follow the same
style of the rest of the code, but if anyone thinks the patch is not
good enough, just talk to me and I will change it as needed.
I didn't made any changes to the curses or gtk UI. Both because I don't
use it and I wanted to see if the developers think I have the right idea
first. I intend to patch them later on if this patch is considered
useful.
This module implements the function for launching the specified mbox reader
command. It doesn't attempt to know what MUA the user wants to use in order to
give him the flexibility of writing his own scripts for handling the job of
reading the mbox file.
diff --git a/reportbug/mboxutils.py b/reportbug/mboxutils.py
new file mode 100644
index 0000000..a654503
--- /dev/null
+++ b/reportbug/mboxutils.py
@@ -0,0 +1,52 @@
+#
+# mboxutils.py - Functions for mbox handling
+#
+# Copyright (C) 2010 Rafael Cunha de Almeida <[email protected]>
+#
+# This program is freely distributable per the following license:
+#
+## Permission to use, copy, modify, and distribute this software and its
+## documentation for any purpose and without fee is hereby granted,
+## provided that the above copyright notice appears in all copies and that
+## both that copyright notice and this permission notice appear in
+## supporting documentation.
+##
+## I DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL I
+## BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
+## DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+## WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+## ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+## SOFTWARE.
+#
+# Version ##VERSION##; see changelog for revision history
+
+import os
+
+from urlutils import open_url
+from tempfiles import TempFile
+
+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.7.2.3
This patch makes the necessary changes in the UI (CLI and text UI) in order to
allow the user to use the new mbox feature.
---
bin/querybts | 14 ++++++--
bin/reportbug | 11 +++++--
reportbug/ui/text_ui.py | 73 ++++++++++++++++++++++++++++++++++++++--------
reportbug/utils.py | 5 ++-
4 files changed, 81 insertions(+), 22 deletions(-)
diff --git a/bin/querybts b/bin/querybts
index c3744d5..0778982 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('-e', '--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/text_ui.py b/reportbug/ui/text_ui.py
index 4bfcda6..53cea67 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
+from reportbug.mboxutils import launch_mbox_reader
ISATTY = sys.stdin.isatty()
charset = 'us-ascii'
@@ -389,7 +390,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 +446,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 +460,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 +473,12 @@ def show_report(number, system, mirrors,
launch_browser(debianbts.get_report_url(
system, number, mirrors, archived))
skip_pager = True
+ elif x == 'e':
+ 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 +489,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 +583,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 +595,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 +640,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 +661,8 @@ 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 a specific report using the specified mbox '
+ 'reader.',
'f' : 'Filter bug list using a pattern.'}
if skipmsg:
helptext['n'] = helptext['n'][:-1]+' (skip to Next page).'
@@ -699,11 +711,27 @@ 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)
+ try:
+ number = int(number)
+ if number not in bugs and 1 <= number <= len(bugs):
+ number = bugs[number-1]
+ launch_mbox_reader(mbox_reader_cmd,
+ debianbts.get_report_url(
+ bts, number, mirrors, 'no', True), http_proxy,
+ timeout)
+ except ValueError:
+ ewrite('Invalid report number: %s\n',
+ number)
else:
if x == 'm' or x == 'i':
if len(bugs) == 1:
@@ -728,7 +756,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 +797,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 +867,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 +890,8 @@ 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 a specific report using the specified mbox '
+ 'reader.',
't' : 'Top of the bug list (remove all filters).'}
if skipmsg:
helptext['n'] = helptext['n'][:-1]+' (skip to Next page).'
@@ -905,7 +936,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 +948,21 @@ 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)
+ try:
+ number = int(number)
+ if number not in bugs and 1 <= number <= len(bugs):
+ number = bugs[number-1]
+ launch_mbox_reader(mbox_reader_cmd,
+ debianbts.get_report_url(
+ bts, number, mirrors, 'no', True), http_proxy,
+ timeout)
+ except ValueError:
+ ewrite('Invalid report number: %s\n',
+ number)
else:
if x == 'm' or x == 'i':
number = our_raw_input(
diff --git a/reportbug/utils.py b/reportbug/utils.py
index 9d241c6..d223b12 100644
--- a/reportbug/utils.py
+++ b/reportbug/utils.py
@@ -784,7 +784,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 +919,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'):
--
1.7.2.3
This patch makes the necessary documentation regarding the new mbox feature.
Including adding it to the template reportbug.conf.
---
conf/reportbug.conf | 3 +++
man/querybts.1 | 6 ++++++
man/reportbug.1 | 6 ++++++
man/reportbug.conf.5 | 9 +++++++++
4 files changed, 24 insertions(+), 0 deletions(-)
diff --git a/conf/reportbug.conf b/conf/reportbug.conf
index 8ed5932..905b1a7 100644
--- a/conf/reportbug.conf
+++ b/conf/reportbug.conf
@@ -106,3 +106,6 @@ verify
# Don't check whether user IDs are outside admin range - root is still checked
# no-check-uid
+
+# Use a command to open the mbox file of the reports
+# mbox_reader_cmd "mutt -f %s"
diff --git a/man/querybts.1 b/man/querybts.1
index 4b78558..c545749 100644
--- a/man/querybts.1
+++ b/man/querybts.1
@@ -35,6 +35,12 @@ check \fB\-\-help\fP for an updated list.
.B \-b, \-\-buglist
Display a bugs list for the given package.
.TP
+.B \-e MBOX_READER_CMD, \-\-mbox\-reader\-cmd=MBOX_READER_CMD
+Specify a command to open the bug reports' mbox file. You can use
+\fB%s\fP to substitute the mbox file to be used, and \fB%%\fP to insert
+a literal percent sign. If no \fB%s\fP is specified, the mbox file name
+is supplied at the end of the argument list.
+.TP
.B \-m, \-\-mbox
Retrieve the given bug number(s) or package name(s) as a mailbox file,
instead of viewing it. It will be dumped to standard output.
diff --git a/man/reportbug.1 b/man/reportbug.1
index 927f3bf..79469cb 100644
--- a/man/reportbug.1
+++ b/man/reportbug.1
@@ -131,6 +131,12 @@ name or comment part, like \[email protected]\fp). This setting will
override the \fBEMAIL\fP and \fBDEBEMAIL\fP environment variables, but
not \fBREPORTBUGEMAIL\fP.
.TP
+.B \-\-mbox\-reader\-cmd=MBOX_READER_CMD
+Specify a command to open the bug reports' mbox file. You can use
+\fB%s\fP to substitute the mbox file to be used, and \fB%%\fP to insert
+a literal percent sign. If no \fB%s\fP is specified, the mbox file name
+is supplied at the end of the argument list.
+.TP
.B \-\-exit\-prompt
Display a prompt before exiting; this is useful if \fBreportbug\fP is
run in a transient terminal (i.e. from its Debian menu entry).
diff --git a/man/reportbug.conf.5 b/man/reportbug.conf.5
index 0217f65..03ebddc 100644
--- a/man/reportbug.conf.5
+++ b/man/reportbug.conf.5
@@ -93,6 +93,15 @@ variables, see \fBreportbug(1)\fP). Example:
\fBemail\fP \fI"[email protected]"\fP
.TP
+.B mbox_reader_cmd
+Specify a command to open the bug reports' mbox file. You can use
+\fB%s\fP to substitute the mbox file to be used, and \fB%%\fP to insert
+a literal percent sign. If no \fB%s\fP is specified, the mbox file name
+is supplied at the end of the argument list. Example:
+
+\fBmbox_reader_cmd\fP \fI"mutt -f %s"\fP
+
+.TP
.B header
Additional headers to add to the bug email. Like:
--
1.7.2.3
_______________________________________________
Reportbug-maint mailing list
[email protected]
http://lists.alioth.debian.org/mailman/listinfo/reportbug-maint