def __init__(self, main, console, selector, frontend, font_size=8): ''' Setup the package info @param main: main window @param console: Widget for writing infomation (gtk.TextView) @param selector: the selector ui widget (gtk.VBox) @param frontend: the frontend instance @param font_size: the fontsize in the console ''' SelectorBase.__init__(self, selector, key_bindings=frontend.key_bindings) self.widget = console self.main_window = main self.frontend = frontend self.console = PackageInfoTextView(console, font_size=font_size, window=main, \ url_handler=self._url_handler) self.deps_view = YumexDepsPackageView(self.frontend.ui.packageDeps, \ self.frontend.settings.color_install, \ self.frontend.settings.color_normal) self.add_button('description', stock='gtk-about', tooltip=_('Package Description'), accel='<alt>i') self.add_button('update', stock='gtk-info', tooltip=_('Update information'), accel='<alt>u') self.add_button('changelog', stock='gtk-edit', tooltip=_('Package Changelog'), accel='<alt>c') self.add_button('filelist', stock='gtk-harddisk', tooltip=_('Package Filelist'), accel='<alt>f') self.add_button('deps', stock='gtk-convert', tooltip=_('Package Dependencies'), accel='<alt>d') self.pkg = None self._selected = 'description' self._set_output_view('description')
class PackageInfo(SelectorBase): ''' Package information gui handler controls the package info Textview and the buttons to show description, changelog and filelist. ''' def __init__(self, main, console, selector, frontend, font_size=8): ''' Setup the package info @param main: main window @param console: Widget for writing infomation (gtk.TextView) @param selector: the selector ui widget (gtk.VBox) @param frontend: the frontend instance @param font_size: the fontsize in the console ''' SelectorBase.__init__(self, selector, key_bindings=frontend.key_bindings) self.widget = console self.main_window = main self.frontend = frontend self.console = PackageInfoTextView(console, font_size=font_size, window=main, \ url_handler=self._url_handler) self.deps_view = YumexDepsPackageView(self.frontend.ui.packageDeps, \ self.frontend.settings.color_install, \ self.frontend.settings.color_normal) self.add_button('description', stock='gtk-about', tooltip=_('Package Description'), accel='<alt>i') self.add_button('update', stock='gtk-info', tooltip=_('Update information'), accel='<alt>u') self.add_button('changelog', stock='gtk-edit', tooltip=_('Package Changelog'), accel='<alt>c') self.add_button('filelist', stock='gtk-harddisk', tooltip=_('Package Filelist'), accel='<alt>f') self.add_button('deps', stock='gtk-convert', tooltip=_('Package Dependencies'), accel='<alt>d') self.pkg = None self._selected = 'description' self._set_output_view('description') def _is_url(self,url): urls = re.findall('^http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+~]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+', url) if urls: return True else: return False def _url_handler(self, url): self.frontend.info('Url activated : ' + url) if self._is_url(url): # just to be sure and prevent shell injection rc = call("xdg-open %s"%url, shell=True) if rc != 0: # failover to gtk.show_uri, if xdg-open fails or is not installed gtk.show_uri(None, url, gtk.gdk.CURRENT_TIME) else: self.frontend.warning("%s is not an url" % url) def update(self, pkg): ''' update the package info with a new package @param pkg: package to show info for @param update: package is an update (used to display update info) ''' if pkg == self.pkg: return self.widget.grab_add() # lock everything but then TextView widget, until we have updated self.pkg = pkg #self.show_dependencies() #self.set_active(self._selected) key = self._selected self.update_console(key) self.widget.grab_remove() def clear(self): ''' clear the package info console ''' self.console.clear() def on_button_clicked(self, widget=None, key=None): ''' button clicked callback handler''' if widget.get_active(): # only work on the active button self._selected = key self.update_console(key) def _set_output_view(self, key): if key == 'deps': self.frontend.ui.packageInfoSW.hide() self.frontend.ui.packageDepsSW.show() else: self.frontend.ui.packageInfoSW.show() self.frontend.ui.packageDepsSW.hide() def update_console(self, key): ''' update the console with information @param key: information to show (description,changelog,filelist) ''' if self.pkg: busyCursor(self.main_window) self.console.clear() self._set_output_view(key) if key == 'description': self.show_description() elif key == 'changelog': self.show_changelog() elif key == 'filelist': self.show_filelist() elif key == 'update': self.show_update() elif key == 'deps': self.show_dependencies() self.console.goTop() normalCursor(self.main_window) def show_update(self): ''' show the package description ''' upd_info = None upd_info_list, updated_po_list = self.pkg.updateinfo progress = self.frontend.get_progress() progress.hide() if not updated_po_list: self.console.write(_("No Update information"), "changelog-header", newline=False) return updated_pkgs = updated_po_list[0] if not upd_info_list: return if updated_pkgs: new_pkg = "%s (%s) --> " % (self.pkg.fullname, self.pkg.size) self.console.write(new_pkg, "changelog-header", newline=False) spaces = " " * len(new_pkg) i = 0 for po in updated_pkgs: if i == 0: msg = str(po) else: msg = "%s %s" % (spaces,po) self.console.write(msg, "changelog-header") self.console.write('\n') for upd_info in sorted(upd_info_list, key=itemgetter('update_id'), reverse=True): if upd_info: msg = "%s\n\n" % upd_info['update_id'] self.console.write(msg, "changelog-header") self.show_update_info(upd_info) def show_dependencies(self): deps = self.pkg.dependencies self.deps_view.populate(deps) def show_description(self): ''' show the package description ''' url = self.pkg.URL self.console.write(_("Project URL : "), "changelog-header", newline=False) self.console.add_url(url, url, newline=True) self.console.write('\n') self.console.write(self.pkg.description) def show_update_info(self, upd_info): head = "" head += ("%14s " % _("Release")) + ": %(release)s\n" head += ("%14s " % _("Type")) + ": %(type)s\n" head += ("%14s " % _("Status")) + ": %(status)s\n" head += ("%14s " % _("Issued")) + ": %(issued)s\n" head = head % upd_info if upd_info['updated'] and upd_info['updated'] != upd_info['issued']: head += " Updated : %s" % upd_info['updated'] self.console.write(head) head = "" # Add our bugzilla references if upd_info['references']: bzs = [ r for r in upd_info['references'] if r and r['type'] == 'bugzilla'] if len(bzs): header = "Bugzilla" for bz in bzs: if 'title' in bz and bz['title']: bug_msg = ' - %s' % bz['title'] else: bug_msg = '' self.console.write("%14s : " % header, newline=False) self.console.add_url(bz['id'], self.frontend.settings.bugzilla_url + bz['id']) self.console.write(bug_msg) header = " " # Add our CVE references if upd_info['references']: cves = [ r for r in upd_info['references'] if r and r['type'] == 'cve'] if len(cves): cvelist = "" header = "CVE" for cve in cves: cvelist += "%14s : %s\n" % (header, cve['id']) header = " " head += cvelist[:-1].rstrip() + '\n\n' if upd_info['description'] is not None: desc = utf8_text_wrap(upd_info['description'], width=64, subsequent_indent=' ' * 14 + ' : ') head += "%14s : %s\n" % (_("Description"), '\n'.join(desc)) head += "\n" self.console.write(head) def show_changelog(self): ''' show the package changelog ''' changelog = self.pkg.changelog progress = self.frontend.get_progress() progress.hide() if changelog: for (c_date, c_ver, msg) in changelog: self.console.write("* %s %s" % (date.fromtimestamp(c_date).isoformat(), c_ver), "changelog-header") for line in msg.split('\n'): self.console.write("%s" % line, "changelog") self.console.write('\n') def show_filelist(self): ''' show the package filelist ''' files = self.pkg.filelist progress = self.frontend.get_progress() progress.hide() if files: # files can be None files.sort() for fn in files: self.console.write(fn, "filelist")