Exemple #1
0
    def __init__(self):
        logger.info("Starting application.")
        upgrade_manager = UpgradeManager()
        upgrade_manager.check()

        # TODO: Disabled and switched from use of AsyncNotifier on
        # 2007-02-05. Possible problem with pynotify and threading, threading
        # was our decision to disable to get users up and running with a 0.0.6
        # bugfix release. Re-enable once the issue is resolved.
        #gtk.gdk.threads_init()

        # Maintain a map of events that have alert windows open to ensure
        # we don't popup multiple windows for the same event that hasn't
        # been confirmed by the user:
        self.__open_alerts = {}

        self.config = WujaConfiguration(GCONF_PATH)
        self.notifier = None
        self.prefs_dialog = None
        self.calendar_window = None
        self.updating = False
        self.feed_update_event_source = None

        actions = (
            ("calendar", gtk.STOCK_INDEX, "View Calendar", None, None,
                self.__open_calendar),
            ("preferences", gtk.STOCK_PREFERENCES, None, None, None,
                self.__open_preferences_dialog),
            ("update_feeds", gtk.STOCK_REFRESH, "Update Feeds", None, None,
                self.__update_feeds),
            ("debug_feeds", gtk.STOCK_EXECUTE, "Debug Feeds", None, None,
                self.__debug_feeds),
            ("about", gtk.STOCK_ABOUT, None, None, None,
                self.__open_about_dialog),
            ("quit", gtk.STOCK_QUIT, None, None, None, self.destroy))
        action_group = gtk.ActionGroup("wuja_menu")
        action_group.add_actions(actions)

        ui_mgr = gtk.UIManager()
        ui_mgr.add_ui_from_file(find_file_on_path("wuja/data/wuja-menu.xml"))
        ui_mgr.insert_action_group(action_group, 0)

        self.menu = ui_mgr.get_widget("/wuja_menu")
        self.menu.show_all()

        self.tray_icon = trayicon.TrayIcon("wuja")
        self.tray_icon.connect('button_press_event', self.__clicked)

        tray_image = gtk.Image()
        tray_image.set_from_file(
            find_file_on_path("wuja/data/wuja-icon-24x24.png"))

        event_box = gtk.EventBox()
        event_box.add(tray_image)
        self.tray_icon.add(event_box)
        self.tray_icon.show_all()

        self.build_notifier()
Exemple #2
0
 def setUp(self):
     self.config = WujaConfiguration(GCONF_TEST_PATH)
