def update_tray_icon(self): if self.need_input: self.statusicon.set_tooltip_text("Yum Extender: Need user input") pixbuf = gtk.gdk.pixbuf_new_from_file(self.image_info) self.set_popup_menu_sensitivity(False) elif self.is_working > 0: self.statusicon.set_tooltip_text("Yum Extender: Working") pixbuf = gtk.gdk.pixbuf_new_from_file(self.image_checking) self.set_popup_menu_sensitivity(False) else: self.set_popup_menu_sensitivity(True) update_count = self.update_count if update_count == -2: self.statusicon.set_tooltip_text(_("Yum Extender")) pixbuf = gtk.gdk.pixbuf_new_from_file(self.image_no_update) elif update_count == -1: self.statusicon.set_tooltip_text(_("Yum Extender: Error")) pixbuf = gtk.gdk.pixbuf_new_from_file(self.image_error) elif update_count == 0: self.statusicon.set_tooltip_text(_("Yum Extender: No Updates")) pixbuf = gtk.gdk.pixbuf_new_from_file(self.image_no_update) else: self.statusicon.set_tooltip_text(_("Yum Extender: %s Updates available") % update_count) pixbuf = self.get_pixbuf_with_text(self.image_updates, str(update_count), self.rel_font_size) self.statusicon.set_from_pixbuf(pixbuf) gtk.main_iteration(False)
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 setup(self, offline=False, repos=None, need_root=True): ''' Setup the backend''' if self.yum_backend_is_running: # Check if backend is already running if self._running_as_root == need_root or self._running_as_root: return self.debug('Restarting backend as root') self.reset() # stop the running backend self._close() # stop the running launcher process self._running_as_root = need_root or os.getuid()==0 self.frontend.info(_("Starting yum child process")) if repos: self.frontend.info(_("Using the following repositories :\n%s\n\n") % (','.join(repos))) plugins = self.frontend.settings.plugins yumdebuglevel = self.frontend.settings.yumdebuglevel proxy = self.frontend.settings.proxy.strip() yum_conf = self.frontend.settings.yum_conf filelog = False if 'show_backend' in self.frontend.debug_options: filelog = True self.debug('Initialize yum backend - BEGIN') rc = YumClient.setup(self, debuglevel=yumdebuglevel, plugins=plugins, filelog=filelog, offline=offline, repos=repos, proxy=proxy, yum_conf=yum_conf, need_root=need_root) self.debug('Initialize yum backend - END') return rc
def setup_view(self): """ Create models and columns for the Repo TextView """ store = gtk.ListStore('gboolean', gobject.TYPE_STRING, gobject.TYPE_STRING, 'gboolean') self.view.set_model(store) # Setup Selection Column col = self.create_selection_column_num(0) col.set_clickable(True) col.connect('clicked', self.on_section_header_clicked) # Setup resent column cell2 = gtk.CellRendererPixbuf() # gpgcheck cell2.set_property('stock-id', gtk.STOCK_DIALOG_AUTHENTICATION) column2 = gtk.TreeViewColumn("", cell2) column2.set_cell_data_func(cell2, self.new_pixbuf) column2.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED) column2.set_fixed_width(20) column2.set_sort_column_id(-1) self.view.append_column(column2) # Setup reponame & repofile column's self.create_text_column_num(_('Repository'), 1) self.create_text_column_num(_('Name'), 2) self.view.set_search_column(1) self.view.set_reorderable(False) return store
def setup_yum(self): ''' setup the yum releated options ''' vbox = self.ui.prefYumVBox self._add_option(PrefBoolean, vbox, 'plugins', _('Enable Yum Plugins')) self._add_option(PrefStr, vbox, 'proxy', _('Proxy')) self._add_option(PrefInt, vbox, 'yumdebuglevel', _('Yum Debug Level')) vbox.show_all()
def setup_view(self): """ Create models and columns for the TextView """ store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, \ gobject.TYPE_STRING, gobject.TYPE_STRING) self.view.set_model(store) self.create_text_column_num(_('Id'), 0) self.create_text_column_num(_('Login User'), 1) self.create_text_column_num(_('Data/Time'), 2) self.create_text_column_num(_('Action(s)'), 3) self.create_text_column_num(_('Altered'), 4) return store
def __init__(self, widget): ''' @param widget: ''' SelectionView.__init__(self, widget) self.view.modify_font(const.SMALL_FONT) self.headers = [_('Repository'), _('Filename')] self.store = self.setup_view() self.state = 'normal' self._last_selected = []
def setup_view(self): """ Create models and columns for the Search Options TextView """ store = gtk.TreeStore('gboolean', gobject.TYPE_STRING, gobject.TYPE_PYOBJECT) self.view.set_model(store) # Setup Selection Column #self.create_selection_colunm('') # Setup Actions and pacakges col = self.create_text_column(_("Package"), 'name', size=350) self.view.set_expander_column(col) self.create_text_column(_("Ver."), 'fullver', size=120) self.create_text_column(_("Arch."), 'arch' , size=60) return store
def __init__(self, widget, qview, frontend): ''' Init the view @param widget: the gtk TreeView widget @param qview: the queue view instance to use for queuing ''' SelectionView.__init__(self, widget) self.view.modify_font(const.SMALL_FONT) self.headers = [_("Package"), _("Ver"), _("Summary"), _("Repo"), _("Architecture"), _("Size")] self.store = self.setupView() self.queue = qview.queue self.queueView = qview self.frontend = frontend
def init_popup_menu(self): menu = gtk.Menu() self.popup_menu = menu quit = gtk.MenuItem(_("Quit")) self.quit_menu = quit search_updates = gtk.MenuItem(_("Search for Updates")) self.search_updates_menu = search_updates menu.append(search_updates) menu.append(quit) menu.show_all() self.statusicon.connect("popup-menu", self.on_popup)
def setup_view(self, view): ''' Setup the TreeView @param view: the TreeView widget ''' model = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING) view.set_model(model) self.create_text_column(_("Name"), view, 0, size=250) self.create_text_column(_("Arch"), view, 1) self.create_text_column(_("Ver"), view, 2) self.create_text_column(_("Repository"), view, 3) self.create_text_column(_("Size"), view, 4) return model
def setup_view(self): """ Create Notebook list for single page """ model = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_STRING) self.view.set_model(model) cell1 = gtk.CellRendererText() column1 = gtk.TreeViewColumn(_("Packages"), cell1, markup=0) column1.set_resizable(True) self.view.append_column(column1) cell2 = gtk.CellRendererText() column2 = gtk.TreeViewColumn(_("Summary"), cell2, text=1) column2.set_resizable(True) self.view.append_column(column2) model.set_sort_column_id(0, gtk.SORT_ASCENDING) self.view.get_selection().set_mode(gtk.SELECTION_MULTIPLE) return model
def setup_view(self): """ Create models and columns for the TextView """ store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING) self.view.set_model(store) self.create_text_column_num(_('Categories'), 1) return store
def check_network_connection(self): ''' Update the network connection status @return True, if network connection state could be detected ''' try: bus = dbus.SystemBus() self._connected = None nm = bus.get_object('org.freedesktop.NetworkManager', '/org/freedesktop/NetworkManager') dev = nm.GetDevices() for d in dev: net = bus.get_object('org.freedesktop.NetworkManager', d) net_props = dbus.Interface(net, 'org.freedesktop.DBus.Properties') props = net_props.GetAll('org.freedesktop.NetworkManager.Device') state = props['State'] interface = "%s (%s)" % (props['Interface'], props['Driver']) #print interface, state if state == 8 or state == 100: # 8 = connected (nm8), 100 = connected (nm9) self.logger.debug(_("network interface %s is connected") % interface) self._connected = True else: # Disconnected or other not connected state if self._connected == None: self._connected = False return True except: # Catch all exceptions # Could not get the state from NetworkManager # It might not be running e = sys.exc_info() print str(e) return False
def reset(self): """ reset the client""" if not self.yum_backend_is_running: # yum backend not running return True if not self.child.isalive(): del self.child self.child = None return True else: cnt = 0 while self.waiting and cnt < 5: self.debug("Trying to close the yum backend") time.sleep(1) cnt += 1 if cnt < 10: rc = self._send_command('exit', []) if rc: cmd, args = self._readline() #self._close() self.debug(cmd) self.yum_backend_is_running = False return True # The yum backend did not ended nicely self.error(_("Yum backend did not close nicely in time")) self.yum_backend_is_running = False self._close() return False
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_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 yum_dnl_progress(self, ftype, name, percent, cur, tot, fread, ftotal, ftime): """ yum download progress handler """ progress = self.frontend.get_progress() if not progress.is_active(): # if the progress is hidden, then show it at set the labels. progress.set_title(_('Getting Package Information')) progress.set_header(_('Getting Package Information')) progress.show() if percent == 0.0: # If we are downloading something, then disable pulse mode progress.set_pulse(False) if progress.tasks.current_running == 'download': width = len("%s" % tot) progress.tasks.set_extra_label('download', "<b>( %*s / %*s )</b>" % (width, cur, width, tot)) elif percent == 100.0: # if not downloading package, and current download is complete progress.set_pulse(True) progress.set_fraction(float(percent) / 100.0, "%3i %% ( %s / %s ) - %s" % (percent, fread, ftotal, ftime)) if ftype == "REPO": # This is repo metadata being downloaded if percent > 0: # only show update labels once. return if '/' in name: values = name.split('/') if len(values) == 3: # Latest version of yum returns (repoid/fedora_release/arch) for repomd repo, mdtype = values[0],"repomd" else: repo, mdtype = values[0],values[-1] # there can be more than 2 values, take first & last else: repo = name mdtype = None markup_repo = "<b>%s</b>" % repo if mdtype: if mdtype in REPO_INFO_MAP: msg = REPO_INFO_MAP[mdtype] % markup_repo else: msg = _("Unknown metadata type (%s) for %s") % (mdtype,markup_repo) self.warning(msg) else: msg = _("Repo Metadata for %s") % markup_repo progress.set_action(msg) self.debug(msg) elif ftype == 'REBUILD': progress.set_action(_('Building rpms from deltarpm')) else: # this is a package being downloaded #self.frontend.debug("DNL (%s): %s - %3i %%" % (ftype,name,percent)) if name: progress.set_action(name) else: self.frontend.debug("DNL (%s): %s - %3i %%" % (ftype, name, percent))
def setup_view(self): """ Create models and columns for the Search Options TextView """ store = gtk.ListStore('gboolean', gobject.TYPE_STRING, gobject.TYPE_STRING) self.view.set_model(store) # Setup Selection Column col = self.create_selection_column_num(0) # Setup reponame & repofile column's self.create_text_column_num(_('Search Keys'), 1) return store
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 populate_list_downgrade(self): ''' ''' pkg_list = self.queue.packages['do'] label = "<b>%s</b>" % P_("Package to downgrade", "Packages to downgrade", len(pkg_list)) if len(pkg_list) > 0: parent = self.model.append(None, [label, ""]) for pkg in pkg_list: item = self.model.append(parent, [str(pkg), pkg.summary]) self.model.append(item, [_("<b>Downgrade to</b> %s ") % str(pkg.downgrade_po), ""])
def __init__(self, frontend, status_icon): ''' Setup the progress dialog @param ui: the UI class containing the dialog @param parent: the parent window widget ''' YumexProgressBase.__init__(self) self.frontend = frontend self.ui = frontend.ui self.dialog = self.ui.Progress self.dialog.set_title("Working....") self.dialog.set_deletable(False) self.dialog.connect('delete_event', self._delete_event) self.parent = frontend.window self.dialog.set_transient_for(self.parent) style = self.ui.packageView.get_style() self.ui.progressEvent.modify_bg(gtk.STATE_NORMAL, style.base[0]) self.progressbar = self.ui.progressBar self.progressbar.modify_font(SMALL_FONT) self.header = self.ui.progressHeader self.header.modify_font(BIG_FONT) self.label = self.ui.progressLabel self.label.modify_font(SMALL_FONT) self.tasks = TaskList(self.ui.progressTasks, self.dialog) self.tasks.add_task('depsolve', _('Resolving Dependencies')) self.tasks.add_task('download', _("Downloading Packages")) self.tasks.add_task('gpg-check', _("Checking Package GPG Signatures")) self.tasks.add_task('test-trans', _("Running RPM Test Transaction")) self.tasks.add_task('run-trans', _("Running RPM Transaction")) self.tasks.hide() self.show_cancel(False) # Hide the Cancel button self.default_w = None self.default_h = None self._extra_widget = None self._active = False self.ui.progressImage.set_from_file(ICON_SPINNER) self.resize() # Setup the initial size self.extra_hidden = True self.task_hidden = True self.progress_hidden = False self.status_icon = status_icon
def setupView(self): ''' Setup the TreeView ''' store = gtk.ListStore(gobject.TYPE_PYOBJECT, str, str, str, str, str, long) self.sort_store = gtk.TreeModelSort(store) self.view.set_model(self.sort_store) self.create_selection_colunm('selected') # Setup resent column cell2 = gtk.CellRendererPixbuf() # new cell2.set_property('stock-id', gtk.STOCK_ADD) column2 = gtk.TreeViewColumn("", cell2) column2.set_cell_data_func(cell2, self.new_pixbuf) column2.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED) column2.set_fixed_width(20) column2.set_sort_column_id(-1) self.view.append_column(column2) column2.set_clickable(True) self.create_text_column(_("Package"), 'name' , size=200, sortcol=1) self.create_text_column(_("Ver."), 'fullver', size=120, sortcol=2) self.create_text_column(_("Arch."), 'arch' , size=60, sortcol=3) self.create_text_column(_("Summary"), 'summary', size=400, sortcol=4) self.create_text_column(_("Repo."), 'repoid' , size=90, sortcol=5) self.create_text_column(_("Size."), 'size' , size=90, sortcol=6) #self.view.set_search_column(1) #self.view.set_enable_search(True) self.sort_store.set_sort_column_id(1, gtk.SORT_ASCENDING) self.view.set_reorderable(False) return store
def media_change(self, prompt_first, media_id, media_name, media_num): ''' Media change callback, triggered from the yum backend, when a media change is needed. @param prompt_first: should prompt user before looking for the media @param media_id: An ID to make sure we got the required disc @param media_name: The media name @param media_num: The media discnum @return: the mountpoint of the requested media or None to cancel ''' prompt = prompt_first if media_num: msg = _("Please insert media labeled %s #%d.") % (media_name, media_num) else: msg = _("Please insert media labeled %s.") % (media_name,) while(1): # breaks if the user cancels it or if we found the needed media if prompt: rc = okCancelDialog(self.frontend.window, msg) if not rc: return None mp = self._get_mount_point(media_id, media_num) if mp: return mp prompt = True
def run(self): ''' run the dialog ''' self.hidden = (self.progress.progress_hidden, self.progress.task_hidden) self.progress.set_header(_("Transaction Result")) self.progress.show_extra() self.view.expand_all() self._active = True self.confirmation = None while self.confirmation == None: doGtkEvents() time.sleep(0.01) return self.confirmation
def process_transaction(self): ''' Process the packages and groups in the queue ''' progress = self.frontend.get_progress() progress.set_header(_("Resolving Dependencies")) progress.tasks.reset() progress.tasks.run_current() rc, msgs, trans, size = self.backend.build_transaction() if rc == 2: self.frontend.debug('Dependency resolving completed without error') progress.show(force=True) if self.frontend.confirm_transaction(trans, size[0]): # Let the user confirm the transaction progress.show() rc = self.backend.run_transaction() progress.tasks.complete_current() progress.tasks.set_extra_label('run-trans', "") return rc else: # Aborted by User return None else: progress.hide() title = _("Dependency Resolution Failed") text = _("Dependency Resolution Failed") longtext = _("Dependency Resolution Errors:") longtext += '\n\n' for msg in msgs: longtext += msg # Show error dialog dialog = ErrorDialog(self.frontend.ui, self.frontend.window, title, text, longtext, modal=True) dialog.run() dialog.destroy() # Write errors to output page self.frontend.error(_('Dependency resolving completed with errors')) for msg in msgs: self.frontend.error(" %s" % msg) return False
def lock_msg(self, state, additional): additional = unpack(additional) progress = self.frontend.get_progress() if state == 'try-lock': progress.set_header(_("Yum is locked: waiting for release")+"\n"+ additional[1]) progress.set_pulse(True) self.lock_is_progress_active = progress.is_active() if not self.lock_is_progress_active: progress.show() elif state == 'got-lock': if not self.lock_is_progress_active: progress.hide()
def yum_state(self, state): ''' @param state: ''' progress = self.frontend.get_progress() if state == 'download': progress.set_header(_("Downloading Packages")) progress.tasks.next() progress.set_pulse(False) elif state == 'gpg-check': progress.set_pulse(True) progress.show_cancel(False) # Don't allow Cancel any more progress.set_header(_("Checking Package GPG Signatures")) progress.tasks.set_extra_label('download', "") progress.tasks.next() elif state == 'test-transaction': progress.set_pulse(True) progress.set_header(_("Running RPM Test Transaction")) progress.tasks.next('gpg-check') elif state == 'transaction': progress.set_pulse(False) progress.set_header(_("Running RPM Transaction")) progress.tasks.next()
def populate(self, pkglist, dnl_size): ''' Populate the TreeView with data @param pkglist: list containing view data ''' model = self.store self.store.clear() for sub, lvl1 in pkglist: label = "<b>%s</b>" % sub level1 = model.append(None, [label, "", "", "", ""]) for name, arch, ver, repo, size, replaces in lvl1: level2 = model.append(level1, [name, arch, ver, repo, size]) for r in replaces: model.append(level2, [ r, "", "", "", ""]) self.ui.transactionLabel.set_text(_("Download Size : %s ") % dnl_size) self.view.expand_all
def setup_advanced(self): ''' setup the advanced options ''' vbox = self.ui.prefAdvVBox self._add_option(PrefBoolean, vbox, 'debug', _('Debug Mode')) self._add_option(PrefBoolean, vbox, 'disable_netcheck', _('Disable startup network check')) self._add_option(PrefBoolean, vbox, 'use_sudo', _('Run backend with sudo (need working sudo nopasswd config)')) self._add_option(PrefStr, vbox, 'color_install', _('Color (Installed)')) self._add_option(PrefStr, vbox, 'color_update', _('Color (Update)')) self._add_option(PrefStr, vbox, 'color_normal', _('Color (Available)')) vbox.show_all()