diff -u gwibber-0.8/debian/changelog gwibber-0.8/debian/changelog --- gwibber-0.8/debian/changelog +++ gwibber-0.8/debian/changelog @@ -1,3 +1,14 @@ +gwibber (0.8-0ubuntu4) jaunty; urgency=low + + * debian/control: + - Added python-xdg to Depends + * debian/patches/01_add_message_indicator_support.patch + - Backported support for the message indicator from trunk (LP: #361120) + * debian/patches/02_twitter_api_fix.patch + - Backported twitter API fixes from trunk (LP: #358341) + + -- Ken VanDine Tue, 14 Apr 2009 11:21:49 -0400 + gwibber (0.8-0ubuntu3) jaunty; urgency=low * Initial release: 0.8 (as of lp:gwibber/1.0 #239) diff -u gwibber-0.8/debian/control gwibber-0.8/debian/control --- gwibber-0.8/debian/control +++ gwibber-0.8/debian/control @@ -12,5 +12,6 @@ Architecture: all XB-Python-Version: ${python:Versions} -Depends: python-dbus, python-gtk2, python-gconf, python-notify, python-egenix-mxdatetime, python-simplejson, python-cairo, libwebkit-1.0-1, python-webkitgtk, librsvg2-2, librsvg2-common, python-feedparser, python-imaging, python-gnome2-desktop, ${python:Depends}, ${misc:Depends} +Depends: python-dbus, python-gtk2, python-gconf, python-notify, python-egenix-mxdatetime, python-simplejson, python-cairo, libwebkit-1.0-1, python-webkitgtk, librsvg2-2, librsvg2-common, python-feedparser, python-imaging, python-gnome2-desktop, python-xdg, ${python:Depends}, ${misc:Depends} +Recommends: python-indicate Description: Open source microblogging client for GNOME It supports Twitter, Jaiku, Identi.ca, Facebook, and Digg. diff -u gwibber-0.8/debian/rules gwibber-0.8/debian/rules --- gwibber-0.8/debian/rules +++ gwibber-0.8/debian/rules @@ -4,6 +4,7 @@ DEB_PYTHON_SYSTEM=pycentral include /usr/share/cdbs/1/rules/debhelper.mk +include /usr/share/cdbs/1/rules/simple-patchsys.mk include /usr/share/cdbs/1/class/python-distutils.mk DEB_PYTHON_INSTALL_ARGS_ALL += --prefix=/usr only in patch2: unchanged: --- gwibber-0.8.orig/debian/patches/02_twitter_api_fix.patch +++ gwibber-0.8/debian/patches/02_twitter_api_fix.patch @@ -0,0 +1,39 @@ +# +# Ubuntu: https://bugs.launchpad.net/gwibber/+bug/358341 +# Description: Fixes for twitter API changes +# Cherrypicked from lp:gwibber revision 285 +# +diff -r 1c89ca166d16 gwibber/microblog/twitter.py +--- a/gwibber/microblog/twitter.py Tue Apr 14 10:31:02 2009 -0400 ++++ b/gwibber/microblog/twitter.py Tue Apr 14 10:43:30 2009 -0400 +@@ -158,17 +158,18 @@ + + def connect(self, url, data = None): + return urllib2.urlopen(urllib2.Request( +- url, data, {"Authorization": self.get_auth()})).read() ++ url, data, headers = {"Authorization": self.get_auth()})).read() + + def get_messages(self): + return simplejson.loads(self.connect( +- "https://twitter.com/statuses/friends_timeline.json", ++ "https://twitter.com/statuses/friends_timeline.json" +'?'+ + urllib.urlencode({"count": self.account["receive_count"] or "20"}))) + ++ + def get_user_messages(self, screen_name): + try: + return simplejson.loads(self.connect( +- "https://twitter.com/statuses/user_timeline/"+ screen_name + ".json", ++ "https://twitter.com/statuses/user_timeline/"+ screen_name + ".json" +'?'+ + urllib.urlencode({"count": self.account["receive_count"] or "20"}))) + except Exception: + profile = [simplejson.loads(self.connect( +@@ -177,7 +178,7 @@ + + def get_replies(self): + return simplejson.loads(self.connect( +- "https://twitter.com/statuses/replies.json", ++ "https://twitter.com/statuses/replies.json" +'?'+ + urllib.urlencode({"count": self.account["receive_count"] or "20"}))) + + def get_direct_messages(self): only in patch2: unchanged: --- gwibber-0.8.orig/debian/patches/01_add_message_indicator_support.patch +++ gwibber-0.8/debian/patches/01_add_message_indicator_support.patch @@ -0,0 +1,180 @@ +# +# Ubuntu: https://bugs.edge.launchpad.net/ubuntu/+source/gwibber/+bug/361120 +# Description: Backported message indicator changes for 0.8 +# Changes cherrypicked from lp:gwibber revisions 237.4.17, +# 272.1.1, 272.1.2, 272.1.3, 272.1.4, 272.1.5, 273, and 291.1.1 +# +diff -r 26a554c33c10 gwibber/client.py +--- a/gwibber/client.py Tue Apr 14 12:58:11 2009 -0400 ++++ b/gwibber/client.py Tue Apr 14 15:39:29 2009 -0400 +@@ -67,6 +67,12 @@ + for _i in CONFIGURABLE_UI_ELEMENTS.keys(): + DEFAULT_PREFERENCES["show_%s" % _i] = True + ++try: ++ import indicate ++ import wnck ++except: ++ indicate = None ++ + class GwibberClient(gtk.Window): + def __init__(self): + +@@ -81,6 +87,7 @@ + self.last_focus_time = None + self.last_clear = None + self._reply_acct = None ++ self.indicator_items = {} + layout = gtk.VBox() + + gtk.rc_parse_string(""" +@@ -112,6 +119,7 @@ + + self.connect("delete-event", self.on_window_close) + self.connect("focus-out-event", self.on_focus_out) ++ self.connect("focus-in-event", self.on_focus) + + for key, value in DEFAULT_PREFERENCES.items(): + if self.preferences[key] == None: self.preferences[key] = value +@@ -134,7 +142,7 @@ + self.tabs.set_property("homogeneous", False) + self.tabs.set_scrollable(True) + self.messages_view = self.add_msg_tab(self.client.receive, _("Messages"), show_icon = "go-home") +- self.add_msg_tab(self.client.responses, _("Replies"), show_icon = "mail-reply-all") ++ self.add_msg_tab(self.client.responses, _("Replies"), show_icon = "mail-reply-all", add_indicator=True) + + saved_position = config.GCONF.get_list("%s/%s" % (config.GCONF_PREFERENCES_DIR, "saved_position"), config.gconf.VALUE_INT) + if saved_position: +@@ -220,6 +228,13 @@ + dbus_interface="org.freedesktop.Notifications", + signal_name="ActionInvoked") + ++ if indicate: ++ self.indicate = indicate.indicate_server_ref_default() ++ self.indicate.set_type("message.gwibber") ++ self.indicate.set_desktop_file(resources.get_desktop_file()) ++ self.indicate.connect("server-display", self.on_toggle_window_visibility) ++ self.indicate.show() ++ + for i in CONFIGURABLE_UI_ELEMENTS.keys(): + config.GCONF.notify_add(config.GCONF_PREFERENCES_DIR + "/show_%s" % i, + lambda *a: self.apply_ui_element_settings()) +@@ -288,6 +303,12 @@ + entry.insert_text(short, entry.get_position()) + gobject.idle_add(lambda: entry.set_position(entry.get_position() + len(short))) + ++ def on_focus(self, w, change): ++ for key, item in self.indicator_items.items(): ++ #self.indicate.remove_indicator(item) ++ item.hide() ++ self.indicator_items = {} ++ + def on_focus_out(self, widget, event): + if self.last_update: + self.last_focus_time = self.last_update +@@ -352,11 +373,12 @@ + + btn.connect("clicked", self.on_tab_close, scroll) + +- def add_msg_tab(self, data_handler, text, show_close=False, show_icon=None, make_active=False, save=None): ++ def add_msg_tab(self, data_handler, text, show_close=False, show_icon=None, make_active=False, save=None, add_indicator=False): + view = gwui.MessageView(self.preferences["theme"]) + view.link_handler = self.on_link_clicked + view.data_retrieval_handler = data_handler + view.config_retrieval_handler = self.get_account_config ++ view.add_indicator = add_indicator + + self.add_scrolled_parent(view, text, show_close, show_icon, make_active, save) + return view +@@ -366,6 +388,7 @@ + view.link_handler = self.on_link_clicked + view.data_retrieval_handler = data_handler + view.config_retrieval_handler = self.get_account_config ++ view.add_indicator = False + + self.add_scrolled_parent(view, text, show_close, show_icon, make_active, save) + return view +@@ -375,6 +398,7 @@ + view.link_handler = self.on_link_clicked + view.data_retrieval_handler = data_handler + view.config_retrieval_handler = self.get_account_config ++ view.add_indicator = False + + self.add_scrolled_parent(view, text, show_close, show_icon, make_active, save) + return view +@@ -414,6 +438,15 @@ + self.present() + self.move(*self.last_position) + ++ def on_indicator_activate(self, w): ++ tab_num = w.get_property("gwibber_tab") ++ if tab_num is not None: ++ self.tabs.set_current_page(int(tab_num)) ++ visible = self.get_property("visible") ++ self.present() ++ if not visible: ++ self.move(*self.last_position) ++ + def external_invoke(self): + logging.info("Invoked by external") + if not self.get_property("visible"): +@@ -905,6 +938,32 @@ + if not message.is_duplicate: + message.first_seen = True + seen.append(message.gId) ++ ++ def is_gwibber_active(self): ++ screen = wnck.screen_get_default() ++ screen.force_update() ++ return self.window.xid == screen.get_active_window().get_xid() ++ ++ def manage_indicator_items(self, data, tab_num=None): ++ if not self.is_gwibber_active(): ++ for msg in data: ++ if msg.first_seen and \ ++ hasattr(msg, "is_unread") and msg.is_unread and \ ++ hasattr(msg, "gId") and msg.gId not in self.indicator_items: ++ indicator = indicate.IndicatorMessage() ++ indicator.set_property("subtype", "im") ++ indicator.set_property("sender", msg.sender_nick) ++ indicator.set_property("body", msg.text) ++ indicator.set_property_time("time", msg.time.gmticks()) ++ if hasattr(msg, "image_path"): ++ pb = gtk.gdk.pixbuf_new_from_file(msg.image_path) ++ indicator.set_property_icon("icon", pb) ++ ++ if tab_num is not None: ++ indicator.set_property("gwibber_tab", str(tab_num)) ++ indicator.connect("user-display", self.on_indicator_activate) ++ indicator.show() ++ self.indicator_items[msg.gId] = indicator + + def update(self, tabs = None): + self.throbber.set_from_animation( +@@ -927,6 +986,10 @@ + gtk.gdk.threads_enter() + view.load_messages() + view.load_preferences(self.get_account_config(), self.get_gtk_theme_prefs()) ++ ++ if indicate and hasattr(view, "add_indicator") and view.add_indicator: ++ self.manage_indicator_items(view.message_store, tab_num=self.tabs.page_num(tab)) ++ + gtk.gdk.threads_leave() + self.show_notification_bubbles(view.message_store) + +diff -r 26a554c33c10 gwibber/resources.py +--- a/gwibber/resources.py Tue Apr 14 12:58:11 2009 -0400 ++++ b/gwibber/resources.py Tue Apr 14 15:39:29 2009 -0400 +@@ -24,6 +24,12 @@ + + DATA_DIRS += [os.path.join(d, PROGRAM_NAME) for d in DATA_BASE_DIRS] + ++def get_desktop_file(): ++ p = os.path.join(LAUNCH_DIR, "gwibber.desktop") ++ if os.path.exists(p): return p ++ for base in DATA_BASE_DIRS: ++ p = os.path.join(base, "applications", "gwibber.desktop") ++ if os.path.exists(p): return p + + def get_theme_paths(): + for base in DATA_DIRS: