def __init__(self, mainloop=None): super(DBusProblemSource, self).__init__() self._mainloop = mainloop if not self._mainloop: self._mainloop = DBusGMainLoop() self._bus = None self._proxy = None self._interface = None self._connect_to_problems_bus() try: self._bus.add_signal_receiver(self._on_new_problem, signal_name=ABRTD_DBUS_SIGNAL, path=ABRTD_DBUS_PATH) except dbus.exceptions.DBusException as ex: logging.warning( _("Can't add receiver of signal '{0}'on DBus system path '{1}': {2}") .format(ABRTD_DBUS_SIGNAL, ABRTD_DBUS_PATH, ex.message)) class ConfigObserver(): def __init__(self, source): self.source = source #pylint: disable=W0613 def option_updated(self, conf, option): if option == "all_problems": self.source.refresh() conf = config.get_configuration() conf.set_watch("all_problems", ConfigObserver(self))
def on_new_problem(self, *args): """Accepts foreign problems only if the all_problems option is enabled """ conf = config.get_configuration() try: if len(args) > 2 and int(args[2]) != os.getuid() and not conf["all_problems"]: logging.debug( "Received the new problem signal with different " "uid '{0}' ('{1}') and the all problems option " "is not configured".format(args[2], os.getuid()) ) return None except ValueError: logging.debug(traceback.format_exc()) return None if len(args) == 2 and not conf["all_problems"]: logging.debug( "Received the new problem signal without the uid " "argument and the all problems option is not configured" ) return None return str(args[1])
def get_problems_method(self): conf = config.get_configuration() if conf['all_problems']: #pylint: disable=W0142 return lambda iface, *args: iface.GetAllProblems(*args) else: #pylint: disable=W0142 return lambda iface, *args: iface.GetProblems(*args)
def fancydate(value, base_date=None): """ Converts a date to a fancy string """ if not base_date: base_date = datetime.datetime.now() old_date = value if base_date < old_date: return _('Future') tmdt = base_date.date() - old_date.date() if tmdt.days == 0: return old_date.time().strftime(get_configuration()['T_FMT']) elif tmdt.days == 1: return _('Yesterday') # this week - return a name of a day if tmdt.days < base_date.isoweekday(): return calendar.day_name[base_date.weekday() - tmdt.days] if old_date.month == base_date.month and old_date.year == base_date.year: # computes a number of calendar weeks (not only 7 days) # Note: the offset will never be negative nor zero because # negative means the future and 0 means today, these cases # have been handled few lines above. The same rule is true # for the code below. offset = int(round((tmdt.days - base_date.isoweekday())/7, 0)) + 1 if offset == 1: return _('Last week') # Translators: This message will never be used for less than # 2 weeks ago nor for more than one month ago. However, the singular # form is necessary for some languages which do not have plural. msg = ngettext('{0:d} week ago', '{0:d} weeks ago', offset) return msg.format(offset) elif old_date.year == base_date.year: offset = base_date.month - old_date.month if offset == 1: return _('Last month') # Translators: This message will never be used for less than # 2 months ago nor for more than one year ago. See the comment above. msg = ngettext('{0:d} month ago', '{0:d} months ago', offset) return msg.format(offset) else: offset = base_date.year - old_date.year if offset == 1: return _('Last year') # Translators: This message will never be used for less than # 2 years ago. However, the singular form is necessary for some # languages which do not have plural (Chinese, Japanese, Korean) # or reuse the singular form for some plural cases (21 in Russian). msg = ngettext('{0:d} year ago', '{0:d} years ago', offset) return msg.format(offset)
def fancydate(value, base_date=None): """ Converts a date to a fancy string """ if not base_date: base_date = datetime.datetime.now() old_date = value if base_date < old_date: return _('Future') tmdt = base_date.date() - old_date.date() if tmdt.days == 0: return old_date.time().strftime(get_configuration()['T_FMT']) elif tmdt.days == 1: return _('Yesterday') # this week - return a name of a day if tmdt.days < base_date.isoweekday(): return calendar.day_name[base_date.weekday() - tmdt.days] if old_date.month == base_date.month and old_date.year == base_date.year: # computes a number of calendar weeks (not only 7 days) # Note: the offset will never be negative nor zero because # negative means the future and 0 means today, these cases # have been handled few lines above. The same rule is true # for the code below. offset = int(round((tmdt.days - base_date.isoweekday()) / 7, 0)) + 1 if offset == 1: return _('Last week') # Translators: This message will never be used for less than # 2 weeks ago nor for more than one month ago. However, the singular # form is necessary for some languages which do not have plural. msg = ngettext('{0:d} week ago', '{0:d} weeks ago', offset) return msg.format(offset) elif old_date.year == base_date.year: offset = base_date.month - old_date.month if offset == 1: return _('Last month') # Translators: This message will never be used for less than # 2 months ago nor for more than one year ago. See the comment above. msg = ngettext('{0:d} month ago', '{0:d} months ago', offset) return msg.format(offset) else: offset = base_date.year - old_date.year if offset == 1: return _('Last year') # Translators: This message will never be used for less than # 2 years ago. However, the singular form is necessary for some # languages which do not have plural (Chinese, Japanese, Korean) # or reuse the singular form for some plural cases (21 in Russian). msg = ngettext('{0:d} year ago', '{0:d} years ago', offset) return msg.format(offset)
def on_new_problem(self, object_path, uid): """Accepts foreign problems only if the all_problems option is enabled """ conf = config.get_configuration() if uid != os.getuid() and not conf['all_problems']: logging.debug("Received the new problem signal with different " "uid '{0}' ('{1}') and the all problems option " "is not configured".format(uid, os.getuid())) return None return object_path
def __init__(self, source): super(StandardProblems, self).__init__(source) class ConfigObserver(object): def __init__(self, source): self._source = source #pylint: disable=W0613 def option_updated(self, conf, option): if option == "all_problems": self._source.refresh() conf = config.get_configuration() conf.set_watch("all_problems", ConfigObserver(self._source))
def _get_problems(self): conf = config.get_configuration() prblms = [] try: if conf['all_problems']: prblms = self._send_dbus_message( #pylint: disable=W0142 lambda iface, *args: iface.GetAllProblems(*args)) else: prblms = self._send_dbus_message( #pylint: disable=W0142 lambda iface, *args: self._interface.GetProblems(*args)) except dbus.exceptions.DBusException as ex: logging.warning( _("Can't get list of problems from DBus service: {0!s}") .format(ex.message)) return (str(pid) for pid in prblms)
def _on_new_problem(self, *args): if len(args) < 2: logging.debug( "Received the new problem signal with invalid number of arguments {0}" .format(args)) return conf = config.get_configuration() if (len(args) > 2 and int(args[2]) != os.getuid() and not conf['all_problems']): logging.debug("Received the new problem signal with different uid " "'{0}' ('{1}') and the all problems option is not configured" .format(args[2], os.getuid())) return if len(args) == 2 and not conf['all_problems']: logging.debug("Received the new problem signal without the uid " "argument and the all problems option is not configured") return self.process_new_problem_id(str(args[1]))
def on_new_problem(self, *args): """Accepts foreign problems only if the all_problems option is enabled """ conf = config.get_configuration() try: if (len(args) > 2 and int(args[2]) != os.getuid() and not conf['all_problems']): logging.debug("Received the new problem signal with different " "uid '{0}' ('{1}') and the all problems option " "is not configured".format(args[2], os.getuid())) return None except ValueError: logging.debug(traceback.format_exc()) return None if len(args) == 2 and not conf['all_problems']: logging.debug( "Received the new problem signal without the uid " "argument and the all problems option is not configured") return None return str(args[1])
def fancydate(value, base_date=None): """ Converts a date to a fancy string """ if not base_date: base_date = datetime.datetime.now() old_date = value if base_date < old_date: return _('Future') tmdt = base_date.date() - old_date.date() if tmdt.days == 0: return old_date.time().strftime(get_configuration()['T_FMT']) elif tmdt.days == 1: return _('Yesterday') # this week - return a name of a day if tmdt.days < base_date.isoweekday(): return calendar.day_name[base_date.weekday() - tmdt.days] if old_date.month == base_date.month and old_date.year == base_date.year: # computes a number of calendar weeks (not only 7 days) offset = int(round((tmdt.days - base_date.isoweekday()) / 7, 0)) + 1 name = _('week') elif old_date.year == base_date.year: offset = base_date.month - old_date.month name = _('month') else: offset = base_date.year - old_date.year name = _('year') if offset == 1: return _("Last {0!s}").format(name) return _("{0:d} {1!s}s ago").format(offset, name)
def fancydate(value, base_date=None): """ Converts a date to a fancy string """ if not base_date: base_date = datetime.datetime.now() old_date = value if base_date < old_date: return _('Future') tmdt = base_date.date() - old_date.date() if tmdt.days == 0: return old_date.time().strftime(get_configuration()['T_FMT']) elif tmdt.days == 1: return _('Yesterday') # this week - return a name of a day if tmdt.days < base_date.isoweekday(): return calendar.day_name[base_date.weekday() - tmdt.days] if old_date.month == base_date.month and old_date.year == base_date.year: # computes a number of calendar weeks (not only 7 days) offset = int(round((tmdt.days - base_date.isoweekday())/7, 0)) + 1 name = _('week') elif old_date.year == base_date.year: offset = base_date.month - old_date.month name = _('month') else: offset = base_date.year - old_date.year name = _('year') if offset == 1: return _("Last {0!s}").format(name) return _("{0:d} {1!s}s ago").format(offset, name)
def _set_problem(self, problem): def destroy_links(widget, _): if widget != self.lbl_reported_value: widget.destroy() self.selected_problem = problem sensitive_btn = problem is not None self.btn_delete.set_sensitive(sensitive_btn) self.btn_report.set_sensitive(sensitive_btn and not problem['not-reportable']) self.vbx_links.foreach(destroy_links, None) self.vbx_problem_messages.foreach(lambda w, u: w.destroy(), None) if problem: self.nb_problem_layout.set_current_page(0) app = problem['application'] if problem['type'] == 'Kerneloops': self.lbl_reason.set_text(_("Unexpected system error")) self.lbl_summary.set_text( _("The system has encountered a problem and recovered.")) elif problem['type'] == 'vmcore': self.lbl_reason.set_text(_("Fatal system failure")) self.lbl_summary.set_text( _("The system has encountered a problem and could not continue." )) else: if not app.name: self.lbl_reason.set_text( # Translators: If Application's name is unknown, # display neutral header # "'Type' problem has been detected". Examples: # Kerneloops problem has been detected # C/C++ problem has been detected # Python problem has been detected # Ruby problem has been detected # VMCore problem has been detected # AVC problem has been detected # Java problem has been detected _("{0} problem has been detected").format( problem['human_type'])) else: self.lbl_reason.set_text( _("{0} quit unexpectedly").format(app.name)) self.lbl_summary.set_text( _("The application encountered a problem and could not continue." )) self.lbl_app_name_value.set_text( # Translators: package name not available problem['package_name'] or _("N/A")) self.lbl_app_version_value.set_text( # Translators: package version not available problem['package_version'] or _("N/A")) self.lbl_detected_value.set_text( humanize.naturaltime(datetime.datetime.now() - problem['date'])) self.lbl_detected_value.set_tooltip_text(problem['date'].strftime( config.get_configuration()['D_T_FMT'])) icon_buf = None scale = self.img_app_icon.get_scale_factor() if app.icon: icon_buf = load_icon(gicon=app.icon, scale=scale) if icon_buf is None: icon_buf = load_icon(name="system-run-symbolic", scale=scale) self.img_app_icon.get_style_context().add_class('dim-label') else: self.img_app_icon.get_style_context().remove_class('dim-label') # icon_buf can be None and if it is None, no icon will be displayed set_icon_from_pixbuf_with_scale(self.img_app_icon, icon_buf, scale) self.lbl_reported_value.show() self.lbl_reported.set_text(_("Reported")) if problem['not-reportable']: self.lbl_reported_value.set_text(_('cannot be reported')) self._show_problem_links(problem['submission']) self._show_problem_message(problem['not-reportable']) elif problem['is_reported']: if self._show_problem_links(problem['submission']): self.lbl_reported.set_text(_("Reports")) self.lbl_reported_value.hide() if (not any((s.name == "Bugzilla" for s in problem['submission']))): self._show_problem_message( _("This problem has been reported, but a <i>Bugzilla</i> ticket has not" " been opened. Our developers may need more information to fix the problem.\n" "Please consider also <b>reporting it</b> to Bugzilla in" " order to provide that. Thank you.")) else: # Translators: Displayed after 'Reported' if a problem # has been reported but we don't know where and when. # Probably a rare situation, usually if a problem is # reported we display a list of reports here. self.lbl_reported_value.set_text(_('yes')) else: # Translators: Displayed after 'Reported' if a problem # has not been reported. self.lbl_reported_value.set_text(_('no')) else: if self._source is not None: self.nb_problem_layout.set_current_page(1) else: self.nb_problem_layout.set_current_page(2)
def __init__(self, application, source, controller): Gtk.ApplicationWindow.__init__(self, title=_('Automatic Bug Reporting Tool'), application=application) self._builder = OopsWindow.OopsGtkBuilder() self.set_default_size(*self._builder.wnd_main.get_size()) self._builder.wnd_main.remove(self._builder.gr_main_layout) #pylint: disable=E1101 self.add(self._builder.gr_main_layout) # move accelators group from the design window to this window self.add_accel_group(self._builder.ag_accelerators) css_prv = Gtk.CssProvider() css_prv.load_from_data("GtkViewport {\n" " background-color : @theme_bg_color;\n" "}\n") stl_ctx = self.get_style_context() stl_ctx.add_provider_for_screen(stl_ctx.get_screen(), css_prv, 6000) self._builder.connect_signals(self) self.selected_problem = None self._source = source self._reloading = False self._controller = controller self._builder.ls_problems.set_sort_column_id(0, Gtk.SortType.DESCENDING) self._builder.ls_problems.set_sort_func(0, time_sort_func, None) self._filter = ProblemsFilter(self, self._builder.tv_problems) class SourceObserver: def __init__(self, wnd): self.wnd = wnd def changed(self, source, change_type=None, problem=None): if not change_type: self.wnd._reload_problems(source) elif change_type == problems.ProblemSource.NEW_PROBLEM: self.wnd._add_problem_to_storage(problem) elif change_type == problems.ProblemSource.DELETED_PROBLEM: self.wnd._remove_problem_from_storage(problem) elif change_type == problems.ProblemSource.CHANGED_PROBLEM: self.wnd._update_problem_in_storage(problem) self._source_observer = SourceObserver(self) self._source.attach(self._source_observer) self._builder.tv_problems.grab_focus() self._reload_problems(self._source) class OptionsObserver: def __init__(self, wnd): self.wnd = wnd def option_updated(self, conf, option): if option == 'problemid' and conf[option]: self.wnd._select_problem_by_id(conf[option]) self._options_observer = OptionsObserver(self) conf = config.get_configuration() conf.set_watch('problemid', self._options_observer) self._options_observer.option_updated(conf, 'problemid')
def _set_problem(self, problem): def destroy_links(widget, _): if widget != self._builder.lbl_reported_value: widget.destroy() self.selected_problem = problem sensitive_btn = problem is not None self._builder.btn_delete.set_sensitive(sensitive_btn) self._builder.btn_report.set_sensitive( sensitive_btn and not problem['not-reportable']) self._builder.btn_detail.set_sensitive(sensitive_btn) self._builder.vbx_links.foreach( destroy_links, None) self._builder.vbx_problem_messages.foreach( lambda w, u: w.destroy(), None) if problem: self._builder.nb_problem_layout.set_current_page(0) app = problem['application'] if problem['type'] == 'Kerneloops': self._builder.lbl_reason.set_text( _("Unexpected system error")) self._builder.lbl_summary.set_text( _("The system has encountered a problem and recovered.")) elif problem['type'] == 'vmcore': self._builder.lbl_reason.set_text( _("Fatal system failure")) self._builder.lbl_summary.set_text( _("The system has encountered a problem and could not continue.")) else: if not app.name: # If Application's name is unknown, display neutral # header "'Type' problem has been detected": # Kerneloops problem has been detected # C/C++ problem has been detected # Python problem has been detected # Ruby problem has been detected # VMCore problem has been detected # AVC problem has been detected # Java problem has been detected self._builder.lbl_reason.set_text( _("{0} problem has been detected").format( problem['human_type'])) else: self._builder.lbl_reason.set_text( _("{0} quit unexpectedly".format(app.name))) self._builder.lbl_summary.set_text( _("The application encountered a problem and could not continue.")) self._builder.lbl_app_name_value.set_text( problem['package_name'] or _("N/A")) self._builder.lbl_app_version_value.set_text( problem['package_version'] or _("N/A")) self._builder.lbl_detected_value.set_text( humanize.naturaltime(datetime.datetime.now()-problem['date'])) self._builder.lbl_detected_value.set_tooltip_text( problem['date'].strftime(config.get_configuration()['D_T_FMT'])) if app.icon: self._builder.img_app_icon.set_from_pixbuf(app.icon) else: self._builder.img_app_icon.clear() self._builder.lbl_reported_value.show() self._builder.lbl_reported.set_text(_("Reported")) if problem['not-reportable']: self._builder.lbl_reported_value.set_text( _('cannot be reported')) self._show_problem_links(problem['submission']) self._show_problem_message(problem['not-reportable']) elif problem['is_reported']: if self._show_problem_links(problem['submission']): self._builder.lbl_reported.set_text(_("Reports")) self._builder.lbl_reported_value.hide() if (not any((s.name == "Bugzilla" for s in problem['submission']))): self._show_problem_message( _("This problem has been reported, but a <i>Bugzilla</i> ticket has not" " been opened. Our developers may need more information to fix the problem.\n" "Please consider also <b>reporting it</b> to Bugzilla in" " order to provide that. Thank you.")) else: self._builder.lbl_reported_value.set_text(_('yes')) else: self._builder.lbl_reported_value.set_text(_('no')) else: if self._source is not None: self._builder.nb_problem_layout.set_current_page(1) else: self._builder.nb_problem_layout.set_current_page(2)
def __init__(self, application, sources, controller): super().__init__(application=application) if not sources: raise ValueError("The source list cannot be empty!") GObject.Binding.bind_property(self.tbtn_search, "active", self.search_bar, "search-mode-enabled", GObject.BindingFlags.BIDIRECTIONAL) label = Gtk.Label.new('') label.show() self.lb_problems.set_placeholder(label) label.connect('map', self.placeholder_mapped, self) label.connect('unmap', self.placeholder_unmapped, self) builder = Gtk.Builder() builder.set_translation_domain(GETTEXT_PROGNAME) builder.add_from_resource( '/org/freedesktop/GnomeAbrt/ui/oops-menus.ui') self.menu_problem_item = builder.get_object('menu_problem_item') self.menu_problem_item = Gtk.Menu.new_from_model( self.menu_problem_item) self.menu_problem_item.attach_to_widget(self) self.menu_multiple_problems = builder.get_object( 'menu_multiple_problems') self.menu_multiple_problems = Gtk.Menu.new_from_model( self.menu_multiple_problems) self.menu_multiple_problems.attach_to_widget(self) #pylint: disable=E1120 css_prv = Gtk.CssProvider.new() css_prv.load_from_resource('/org/freedesktop/GnomeAbrt/css/oops.css') stl_ctx = self.get_style_context() stl_ctx.add_provider_for_screen(stl_ctx.get_screen(), css_prv, 6000) self.search_bar.connect_entry(self.se_problems) self._source_observer = OopsWindow.SourceObserver(self) self._source_observer.disable() self._reloading = False self._controller = controller self.selected_problem = None self._all_sources = [] self._source = None self._handling_source_click = False self._configure_sources(sources) self._set_button_toggled(self._source.button, True) # a set where invalid problems found while sorting of the problem list # are stored self._trash = set() self.lb_problems.set_sort_func(time_sort_func, self._trash) self.lss_problems = ListBoxSelection(self.lb_problems, self.on_tvs_problems_changed) self._filter = ProblemsFilter(self.lb_problems, self.lss_problems) self.lb_problems.grab_focus() try: self._reload_problems(self._source) except errors.UnavailableSource as ex: self._disable_source(ex.source, ex.temporary) self._options_observer = OopsWindow.OptionsObserver(self) conf = config.get_configuration() conf.set_watch('problemid', self._options_observer) conf.set_watch('T_FMT', self._options_observer) conf.set_watch('D_T_FMT', self._options_observer) self._options_observer.option_updated(conf, 'problemid') # enable observer self._source_observer.enable() self.connect("key-press-event", self._on_key_press_event) self._add_actions(application)
def on_gac_opt_all_problems_activate(self, action): conf = config.get_configuration() conf['all_problems'] = self._builder.chb_all_problems.get_active()
def _set_problem(self, problem): def destroy_links(widget, _): if widget != self._builder.lbl_reported_value: widget.destroy() self.selected_problem = problem sensitive_btn = problem is not None self._builder.btn_delete.set_sensitive(sensitive_btn) self._builder.btn_report.set_sensitive( sensitive_btn and not problem['not-reportable']) self._builder.btn_detail.set_sensitive(sensitive_btn) self._builder.vbx_links.foreach(destroy_links, None) self._builder.vbx_problem_messages.foreach(lambda w, u: w.destroy(), None) if problem: self._builder.nb_problem_layout.set_current_page(0) app = problem['application'] if problem['type'] == 'Kerneloops': self._builder.lbl_reason.set_text(_("Unexpected system error")) self._builder.lbl_summary.set_text( _("The system has encountered a problem and recovered.")) elif problem['type'] == 'vmcore': self._builder.lbl_reason.set_text(_("Fatal system failure")) self._builder.lbl_summary.set_text( _("The system has encountered a problem and could not continue." )) else: if not app.name: # If Application's name is unknown, display neutral # header "'Type' problem has been detected": # Kerneloops problem has been detected # C/C++ problem has been detected # Python problem has been detected # Ruby problem has been detected # VMCore problem has been detected # AVC problem has been detected # Java problem has been detected self._builder.lbl_reason.set_text( _("{0} problem has been detected").format( problem['human_type'])) else: self._builder.lbl_reason.set_text( _("{0} quit unexpectedly".format(app.name))) self._builder.lbl_summary.set_text( _("The application encountered a problem and could not continue." )) self._builder.lbl_app_name_value.set_text(problem['package_name'] or _("N/A")) self._builder.lbl_app_version_value.set_text( problem['package_version'] or _("N/A")) self._builder.lbl_detected_value.set_text( humanize.naturaltime(datetime.datetime.now() - problem['date'])) self._builder.lbl_detected_value.set_tooltip_text( problem['date'].strftime( config.get_configuration()['D_T_FMT'])) if app.icon: self._builder.img_app_icon.set_from_pixbuf( Gtk.IconTheme.get_default().lookup_by_gicon( app.icon, 128, Gtk.IconLookupFlags.FORCE_SIZE).load_icon()) else: self._builder.img_app_icon.set_from_pixbuf( Gtk.IconTheme.get_default().lookup_icon( "system-run-symbolic", 128, Gtk.IconLookupFlags.FORCE_SIZE | Gtk.IconLookupFlags.FORCE_SYMBOLIC).load_icon()) self._builder.lbl_reported_value.show() self._builder.lbl_reported.set_text(_("Reported")) if problem['not-reportable']: self._builder.lbl_reported_value.set_text( _('cannot be reported')) self._show_problem_links(problem['submission']) self._show_problem_message(problem['not-reportable']) elif problem['is_reported']: if self._show_problem_links(problem['submission']): self._builder.lbl_reported.set_text(_("Reports")) self._builder.lbl_reported_value.hide() if (not any((s.name == "Bugzilla" for s in problem['submission']))): self._show_problem_message( _("This problem has been reported, but a <i>Bugzilla</i> ticket has not" " been opened. Our developers may need more information to fix the problem.\n" "Please consider also <b>reporting it</b> to Bugzilla in" " order to provide that. Thank you.")) else: self._builder.lbl_reported_value.set_text(_('yes')) else: self._builder.lbl_reported_value.set_text(_('no')) else: if self._source is not None: self._builder.nb_problem_layout.set_current_page(1) else: self._builder.nb_problem_layout.set_current_page(2)
def _set_problem(self, problem): def destroy_links(widget, _): if widget != self._builder.lbl_reported_value: widget.destroy() self.selected_problem = problem sensitive_btn = problem is not None self._builder.btn_delete.set_sensitive(sensitive_btn) self._builder.btn_report.set_sensitive(sensitive_btn and not problem["not-reportable"]) self._builder.vbx_links.foreach(destroy_links, None) self._builder.vbx_problem_messages.foreach(lambda w, u: w.destroy(), None) if problem: self._builder.nb_problem_layout.set_current_page(0) app = problem["application"] if problem["type"] == "Kerneloops": self._builder.lbl_reason.set_text(_("Unexpected system error")) self._builder.lbl_summary.set_text(_("The system has encountered a problem and recovered.")) elif problem["type"] == "vmcore": self._builder.lbl_reason.set_text(_("Fatal system failure")) self._builder.lbl_summary.set_text(_("The system has encountered a problem and could not continue.")) else: if not app.name: # If Application's name is unknown, display neutral # header "'Type' problem has been detected": # Kerneloops problem has been detected # C/C++ problem has been detected # Python problem has been detected # Ruby problem has been detected # VMCore problem has been detected # AVC problem has been detected # Java problem has been detected self._builder.lbl_reason.set_text(_("{0} problem has been detected").format(problem["human_type"])) else: self._builder.lbl_reason.set_text(_("{0} quit unexpectedly").format(app.name)) self._builder.lbl_summary.set_text(_("The application encountered a problem and could not continue.")) self._builder.lbl_app_name_value.set_text(problem["package_name"] or _("N/A")) self._builder.lbl_app_version_value.set_text(problem["package_version"] or _("N/A")) self._builder.lbl_detected_value.set_text(humanize.naturaltime(datetime.datetime.now() - problem["date"])) self._builder.lbl_detected_value.set_tooltip_text( problem["date"].strftime(config.get_configuration()["D_T_FMT"]) ) icon_buf = None scale = self._builder.img_app_icon.get_scale_factor() if app.icon: icon_buf = load_icon(gicon=app.icon, scale=scale) if icon_buf is None: icon_buf = load_icon(name="system-run-symbolic", scale=scale) # icon_buf can be None and if it is None, no icon will be displayed set_icon_from_pixbuf_with_scale(self._builder.img_app_icon, icon_buf, scale) self._builder.lbl_reported_value.show() self._builder.lbl_reported.set_text(_("Reported")) if problem["not-reportable"]: self._builder.lbl_reported_value.set_text(_("cannot be reported")) self._show_problem_links(problem["submission"]) self._show_problem_message(problem["not-reportable"]) elif problem["is_reported"]: if self._show_problem_links(problem["submission"]): self._builder.lbl_reported.set_text(_("Reports")) self._builder.lbl_reported_value.hide() if not any((s.name == "Bugzilla" for s in problem["submission"])): self._show_problem_message( _( "This problem has been reported, but a <i>Bugzilla</i> ticket has not" " been opened. Our developers may need more information to fix the problem.\n" "Please consider also <b>reporting it</b> to Bugzilla in" " order to provide that. Thank you." ) ) else: self._builder.lbl_reported_value.set_text(_("yes")) else: self._builder.lbl_reported_value.set_text(_("no")) else: if self._source is not None: self._builder.nb_problem_layout.set_current_page(1) else: self._builder.nb_problem_layout.set_current_page(2)
def __init__(self, application, sources, controller): Gtk.ApplicationWindow.__init__(self, title=OopsWindow._TITLE, application=application) if not sources: raise ValueError("The source list cannot be empty!") self._builder = OopsWindow.OopsGtkBuilder() self._builder.reset_window(self, OopsWindow._TITLE) #pylint: disable=E1120 css_prv = Gtk.CssProvider.new() css_prv.load_from_data("GtkListBoxRow {\n" " padding : 12px;\n" "}\n" ".app-name-label {\n" " font-weight : bold;\n" "}\n" ".oops-reason {\n" " font-size : 120%;\n" " font-weight : bold;\n" "}\n".encode() ) stl_ctx = self.get_style_context() stl_ctx.add_provider_for_screen(stl_ctx.get_screen(), css_prv, 6000) self._builder.connect_signals(self) self._source_observer = OopsWindow.SourceObserver(self) self._source_observer.disable() self._reloading = False self._controller = controller self.selected_problem = None self._all_sources = [] self._source = None self._handling_source_click = False self._configure_sources(sources) self._set_button_toggled(self._source.button, True) # a set where invalid problems found while sorting of the problem list # are stored self._trash = set() self._builder.lb_problems.set_sort_func(time_sort_func, self._trash) self.lss_problems = ListBoxSelection(self._builder.lb_problems, self.on_tvs_problems_changed) self._filter = ProblemsFilter(self._builder.lb_problems, self.lss_problems) self._builder.lb_problems.grab_focus() try: self._reload_problems(self._source) except errors.UnavailableSource as ex: self._disable_source(ex.source, ex.temporary) self._options_observer = OopsWindow.OptionsObserver(self) conf = config.get_configuration() conf.set_watch('problemid', self._options_observer) conf.set_watch('T_FMT', self._options_observer) conf.set_watch('D_T_FMT', self._options_observer) self._options_observer.option_updated(conf, 'problemid') self._builder.mi_detail.set_visible(conf['expert']) # enable observer self._source_observer.enable() self.connect("key-press-event", self._on_key_press_event)
def __init__(self, application, sources, controller): Gtk.ApplicationWindow.__init__(self, title=_('Problem Reporting'), application=application) if not sources: raise ValueError("The source list cannot be empty!") self._builder = OopsWindow.OopsGtkBuilder() self.set_default_size(*self._builder.wnd_main.get_size()) self._builder.wnd_main.remove(self._builder.gr_main_layout) #pylint: disable=E1101 self.add(self._builder.gr_main_layout) # move accelators group from the design window to this window self.add_accel_group(self._builder.ag_accelerators) #pylint: disable=E1120 css_prv = Gtk.CssProvider.new() css_prv.load_from_data("GtkViewport {\n" " background-color : @theme_bg_color;\n" "}\n") stl_ctx = self.get_style_context() stl_ctx.add_provider_for_screen(stl_ctx.get_screen(), css_prv, 6000) self._builder.connect_signals(self) self._source_observer = OopsWindow.SourceObserver(self) self._source_observer.disable() self._reloading = False self._controller = controller self.selected_problem = None self._all_sources = [] self._source = None self._handling_source_click = False for name, src in sources: self._all_sources.append(src) src.attach(self._source_observer) label = None try: label = format_button_source_name(name, src) except errors.UnavailableSource: logging.debug("Unavailable source: {0}".format(name)) continue src_btn = Gtk.ToggleButton.new_with_label(label) src_btn.set_visible(True) # add an extra member source (I don't like it but it so easy) src_btn.source = src self._builder.hbox_source_btns.pack_start(src_btn, True, True, 0) # add an extra member name (I don't like it but it so easy) src.name = name # add an extra member button (I don't like it but it so easy) src.button = src_btn src_btn.connect("clicked", self._on_source_btn_clicked, src) self._source = self._all_sources[0] self._set_button_toggled(self._source.button, True) self._builder.ls_problems.set_sort_column_id(0, Gtk.SortType.DESCENDING) # a set where invalid problems found while sorting of the problem list # are stored self._trash = set() self._builder.ls_problems.set_sort_func(0, time_sort_func, self._trash) self._filter = ProblemsFilter(self, self._builder.tv_problems) self._builder.tv_problems.grab_focus() try: self._reload_problems(self._source) except errors.UnavailableSource as ex: self._disable_source(ex.source, ex.temporary) self._options_observer = OopsWindow.OptionsObserver(self) conf = config.get_configuration() conf.set_watch('problemid', self._options_observer) conf.set_watch('T_FMT', self._options_observer) conf.set_watch('D_T_FMT', self._options_observer) self._options_observer.option_updated(conf, 'problemid') self._builder.btn_detail.set_visible(conf['expert']) self._builder.mi_detail.set_visible(conf['expert']) # enable observer self._source_observer.enable() self._builder.tv_problems.set_search_entry(self._builder.se_problems) self.connect("key-press-event", self._on_key_press_event, None)
def _set_problem(self, problem): def destroy_links(widget, _): if widget != self._builder.lbl_reported_value: widget.destroy() self.selected_problem = problem sensitive_btn = problem is not None self._builder.btn_delete.set_sensitive(sensitive_btn) self._builder.btn_report.set_sensitive( sensitive_btn and not problem['not-reportable']) self._builder.vbx_links.foreach( destroy_links, None) self._builder.vbx_problem_messages.foreach( lambda w, u: w.destroy(), None) if problem: self._builder.nb_problem_layout.set_current_page(0) app = problem['application'] if problem['type'] == 'Kerneloops': self._builder.lbl_reason.set_text( _("Unexpected system error")) self._builder.lbl_summary.set_text( _("The system has encountered a problem and recovered.")) elif problem['type'] == 'vmcore': self._builder.lbl_reason.set_text( _("Fatal system failure")) self._builder.lbl_summary.set_text( _("The system has encountered a problem and could not continue.")) else: if not app.name: self._builder.lbl_reason.set_text( # Translators: If Application's name is unknown, # display neutral header # "'Type' problem has been detected". Examples: # Kerneloops problem has been detected # C/C++ problem has been detected # Python problem has been detected # Ruby problem has been detected # VMCore problem has been detected # AVC problem has been detected # Java problem has been detected _("{0} problem has been detected").format( problem['human_type'])) else: self._builder.lbl_reason.set_text( _("{0} quit unexpectedly").format(app.name)) self._builder.lbl_summary.set_text( _("The application encountered a problem and could not continue.")) self._builder.lbl_app_name_value.set_text( # Translators: package name not available problem['package_name'] or _("N/A")) self._builder.lbl_app_version_value.set_text( # Translators: package version not available problem['package_version'] or _("N/A")) self._builder.lbl_detected_value.set_text( humanize.naturaltime(datetime.datetime.now()-problem['date'])) self._builder.lbl_detected_value.set_tooltip_text( problem['date'].strftime(config.get_configuration()['D_T_FMT'])) icon_buf = None scale = self._builder.img_app_icon.get_scale_factor() if app.icon: icon_buf = load_icon(gicon=app.icon, scale=scale) if icon_buf is None: icon_buf = load_icon(name="system-run-symbolic", scale=scale) self._builder.img_app_icon.get_style_context().add_class( 'dim-label') else: self._builder.img_app_icon.get_style_context().remove_class( 'dim-label') # icon_buf can be None and if it is None, no icon will be displayed set_icon_from_pixbuf_with_scale(self._builder.img_app_icon, icon_buf, scale) self._builder.lbl_reported_value.show() self._builder.lbl_reported.set_text(_("Reported")) if problem['not-reportable']: self._builder.lbl_reported_value.set_text( _('cannot be reported')) self._show_problem_links(problem['submission']) self._show_problem_message(problem['not-reportable']) elif problem['is_reported']: if self._show_problem_links(problem['submission']): self._builder.lbl_reported.set_text(_("Reports")) self._builder.lbl_reported_value.hide() if (not any((s.name == "Bugzilla" for s in problem['submission']))): self._show_problem_message( _("This problem has been reported, but a <i>Bugzilla</i> ticket has not" " been opened. Our developers may need more information to fix the problem.\n" "Please consider also <b>reporting it</b> to Bugzilla in" " order to provide that. Thank you.")) else: # Translators: Displayed after 'Reported' if a problem # has been reported but we don't know where and when. # Probably a rare situation, usually if a problem is # reported we display a list of reports here. self._builder.lbl_reported_value.set_text(_('yes')) else: # Translators: Displayed after 'Reported' if a problem # has not been reported. self._builder.lbl_reported_value.set_text(_('no')) else: if self._source is not None: self._builder.nb_problem_layout.set_current_page(1) else: self._builder.nb_problem_layout.set_current_page(2)
def __init__(self, application, sources, controller): super().__init__(application=application) if not sources: raise ValueError("The source list cannot be empty!") GObject.Binding.bind_property( self.tbtn_search, "active", self.search_bar, "search-mode-enabled", GObject.BindingFlags.BIDIRECTIONAL) label = Gtk.Label.new('') label.show() self.lb_problems.set_placeholder(label) label.connect('map', self.placeholder_mapped, self) label.connect('unmap', self.placeholder_unmapped, self) builder = Gtk.Builder() builder.set_translation_domain(GETTEXT_PROGNAME) builder.add_from_resource('/org/freedesktop/GnomeAbrt/ui/oops-menus.ui') self.menu_problem_item = builder.get_object('menu_problem_item') self.menu_problem_item = Gtk.Menu.new_from_model(self.menu_problem_item) self.menu_problem_item.attach_to_widget(self) self.menu_multiple_problems = builder.get_object( 'menu_multiple_problems') self.menu_multiple_problems = Gtk.Menu.new_from_model( self.menu_multiple_problems) self.menu_multiple_problems.attach_to_widget(self) #pylint: disable=E1120 css_prv = Gtk.CssProvider.new() css_prv.load_from_resource('/org/freedesktop/GnomeAbrt/css/oops.css') stl_ctx = self.get_style_context() stl_ctx.add_provider_for_screen(stl_ctx.get_screen(), css_prv, 6000) self.search_bar.connect_entry(self.se_problems) self._source_observer = OopsWindow.SourceObserver(self) self._source_observer.disable() self._reloading = False self._controller = controller self.selected_problem = None self._all_sources = [] self._source = None self._handling_source_click = False self._configure_sources(sources) self._set_button_toggled(self._source.button, True) # a set where invalid problems found while sorting of the problem list # are stored self._trash = set() self.lb_problems.set_sort_func(time_sort_func, self._trash) self.lss_problems = ListBoxSelection(self.lb_problems, self.on_tvs_problems_changed) self._filter = ProblemsFilter(self.lb_problems, self.lss_problems) self.lb_problems.grab_focus() try: self._reload_problems(self._source) except errors.UnavailableSource as ex: self._disable_source(ex.source, ex.temporary) self._options_observer = OopsWindow.OptionsObserver(self) conf = config.get_configuration() conf.set_watch('problemid', self._options_observer) conf.set_watch('T_FMT', self._options_observer) conf.set_watch('D_T_FMT', self._options_observer) self._options_observer.option_updated(conf, 'problemid') # enable observer self._source_observer.enable() self.connect("key-press-event", self._on_key_press_event) self._add_actions(application)
def _set_problem(self, problem): def destroy_links(widget, _): if widget != self.lbl_reported_value: widget.destroy() self.selected_problem = problem action_enabled = problem is not None self.lookup_action('delete').set_enabled(action_enabled) self.lookup_action('report').set_enabled( action_enabled and not problem['not-reportable']) self.vbx_links.foreach(destroy_links, None) self.vbx_problem_messages.foreach(lambda w, u: w.destroy(), None) if not problem: self.nb_problem_layout.set_visible_child( self.vbx_empty_page if self._source else self. vbx_no_source_page) return self.nb_problem_layout.set_visible_child(self.gd_problem_info) app = problem['application'] self.lbl_reason.set_text( self._get_reason_for_problem_type(app, problem['type'], problem['human_type'])) self.lbl_summary.set_text( self._get_summary_for_problem_type(problem['type'])) # Translators: package name not available self.lbl_app_name_value.set_text(problem['package_name'] or _("N/A")) # Translators: package version not available self.lbl_app_version_value.set_text(problem['package_version'] or _("N/A")) self.lbl_detected_value.set_text( humanize.naturaltime(datetime.datetime.now() - problem['date'])) self.lbl_detected_value.set_tooltip_text(problem['date'].strftime( config.get_configuration()['D_T_FMT'])) theme = Gtk.IconTheme.get_default() scale = self.img_app_icon.get_scale_factor() style_context = self.img_app_icon.get_style_context() style_context.remove_class(Gtk.STYLE_CLASS_DIM_LABEL) pixbuf = None if app.icon: icon_info = theme.lookup_by_gicon_for_scale( app.icon, 128, scale, Gtk.IconLookupFlags.FORCE_SIZE) try: pixbuf = icon_info.load_icon() if icon_info else None except GLib.Error as ex: logging.warning( 'Failed to load default icon for {}: {}'.format( app.name, ex)) if not pixbuf: try: pixbuf = theme.load_icon_for_scale( 'system-run-symbolic', 128, scale, (Gtk.IconLookupFlags.FORCE_SIZE | Gtk.IconLookupFlags.FORCE_SYMBOLIC)) style_context.add_class(Gtk.STYLE_CLASS_DIM_LABEL) except GLib.Error as ex: logging.warning( 'Failed to load system-run-symbolic: {}'.format(ex)) if pixbuf: surface = Gdk.cairo_surface_create_from_pixbuf( pixbuf, scale, self.img_app_icon.get_window()) self.img_app_icon.set_from_surface(surface) else: self.img_app_icon.clear() self.lbl_reported_value.show() self.lbl_reported.set_text(_("Reported")) if problem['not-reportable']: self.lbl_reported_value.set_text(_('cannot be reported')) self._show_problem_links(problem['submission']) self._show_problem_message(problem['not-reportable']) elif problem['is_reported']: if self._show_problem_links(problem['submission']): self.lbl_reported.set_text(_("Reports")) self.lbl_reported_value.hide() if not any( (s.name == "Bugzilla" for s in problem['submission'])): self._show_problem_message( _("This problem has been reported, but a <i>Bugzilla</i> ticket has not" " been opened. Our developers may need more information to fix the problem.\n" "Please consider also <b>reporting it</b> to Bugzilla in" " order to provide that. Thank you.")) else: # Translators: Displayed after 'Reported' if a problem # has been reported but we don't know where and when. # Probably a rare situation, usually if a problem is # reported we display a list of reports here. self.lbl_reported_value.set_text(_('yes')) else: # Translators: Displayed after 'Reported' if a problem # has not been reported. self.lbl_reported_value.set_text(_('no'))