Exemple #3
0
class WujaApplication:

    """ The main Wuja application. """

    def __init__(self):
        logger.info("Starting application.")
        upgrade_manager = UpgradeManager()
        upgrade_manager.check()

        # TODO: Disabled and switched from use of AsyncNotifier on
        # 2007-02-05. Possible problem with pynotify and threading, threading
        # was our decision to disable to get users up and running with a 0.0.6
        # bugfix release. Re-enable once the issue is resolved.
        #gtk.gdk.threads_init()

        # Maintain a map of events that have alert windows open to ensure
        # we don't popup multiple windows for the same event that hasn't
        # been confirmed by the user:
        self.__open_alerts = {}

        self.config = WujaConfiguration(GCONF_PATH)
        self.notifier = None
        self.prefs_dialog = None
        self.calendar_window = None
        self.updating = False
        self.feed_update_event_source = None

        actions = (
            ("calendar", gtk.STOCK_INDEX, "View Calendar", None, None,
                self.__open_calendar),
            ("preferences", gtk.STOCK_PREFERENCES, None, None, None,
                self.__open_preferences_dialog),
            ("update_feeds", gtk.STOCK_REFRESH, "Update Feeds", None, None,
                self.__update_feeds),
            ("debug_feeds", gtk.STOCK_EXECUTE, "Debug Feeds", None, None,
                self.__debug_feeds),
            ("about", gtk.STOCK_ABOUT, None, None, None,
                self.__open_about_dialog),
            ("quit", gtk.STOCK_QUIT, None, None, None, self.destroy))
        action_group = gtk.ActionGroup("wuja_menu")
        action_group.add_actions(actions)

        ui_mgr = gtk.UIManager()
        ui_mgr.add_ui_from_file(find_file_on_path("wuja/data/wuja-menu.xml"))
        ui_mgr.insert_action_group(action_group, 0)

        self.menu = ui_mgr.get_widget("/wuja_menu")
        self.menu.show_all()

        self.tray_icon = trayicon.TrayIcon("wuja")
        self.tray_icon.connect('button_press_event', self.__clicked)

        tray_image = gtk.Image()
        tray_image.set_from_file(
            find_file_on_path("wuja/data/wuja-icon-24x24.png"))

        event_box = gtk.EventBox()
        event_box.add(tray_image)
        self.tray_icon.add(event_box)
        self.tray_icon.show_all()

        self.build_notifier()

    def _reset_feed_update(self):
        """ Restart the feed update timer. """
        self.feed_update_event_source = gobject.timeout_add(
            FEED_UPDATE_INTERVAL * 1000 * 60, self.notifier.update)
        logger.debug("Updating feeds from Google servers every %s minutes."
            % FEED_UPDATE_INTERVAL)

    def __update_feeds(self, widget):
        """
        Pass call to update feeds along to the notifier and reset
        timers.
        """
        gobject.source_remove(self.feed_update_event_source)
        self.notifier.update()
        self._reset_feed_update()

    def __debug_feeds(self, widget):
        """ Print out debug info on all feeds to the log file. """
        logger.info("Calendar Debug Info:")
        for cal in self.notifier.cache.load_all():
            logger.info(cal.title + ":")
            for entry in cal.entries:
                logger.info("   " + entry.get_debug_info())

    def __clicked(self, widget, data):
        """ Handle mouse clicks on the tray icon. (pop up the menu) """
        # 1 = left, 2 = middle, 3 = right:
        self.menu.popup(None, None, None, data.button, data.time)

    def __open_preferences_dialog(self, widget):
        """ Open the preferences dialog. """
        self.prefs_dialog = PreferencesDialog(self.config, self.notifier)

    def __open_calendar(self, widget):
        """ Open the calendar display dialog. """
        self.calendar_window = CalendarWindow(self.notifier.cache, self.config)

    def __close_dialog(self, widget):
        """ Close the preferences dialog. """
        self.prefs_dialog.close()

    def __open_about_dialog(self, widget):
        """ Open the about dialog. """
        glade_file = 'wuja/data/wuja-about.glade'
        glade_xml = gtk.glade.XML(find_file_on_path(glade_file))
        about_dialog = glade_xml.get_widget('WujaAbout')

        signals = {
            'on_WujaAbout_close': self.__close_about_dialog,
        }
        glade_xml.signal_autoconnect(signals)

        about_dialog.show_all()

    def __close_about_dialog(self, widget, response):
        """ Close the about dialog. """
        widget.destroy()

    def build_notifier(self):
        """ Builds the notifier object. """
        self.notifier = Notifier(self.config)
        # register ourselves as an observer
        self.notifier.connect("feeds-updated", self.notify)

        gobject.timeout_add(NOTIFICATION_INTERVAL * 1000 * 60,
            self.notifier.check_for_notifications)
        self.notifier.check_for_notifications()
        logger.debug("Checking for notifications every %s minutes."
            % NOTIFICATION_INTERVAL)

        self._reset_feed_update()

    def delete_event(self, widget, event, data=None):
        """ GTK function. """
        return False

    def destroy(self, widget, data=None):
        """ Quit the application. """
        self.notifier.cache.close()
        gtk.main_quit()

    def notify(self, notifier, event):
        """
        Triggered by the notifier when a notifaction of an event needs to
        go out to the user.
        """
        self.display_notification(None, event)

    def display_notification(self, widget, event):
        """
        Display a notification for an event.

        Check first to see if we already have a notification open.
        """
        # Check if we already have a notification window open for this event:
        if self.__open_alerts.has_key(event.key):
            logger.debug("Alert window already open for event: " + \
                event.entry.title)
            return

        alert_type = self.config.get_alert_type()
        if alert_type == ALERT_NOTIFICATION:
            alert_window = AlertNotification(event, self.tray_icon, self.config)
        else:
            alert_window = AlertDialog(event, self.config)

        alert_window.connect("alert-closed", self.on_alert_closed)
        self.__open_alerts[event.key] = alert_window

    def on_alert_closed(self, alert):
        self.__open_alerts.pop(alert.event.key)

    def main(self):
        """ Launches the GTK main loop. """
        gtk.main()
