From c01b9bc9960b63f5ee300ad00a1764199166ab8f Mon Sep 17 00:00:00 2001 From: Fabio Erculiani Date: Sat, 2 May 2009 17:05:42 +0200 Subject: [PATCH] entropy notification applet: port to the new dbus-based service. --- .../gfx/applet/applet-disconnect.png | Bin 976 -> 0 bytes entropy-notification-applet/src/applet.py | 20 +- entropy-notification-applet/src/etp_applet.py | 788 ++++++------------ .../src/etp_applet_animation.py | 111 --- ...et_dialogs.py => etp_applet_components.py} | 267 +++--- .../src/etp_applet_config.py | 11 +- 6 files changed, 387 insertions(+), 810 deletions(-) delete mode 100644 entropy-notification-applet/gfx/applet/applet-disconnect.png delete mode 100644 entropy-notification-applet/src/etp_applet_animation.py rename entropy-notification-applet/src/{etp_applet_dialogs.py => etp_applet_components.py} (52%) diff --git a/entropy-notification-applet/gfx/applet/applet-disconnect.png b/entropy-notification-applet/gfx/applet/applet-disconnect.png deleted file mode 100644 index d36ce29cc71c54b554acef48fcf504f655b99641..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 976 zcmV;>126oEP)Dy` zV<#X}bY*F7WpXDo?^pl;0~JX`K~y-)m6Ts-Q&$+ke<%0enq<{c6Dt^6m6B3h?bdc3 ztc>|JDZNY(hKiAj3f^tMT` zx3)=Z?mcG@Nkh9a~H}z;UXNq3H`wdv{U_25k@B^AS8_wwPB2)bnf;OyLqeV`3K{bXPbxLT$1lan<5@+%F&AmM|D z@YUCYlq}555PkTNsed0`8HV5bz|^Z&N-0K9pQf{;gT}5d9Mi;o{v0JG{@PkTK6Z@l zqocf>w*DN3F1=c%KAITCr$a+$C(C1FD91rbiBt-e%c0U~LhbFOh7jsn#e){S4yOmNY^di7YZyV671>j_G@rT2QUl+ zfZ62KJB!4{xV^s0m zC?(5#mf~@|jg4h1hHl>(>96E)Lts00G>YFaNPqDqZxab*p-_aE+Tz)?t*tD*dW9-M%U~h!wzQCpL>48C=m4oy z3IMOyOE#NbbJDuHx?+#dp5@uSdrVFw+11lSJ`zD@GDsoNf%s" % (upd_len,), + _("updates available"), + ), + urgency = "critical" + ) + else: + # all fine, no updates + self.update_tooltip(_("Your Sabayon is up-to-date")) + self.set_state("OKAY") + self.show_alert(_("Your Sabayon is up-to-date"), + _("No updates available at this time, cool!") + ) + + def do_first_check(self): + + def _do_check(): + self.send_check_updates_signal() + return False + + if self._dbus_service_available: + # after 20 seconds + gobject.timeout_add(10000, _do_check) + + def send_check_updates_signal(self, widget=None): + + # enable applet if disabled + skip_tc = False + if not etp_applet_config.settings['APPLET_ENABLED']: + self.enable_applet(do_check = False) + skip_tc = True + + # avoid flooding + cur_t = time.time() + if ((cur_t - self.last_trigger_check_t) < 15) and (not skip_tc): + # ignore + return + self.last_trigger_check_t = cur_t + + if self._dbus_service_available: + iface = dbus.Interface( + self.__entropy_dbus_object, dbus_interface="org.entropy.Client") + iface.trigger_check() + + def close_service(self): + if self._dbus_service_available: + iface = dbus.Interface( + self.__entropy_dbus_object, dbus_interface="org.entropy.Client") + iface.close_connection() + entropyTools.kill_threads() + + def unblink_icon_after_secs(self, secs): + def do_unblink(): + self.status_icon.set_blinking(False) + gobject.timeout_add(secs*1000, do_unblink) + + def set_state(self, new_state, use_busy_icon = 0): + + if not new_state in etp_applet_config.APPLET_STATES: + raise IncorrectParameter("Error: invalid state %s" % new_state) + + self.status_icon.set_blinking(False) + if new_state == "OKAY": + self.change_icon("okay") + elif new_state == "BUSY": + if use_busy_icon: + self.set_displayed_image("busy") + elif new_state == "CRITICAL": + self.status_icon.set_blinking(True) + self.unblink_icon_after_secs(10) + if self.never_viewed_notices: + self.change_icon("critical") + else: + self.set_displayed_image("critical") + elif new_state == "DISABLE": + self.change_icon("disable") + elif new_state == "ERROR": + self.change_icon("error") + self.current_state = new_state def set_menu_image(self, widget, name): img = gtk.Image() @@ -322,30 +368,13 @@ class EntropyApplet: img.set_from_pixbuf(pix) widget.set_image(img) - def enable_refresh_timer(self, when = etp_applet_config.settings['REFRESH_INTERVAL'] * 1000): - if self.current_state in [ "CRITICAL" ]: return - if not self.refresh_timeout_tag: - self.refresh_timeout_tag = TimeScheduled(when/1000, self.refresh_handler) - self.refresh_timeout_tag.set_delay_before(True) - self.refresh_timeout_tag.start() - - def disable_refresh_timer(self): - if self.refresh_timeout_tag: - self.refresh_timeout_tag.kill() - self.refresh_timeout_tag = None - - def start_working(self): - self.isWorking = True - - def end_working(self): - self.isWorking = False - def change_icon(self, image): to_image = self.icons.best_match(image, self.applet_size) self.status_icon.set_from_pixbuf(to_image) def set_displayed_image(self, image): - if isinstance(image,basestring): new_image = self.icons.best_match(image, self.applet_size) + if isinstance(image,basestring): + new_image = self.icons.best_match(image, self.applet_size) else: new_image = image self.current_image = new_image self.redraw() @@ -357,60 +386,52 @@ class EntropyApplet: def load_packages_url(self, *data): try: - gnome.url_show("http://packages.sabayonlinux.org/") + gnome.url_show("http://www.sabayon.org/packages") except gobject.GError: - self.load_browser("http://packages.sabayonlinux.org/") + self.load_url("http://www.sabayon.org/packages") def load_website(self, *data): try: - gnome.url_show("http://www.sabayonlinux.org/") + gnome.url_show("http://www.sabayon.org/") except gobject.GError: - self.load_browser("http://www.sabayonlinux.org/") + self.load_url("http://www.sabayon.org/") - def load_browser(self, url): - browser = None - konq_ret = subprocess.call("which konqueror &> /dev/null", shell = True) - if os.access("/usr/bin/firefox",os.X_OK): - browser = "/usr/bin/firefox" - elif konq_ret: - browser = "konqueror" - elif os.access("/usr/bin/opera",os.X_OK): - browser = "/usr/bin/opera" - if browser: - subprocess.call([browser,url]) + def load_url(self, url): + subprocess.call(['xdg-open',url]) def disable_applet(self, *args): self.update_tooltip(_("Updates Notification Applet Disabled")) - self.disable_refresh_timer() self.set_state("DISABLE") etp_applet_config.settings['APPLET_ENABLED'] = 0 etp_applet_config.save_settings(etp_applet_config.settings) self.menu_items['disable_applet'].hide() self.menu_items['enable_applet'].show() - def enable_applet(self, init = False): + def enable_applet(self, w = None, do_check = True): + if not self._dbus_service_available: + self.show_service_not_available() + return self.update_tooltip(_("Updates Notification Applet Enabled")) - if not init: - self.enable_refresh_timer() self.set_state("OKAY") etp_applet_config.settings['APPLET_ENABLED'] = 1 etp_applet_config.save_settings(etp_applet_config.settings) self.menu_items['disable_applet'].show() self.menu_items['enable_applet'].hide() + if self._dbus_service_available and do_check: + self.send_check_updates_signal() def launch_package_manager(self, *data): - def spawn_spritz(): os.execv('/usr/bin/spritz', ['spritz']) - - t = ParallelTask(spawn_spritz) - t.start() + pid = os.fork() + if pid == 0: + spawn_spritz() + os._exit(0) def show_alert(self, title, text, urgency = None): if (title,text) == self.last_alert: return - pynotify.init("XY") n = pynotify.Notification(title, text) if urgency == 'critical': @@ -421,246 +442,12 @@ class EntropyApplet: n.attach_to_status_icon(self.status_icon) n.show() - def compare_repositories_status(self): - repos = {} - - try: - repoConn = self.Entropy.Repositories(noEquoCheck = True, fetchSecurity = False) - except MissingParameter: - return repos,1 # no repositories specified - except OnlineMirrorError: - return repos,2 # not connected ?? - except Exception, e: - return repos,str(e) # unknown error - - # now get remote - for repoid in self.Entropy.SystemSettings['repositories']['available']: - if repoConn.is_repository_updatable(repoid): - self.Entropy.repository_move_clear_cache(repoid) - repos[repoid] = {} - repos[repoid]['local_revision'] = self.Entropy.get_repository_revision(repoid) - repos[repoid]['remote_revision'] = repoConn.get_online_repository_revision(repoid) - - del repoConn - - return repos, 0 - - def refresh_handler(self, force = 0, after = 0): - if after: time.sleep(after) - self.refresh(force) - - def refresh(self, force = 0): - - if not self.Entropy: - if self.debug: print "refresh: Entropy interface not loaded" - return - if not etp_applet_config.settings['APPLET_ENABLED']: - if self.debug: print "refresh: applet not enabled" - return - if self.debug: print "refresh: all fine, getting lock and running run_refresh" - - self.refresh_lock.acquire() - try: - t = ParallelTask(self.run_refresh, force) - t.start() - while t.isAlive(): - self.status_icon.set_visible(True) - self.task_queue_executor() - time.sleep(0.3) - return t.get_rc() - finally: - self.refresh_lock.release() - - - def run_refresh(self, force): - - locked = self.Entropy.application_lock_check(silent = True) - - if self.debug: print "run_refresh: I am here" - - self.start_working() - old_tip = self.tooltip_text - old_state = self.current_state - - self.disable_network_timer() - self.set_state("BUSY", use_busy_icon = force) - self.update_tooltip(_("Checking for updates...")) - - self.last_error = None - self.last_error_is_network_error = 0 - self.error_threshold = 0 - self.available_packages = [] - - rc = 0 - if not locked: - - # compare repos - if self.debug: print "run_refresh: launching compare_repositories_status" - repositories_to_update, rc = self.compare_repositories_status() - if self.debug: print "run_refresh: completed compare_repositories_status: %s" % ((repositories_to_update, rc),) - - if repositories_to_update and rc == 0: - repos = repositories_to_update.keys() - - if self.debug: print "run_refresh: loading repository interface" - try: - repoConn = self.Entropy.Repositories(repos, fetchSecurity = False, noEquoCheck = True) - if self.debug: print "run_refresh: repository interface loaded" - except MissingParameter, e: - self.last_error = "%s: %s" % (_("No repositories specified in"),etpConst['repositoriesconf'],) - self.error_threshold += 1 - if self.debug: print "run_refresh: MissingParameter exception, error: %s" % (e,) - except OnlineMirrorError, e: - self.last_error = _("Repository Network Error") - self.last_error_is_network_error = 1 - if self.debug: print "run_refresh: OnlineMirrorError exception, error: %s" % (e,) - except Exception, e: - self.error_threshold += 1 - self.last_error_is_exception = 1 - self.last_error = "%s: %s" % (_('Unhandled exception'),e,) - if self.debug: print "run_refresh: Unhandled exception, error: %s" % (e,) - else: - # -128: sync error, something bad happened - # -2: repositories not available (all) - # -1: not able to update all the repositories - if self.debug: print "run_refresh: preparing to run sync" - rc = repoConn.sync() - rc = rc*-1 - del repoConn - if self.debug: print "run_refresh: sync done" - if self.debug: print "run_refresh: sync closed, rc: %s" % (rc,) - - if rc == 1: - err = _("No repositories specified. Cannot check for package updates.") - self.show_alert( _("Updates: attention"), err ) - self.error_threshold += 1 - self.last_error = err - elif rc == 2: - err = _("Cannot connect to the Updates Service, you're probably not connected to the world.") - self.show_alert( _("Updates: connection issues"), err ) - self.last_error_is_network_error = 1 - self.last_error = err - elif rc == -1: - err = _("Not all the repositories have been fetched for checking") - self.show_alert( _("Updates: repository issues"), err ) - self.last_error_is_network_error = 1 - self.last_error = err - elif rc == -2: - err = _("No repositories found online") - self.show_alert( _("Updates: repository issues"), err ) - self.last_error_is_network_error = 1 - self.last_error = err - elif rc == -128: - err = _("Synchronization errors. Cannot update repositories. Check logs.") - self.show_alert( _("Updates: sync issues"), err ) - self.error_threshold += 1 - self.last_error = err - elif isinstance(rc,basestring): - self.show_alert( _("Updates: unhandled error"), rc ) - self.error_threshold += 1 - self.last_error_is_exception = 1 - self.last_error = rc - - if self.last_error_is_network_error: - self.update_tooltip(_("Updates: connection issues")) - self.set_state("DISCONNECTED") - self.end_working() - return False - - try: - update, remove, fine = self.Entropy.calculate_world_updates() - del fine, remove - except Exception, e: - msg = "%s: %s" % (_("Updates: error"),e,) - self.show_alert(_("Updates: error"), msg) - self.error_threshold += 1 - self.last_error_is_exception = 1 - self.last_error = str(e) - - if self.last_error: - self.disable_refresh_timer() - msg = "%s: %s" % (_("Updates issue:"),self.last_error,) - self.update_tooltip(msg) - self.set_state("ERROR") - self.end_working() - return False - - if rc == 0: - self.update_tooltip(old_tip) - - if update: - self.available_packages = update[:] - self.set_state("CRITICAL") - msg = "%s %d %s" % (_("There are"),len(update),_("updates available."),) - self.update_tooltip(msg) - self.show_alert( _("Updates available"), - msg, - urgency = 'critical' - ) - if self.notice_window: - self.refresh_notice_window() - - else: - self.set_state(old_state) - self.update_tooltip(_("So far, so good. w00t!")) - self.show_alert( _("Everything up-to-date"), - _("So far, so good. w00t!"), - urgency = 'low' - ) - - self.end_working() - return True - - def is_network_error(self, msg): - if msg.find("SysCallError") >= 0 and msg.find("104") >= 0: - return 1 - if msg.find("onnection") >= 0: - return 1 - if msg.find("etwork") >= 0: - return 1 - if msg.find("certificate verify failed") >= 0: - return 0 - if msg.find("SSL") >= 0: - return 1 - return 0 - - def network_retry_handler(self, force): - self.refresh(force) - - def enable_network_timer(self, when = etp_applet_config.settings['NETWORK_RETRY_INTERVAL'] * 1000, force = 0): - if self.current_state != "DISCONNECTED": return - if not self.network_timeout_tag: - self.network_timeout_tag = TimeScheduled(when/1000, self.network_retry_handler, force = force) - self.network_timeout_tag.set_delay_before(True) - self.network_timeout_tag.start() - - def disable_network_timer(self): - if self.network_timeout_tag: - self.network_timeout_tag.kill() - self.network_timeout_tag = None - def update_tooltip(self, tip): self.tooltip_text = tip - def _update_tooltip(tip): - self.status_icon.set_tooltip(tip) - if self.debug: print "queued:",_update_tooltip - self.TaskQueue.append((_update_tooltip,[tip],{},)) - - def update_from_server(self, widget=None): - self.enable_applet() - self.refresh(force = 1) - - def user_consented(self): - self.consent = 1 - - def notice_window_closed(self): - self.notice_window = None + self.status_icon.set_tooltip(tip) def exit_applet(self, *args): - - entropyTools.kill_threads() - self.TaskQueueAlive = False - + self.close_service() gtk.main_quit() raise SystemExit(0) @@ -668,110 +455,91 @@ class EntropyApplet: if self.session: self.session.set_clone_command(1, ["/usr/bin/entropy-update-applet"]) self.session.set_restart_command(1, ["/usr/bin/entropy-update-applet"]) - return True def about(self, *data): if self.about_window: return - self.about_window = rhnAppletAboutWindow(self) + self.about_window = AppletAboutWindow(self) def about_dialog_closed(self): self.about_window = None - def rhnreg_dialog_closed(self): - self.rhnreg_dialog = None + def notice_window_closed(self): + self.notice_window = None def error_dialog_closed(self): self.error_dialog = None self.last_error = None - self.last_error_is_exception = 0 - self.last_error_is_network_error = 0 self.set_state("OKAY") self.update_tooltip(_("Waiting before checkin...")) - self.enable_refresh_timer() def applet_face_click(self, icon, button, activate_time): - if button == 3: self.menu.popup(None, None, None, 0, activate_time) return def applet_face_click2(self, icon): - if not self.current_state in [ "OKAY", "ERROR", "DISCONNECTED", "CRITICAL" ]: + if not self.current_state in [ "OKAY", "ERROR", "CRITICAL" ]: return if self.last_error: if self.error_dialog: return - if self.last_error_is_exception: - self.error_dialog = rhnAppletExceptionDialog(self, self.last_error) - else: - self.error_dialog = rhnAppletErrorDialog(self, self.last_error) + self.error_dialog = AppletErrorDialog(self, self.last_error) return self.never_viewed_notices = 0 - if self.notice_window and not self.rhnreg_dialog: + if self.notice_window: self.notice_window.close_window() return if not self.notice_window: - self.notice_window = rhnAppletNoticeWindow(self) + self.notice_window = AppletNoticeWindow(self) self.refresh_notice_window() - if self.rhnreg_dialog: - self.rhnreg_dialog.set_transient(self.notice_window) - self.rhnreg_dialog.raise_() - def refresh_notice_window(self): - self.notice_window.clear_window() - if not self.available_packages: + self.notice_window.clear_window() + if not self.package_updates: return - names = {} - entropy_data = {} - for pkg in self.available_packages: - dbconn = self.Entropy.open_repository(pkg[1]) - atom = dbconn.retrieveAtom(pkg[0]) - avail = dbconn.retrieveVersion(pkg[0]) - avail_rev = dbconn.retrieveRevision(pkg[0]) - key, slot = dbconn.retrieveKeySlot(pkg[0]) - installed_match = self.Entropy.clientDbconn.atomMatch(key, matchSlot = slot) + entropy_ver = None + packages = [] + for atom in self.package_updates: + + key = entropyTools.dep_getkey(atom) + avail_rev = entropyTools.dep_get_entropy_revision(atom) + avail_tag = entropyTools.dep_gettag(atom) + my_pkg = entropyTools.remove_entropy_revision(atom) + my_pkg = entropyTools.remove_tag(my_pkg) + pkgcat, pkgname, pkgver, pkgrev = entropyTools.catpkgsplit(my_pkg) + ver = pkgver + if pkgrev != "r0": + ver += "-%s" % (pkgrev,) + if avail_tag: + ver += "#%s" % (avail_tag,) + if avail_rev: + ver += "~%s" % (avail_tag,) - if installed_match[0] != -1: - installed = self.Entropy.clientDbconn.retrieveVersion(installed_match[0]) - installed_rev = self.Entropy.clientDbconn.retrieveRevision(installed_match[0]) - else: - installed = _("Not installed") if key == "sys-apps/entropy": - entropy_data['avail'] = avail+"~"+str(avail_rev)[:] - entropy_data['installed'] = installed+"~"+str(installed_rev) + entropy_ver = ver - names[atom] = {} - names[atom]['installed'] = installed+"~"+str(installed_rev) - names[atom]['avail'] = avail+"~"+str(avail_rev) + packages.append((key, ver,)) - ordered_names = names.keys() - ordered_names.sort() - for name in ordered_names: - self.notice_window.add_package( name, - names[name]['installed'], - names[name]['avail'] - ) + self.notice_window.fill(packages) critical_text = [] - if entropy_data.has_key("avail"): - msg = "%s sys-apps/entropy %s %s, %s %s. %s." % ( - _("Your system currently has"), - entropy_data['installed'], - _("installed"), - _("but the latest available version is"), - entropy_data['avail'], - _("It is recommended that you upgrade to the latest before updating any other packages") + if entropy_ver != None: + msg = "%s sys-apps/entropy %s, %s %s. %s." % ( + _("Your system currently has an outdated version of"), + _("installed"), + _("the latest available version is"), + entropy_ver, + _("It is recommended that you upgrade to the latest before updating any other packages") ) critical_text.append(msg) diff --git a/entropy-notification-applet/src/etp_applet_animation.py b/entropy-notification-applet/src/etp_applet_animation.py deleted file mode 100644 index e336dc39b..000000000 --- a/entropy-notification-applet/src/etp_applet_animation.py +++ /dev/null @@ -1,111 +0,0 @@ -# This file is a portion of the Red Hat Network Panel Applet -# -# Copyright (C) 1999-2002 Red Hat, Inc. All Rights Reserved. -# Distributed under GPL version 2. -# -# Author: Chip Turner -# -# def help added by Tammy Fox -# -# $Id: rhn_applet_animation.py,v 1.3 2002/09/02 22:26:11 cturner Exp $ - -import gtk -import gtk.gdk -import math -import os -from spritz_setup import const - -class rhnAppletIconPixbuf: - def __init__(self): - self.images = {} - def add_file(self, name, filename): - if not self.images.has_key(name): - self.images[name] = [] - - filepath = const.PIXMAPS_PATH + "/applet/" + filename - if not os.path.isfile(filepath): - filename = "../gfx/applet/" + filename - else: - filename = filepath - - if not os.access(filename, os.R_OK): - raise Exception,"Cannot open image file %s" % filename - - pixbuf = gtk.gdk.pixbuf_new_from_file(filename) - - self.add(name, pixbuf) - def add(self, name, pixbuf): - self.images[name].append(pixbuf) - - # find image closest to the requested size. will be scaled later... - def best_match(self, name, size): - best = None - - for image in self.images[name]: - if not best: - best = image - continue - if abs(size - image.height) < abs(size - best.height): - best = image - - return best - -class rhnAppletAnimation: - def __init__(self): - self.frames = [] - self.cycle_frames = [] - - self.frame = 0 - self.direction = 1 - - # final frame is a PUBLIC DATA MEMBER... yeah, naughty - self.final_frame = None - - def append_frames(self, frames): - self.frames = self.frames + frames - self.final_frame = self.frames[-1] - - def append_cycle(self, frames): - self.cycle_frames = self.cycle_frames + frames - - def next_frame(self): - if len(self.frames): - return self.frames.pop(0) - - if len(self.cycle_frames): - ret = self.cycle_frames[self.frame] - self.frame = self.frame + self.direction - - if self.frame < 0 or self.frame >= len(self.cycle_frames): - # oops, we moved too far. change direction, undo last move - self.direction = -self.direction - self.frame = self.frame + self.direction - - return ret - - return None - -def alpha_tween(start_image, end_image, steps): - tmp = start_image.copy() - - frames = [ start_image ] - stepsize = 256/steps - - for i in range(2, steps): - buf = tmp.copy() - - end_image.composite(buf, - # dest x, y, w, h - 0, 0, buf.get_width(), buf.get_height(), - # ofset x, y - 0, 0, - # scale factor x, y - 1.0, 1.0, - gtk.gdk.INTERP_BILINEAR, - i * stepsize - 1) - - frames.append(buf) - - frames.append(end_image) - - return frames diff --git a/entropy-notification-applet/src/etp_applet_dialogs.py b/entropy-notification-applet/src/etp_applet_components.py similarity index 52% rename from entropy-notification-applet/src/etp_applet_dialogs.py rename to entropy-notification-applet/src/etp_applet_components.py index c873129fc..40ecb91f1 100644 --- a/entropy-notification-applet/src/etp_applet_dialogs.py +++ b/entropy-notification-applet/src/etp_applet_components.py @@ -1,11 +1,25 @@ -# This file is a portion of the Red Hat Network Panel Applet -# -# Copyright (C) 1999-2002 Red Hat, Inc. All Rights Reserved. -# Distributed under GPL version 2. -# -# Author: Chip Turner -# -# $Id: rhn_applet_dialogs.py,v 1.30 2003/10/14 17:41:34 veillard Exp $ +# -*- coding: utf-8 -*- +""" + # DESCRIPTION: + # Entropy updates Notification Applet + + Copyright (C) 2007-2009 Fabio Erculiani + Forking RHN Applet + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +""" import os import gnome @@ -20,7 +34,8 @@ from entropy.i18n import _ from entropy.core import SystemSettings SysSettings = SystemSettings() -class rhnGladeWindow: +class GladeWindow: + def __init__(self, filename, window_name): self.filename = filename if not os.path.isfile(filename): @@ -31,24 +46,28 @@ class rhnGladeWindow: def get_widget(self, widget): return self.xml.get_widget(widget) -class rhnAppletNoticeWindow(rhnGladeWindow): +class AppletNoticeWindow(GladeWindow): + def __init__(self, parent): - rhnGladeWindow.__init__(self, "etp_applet.glade", "notice_window_2") + GladeWindow.__init__(self, "etp_applet.glade", "notice_window_2") self.parent = parent self.window.connect('delete_event', self.close_window) self.package_list = self.get_widget('update_clist') - self.package_list.append_column(gtk.TreeViewColumn(_("Package Name"), gtk.CellRendererText(), text=0)) - self.package_list.append_column(gtk.TreeViewColumn(_("Version Installed"), gtk.CellRendererText(), text=1)) - self.package_list.append_column(gtk.TreeViewColumn(_("Available"), gtk.CellRendererText(), text=2)) + self.package_list.append_column( + gtk.TreeViewColumn( + _("Application"), gtk.CellRendererText(), text=0)) + self.package_list.append_column( + gtk.TreeViewColumn(_("Latest version"), gtk.CellRendererText(), text=1)) self.package_list.get_selection().set_mode(gtk.SELECTION_NONE) self.notebook = self.get_widget('notice_notebook') self.critical_tab = None self.critical_tab_contents = None - self.package_list_model = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING) + self.package_list_model = gtk.ListStore(gobject.TYPE_STRING, + gobject.TYPE_STRING) self.package_list.set_model(self.package_list_model) self.xml.signal_autoconnect ( @@ -74,6 +93,7 @@ class rhnAppletNoticeWindow(rhnGladeWindow): print "url: %s" % url def set_critical(self, text, critical_active): + if not self.critical_tab_contents: html_view = gtkhtml2.View() self.html_view = html_view @@ -94,8 +114,9 @@ class rhnAppletNoticeWindow(rhnGladeWindow): self.critical_tab_contents = sw if critical_active: - self.notebook.set_current_page(self.notebook.page_num(self.critical_tab_contents)) - + self.notebook.set_current_page( + self.notebook.page_num(self.critical_tab_contents)) + self.set_critical_tab_text(text) else: if self.critical_tab_text != text: @@ -107,7 +128,8 @@ class rhnAppletNoticeWindow(rhnGladeWindow): self.html_doc.clear() self.html_doc.connect('link_clicked', self.on_link_clicked) self.html_doc.open_stream("text/html") - self.html_doc.write_stream('' + text) + self.html_doc.write_stream( + '' + text) self.html_doc.close_stream() self.html_view.set_document(self.html_doc) @@ -115,53 +137,24 @@ class rhnAppletNoticeWindow(rhnGladeWindow): if not self.critical_tab_contents: return - self.notebook.remove_page(self.notebook.page_num(self.critical_tab_contents)) + self.notebook.remove_page( + self.notebook.page_num(self.critical_tab_contents)) - def add_package(self, name, installed, avail): - myiter = self.package_list_model.append() - self.package_list_model.set_value(myiter, 0, name) - self.package_list_model.set_value(myiter, 1, installed) - self.package_list_model.set_value(myiter, 2, avail) + def fill(self, pkg_data): + self.package_list_model.clear() + for name, avail in pkg_data: + self.package_list_model.append((name, avail,)) -class rhnRegistrationPromptDialog(rhnGladeWindow): - def __init__(self, parent): - rhnGladeWindow.__init__(self, "etp_applet.glade", "need_to_register_dialog") - - self.parent = parent - self.window.connect('delete_event', self.close_dialog) - self.xml.signal_autoconnect ( - { - "on_launch_rhnreg_clicked" : self.on_rhnreg, - "on_close_clicked" : self.on_close, - }) - - def raise_(self): - self.window.window.raise_() - - def set_transient(self, papa): - self.window.set_transient_for(papa.window) - - def on_rhnreg(self, button): - self.parent.launch_rhnreg() - self.close_dialog() - - def close_dialog(self, *rest): - self.window.destroy() - self.parent.rhnreg_dialog_closed() - - def on_close(self, close_button): - self.close_dialog() - -class rhnAppletAboutWindow: +class AppletAboutWindow: def __init__(self, parent): self.window = gnome.ui.About("%s Updates Applet" % ( SysSettings['system']['name'], ), etpConst['entropyversion'], "Copyright (C) 2009, Sabayon Linux", - "Sabayon Linux. What else?", - [ "Sabayon Linux Team", "devel@sabayonlinux.org" ]) + "Sabayon, what else?", + [ "Sabayon Linux", "sabayon@sabayonlinux.org" ]) self.window.connect("destroy", self.on_close) self.parent = parent self.window.show() @@ -172,122 +165,11 @@ class rhnAppletAboutWindow: def on_close(self, *data): self.close_dialog() -class rhnAppletFirstTimeDruid(rhnGladeWindow): - def __init__(self, parent, proxy_url, proxy_username, proxy_password): - rhnGladeWindow.__init__(self, "etp_applet.glade", "first_time_druid") - - self.parent = parent - self.window.connect('delete_event', self.close_dialog) - self.xml.signal_autoconnect ( - { - "on_cancel" : self.on_cancel, - "on_remove_from_panel" : self.on_remove_from_panel, - "on_finish" : self.on_finish, - }) - - color = gtk.gdk.color_parse("#cc0000") - page = self.xml.get_widget("druidpagestart1") - page.set_bg_color(color) - page = self.xml.get_widget("druidpagefinish1") - page.set_bg_color(color) - - html_sw = self.get_widget("tos_window") - self.tos_document = gtkhtml2.Document() - self.tos_view = gtkhtml2.View() - html_sw.add(self.tos_view) - self.tos_view.show() - html_sw.show() - self.tos_document.clear() - self.tos_document.connect('link_clicked', self.on_link_clicked) - self.tos_document.open_stream("text/html") - - self.tos_document.close_stream() - self.tos_view.set_document(self.tos_document) - - self.enable_proxy = self.get_widget("enable_proxy_check") - self.enable_proxy.connect("toggled", self.on_enable_proxy_toggle) - - self.enable_auth = self.get_widget("use_auth_check") - self.enable_auth.connect("toggled", self.on_use_auth_toggle) - - self.proxy_entry = self.get_widget("proxy_entry") - self.username_entry = self.get_widget("username_entry") - self.password_entry = self.get_widget("password_entry") - self.username_entry_label = self.get_widget("username_entry_label") - self.password_entry_label = self.get_widget("password_entry_label") - - self.use_auth = 0 - self.use_proxy = 0 - - self.proxy_entry.set_text(proxy_url) - if proxy_url: - self.use_proxy = 1 - self.enable_proxy.set_sensitive(gtk.TRUE) - self.enable_proxy.activate() - - if proxy_username: - self.use_auth = 1 - self.username_entry.set_text(proxy_username) - self.password_entry.set_text(proxy_password) - self.enable_auth.set_sensitive(gtk.TRUE) - self.enable_auth.activate() - self.window.show_all() - - def on_link_clicked(self, html, url): - gnome.url_show(url) - - def on_enable_proxy_toggle(self, button): - state = button.get_active() - self.use_proxy = state - - self.get_widget("proxy_entry").set_sensitive(state) - self.enable_auth.set_sensitive(state) - - if self.use_auth: - self.username_entry.set_sensitive(state) - self.username_entry_label.set_sensitive(state) - self.password_entry.set_sensitive(state) - self.password_entry_label.set_sensitive(state) - - def on_use_auth_toggle(self, button): - state = button.get_active() - self.use_auth = state - - self.username_entry.set_sensitive(state) - self.username_entry_label.set_sensitive(state) - self.password_entry.set_sensitive(state) - self.password_entry_label.set_sensitive(state) - - def close_dialog(self, *data, **kwarg): - if kwarg.has_key("remove"): - self.parent.first_time_druid_closed(kwarg["remove"]) - else: - self.parent.first_time_druid_closed(0) - self.window.hide() - - def on_cancel(self, cancel_button): - self.close_dialog(remove=0) - - def on_remove_from_panel(self, cancel_button): - self.close_dialog(remove=1) - - def on_finish(self, *data): - if self.use_proxy: - args = [ self.proxy_entry.get_text() ] - if self.use_auth: - args.append(self.username_entry.get_text()) - args.append(self.password_entry.get_text()) - apply(self.parent.set_proxy, args) - else: - self.parent.set_proxy() - - self.parent.user_consented() - self.close_dialog() - -class rhnAppletErrorDialog(rhnGladeWindow): +class AppletErrorDialog(GladeWindow): def __init__(self, parent, error): - rhnGladeWindow.__init__(self) - self.window = gtk.MessageDialog(None, 0, gtk.MESSAGE_WARNING, gtk.BUTTONS_OK, str(error)) + GladeWindow.__init__(self) + self.window = gtk.MessageDialog(None, 0, + gtk.MESSAGE_WARNING, gtk.BUTTONS_OK, str(error)) self.window.set_modal(gtk.TRUE) self.window.connect("close", self.on_close) self.window.connect('response', self.on_close) @@ -355,13 +237,14 @@ class WrappingLabel(gtk.Label): self.ignoreEvents = 0 self.connect("size-allocate", growToParent) -class rhnAppletExceptionDialog: +class AppletExceptionDialog: + def __init__ (self, parent, text): self.parent = parent win = gtk.Dialog("Exception Occured", None) self.window = win win.add_button('gtk-ok', 0) - + mybuf = gtk.TextBuffer(None) mybuf.set_text(text) textbox = gtk.TextView() @@ -396,3 +279,41 @@ class rhnAppletExceptionDialog: def on_close(self, *data): self.close_dialog() + +class AppletIconPixbuf: + + def __init__(self): + self.images = {} + + def add_file(self, name, filename): + + if not self.images.has_key(name): + self.images[name] = [] + from spritz_setup import const + filepath = const.PIXMAPS_PATH + "/applet/" + filename + if not os.path.isfile(filepath): + filename = "../gfx/applet/" + filename + else: + filename = filepath + + if not os.access(filename, os.R_OK): + raise Exception,"Cannot open image file %s" % filename + + pixbuf = gtk.gdk.pixbuf_new_from_file(filename) + + self.add(name, pixbuf) + + def add(self, name, pixbuf): + self.images[name].append(pixbuf) + + def best_match(self, name, size): + best = None + + for image in self.images[name]: + if not best: + best = image + continue + if abs(size - image.height) < abs(size - best.height): + best = image + + return best diff --git a/entropy-notification-applet/src/etp_applet_config.py b/entropy-notification-applet/src/etp_applet_config.py index 0e7df5305..94d15fcaf 100644 --- a/entropy-notification-applet/src/etp_applet_config.py +++ b/entropy-notification-applet/src/etp_applet_config.py @@ -8,8 +8,10 @@ import os import entropy.dump as dumpTools -APPLET_STATES = [ "STARTUP", "NOCONSENT", "CONFIGURING", "OKAY", "CRITICAL", "BUSY", "ERROR", "DISCONNECTED", "DISABLE" ] -APPLET_MENUS = [ "about", "update_now", "web_panel", "web_site", "configure_applet", "check_now" ] +APPLET_STATES = [ "STARTUP", "NOCONSENT", "CONFIGURING", "OKAY", + "CRITICAL", "BUSY", "ERROR", "DISCONNECTED", "DISABLE" ] +APPLET_MENUS = [ "about", "update_now", "web_panel", "web_site", + "configure_applet", "check_now" ] APPLET_SENSITIVE_MENU = { "STARTUP" : [ "" ], @@ -33,7 +35,8 @@ ANIMATION_TOTAL_TIME = 0.75 home = os.getenv("HOME") if not home: home = "/tmp" -SETTINGS_FILE = os.path.join(home, ".config/entropy/entropy-notification-applet.conf") +SETTINGS_FILE = os.path.join(home, + ".config/entropy/entropy-notification-applet.conf") def save_settings(settings): global SETTINGS_FILE @@ -49,8 +52,6 @@ if settings == None: settings = {} myconst = [ - ['REFRESH_INTERVAL',int], - ['NETWORK_RETRY_INTERVAL',int], ['ERROR_THRESHOLD',int], ['ANIMATION_TOTAL_TIME',float], ['APPLET_ENABLED',int],