diff options
author | René 'Necoro' Neumann <necoro@necoro.net> | 2008-06-23 22:33:20 +0200 |
---|---|---|
committer | René 'Necoro' Neumann <necoro@necoro.net> | 2008-06-23 22:33:20 +0200 |
commit | 88d60d9f5082d6dd62778614681638415f25a8d6 (patch) | |
tree | 12c4863eed252b23d4ce4675b1a7c33abd2f158b /portato/gui | |
parent | 84ce6de169ab527d8393bfe9da63944c550ee16a (diff) | |
parent | 0392a7dcbaa08cbc73e091422bf6f68dbfa8d7f6 (diff) | |
download | portato-88d60d9f5082d6dd62778614681638415f25a8d6.tar.gz portato-88d60d9f5082d6dd62778614681638415f25a8d6.tar.bz2 portato-88d60d9f5082d6dd62778614681638415f25a8d6.zip |
Added the possibility to directly mail bugs
Diffstat (limited to 'portato/gui')
-rw-r--r-- | portato/gui/exception_handling.py | 30 | ||||
-rw-r--r-- | portato/gui/templates/MailInfoWindow.glade | 202 | ||||
-rw-r--r-- | portato/gui/utils.py | 23 | ||||
-rw-r--r-- | portato/gui/windows/mailinfo.py | 86 | ||||
-rw-r--r-- | portato/gui/windows/main.py | 3 |
5 files changed, 318 insertions, 26 deletions
diff --git a/portato/gui/exception_handling.py b/portato/gui/exception_handling.py index 29cd4e6..eadf124 100644 --- a/portato/gui/exception_handling.py +++ b/portato/gui/exception_handling.py @@ -16,32 +16,12 @@ from __future__ import absolute_import, with_statement import gtk, pango, gobject import sys, traceback -from threading import Thread from StringIO import StringIO from ..helper import debug, error from .dialogs import file_chooser_dialog, io_ex_dialog - -# for the i18n -from ..constants import LOCALE_DIR, APP -import gettext - -class GtkThread (Thread): - def run(self): - # for some reason, I have to install this for each thread ... - gettext.install(APP, LOCALE_DIR, unicode = True) - try: - Thread.run(self) - except SystemExit: - raise # let normal thread handle it - except: - type, val, tb = sys.exc_info() - try: - sys.excepthook(type, val, tb, thread = self.getName()) - except TypeError: - raise type, val, tb # let normal thread handle it - finally: - del type, val, tb +from .windows.mailinfo import MailInfoWindow +from .utils import GtkThread class UncaughtExceptionDialog(gtk.MessageDialog): """Original idea by Gustavo Carneiro - original code: http://www.daa.com.au/pipermail/pygtk/attachments/20030828/2d304204/gtkexcepthook.py.""" @@ -53,6 +33,7 @@ class UncaughtExceptionDialog(gtk.MessageDialog): self.format_secondary_text(_("It probably isn't fatal, but should be reported to the developers nonetheless.")) self.add_button(_("Show Details"), 1) + self.add_button(_("Send..."), 3) self.add_button(gtk.STOCK_SAVE_AS, 2) self.add_button(gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE) @@ -103,6 +84,11 @@ class UncaughtExceptionDialog(gtk.MessageDialog): else: debug("Nothing to save") + elif resp == 3: + debug("Send bug per mail") + self.destroy() + MailInfoWindow(None, self.text) + return else: break self.destroy() diff --git a/portato/gui/templates/MailInfoWindow.glade b/portato/gui/templates/MailInfoWindow.glade new file mode 100644 index 0000000..743c81c --- /dev/null +++ b/portato/gui/templates/MailInfoWindow.glade @@ -0,0 +1,202 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd"> +<!--Generated with glade3 3.4.4 on Mon Jun 23 22:23:44 2008 --> +<glade-interface> + <widget class="GtkWindow" id="MailInfoWindow"> + <property name="title" translatable="yes">Send Bug Mail ...</property> + <property name="window_position">GTK_WIN_POS_CENTER</property> + <property name="default_width">450</property> + <property name="default_height">230</property> + <property name="destroy_with_parent">True</property> + <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property> + <property name="skip_taskbar_hint">True</property> + <property name="skip_pager_hint">True</property> + <child> + <widget class="GtkVBox" id="vbox1"> + <property name="visible">True</property> + <child> + <widget class="GtkTable" id="table1"> + <property name="visible">True</property> + <property name="n_rows">4</property> + <property name="n_columns">2</property> + <property name="row_spacing">10</property> + <child> + <widget class="GtkScrolledWindow" id="scrolledwindow1"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hscrollbar_policy">GTK_POLICY_NEVER</property> + <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> + <property name="shadow_type">GTK_SHADOW_IN</property> + <child> + <widget class="GtkTextView" id="commentEntry"> + <property name="height_request">50</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + </widget> + </child> + </widget> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">3</property> + <property name="bottom_attach">4</property> + <property name="x_padding">5</property> + </packing> + </child> + <child> + <widget class="GtkLabel" id="label4"> + <property name="visible">True</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Comments / +what did you do to hit the bug?</property> + </widget> + <packing> + <property name="top_attach">3</property> + <property name="bottom_attach">4</property> + <property name="x_options">GTK_FILL</property> + <property name="x_padding">5</property> + </packing> + </child> + <child> + <widget class="GtkLabel" id="label1"> + <property name="visible">True</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Name:</property> + <property name="single_line_mode">True</property> + </widget> + <packing> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options">GTK_FILL</property> + <property name="x_padding">5</property> + </packing> + </child> + <child> + <widget class="GtkLabel" id="label2"> + <property name="visible">True</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Email address:</property> + <property name="single_line_mode">True</property> + </widget> + <packing> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options">GTK_FILL</property> + <property name="x_padding">5</property> + </packing> + </child> + <child> + <widget class="GtkEntry" id="mailEntry"> + <property name="visible">True</property> + <property name="can_focus">True</property> + </widget> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options">GTK_FILL</property> + <property name="x_padding">5</property> + </packing> + </child> + <child> + <widget class="GtkEntry" id="nameEntry"> + <property name="visible">True</property> + <property name="can_focus">True</property> + </widget> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="y_options">GTK_FILL</property> + <property name="x_padding">5</property> + </packing> + </child> + <child> + <widget class="GtkLabel" id="label3"> + <property name="visible">True</property> + <property name="label" translatable="yes"><b><u>Additional Information</u></b> + +(all optional)</property> + <property name="use_markup">True</property> + <property name="justify">GTK_JUSTIFY_CENTER</property> + </widget> + <packing> + <property name="right_attach">2</property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">5</property> + </packing> + </child> + <child> + <widget class="GtkHButtonBox" id="hbuttonbox1"> + <property name="visible">True</property> + <property name="homogeneous">True</property> + <property name="layout_style">GTK_BUTTONBOX_SPREAD</property> + <child> + <widget class="GtkButton" id="cancelBtn"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="label" translatable="yes">gtk-cancel</property> + <property name="use_stock">True</property> + <property name="response_id">0</property> + <signal name="clicked" handler="cb_cancel_clicked"/> + </widget> + </child> + <child> + <widget class="GtkButton" id="sendBtn"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="response_id">0</property> + <signal name="clicked" handler="cb_send_clicked"/> + <child> + <widget class="GtkHBox" id="hbox1"> + <property name="visible">True</property> + <property name="spacing">2</property> + <child> + <widget class="GtkImage" id="image1"> + <property name="visible">True</property> + <property name="xalign">1</property> + <property name="stock">gtk-ok</property> + </widget> + </child> + <child> + <widget class="GtkLabel" id="label5"> + <property name="visible">True</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">_Send</property> + <property name="use_underline">True</property> + <property name="single_line_mode">True</property> + </widget> + <packing> + <property name="position">1</property> + </packing> + </child> + </widget> + </child> + </widget> + <packing> + <property name="position">1</property> + </packing> + </child> + </widget> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="padding">5</property> + <property name="position">1</property> + </packing> + </child> + </widget> + </child> + </widget> +</glade-interface> diff --git a/portato/gui/utils.py b/portato/gui/utils.py index 0a2930b..6e04814 100644 --- a/portato/gui/utils.py +++ b/portato/gui/utils.py @@ -14,19 +14,38 @@ from __future__ import absolute_import, with_statement # some stuff needed import re +import sys import logging +import gettext from collections import defaultdict -from threading import RLock +from threading import Thread, RLock from functools import wraps # some backend things from ..backend import flags, system, set_system from ..helper import debug, info, set_log_level -from ..constants import USE_CATAPULT +from ..constants import USE_CATAPULT, APP, LOCALE_DIR # parser from ..config_parser import ConfigParser +class GtkThread (Thread): + def run(self): + # for some reason, I have to install this for each thread ... + gettext.install(APP, LOCALE_DIR, unicode = True) + try: + Thread.run(self) + except SystemExit: + raise # let normal thread handle it + except: + type, val, tb = sys.exc_info() + try: + sys.excepthook(type, val, tb, thread = self.getName()) + except TypeError: + raise type, val, tb # let normal thread handle it + finally: + del type, val, tb + class Config (ConfigParser): def __init__ (self, cfgFile): diff --git a/portato/gui/windows/mailinfo.py b/portato/gui/windows/mailinfo.py new file mode 100644 index 0000000..8e476c6 --- /dev/null +++ b/portato/gui/windows/mailinfo.py @@ -0,0 +1,86 @@ +# -*- coding: utf-8 -*- +# +# File: portato/gui/windows/mailinfo.py +# This file is part of the Portato-Project, a graphical portage-frontend. +# +# Copyright (C) 2008 René 'Necoro' Neumann +# This is free software. You may redistribute copies of it under the terms of +# the GNU General Public License version 2. +# There is NO WARRANTY, to the extent permitted by law. +# +# Written by René 'Necoro' Neumann <necoro@necoro.net> + +from __future__ import absolute_import + +import smtplib +import time + +from .basic import AbstractDialog +from ..utils import GtkThread +from ...helper import debug, info +from ...constants import VERSION + +class MailInfoWindow (AbstractDialog): + TO = "bugs@portato.necoro.net" + + def __init__ (self, parent, tb): + + AbstractDialog.__init__(self, parent) + + self.tb = tb + self.window.show_all() + + def set_data (self): + name = self.tree.get_widget("nameEntry").get_text() + addr = self.tree.get_widget("mailEntry").get_text() + + if not addr: + addr = self.TO + + if name: + fro = "%s <%s>" % (name, addr) + else: + fro = addr + + commentBuffer = self.tree.get_widget("commentEntry").get_buffer() + text = commentBuffer.get_text(*commentBuffer.get_bounds()) + + if text: + text += "\n\n===========\n" + + text += self.tb + + message = """From: %s +To: %s +Subject: %s +%s""" % ( fro, self.TO, ("[Bug Report] Bug in Portato %s" % VERSION), text) + + self.addr = addr + self.message = message + + def send (self): + debug("Connecting to server") + server = smtplib.SMTP("mail.necoro.eu") + debug("Sending mail") + try: + try: + server.sendmail(self.addr, self.TO, self.message) + except smtplib.SMTPRecipientsRefused, e: + info(_("An error occurred while sending. I think we where greylisted. The error: %s") % e) + info(_("Wait 60 seconds and try again.")) + time.sleep(60) + server.sendmail(self.addr, self.TO, self.message) + debug("Sent") + finally: + server.quit() + + def cb_cancel_clicked (self, *args): + + self.close() + return True + + def cb_send_clicked (self, *args): + self.set_data() + GtkThread(target = self.send, name = "Mail Send Thread").start() + self.close() + return True diff --git a/portato/gui/windows/main.py b/portato/gui/windows/main.py index b675d17..8e5eafb 100644 --- a/portato/gui/windows/main.py +++ b/portato/gui/windows/main.py @@ -30,11 +30,10 @@ from ...constants import CONFIG_LOCATION, VERSION, APP_ICON, ICON_DIR from ...backend.exceptions import PackageNotFoundException, BlockedException # more GUI stuff -from ..utils import Database, Config +from ..utils import Database, Config, GtkThread from ..queue import EmergeQueue from ..session import SESSION_VERSION, SessionException, OldSessionException, NewSessionException from ..wrapper import GtkTree, GtkConsole -from ..exception_handling import GtkThread from ..views import LogView, HighlightView, InstalledOnlyView from ..dialogs import (blocked_dialog, changed_flags_dialog, io_ex_dialog, nothing_found_dialog, queue_not_empty_dialog, remove_deps_dialog, |