Exemple #4
0
class WujaConfigurationTests(unittest.TestCase):

    def setUp(self):
        self.config = WujaConfiguration(GCONF_TEST_PATH)

    def tearDown(self):
        # NOTE: Couldn't find a way to actually delete the directory, this just
        # unsets all the properties beneath it.
        client = gconf.client_get_default()
        client.recursive_unset(GCONF_TEST_PATH,
            gconf.UNSET_INCLUDING_SCHEMA_NAMES)

    def test_add_feed_url(self):
        self.config.add_feed_url('url1')
        urls = self.config.get_feed_urls()
        self.assertEqual(1, len(urls))
        self.assertEqual('url1', urls[0])

    def test_add_multiple_feed_urls(self):
        urls = ['url1', 'url2', 'url3']
        for url in urls:
            self.config.add_feed_url(url)
        result_urls = self.config.get_feed_urls()
        self.assertEqual(urls, result_urls)

    def test_remove_feed_url(self):
        urls = ['url1', 'url2', 'url3']
        for url in urls:
            self.config.add_feed_url(url)
        self.config.remove_feed_url(urls[1])
        self.assertEqual([urls[0], urls[2]], self.config.get_feed_urls())

    def test_remove_nonexistent_url(self):
        urls = ['url1', 'url2', 'url3']
        for url in urls:
            self.config.add_feed_url(url)
        self.assertRaises(ValueError, self.config.remove_feed_url,
            'not a real url')

    def test_remove_all_urls(self):
        urls = ['url1', 'url2', 'url3']
        for url in urls:
            self.config.add_feed_url(url)
        self.config.remove_all_feed_urls()
        self.assertEqual(0, len(self.config.get_feed_urls()))

    def test_basic_url_replacement(self):
        """ /basic URLs lack data Wuja needs. """
        urls = ['url1/basic']
        for url in urls:
            self.config.add_feed_url(url)
        lookup_urls = self.config.get_feed_urls()
        self.assertEqual('url1/full', lookup_urls[0])

    def test_ignore_empty_url(self):
        """ Add an emptry string URL and ensure it doesn't get added to
        the configuration.
        """
        self.assertEqual(0, len(self.config.get_feed_urls()))
        self.config.add_feed_url('')
        self.assertEqual(0, len(self.config.get_feed_urls()))

    def test_default_timestamp_format(self):
        """
        If no timestamp is defined in gconf, test that a default
        value is returned.
        """
        self.assertEqual(DEFAULT_TIMESTAMP_FORMAT,
            self.config.get_timestamp_format())

    def test_set_timestamp_format(self):
        client = gconf.client_get_default()
        self.assertEqual(None, client.get_string(os.path.join(GCONF_TEST_PATH,
            "timestamp_format")))
        new_format = "%H:%M"
        self.config.set_timestamp_format(new_format)
        self.assertEqual(new_format, self.config.get_timestamp_format())

    def test_set_reminder(self):
        client = gconf.client_get_default()
        self.assertEqual(None, client.get_string(os.path.join(GCONF_TEST_PATH,
            "default_reminder")))

        # Reminder should default to 10 if the user hasn't set one explicitly:
        self.assertEqual(DEFAULT_REMINDER, self.config.get_reminder())

        self.config.set_reminder(25)
        self.assertEqual(25, self.config.get_reminder())

    def test_set_snooze(self):
        client = gconf.client_get_default()
        self.assertEqual(None, client.get_string(os.path.join(GCONF_TEST_PATH,
            "snooze_mins")))

        # Snooze should default to 10 if the user hasn't set one explicitly:
        self.assertEqual(DEFAULT_SNOOZE, self.config.get_snooze())

        self.config.set_snooze(25)
        self.assertEqual(25, self.config.get_snooze())