0.6.0 added widget
authorYves <ymarcoz@n900-sdk.(none)>
Sun, 11 Apr 2010 21:01:22 +0000 (14:01 -0700)
committerYves <ymarcoz@n900-sdk.(none)>
Sun, 11 Apr 2010 21:01:22 +0000 (14:01 -0700)
12 files changed:
Makefile
debian/changelog
debian/control
src/FeedingIt.py
src/config.py
src/feedingit.conf [new file with mode: 0644]
src/feedingit_widget.desktop [new file with mode: 0644]
src/feedingit_widget.py [new file with mode: 0644]
src/feedingitdbus.py
src/feedparser.pyc [new file with mode: 0644]
src/rss.py
src/rss.pyc [new file with mode: 0644]

index 9328e2c..7bf2d8c 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -28,6 +28,12 @@ install:
        install src/feedingit.service ${DESTDIR}/usr/share/dbus-1/services/
        install -d ${DESTDIR}/etc/osso-backup/applications/
        install src/feedingit.conf ${DESTDIR}/etc/osso-backup/applications/
+       install -d ${DESTDIR}/usr/share/applications/hildon-home/
+       install src/feedingit_widget.desktop ${DESTDIR}/usr/share/applications/hildon-home/
+       install -d ${DESTDIR}/usr/lib/hildon-desktop/
+       install src/feedingit_widget.py ${DESTDIR}/usr/lib/hildon-desktop/
+       
+       
        
 clean:
        rm src/*pyo
index 48d0e8a..f5190b9 100644 (file)
@@ -1,3 +1,12 @@
+feedingit (0.6.0-0) stable; urgency=low
+
+  * Added home widget
+  * Fixed a few more HTML characters in titles
+  * Fixed crash caused by imageHandler
+  * Added loading indicator for links
+
+ -- Yves <yves@marcoz.org>  Sun, 11 Apr 2010 09:45:19 -0800
+
 feedingit (0.5.4-3) stable; urgency=low
 
   * Fixed Article font size setting
index 5d51660..3963b89 100644 (file)
@@ -10,7 +10,8 @@ XSBC-Bugtracker: https://garage.maemo.org/tracker/?func=browse&group_id=1202&ati
 Package: feedingit
 Architecture: any
 Depends: ${shlibs:Depends}, ${misc:Depends}, python, python-hildon,
- python-dbus, python-osso, python-gconf, python2.5-webkit
+ python-dbus, python-osso, python-gconf, python2.5-webkit,
+ python-hildondesktop, hildon-desktop-python-loader
 Description:
  RSS Reader
  Its main features are:
index 8f39811..ce0369c 100644 (file)
@@ -404,6 +404,8 @@ class DisplayArticle(hildon.StackableWindow):
         #if key=="ArchivedArticles":
         self.view.open("file://" + contentLink)
         self.view.connect("motion-notify-event", lambda w,ev: True)
+        self.view.connect('load-started', self.load_started)
+        self.view.connect('load-finished', self.load_finished)
 
         #else:
         #self.view.load_html_string(self.text, contentLink) # "text/html", "utf-8", self.link)
@@ -451,6 +453,12 @@ class DisplayArticle(hildon.StackableWindow):
         self.gestureId = self.view.connect("button_release_event", self.button_released)
         #self.timeout_handler_id = gobject.timeout_add(300, self.reloadArticle)
 
+    def load_started(self, *widget):
+        hildon.hildon_gtk_window_set_progress_indicator(self, 1)
+        
+    def load_finished(self, *widget):
+        hildon.hildon_gtk_window_set_progress_indicator(self, 0)
+
     def button_pressed(self, window, event):
         #print event.x, event.y
         self.coords = (event.x, event.y)
@@ -564,7 +572,7 @@ class DisplayFeed(hildon.StackableWindow):
         self.buttons = {}
         for id in self.feed.getIds():
             title = self.feed.getTitle(id)
-            esc_title = title.replace("<em>","").replace("</em>","").replace("&amp;","&")
+            esc_title = title.replace("<em>","").replace("</em>","").replace("&amp;","&").replace("&mdash;", "-").replace("&#8217;", "'")
             button = gtk.Button(esc_title)
             button.set_alignment(0,0)
             label = button.child
@@ -730,7 +738,7 @@ class FeedingIt:
         gobject.idle_add(self.enableDbus)
         
     def enableDbus(self):
-        dbusHandler = ServerObject(self)
+        self.dbusHandler = ServerObject(self)
 
     def button_markAll(self, button):
         for key in self.listing.getListOfFeeds():
@@ -781,6 +789,7 @@ class FeedingIt:
         self.downloadDialog = False
         #self.displayListing()
         self.refreshList()
+        self.dbusHandler.ArticleCountUpdated()
 
     def button_preferences_clicked(self, button):
         dialog = self.config.createDialog()
@@ -848,6 +857,7 @@ class FeedingIt:
     def onFeedClosed(self, object, key):
         self.listing.saveConfig()
         self.refreshList()
+        self.dbusHandler.ArticleCountUpdated()
      
     def run(self):
         self.window.connect("destroy", gtk.main_quit)
index baa7065..2e7f817 100644 (file)
@@ -183,9 +183,9 @@ class Config():
     def getUpdateInterval(self):
         return float(self.config["updateInterval"])
     def getReadFont(self):
-        return "sans %s" % self.config["fontSize"]
+        return "sans italic %s" % self.config["fontSize"]
     def getUnreadFont(self):
-        return "sans bold %s" % self.config["fontSize"]
+        return "sans %s" % self.config["fontSize"]
     def getOrientation(self):
         return ranges["orientation"].index(self.config["orientation"])
     def getImageCache(self):
diff --git a/src/feedingit.conf b/src/feedingit.conf
new file mode 100644 (file)
index 0000000..4f2138e
--- /dev/null
@@ -0,0 +1,5 @@
+<backup-configuration>
+  <locations>
+        <location type="dir" category="settings">/home/user/.feedingit</location>
+  </locations>
+</backup-configuration>
\ No newline at end of file
diff --git a/src/feedingit_widget.desktop b/src/feedingit_widget.desktop
new file mode 100644 (file)
index 0000000..2965966
--- /dev/null
@@ -0,0 +1,5 @@
+[Desktop Entry]
+Name=FeedingIt
+Comment=FeedingIt RSS Widget
+Type=python
+X-Path=feedingit_widget.py
diff --git a/src/feedingit_widget.py b/src/feedingit_widget.py
new file mode 100644 (file)
index 0000000..ed080b3
--- /dev/null
@@ -0,0 +1,215 @@
+#!/usr/bin/env python2.5
+
+# 
+# Copyright (c) 2007-2008 INdT.
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+#
+#  You should have received a copy of the GNU Lesser General Public License
+#  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+# ============================================================================
+# Name        : FeedingIt.py
+# Author      : Yves Marcoz
+# Version     : 0.5.4
+# Description : Simple RSS Reader
+# ============================================================================
+#import sys
+#sys.path.insert(0, '/opt/FeedingIt')
+#sys.path.insert(0, '/home/user/workspace/feedingit/src/')
+
+import gtk, pickle, gobject, dbus
+import hildondesktop, hildon
+#from rss import Listing
+
+# Create a session bus.
+import dbus
+from dbus.mainloop.glib import DBusGMainLoop
+dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
+bus = dbus.SessionBus()
+
+CONFIGDIR="/home/user/.feedingit/"
+
+class FeedingItHomePlugin(hildondesktop.HomePluginItem):
+    def __init__(self):
+      try:
+        hildondesktop.HomePluginItem.__init__(self)
+        self.set_settings(True)
+        self.connect("show-settings", self.show_settings)
+        self.feed_list = {}
+        
+        vbox = gtk.VBox(False, 0)
+        
+        button = gtk.Button("Update")
+        button.connect("clicked", self.update_list)
+        button.show_all()
+        vbox.pack_start(button)        
+        
+        #for feed in ["Slashdot", "Engadget", "Cheez"]:
+        #    self.treestore.append([feed, "0"])
+        self.treeview = gtk.TreeView()
+        self.update_list()
+        self.treeview.append_column(gtk.TreeViewColumn('Feed Name', gtk.CellRendererText(), text = 0))
+        self.treeview.append_column(gtk.TreeViewColumn('Unread Items', gtk.CellRendererText(), text = 1))
+        #self.treeview.get_selection().set_mode(gtk.SELECTION_NONE)
+        #hildon.hildon_gtk_tree_view_set_ui_mode(self.treeview, gtk.HILDON_UI_MODE_NORMAL)
+        
+        vbox.pack_start(self.treeview)
+        
+        self.add(vbox)
+        self.treeview.connect("row-activated", self.row_activated)
+        vbox.show_all()
+        #self.setupDbus()
+        gobject.timeout_add_seconds(30*60, self.update_list)
+      except:
+          import traceback
+          file = open("/home/user/.feedingit/feedingit_widget.log", "w")
+          traceback.print_exc(file=file)
+
+    def row_activated(self, treeview, treepath, column):
+        (model, iter) = self.treeview.get_selection().get_selected()
+        key = model.get_value(iter, 2)
+        # Create an object that will proxy for a particular remote object.
+        remote_object = bus.get_object("org.maemo.feedingit", # Connection name
+                               "/org/maemo/feedingit" # Object's path
+                              )
+        iface = dbus.Interface(remote_object, 'org.maemo.feedingit')
+        iface.OpenFeed(key)
+
+    def update_list(self, *widget):
+        #listing = Listing(CONFIGDIR)
+        treestore = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING)
+        
+        if self.feed_list == {}:
+            self.load_config()
+
+        list = []
+        #for key in listOfFeeds["feedingit-order"]:
+        for key in self.feed_list.keys():
+            try:
+                file = open(CONFIGDIR+key+".d/unread", "r")
+                readItems = pickle.load( file )
+                file.close()
+                countUnread = 0
+                for id in readItems.keys():
+                    if readItems[id]==False:
+                        countUnread = countUnread + 1
+                list.append([self.feed_list[key], countUnread, key])
+            except:
+                pass
+        list = sorted(list, key=lambda item: item[1], reverse=True)
+        for item in list[0:8]:
+            treestore.append(item)
+        self.treeview.set_model(treestore)
+        self.treeview.get_selection().unselect_all()
+        return True
+        
+    def show_settings(self, widget):
+        file = open(CONFIGDIR+"feeds.pickle")
+        listOfFeeds = pickle.load(file)
+        file.close()
+        dialog = gtk.Dialog("Settings", None, gtk.DIALOG_DESTROY_WITH_PARENT | gtk.DIALOG_NO_SEPARATOR, (gtk.STOCK_OK, gtk.RESPONSE_ACCEPT, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
+
+        self.pannableArea = hildon.PannableArea()
+        
+        #self.treestore_settings = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
+        self.treeview_settings = gtk.TreeView()
+        
+        self.treeview_settings.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
+        hildon.hildon_gtk_tree_view_set_ui_mode(self.treeview_settings, gtk.HILDON_UI_MODE_EDIT)
+        dialog.vbox.pack_start(self.pannableArea)
+        
+        self.treeview_settings.append_column(gtk.TreeViewColumn('Feed Name', gtk.CellRendererText(), text = 0))
+        self.treestore_settings = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
+        self.treeview_settings.set_model(self.treestore_settings)
+        
+        for key in listOfFeeds["feedingit-order"]:
+            title = listOfFeeds[key]["title"]
+            item = self.treestore_settings.append([title, key])
+            if key in self.feed_list:
+                self.treeview_settings.get_selection().select_iter(item)
+            
+        self.pannableArea.add(self.treeview_settings)
+        self.pannableArea.show_all()
+        dialog.set_default_size(-1, 600)
+        dialog.show_all()
+        response = dialog.run()
+        print response
+        if response == gtk.RESPONSE_ACCEPT:
+            self.feed_list = self.getItems()
+        dialog.destroy()
+        self.update_list()
+        #self.treeview_settings.get_selection().select_all()
+        
+    def getItems(self):
+        list = {}
+        treeselection = self.treeview_settings.get_selection()
+        (model, pathlist) = treeselection.get_selected_rows()
+        for path in pathlist:
+            list[model.get_value(model.get_iter(path),1)] = model.get_value(model.get_iter(path),0)
+        return list
+        
+    def setupDbus(self):
+        
+        #from dbus.mainloop.glib import DBusGMainLoop
+        #dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
+        #import gobject
+        #loop = gobject.MainLoop()
+        #bus = dbus.Bus(dbus.Bus.TYPE_SESSION)
+        #bus = dbus.SessionBus(mainloop=loop)
+        #bus = dbus.Bus.get_system()
+        #bus = dbus.Bus.get_session(True)
+        #bus.set_exit_on_disconnect(False)
+        
+        remote_object = bus.get_object("org.maemo.feedingit", # Connection name
+                               "/org/maemo/feedingit" # Object's path
+                              )
+        iface = dbus.Interface(remote_object, 'org.maemo.feedingit')
+        iface.connect_to_signal("ArticleCountUpdated", self.update_list)
+
+        #bus.add_signal_receiver(self.update_list,
+        #                dbus_interface="org.maemo.feedingit",
+        #                signal_name="ArticleCountUpdated",
+        #                path="/org/maemo/feedingit")
+        
+    def save_config(self):
+            if not isdir(CONFIGDIR):
+                mkdir(CONFIGDIR)
+            file = open(CONFIGDIR+"widget", "w")
+            pickle.dump(self.feed_list, file )
+            file.close()
+            
+    def load_config(self):
+            try:
+                file = open(CONFIGDIR+"widget", "r")
+                self.feed_list = pickle.load( file )
+                file.close()
+            except:
+                file = open(CONFIGDIR+"feeds.pickle")
+                listOfFeeds = pickle.load(file)
+                file.close()
+            
+                #self.feed_list = listOfFeeds["feedingit-order"]
+                for key in listOfFeeds["feedingit-order"]:
+                    self.feed_list[key] = listOfFeeds[key]["title"]
+                del listOfFeeds
+
+
+hd_plugin_type = FeedingItHomePlugin
+
+# The code below is just for testing purposes.
+# It allows to run the widget as a standalone process.
+if __name__ == "__main__":
+    import gobject
+    gobject.type_register(hd_plugin_type)
+    obj = gobject.new(hd_plugin_type, plugin_id="plugin_id")
+    obj.show_all()
+    gtk.main()
index e6fd0bd..68d73d7 100644 (file)
@@ -48,3 +48,13 @@ class ServerObject(dbus.service.Object):
     def Update(self):
         self.app.automaticUpdate()
         return "Done"
+
+    @dbus.service.method('org.maemo.feedingit')
+    def OpenFeed(self, key):
+        self.app.buttonFeedClicked(None, self.app, None, key)
+        return "Done"    
+
+    # A signal that will be exported to dbus
+    @dbus.service.signal('org.maemo.feedingit', signature='')
+    def ArticleCountUpdated(self):
+        pass
diff --git a/src/feedparser.pyc b/src/feedparser.pyc
new file mode 100644 (file)
index 0000000..e33edbc
Binary files /dev/null and b/src/feedparser.pyc differ
index cad5730..8a30f7f 100644 (file)
@@ -455,11 +455,11 @@ class Listing:
             file.close()
         else:
             self.listOfFeeds = {getId("Slashdot"):{"title":"Slashdot", "url":"http://rss.slashdot.org/Slashdot/slashdot", "unread":0, "updateTime":"Never"}, }
-        if isfile(self.configdir+"images.pickle"):
+        try:
             file = open(self.configdir+"images.pickle")
             self.imageHandler = pickle.load(file)
             file.close()
-        else:
+        except:
             self.imageHandler = ImageHandler(self.configdir)
         if self.listOfFeeds.has_key("font"):
             del self.listOfFeeds["font"]
diff --git a/src/rss.pyc b/src/rss.pyc
new file mode 100644 (file)
index 0000000..fb4df30
Binary files /dev/null and b/src/rss.pyc differ