[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

[PATCH/PROGRAM] Reportbug-Frontend in X-Dialog



Hi,

I read the discussion about "We need a web-based BTS" and today had some spare 
time and thought well I could look if reportbug could not be able to use 
another frontend - as both newt _and_ gnome do not work reliable anymore.

Well the result of some hours of work (well I did not program in python before 
much ...) can be seen attached.

Everything at least seems to work in Xdialog-mode, although a console is still 
needed.

The problem now is:

- How to design the "GUI" (well we just have some commands for (X)dialog) for 
the Choose of the BTS-Entries ?!

- Would users use such a frontend, which could also be available in a menu 
item then ...

Yes, and the last "Bug", which cannot so easily overcome: The console 
reportbug had some nice "autocomplete" features (I just noticed this, when 
developing) ...

Of course its _not_ so easily possible to just hack the dialog and have it 
also have custom readline-support with completion ...

But what would work, was to let the user specifiy the first x chars, then he 
clicks 'ok', and if its not to many items, can choose from a list including 
the original input ...

Well of course, what would be even nicer was if there were like with debconf 
KDE / GNOME2 / ...  and perhaps Web Wizards, that were really user friendly.

If its needed is another question ...

cu

Fabian
# Text user interface for reportbug
#   Written by Chris Lawrence <lawrencc@debian.org>
#   (C) 2001-02 Chris Lawrence
#
# 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.

import commands, sys, os, re, math, string, debianbts, errno
from reportbug_exceptions import *
from urlutils import launch_browser
from types import StringTypes
import dircache
import glob
import getpass

# Simple wrapper around (X)dialog.

# If the environment variable DISPLAY is set, then the X version is used, the
# text based otherwise.

# (C) 2003 Chris Liechti <cliechti@gmx.net>
#
# License: GPL

# To make it work with reportbug:

# Copyright (c) 2004 by Fabian Franz <debian@fabian-franz.de>

#find out which version to use
if os.getenv('DISPLAY')!="":
    DIALOG = 'Xdialog'
    GUI = 1
else:
    DIALOG = 'dialog'
    GUI = 0

title="reportbug gui"

def _checkresult(exitcode, result):
    """Check exit code of (X)dialog and raise an exeception if aborted."""
    if exitcode == 1 or exitcode >= 255:
        raise KeyboardInterrupt, "User aborted"
    return result

def start_dialog(exit, text,*args):
    """Wrap the starting"""
    start=(text%args).replace("`","'")
    #sys.stderr.write(start)
    fin = os.popen(start)
    result = fin.read()
    status = fin.close()
    if exit:
      return _checkresult(status, result.replace("\n",""))
    else:
      return result.replace("\n","")

def get_file(path=os.curdir+'/', title="Please choose a file"):
    """Open a file entry dialog."""
    #sizing is different...
    fin = os.popen('%s --stdout --title %r --fselect %s %s' % (DIALOG, title, path, GUI and '0 0' or '14 48'))
    result = fin.read()
    status = fin.close()
    return _checkresult(status, result)

try:
    import textwrap
except:
    from optik import textwrap

ISATTY = sys.stdin.isatty()

try:
    r, c = commands.getoutput('stty size').split()
    rows, columns = int(r) or 24, int(c) or 79
except:
    rows, columns = 24, 79

def ewrite(message, *args):
    if not ISATTY:
        return

    sys.stderr.write(message % args)

log_message = ewrite



def indent_wrap_text(text, starttext='', indent=0, linelen=None):
    """Wrapper for textwrap.fill to the existing API."""
    if not linelen:
        linelen = columns-1

    if indent:
        si = ' '*indent
    else:
        si = ''

    text = ' '.join(text.split())
    output = textwrap.fill(text, width=linelen, initial_indent=starttext,
                           subsequent_indent=si)
    if output[-1] == '\n':
        return output
    return output + '\n'

# Readline support, if available
try:
    import readline
    readline.parse_and_bind("tab: complete")

    try:
        # minimize the word delimeter list if possible
        readline.set_completer_delims(' ')
    except:
        pass
except:
    readline = None


class our_completer(object):
    def __init__(self, completions=None):
        self.completions = None
        if completions:
            self.completions = tuple(map(str, completions))

    def complete(self, text, i):
        if not self.completions: return None
        
        matching = [x for x in self.completions if x.startswith(text)]
        if i < len(matching):
            return matching[i]
        else:
            return None

def our_raw_input(prompt = None, completions=None, completer=None):
    istty = sys.stdout.isatty()
    if not istty:
        sys.stderr.write(prompt)
    sys.stderr.flush()
    if readline:
        if completions and not completer:
            completer = our_completer(completions).complete
        if completer:
            readline.set_completer(completer)

    try:
        if istty:
            ret = raw_input(prompt)
        else:
            ret = raw_input()
    except EOFError:
        ewrite('\nUser interrupt (^D).\n')
        raise SystemExit

    if readline:
        readline.set_completer(None)
    return ret.strip()

def select_options(msg, ok, help, allow_numbers=None, nowrap=False):
   
    return start_dialog(True,'%s --stdout --title %r --menu %r %s %s %s',DIALOG, title, msg, "0 0", 10, ' '.join(["%r %r" % (x,help[x]) for x in help.keys()]))
    
    err_message = ''
    for option in ok:
        if option in string.ascii_uppercase:
            default=option
            break
    
    if not help: help = {}

    if '?' not in ok: ok = ok+'?'

    if nowrap:
        longmsg = msg+' ['+'|'.join(ok)+']?'+' '
    else:
        longmsg = indent_wrap_text(msg+' ['+'|'.join(ok)+']?').strip()+' '
    ch = our_raw_input(longmsg, allow_numbers)
    # Allow entry of a bug number here
    if allow_numbers:
        while ch and ch[0] == '#': ch = ch[1:]
        if type(allow_numbers) == type(1):
            try:
                return str(int(ch))
            except ValueError:
                pass
        else:
            try:
                number = int(ch)
                if number in allow_numbers:
                    return str(number)
                else:
                    nums = list(allow_numbers)
                    nums.sort()
                    err_message = 'Only the following entries are allowed: '+\
                                  ', '.join(map(str, nums))
            except (ValueError, TypeError):
                pass
                
    if not ch: ch = default
    ch = ch[0]
    if ch=='?':
        help['?'] = 'Display this help.'
        for ch in ok:
            if ch in string.ascii_uppercase:
                desc = '(default) '
            else:
                desc = ''
            desc += help.get(ch, help.get(ch.lower(),
                                          'No help for this option.'))
            ewrite(indent_wrap_text(desc+'\n', '%s - '% ch, 4))
        return select_options(msg, ok, help, allow_numbers)
    elif (ch.lower() in ok) or (ch.upper() in ok):
        return ch.lower()
    elif err_message:
        ewrite(indent_wrap_text(err_message))
    else:
        ewrite('Invalid selection.\n')
        
    return select_options(msg, ok, help, allow_numbers, nowrap)

def yes_no(msg, yeshelp, nohelp, default=1, nowrap=False):
    """Ask a yes/no question, return 1 == yes, 0 == no."""
    fin = os.popen('%s --stdout %r --title %r --yesno %r %s' % (DIALOG, default and '' or (GUI and '--default-no' or '--defaultno'), title, indent_wrap_text(msg)+"\nYes: "+indent_wrap_text(yeshelp)+"\nNo: "+indent_wrap_text(nohelp), "0 0"))
    result = fin.read()
    status = fin.close()
    return not status

def long_message(text, *args):
    return start_dialog(True,'%s --stdout --title %r --msgbox %r %s', DIALOG, title,indent_wrap_text(text % args), '0 0')

def get_string(prompt, options=None, title="", force_prompt=False,
               default='', completer=None):
    """Open a input dialog."""

    if (options!=None and len(options)<=1):
      return start_dialog(True,'%s --stdout --title %r --inputbox %r %s %r', DIALOG, title, indent_wrap_text(prompt), '0 0', len(options)==1 and options[0])
    else:
      return start_dialog(True,'%s --stdout --title %r --inputbox %r %s %r', DIALOG, title, indent_wrap_text(prompt), '0 0', "")

def get_password(prompt=None):
    return start_dialog(True,'%s --stdout --insecure --title %r --passwordbox %r %s', DIALOG, title, indent_wrap_text(prompt), '0 0')

def get_filename(prompt, title=None, force_prompt=False, default=''):
    return start_dialog(False,'%s --stdout --title %r --fselect %r %s', DIALOG, prompt, default or '', '0 0')

def select_multiple(par, options, prompt, title=None, order=None, extras=None):
    return menu(par, options, prompt, title=title, order=order, extras=extras,
                multiple=True, empty_ok=False)

def menu(par, options, prompt, default=None, title=None, any_ok=False,
         order=None, extras=None, multiple=False, empty_ok=False):
    selected = {}

    if not extras:
        extras = []
    else:
        extras = list(extras)

    if title:
        ewrite(title+'\n\n')

    ewrite(indent_wrap_text(par, linelen=columns)+'\n')

    if type(options) == type({}):
        options = options.copy()
        # Convert to a list
        if order:
            olist = []
            for key in order:
                if options.has_key(key):
                    olist.append( (key, indent_wrap_text(options[key])) )
                    del options[key]

            # Append anything out of order
            options = options.items()
            options.sort()
            for option in options:
                olist.append( option )
            options = olist
        else:
            options = options.items()
            options.sort()
    
    if multiple:
    # fixme: parse checklist
      ret_text=start_dialog(True,'%s --stdout --title %r --checklist %r %s %s %s',DIALOG, title, prompt, "0 0", 10, ' '.join(["%r %r off" % x for x in options]))
      return ret_text.replace("/"," ").split(" ")
    else:
      return start_dialog(True,'%s --stdout --title %r %r %r --menu %r %s %s %s',DIALOG, title, default and "--default-item", default and default, prompt, "0 0", 10, ' '.join(["%r %r" % x for x in options]))

# Things that are very UI dependent go here
def show_report(number, system, mirrors,
                http_proxy, screen=None, queryonly=False, title='',
                archived='no'):
    import debianbts

    sysinfo = debianbts.SYSTEMS[system]
    ewrite('Retrieving report #%d from %s bug tracking system...\n',
           number, sysinfo['name'])

    try:
        info = debianbts.get_report(number, system, mirrors=mirrors,
                                    followups=1,
                                    http_proxy=http_proxy, archived=archived)
    except:
        info = None
        
    if not info:
        ewrite('No report available: #%s\n', number)
        return
               
    (title, messages) = info
    current_message = 0
    skip_pager = False

    while 1:
        if current_message:
            text = 'Followup %d - %s\n\n%s' % (current_message, title,
                                                 messages[current_message])
        else:
            text = 'Original report - %s\n\n%s' % (title, messages[0])
            
        if not skip_pager:
            fd = os.popen('sensible-pager', 'w')
            try:
                fd.write(text)
                fd.close()
            except IOError, x:
                if x.errno == errno.EPIPE:
                    pass
                else:
                    raise
        skip_pager = False

        if queryonly:
            options = 'Orbq'
        else:
            options = 'xOrbq'
            
        if (current_message+1) < len(messages):
            options = 'N'+options.lower()
        if (current_message):
            options = 'p'+options

        x = select_options("What do you want to do now?", options,
                           {'x' : 'Provide extra information.',
                            'o' : 'Show other bug reports (return to '
                            'bug listing).',
                            'n' : 'Show next message (followup).',
                            'p' : 'Show previous message (followup).',
                            'r' : 'Redisplay this message.',
                            'b' : 'Launch web browser to read '
                            'full log.',
                            'q' : "I'm bored; quit please."},
                           allow_numbers = range(1, len(messages)+1))
        if x == 'x':
            return number
        elif x == 'q':
            raise NoReport
        elif x == 'b':
            launch_browser(debianbts.get_report_url(
                system, number, mirrors, archived))
            skip_pager = True
        elif x == 'o':
            break
        elif x == 'n':
            current_message += 1
        elif x == 'p':
            current_message -= 1
    return

def handle_bts_query(package, bts, mirrors=None, http_proxy="",
                     queryonly=False, title="", screen=None, archived='no',
                     source=False):
    import debianbts
    
    root = debianbts.SYSTEMS[bts].get('btsroot')
    if not root:
        ewrite('%s bug tracking system has no web URL; bypassing query\n',
               debianbts.SYSTEMS[bts]['name'])
        return

    if isinstance(package, StringTypes):
        ewrite('Querying %s bug tracking system for reports on %s\n',
               debianbts.SYSTEMS[bts]['name'], package)
    else:
        ewrite('Querying %s bug tracking system for reports %s\n',
               debianbts.SYSTEMS[bts]['name'], ' '.join([str(x) for x in
                                                         package]))
               
    #ewrite('(Use ? for help at prompts.)\n')
    bugs = []

    try:
        (count, title, hierarchy)=debianbts.get_reports(
            package, bts, mirrors=mirrors,
            source=source, http_proxy=http_proxy, archived=archived)
        if debianbts.SYSTEMS[bts].has_key('namefmt'):
            package2 = debianbts.SYSTEMS[bts]['namefmt'] % package
            (count2, title2, hierarchy2) = \
                     debianbts.get_reports(package2, bts,
                                           mirrors=mirrors, source=source,
                                           http_proxy=http_proxy)
            count = count+count2
            for entry in hierarchy2:
                hierarchy.append( (package2+' '+entry[0], entry[1]) )

        exp = re.compile(r'\#(\d+):')
        for entry in hierarchy or []:
            for bug in entry[1]:
                match = exp.match(bug)
                if match:
                    bugs.append(int(match.group(1)))

        if not count:
            if hierarchy == None:
                raise NoPackage
            else:
                raise NoBugs
        elif count == 1:
            ewrite('%d bug report found:\n\n', count)
        else:
            ewrite('%d bug reports found:\n\n', count)

        return browse_bugs(hierarchy, count, bugs, bts, queryonly,
                           mirrors, http_proxy, screen, title)

    except IOError:
        res = select_options('Unable to connect to BTS; continue', 'yN',
                             {'y': 'Keep going.',
                              'n': 'Abort.'})
        if res == 'n':
            raise NoNetwork

def browse_bugs(hierarchy, count, bugs, bts, queryonly, mirrors,
                http_proxy, screen, title):
    endcount = catcount = 0
    scount = startcount = 1
    category = hierarchy[0]
    lastpage = []
    digits = len(str(len(bugs)))
    linefmt = '  %'+str(digits)+'d) %s\n'
    while category:
        scount = scount + 1
        catname, reports = category[0:2]
        while catname[-1] == ':': catname = catname[:-1]
        total = len(reports)

        while len(reports):
            these = reports[:rows-2]
            reports = reports[rows-2:]
            remain = len(reports)

            tplural = rplural = 's'
            if total == 1: tplural=''
            if remain != 1: rplural=''

            if remain:
                lastpage.append(' %s: %d remain%s\n' %
                                (catname, remain, rplural))
            else:
                lastpage.append(catname+'\n')

            oldscount, oldecount = scount, endcount
            for report in these:
                scount = scount + 1
                endcount = endcount + 1
                lastpage.append(linefmt % (endcount,report[:columns-digits-5]))

            if category == hierarchy[-1] or \
               (scount >= (rows - len(hierarchy[catcount+1][1]) - 1)):
                skipmsg = ' (s to skip rest)'
                if endcount == count:
                    skipmsg = ''

                options = 'yNmrqsf'
                if queryonly: options = 'Nmrqf'

                rstr = "(%d-%d/%d) " % (startcount, endcount, count)
                pstr = rstr + "Is the bug you found listed above"
                if queryonly:
                    pstr = rstr + "What would you like to do next"
                allowed = bugs+range(1, count+1)
                helptext = {
                    'y' : 'Problem already reported; optionally '
                    'add extra information.',
                    'n' : 'Problem not listed above; possibly '
                    'check more.',
                    'm' : 'Get more information about a bug (you '
                    'can also enter a number\n'
                    '     without selecting "m" first).',
                    'r' : 'Redisplay the last bugs shown.',
                    'q' : "I'm bored; quit please.",
                    's' : 'Skip remaining problems; file a new '
                    'report immediately.',
                    'f' : 'Filter bug list using a pattern.'}
                if skipmsg:
                    helptext['n'] = helptext['n'][:-1]+' (skip to Next page).'
                    
                while 1:
                    sys.stderr.writelines(lastpage)
                    x = select_options(pstr, options, helptext,
                                       allow_numbers=allowed)
                    if x == 'n':
                        lastpage = []
                        break
                    elif x == 'r':
                        continue
                    elif x == 'q':
                        raise NoReport
                    elif x == 's':
                        return
                    elif x == 'y':
                        if queryonly:
                            return

                        if len(bugs) == 1:
                            number = '1'
                        else:
                            number = our_raw_input(
                                'Enter the number of the bug report '
                                'you want to give more info on,\n'
                                'or press ENTER to exit: #', allowed)
                        while number and number[0] == '#':
                            number=number[1:]
                        if number:
                            try:
                                number = int(number)
                                if number not in bugs and 1 <= number <= len(bugs):
                                    number = bugs[number-1]
                                return number
                            except ValueError:
                                ewrite('Invalid report number: %s\n',
                                       number)
                        else:
                            raise NoReport
		    elif x == 'f':
			# Do filter. Recursive done.
			retval = search_bugs(hierarchy,bts, queryonly, mirrors,
                                             http_proxy, screen, title)
			if retval in ["FilterEnd", "Top"]:
			    continue
			else:
			    return retval
                    else:
                        if x == 'm' or x == 'i':
                            if len(bugs) == 1:
                                number = '1'
                            else:
                                number = our_raw_input(
                                    'Please enter the number of the bug '
                                    'you would like more info on: #',
                                    allowed)
                        else:
                            number = x

                        while number and number[0] == '#':
                            number=number[1:]

                        if number:
                            try:
                                number = int(number)
                                if number not in bugs and 1 <= number <= len(bugs):
                                    number = bugs[number-1]
                                res = show_report(number, bts, mirrors,
                                                  http_proxy,
                                                  queryonly=queryonly,
                                                  screen=screen,
                                                  title=title)
                                if res:
                                    return res
                            except ValueError:
                                ewrite('Invalid report number: %s\n',
                                       number)

                startcount = endcount+1
                scount = 0

            # these now empty

        if category == hierarchy[-1]: break

        catcount = catcount+1
        category = hierarchy[catcount]
        if scount:
            lastpage.append('\n')
            scount = scount + 1

def proc_hierarchy(hierarchy):
    """Find out bug count and bug # in the hierarchy."""

    lenlist = [len(i[1]) for i in hierarchy]
    if lenlist:
	count = reduce(lambda x, y: x+y, lenlist)
    else:
	return 0, 0

    # Copy & paste from handle_bts_query()
    bugs = []
    exp = re.compile(r'\#(\d+):')
    for entry in hierarchy or []:
	for bug in entry[1]:
	    match = exp.match(bug)
	    if match:
		bugs.append(int(match.group(1)))
    return count, bugs
    
def search_bugs(hierarchyfull, bts, queryonly, mirrors,
                http_proxy, screen, title):
    """Search for the bug list using a pattern."""
    """Return string "FilterEnd" when we are done with search."""

    pattern = our_raw_input(
	'Enter the search pattern (a Perl-compatible regular expression)\n'
	'or press ENTER to exit: ')
    if not pattern:
	return "FilterEnd"

    " Create new hierarchy match the pattern."
    import hiermatch
    try:
        hierarchy = hiermatch.matched_hierarchy(hierarchyfull, pattern)
    except InvalidRegex:
	our_raw_input('Invalid regular expression, press ENTER to continue.')
	return "FilterEnd"
        
    count, bugs = proc_hierarchy(hierarchy)
    
    if not count:
	our_raw_input('No match found, press ENTER to continue.')
	return "FilterEnd"

    endcount = catcount = 0
    scount = startcount = 1
    category = hierarchy[0]
    lastpage = []
    digits = len(str(len(bugs)))
    linefmt = '  %'+str(digits)+'d) %s\n'
    while category:
        scount = scount + 1
        catname, reports = category[0:2]
        while catname[-1] == ':': catname = catname[:-1]
        total = len(reports)

        while len(reports):
            these = reports[:rows-2]
            reports = reports[rows-2:]
            remain = len(reports)

            tplural = rplural = 's'
            if total == 1: tplural=''
            if remain != 1: rplural=''

            if remain:
                lastpage.append(' %s: %d report%s (%d remain%s)\n' %
                                (catname, total, tplural, remain, rplural))
            else:
                lastpage.append(' %s: %d report%s\n' %
                                (catname, total, tplural))

            oldscount, oldecount = scount, endcount
            for report in these:
                scount = scount + 1
                endcount = endcount + 1
                lastpage.append(linefmt % (endcount,report[:columns-digits-5]))

            if category == hierarchy[-1] or \
               (scount >= (rows - len(hierarchy[catcount+1][1]) - 1)):
                skipmsg = ' (s to skip rest)'
                if endcount == count:
                    skipmsg = ''

                options = 'yNmrqsfut'
                if queryonly: options = 'Nmrqfut'

                rstr = "(%d-%d/%d) " % (startcount, endcount, count)
                pstr = rstr + "Is the bug you found listed above"
                if queryonly:
                    pstr = rstr + "What would you like to do next"
                allowed = bugs+range(1, count+1)
                helptext = {
                    'y' : 'Problem already reported; optionally '
                    'add extra information.',
                    'n' : 'Problem not listed above; possibly '
                    'check more.',
                    'm' : 'Get more information about a bug (you '
                    'can also enter a number\n'
                    '     without selecting "m" first).',
                    'r' : 'Redisplay the last bugs shown.',
                    'q' : "I'm bored; quit please.",
                    's' : 'Skip remaining problems; file a new '
                    'report immediately.',
		    'f' : 'Filter bug list using a pattern.',
		    'u' : 'Up one level of filter.',
		    't' : 'Top of the bug list (remove all filters).'}
                if skipmsg:
                    helptext['n'] = helptext['n'][:-1]+' (skip to Next page).'
                    
                while 1:
                    sys.stderr.writelines(lastpage)
                    x = select_options(pstr, options, helptext,
                                       allow_numbers=allowed)
                    if x == 'n':
                        lastpage = []
                        break
                    elif x == 'r':
                        continue
                    elif x == 'q':
                        raise NoReport
                    elif x == 's':
                        return 
                    elif x == 'y':
                        if queryonly:
                            return

                        number = our_raw_input(
                            'Enter the number of the bug report '
                            'you want to give more info on,\n'
                            'or press ENTER to exit: #', allowed)
                        while number and number[0] == '#':
                            number=number[1:]
                        if number:
                            try:
                                number = int(number)
                                if number not in bugs and 1 <= number <= len(bugs):
                                    number = bugs[number-1]
                                return number
                            except ValueError:
                                ewrite('Invalid report number: %s\n',
                                       number)
                        else:
                            raise NoReport
		    elif x == 'f':
			# Do filter. Recursive done.
			retval = search_bugs(hierarchy, bts, queryonly, mirrors,
			    http_proxy, screen, title)
			if retval == "FilterEnd":
			    continue
			else:
			    return retval
		    elif x == 'u':
			# Up a level
			return "FilterEnd"
		    elif x == 't':
			# go back to the Top level.
			return "Top"
                    else:
                        if x == 'm' or x == 'i':
                            number = our_raw_input(
                                'Please enter the number of the bug '
                                'you would like more info on: #',
                                allowed)
                        else:
                            number = x

                        while number and number[0] == '#':
                            number=number[1:]

                        if number:
                            try:
                                number = int(number)
                                if number not in bugs and 1 <= number <= len(bugs):
                                    number = bugs[number-1]
                                res = show_report(number, bts, mirrors,
                                                  http_proxy,
                                                  queryonly=queryonly,
                                                  screen=screen,
                                                  title=title)
                                if res:
                                    return res
                            except ValueError:
                                ewrite('Invalid report number: %s\n',
                                       number)

                startcount = endcount+1
                scount = 0

            # these now empty

        if category == hierarchy[-1]: break

        catcount = catcount+1
        category = hierarchy[catcount]
        if scount:
            lastpage.append('\n')
            scount = scount + 1
    return "FilterEnd"
--- /usr/bin/reportbug	2004-03-30 01:00:22.000000000 +0200
+++ reportbug	2004-04-13 02:01:28.000000000 +0200
@@ -393,7 +393,7 @@
                             'interface for reportbug.', reportbug.UIS,
                             'Select interface: ', options.interface)
     else:
-        interface = 'text'
+        interface = 'dialog'
 
     online = ui.yes_no('Will reportbug often have direct '
                        'Internet access?  (You should answer yes to this '
@@ -568,6 +568,10 @@
     if charset.lower() == 'ansi_x3.4-1968':
         charset = 'us-ascii'
 
+    iface = 'reportbug_ui_dialog'
+    exec 'import '+iface
+    ui = eval(iface)
+
     notatty = not ui.ISATTY
     body = ''
     filename = None
@@ -869,7 +873,7 @@
     # Fix up command line options for GNOME interface
     sys.argv = sys.argv[:1] + list(args)
     if options.interface:
-        if options.interface in ('gnome', 'newt'):
+        if options.interface in ('gnome', 'newt','dialog'):
             ui.long_message("The %s interface is not supported.  Unless you "
                             "are debugging reportbug, please do not use it.  "
                             "If you are debugging reportbug, please DO NOT "
@@ -880,6 +884,10 @@
         iface = 'reportbug_ui_'+options.interface
         exec 'import '+iface
         ui = eval(iface)
+        
+    iface = 'reportbug_ui_dialog'
+    exec 'import '+iface
+    ui = eval(iface)
 
     if (reportbug.first_run() and not args):
         offer_configuration(options)

Reply to: