0.4.5-1
authorYves <ymarcoz@n900-sdk.(none)>
Mon, 8 Feb 2010 01:00:35 +0000 (17:00 -0800)
committerYves <ymarcoz@n900-sdk.(none)>
Mon, 8 Feb 2010 01:00:35 +0000 (17:00 -0800)
Makefile
debian/changelog
src/FeedingIt.py
src/config.py
src/feedingitdbus.py
src/rss.py

index d82c148..e612da8 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -25,6 +25,8 @@ install:
        install data/64px.png ${DESTDIR}/usr/share/icons/hicolor/64x64/apps/feedingit.png
        install -d ${DESTDIR}/usr/share/dbus-1/services/
        install src/feedingit.service ${DESTDIR}/usr/share/dbus-1/services/
+       install -d ${DESTDIR}/etc/osso-backup/applications
+       install src/feedingit.conf /etc/osso-backup/applications/
        
 clean:
        rm src/*pyo
index 353776c..244941c 100644 (file)
@@ -1,4 +1,22 @@
-feedingit (0.4.3-5) unstable; urgency=low
+feedingit (0.4.5-1) unstable; urgency=low
+
+  * Fixed utf-8 support
+  * Fixed dbus add feed dialog
+  * Re-added single feed update
+  * Open in external browser now uses load_url dbus call
+  
+ -- Yves <yves@marcoz.org>  Sun, 31 Jan 2010 10:43:19 -0800
+
+feedingit (0.4.5-0) unstable; urgency=low
+
+  * Added support for webkit widget
+  * Added Backup configuration
+  * Changed gesture mechanism to make it less sensitive
+  * Fixed app not starting after a crash if a feed was deleted
+  
+ -- Yves <yves@marcoz.org>  Sun, 31 Jan 2010 10:43:19 -0800
+
+feedingit (0.4.4-1) unstable; urgency=low
 
   * Fix timing of autoupdate
   * Fix specific feeds
@@ -6,7 +24,7 @@ feedingit (0.4.3-5) unstable; urgency=low
   * Fix export of feeds with "&" symbols
   * Added GetStatus dbus call to get the listing of unread items
   
- -- Yves <yves@marcoz.org>  Tue, 29 Jan 2010 21:47:19 -0800
+ -- Yves <yves@marcoz.org>  Fri, 29 Jan 2010 21:47:19 -0800
 
 feedingit (0.4.3-1) unstable; urgency=low
 
index 4a18262..11cd448 100644 (file)
@@ -27,7 +27,13 @@ import gtk
 import feedparser
 import pango
 import hildon
-import gtkhtml2
+#import gtkhtml2
+try:
+    import webkit
+    has_webkit=True
+except:
+    import gtkhtml2
+    has_webkit=False
 import time
 import dbus
 import pickle
@@ -160,13 +166,14 @@ class Download(threading.Thread):
 
         
 class DownloadBar(gtk.ProgressBar):
-    def __init__(self, parent, listing, listOfKeys, config):
+    def __init__(self, parent, listing, listOfKeys, config, single=False):
         gtk.ProgressBar.__init__(self)
         self.listOfKeys = listOfKeys[:]
         self.listing = listing
         self.total = len(self.listOfKeys)
         self.config = config
         self.current = 0
+        self.single = single
         
         if self.total>0:
             #self.progress = gtk.ProgressBar()
@@ -199,7 +206,7 @@ class DownloadBar(gtk.ProgressBar):
             if len(self.listOfKeys)>0:
                 self.current = self.current+1
                 key = self.listOfKeys.pop()
-                if not self.listing.getCurrentlyDisplayedFeed() == key:
+                if (not self.listing.getCurrentlyDisplayedFeed() == key) or (self.single == True):
                     # Check if the feed is being displayed
                     download = Download(self.listing, key, self.config)
                     download.start()
@@ -355,7 +362,7 @@ class SortList(gtk.Dialog):
                
 
 class DisplayArticle(hildon.StackableWindow):
-    def __init__(self, title, text, link, index, key, listing):
+    def __init__(self, title, text, link, index, key, listing, config):
         hildon.StackableWindow.__init__(self)
         self.imageDownloader = ImageDownloader()
         self.listing=listing
@@ -364,25 +371,35 @@ class DisplayArticle(hildon.StackableWindow):
         self.text = text
         self.link = link
         self.set_title(title)
+        self.config = config
         self.images = []
         
-        # Init the article display    
-        self.view = gtkhtml2.View()
+        # Init the article display
+        if has_webkit:
+            self.view = webkit.WebView()
+            #self.view.set_editable(False)
+        else:
+            self.view = gtkhtml2.View()
+            self.document = gtkhtml2.Document()
+            self.view.set_document(self.document)
+            self.document.connect("link_clicked", self._signal_link_clicked)
         self.pannable_article = hildon.PannableArea()
         self.pannable_article.add(self.view)
         #self.pannable_article.set_property("mov-mode", hildon.MOVEMENT_MODE_BOTH)
-        self.gestureId = self.pannable_article.connect('horizontal-movement', self.gesture)
-        self.document = gtkhtml2.Document()
-        self.view.set_document(self.document)
-        
-        self.document.connect("link_clicked", self._signal_link_clicked)
-        if not key == "1295627ef630df9d239abeb0ba631c3f":
-            # Do not download images if the feed is "Archived Articles"
-            self.document.connect("request-url", self._signal_request_url)
-        self.document.clear()
-        self.document.open_stream("text/html")
-        self.document.write_stream(self.text)
-        self.document.close_stream()
+        #self.gestureId = self.pannable_article.connect('horizontal-movement', self.gesture)
+
+        if has_webkit:
+            self.view.load_string(self.text, "text/html", "utf-8", self.link)
+            self.view.set_zoom_level(float(config.getArtFontSize())/10.)
+        else:
+            if not key == "1295627ef630df9d239abeb0ba631c3f":
+                # Do not download images if the feed is "Archived Articles"
+                self.document.connect("request-url", self._signal_request_url)
+            
+            self.document.clear()
+            self.document.open_stream("text/html")
+            self.document.write_stream(self.text)
+            self.document.close_stream()
         
         menu = hildon.AppMenu()
         # Create a button and add it to the menu
@@ -404,18 +421,41 @@ class DisplayArticle(hildon.StackableWindow):
         self.set_app_menu(menu)
         menu.show_all()
         
+        #self.event_box = gtk.EventBox()
+        #self.event_box.add(self.pannable_article)
         self.add(self.pannable_article)
         
+        
         self.pannable_article.show_all()
 
         self.destroyId = self.connect("destroy", self.destroyWindow)
+        
+        self.view.connect("button_press_event", self.button_pressed)
+        self.view.connect("button_release_event", self.button_released)
         #self.timeout_handler_id = gobject.timeout_add(300, self.reloadArticle)
 
-    def gesture(self, widget, direction, startx, starty):
-        if (direction == 3):
-            self.emit("article-next", self.index)
-        if (direction == 2):
-            self.emit("article-previous", self.index)
+    def button_pressed(self, window, event):
+        #print event.x, event.y
+        self.coords = (event.x, event.y)
+        
+    def button_released(self, window, event):
+        x = self.coords[0] - event.x
+        y = self.coords[1] - event.y
+        
+        if (abs(y) < 20):
+            if (x > 30):
+                self.emit("article-previous", self.index)
+            elif (x<-30):
+                self.emit("article-next", self.index)   
+        #print x, y
+        #print "Released"
+
+    #def gesture(self, widget, direction, startx, starty):
+    #    if (direction == 3):
+    #        self.emit("article-next", self.index)
+    #    if (direction == 2):
+    #        self.emit("article-previous", self.index)
+        #print startx, starty
         #self.timeout_handler_id = gobject.timeout_add(200, self.destroyWindow)
 
     def destroyWindow(self, *args):
@@ -448,7 +488,7 @@ class DisplayArticle(hildon.StackableWindow):
         bus = dbus.SystemBus()
         proxy = bus.get_object("com.nokia.osso_browser", "/com/nokia/osso_browser/request")
         iface = dbus.Interface(proxy, 'com.nokia.osso_browser')
-        iface.open_new_window(link)
+        iface.load_url(link)
 
     def _signal_request_url(self, object, url, stream):
         #print url
@@ -468,15 +508,17 @@ class DisplayFeed(hildon.StackableWindow):
         self.key=key
         self.config = config
         
+        self.downloadDialog = False
+        
         self.listing.setCurrentlyDisplayedFeed(self.key)
         
         self.disp = False
         
         menu = hildon.AppMenu()
-        #button = hildon.GtkButton(gtk.HILDON_SIZE_AUTO)
-        #button.set_label("Update Feed")
-        #button.connect("clicked", self.button_update_clicked)
-        #menu.append(button)
+        button = hildon.GtkButton(gtk.HILDON_SIZE_AUTO)
+        button.set_label("Update Feed")
+        button.connect("clicked", self.button_update_clicked)
+        menu.append(button)
         
         button = hildon.GtkButton(gtk.HILDON_SIZE_AUTO)
         button.set_label("Mark All As Read")
@@ -529,7 +571,7 @@ class DisplayFeed(hildon.StackableWindow):
         self.remove(self.pannableFeed)
 
     def button_clicked(self, button, index, previous=False, next=False):
-        newDisp = DisplayArticle(self.feedTitle, self.feed.getArticle(index), self.feed.getLink(index), index, self.key, self.listing)
+        newDisp = DisplayArticle(self.feedTitle, self.feed.getArticle(index), self.feed.getLink(index), index, self.key, self.listing, self.config)
         stack = hildon.WindowStack.get_default()
         if previous:
             tmp = stack.peek()
@@ -586,8 +628,20 @@ class DisplayFeed(hildon.StackableWindow):
         label.modify_font(pango.FontDescription(self.config.getReadFont()))
         self.buttons[index].show()
 
-    #def button_update_clicked(self, button):
-    #    bar = DownloadBar(self, self.listing, [self.key,], self.config )       
+    def button_update_clicked(self, button):
+        #bar = DownloadBar(self, self.listing, [self.key,], self.config ) 
+        if not type(self.downloadDialog).__name__=="DownloadBar":
+            self.pannableFeed.destroy()
+            self.vbox = gtk.VBox(False, 10)
+            self.downloadDialog = DownloadBar(self.window, self.listing, [self.key,], self.config, single=True )
+            self.downloadDialog.connect("download-done", self.onDownloadsDone)
+            self.vbox.pack_start(self.downloadDialog, expand=False, fill=False)
+            self.add(self.vbox)
+            self.show_all()
+            
+    def onDownloadsDone(self, *widget):
+        self.vbox.destroy()
+        self.displayFeed()
         #self.feed.updateFeed()
     #    self.clear()
     #    self.displayFeed()
@@ -618,8 +672,8 @@ class FeedingIt:
         self.listing = Listing(CONFIGDIR)
         
         self.downloadDialog = False
-        self.orientation = FremantleRotation("FeedingIt", main_window=self.window)
-        self.orientation.set_mode(self.config.getOrientation())
+        #self.orientation = FremantleRotation("FeedingIt", main_window=self.window)
+        #self.orientation.set_mode(self.config.getOrientation())
         
         menu = hildon.AppMenu()
         # Create a button and add it to the menu
@@ -664,7 +718,6 @@ class FeedingIt:
         self.checkAutoUpdate()
         hildon.hildon_gtk_window_set_progress_indicator(self.window, 0)
 
-
     def button_markAll(self, button):
         for key in self.listing.getListOfFeeds():
             feed = self.listing.getFeed(key)
@@ -682,6 +735,16 @@ class FeedingIt:
             self.listing.addFeed(title, url)
         self.displayListing()
 
+    def addFeed(self, urlIn="http://"):
+        wizard = AddWidgetWizard(self.window, urlIn)
+        ret = wizard.run()
+        if ret == 2:
+            (title, url) = wizard.getData()
+            if (not title == '') and (not url == ''): 
+               self.listing.addFeed(title, url)
+        wizard.destroy()
+        self.displayListing()
+
     def button_organize_clicked(self, button):
         org = SortList(self.window, self.listing)
         org.run()
@@ -729,7 +792,7 @@ class FeedingIt:
 
         self.buttons = {}
         list = self.listing.getListOfFeeds()[:]
-        list.reverse()
+        #list.reverse()
         for key in list:
             #button = gtk.Button(item)
             button = hildon.Button(gtk.HILDON_SIZE_AUTO_WIDTH | gtk.HILDON_SIZE_FINGER_HEIGHT,
@@ -747,10 +810,14 @@ class FeedingIt:
         self.window.show_all()
 
     def refreshList(self):
-        for key in self.buttons.keys():
-            button = self.buttons[key]
-            button.set_text(self.listing.getFeedTitle(key), self.listing.getFeedUpdateTime(key) + " / " 
+        for key in self.listing.getListOfFeeds():
+            if self.buttons.has_key(key):
+                button = self.buttons[key]
+                button.set_text(self.listing.getFeedTitle(key), self.listing.getFeedUpdateTime(key) + " / " 
                             + str(self.listing.getFeedNumberOfUnreadItems(key)) + " Unread Items")
+            else:
+                self.displayListing()
+                break
 
     def buttonFeedClicked(widget, button, self, window, key):
         disp = DisplayFeed(self.listing, self.listing.getFeed(key), self.listing.getFeedTitle(key), key, self.config)
index b6bf8ee..5b92052 100644 (file)
@@ -29,9 +29,9 @@ import ConfigParser
 import gobject
 
 section = "FeedingIt"
-ranges = { "updateInterval":[0.5, 1, 2, 4, 12, 24], "expiry":[24, 48, 72], "fontSize":range(12,24), "orientation":["Automatic", "Landscape", "Portrait"]}
-titles = {"updateInterval":"Auto-update Interval", "expiry":"Expiry For Articles", "fontSize":"Font Size For Article Listing", "orientation":"Display Orientation"}
-subtitles = {"updateInterval":"Update every %s hours", "expiry":"Delete articles after %s hours", "fontSize":"%s pixels", "orientation":"%s"}
+ranges = { "updateInterval":[0.5, 1, 2, 4, 12, 24], "expiry":[24, 48, 72], "fontSize":range(12,24), "orientation":["Automatic", "Landscape", "Portrait"], "artFontSize":[10, 12, 14, 16, 18, 20]}
+titles = {"updateInterval":"Auto-update Interval", "expiry":"Expiry For Articles", "fontSize":"Font Size For Article Listing", "orientation":"Display Orientation", "artFontSize":"Font Size For Articles"}
+subtitles = {"updateInterval":"Update every %s hours", "expiry":"Delete articles after %s hours", "fontSize":"%s pixels", "orientation":"%s", "artFontSize":"%s pixels"}
 
 class Config():
     def __init__(self, parent, configFilename):
@@ -43,9 +43,12 @@ class Config():
     def createDialog(self):
         
         self.window = gtk.Dialog("Preferences", self.parent)
-        #self.vbox = gtk.VBox(False, 10)
+        self.window.set_default_size(-1, 600)
+        panArea = hildon.PannableArea()
+        
+        vbox = gtk.VBox(False, 10)
         self.buttons = {}
-        for setting in ["fontSize", "expiry", "orientation", "updateInterval",]:
+        for setting in ["fontSize", "artFontSize", "expiry", "orientation", "updateInterval",]:
             picker = hildon.PickerButton(gtk.HILDON_SIZE_FINGER_HEIGHT, hildon.BUTTON_ARRANGEMENT_VERTICAL)
             selector = self.create_selector(ranges[setting], setting)
             picker.set_selector(selector)
@@ -54,15 +57,17 @@ class Config():
             picker.set_name('HildonButton-finger')
             picker.set_alignment(0,0,1,1)
             self.buttons[setting] = picker
-            self.window.vbox.pack_start(picker)
+            vbox.pack_start(picker)
         
         button = hildon.CheckButton(gtk.HILDON_SIZE_FINGER_HEIGHT)
         button.set_label("Auto-update Enabled")
         button.set_active(self.config["autoupdate"])
         button.connect("toggled", self.button_toggled)
         
-        self.window.vbox.pack_start(button)
+        vbox.pack_start(button)
+        panArea.add_with_viewport(vbox)
         
+        self.window.vbox.add(panArea)        
         self.window.connect("destroy", self.onExit)
         #self.window.add(self.vbox)
         self.window.show_all()
@@ -97,12 +102,14 @@ class Config():
             configParser = ConfigParser.RawConfigParser()
             configParser.read(self.configFilename)
             self.config["fontSize"] = configParser.getint(section, "fontSize")
+            self.config["artFontSize"] = configParser.getint(section, "artFontSize")
             self.config["expiry"] = configParser.getint(section, "expiry")
             self.config["autoupdate"] = configParser.getboolean(section, "autoupdate")
             self.config["updateInterval"] = configParser.getfloat(section, "updateInterval")
             self.config["orientation"] = configParser.get(section, "orientation")
         except:
             self.config["fontSize"] = 16
+            self.config["artFontSize"] = 18
             self.config["expiry"] = 24
             self.config["autoupdate"] = False
             self.config["updateInterval"] = 4
@@ -112,6 +119,7 @@ class Config():
         configParser = ConfigParser.RawConfigParser()
         configParser.add_section(section)
         configParser.set(section, 'fontSize', str(self.config["fontSize"]))
+        configParser.set(section, 'artFontSize', str(self.config["artFontSize"]))
         configParser.set(section, 'expiry', str(self.config["expiry"]))
         configParser.set(section, 'autoupdate', str(self.config["autoupdate"]))
         configParser.set(section, 'updateInterval', str(self.config["updateInterval"]))
@@ -138,6 +146,8 @@ class Config():
 
     def getFontSize(self):
         return self.config["fontSize"]
+    def getArtFontSize(self):
+        return self.config["artFontSize"]
     def getExpiry(self):
         return self.config["expiry"]
     def isAutoUpdateEnabled(self):
index 372e809..fee9d7e 100644 (file)
@@ -37,7 +37,7 @@ class ServerObject(dbus.service.Object):
     # Here the interface name, and the method is named same as on dbus.
     @dbus.service.method('org.maemo.feedingit')
     def AddFeed(self, url):
-        self.app.button_add_clicked(None, url)
+        self.app.addFeed(None, url)
         return "Done"
     
     @dbus.service.method('org.maemo.feedingit')
index 9d8df0b..5083ce7 100644 (file)
@@ -95,6 +95,11 @@ class Feed:
         if self.readItems[self.getUniqueId(index)]==False:
             self.countUnread = self.countUnread - 1
             self.readItems[self.getUniqueId(index)] = True
+            
+    def setEntryUnread(self, index):
+        if self.readItems[self.getUniqueId(index)]==True:
+            self.countUnread = self.countUnread + 1
+            self.readItems[self.getUniqueId(index)] = False
     
     def isEntryRead(self, index):
         return self.readItems[self.getUniqueId(index)]
@@ -150,7 +155,7 @@ class Feed:
         if entry.has_key('content'):
             if len(entry.content[0].value) > len(content):
                 content = entry.content[0].value
-        else:
+        if content == "":
             content = entry.get('description', '')
         return content
     
@@ -170,11 +175,13 @@ class Feed:
             date = ""
         #text = '''<div style="color: black; background-color: white;">'''
         text = '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>'
-        text += '<div><a href=\"' + link + '\">' + title + "</a>"
+        text += '<head><style> body {-webkit-user-select: none;} </style></head>'
+        text += '<body><div><a href=\"' + link + '\">' + title + "</a>"
         text += "<BR /><small><i>Date: " + date + "</i></small></div>"
         text += "<BR /><BR />"
         text += content
-        return text    
+        text += "</body>"
+        return text
 
 class ArchivedArticles(Feed):
     def addArchivedArticle(self, title, link, updated_parsed, configdir):
@@ -192,6 +199,7 @@ class ArchivedArticles(Feed):
         #print entry
         
     def updateFeed(self, configdir, expiryTime=24):
+        index = 0
         for entry in self.getEntries():
             if not entry["downloaded"]:
                 try:
@@ -201,12 +209,14 @@ class ArchivedArticles(Feed):
                     if len(entry["summary"]) > 0:
                         entry["downloaded"] = True
                         entry["time"] = time.time()
+                        self.setEntryUnread(index)
                 except:
                     pass
             currentTime = time.time()
             expiry = float(expiryTime) * 3600
             if currentTime - entry["time"] > expiry:
                 self.entries.remove(entry)
+            index += 1
         self.updateTime = time.asctime()
         self.saveFeed(configdir)
 
@@ -236,11 +246,19 @@ class Listing:
             if "font" in self.sortedKeys:
                 self.sortedKeys.remove("font")
             self.sortedKeys.sort(key=lambda obj: self.getFeedTitle(obj))
-        for key in self.sortedKeys:
+        list = self.sortedKeys[:]
+        for key in list:
             try:
                 self.loadFeed(key)
             except:
+                #import traceback
+                #if key.startswith('d8'):
+                #traceback.print_exc()
                 self.sortedKeys.remove(key)
+            #print key
+                #print key in self.sortedKeys
+        #print "d8eb3f07572892a7b5ed9c81c5bb21a2" in self.sortedKeys
+        #print self.listOfFeeds["d8eb3f07572892a7b5ed9c81c5bb21a2"]
         self.closeCurrentlyDisplayedFeed()
         #self.saveConfig()
 
@@ -262,6 +280,7 @@ class Listing:
                 self.feeds[key] = pickle.load(file)
                 file.close()
             else:
+                #print key
                 title = self.listOfFeeds[key]["title"]
                 url = self.listOfFeeds[key]["url"]
                 self.feeds[key] = Feed(title, url)
@@ -282,6 +301,7 @@ class Listing:
         return self.feeds[key]
     
     def getFeedUpdateTime(self, key):
+        #print self.listOfFeeds.has_key(key)
         return self.feeds[key].getUpdateTime()
     
     def getFeedNumberOfUnreadItems(self, key):
@@ -312,6 +332,7 @@ class Listing:
         del self.feeds[key]
         if isfile(self.configdir+key):
            remove(self.configdir+key)
+        self.saveConfig()
     
     def saveConfig(self):
         self.listOfFeeds["feedingit-order"] = self.sortedKeys
@@ -335,4 +356,12 @@ class Listing:
     def closeCurrentlyDisplayedFeed(self):
         self.currentlyDisplayedFeed = False
     def getCurrentlyDisplayedFeed(self):
-        return self.currentlyDisplayedFeed
\ No newline at end of file
+        return self.currentlyDisplayedFeed
+    
+if __name__ == "__main__":
+    listing = Listing('/home/user/.feedingit/')
+    list = listing.getListOfFeeds()[:]
+        #list.reverse()
+    for key in list:
+        if key.startswith('d8'):
+            print listing.getFeedUpdateTime(key)
\ No newline at end of file