import os
from os import mkdir, remove, stat, environ
from os.path import isfile, isdir, exists
+import codecs
+import dbus
+# import python dbus GLib mainloop support
+import dbus.mainloop.glib
+# Enable glib main loop support
+dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
# Comment the line below if you don't want to use OpenGL for QML rendering or if it is not supported
from PySide import QtOpenGL, QtCore
from rss_sqlite import Listing
-CONFIGDIR = environ.get("HOME", "/home/user") + "/.feedingit"
+CONFIGDIR = environ.get("HOME", "/home/user") + "/.feedingit/"
#CONFIGDIR = "/home/user/.feedingit"
import logging
-#logger = logging.getLogger(__name__)
+logger = logging.getLogger(__name__)
import debugging
debugging.init(dot_directory=".feedingit", program_name="feedingit-pyside")
from cgi import escape
from re import sub
-class FeedWrapper(QtCore.QObject):
- def __init__(self, key):
- QtCore.QObject.__init__(self)
- self._key = key
- def _name(self):
- return listing.getFeedTitle(self._key)
- def _unread(self):
- return listing.getFeedNumberOfUnreadItems(self._key)
- def _updatedDate(self):
- return listing.getFeedUpdateTime(self._key)
- def _icon(self):
- return listing.getFavicon(self._key)
- def _feedid(self):
- return self._key
- def _updating(self):
- return false
-
- changed = QtCore.Signal()
-
- title = QtCore.Property(unicode, _name, notify=changed)
- feedid = QtCore.Property(unicode, _feedid, notify=changed)
- unread = QtCore.Property(unicode, _unread, notify=changed)
- updatedDate= QtCore.Property(unicode, _updatedDate, notify=changed)
- icon = QtCore.Property(unicode, _icon, notify=changed)
- updating = QtCore.Property(unicode, _icon, notify=changed)
-
-class FeedsModel(QtCore.QAbstractListModel):
- COLUMNS = ('feed', )
- _category = None
-
- def __init__(self):
- QtCore.QAbstractListModel.__init__(self)
- self._feeds = listing.getListOfFeeds(self._category)
- self.setRoleNames(dict(enumerate(FeedsModel.COLUMNS)))
-
- def rowCount(self, parent=QtCore.QModelIndex()):
- return len(self._feeds)
-
- def data(self, index, role):
- if index.isValid() and role == FeedsModel.COLUMNS.index('feed'):
- print self._feeds[index.row()]
- return FeedWrapper(self._feeds[index.row()])
- return None
-
-class ArticleWrapper(QtCore.QObject):
- def __init__(self, feed, articleid):
- QtCore.QObject.__init__(self)
- self._feed = feed
- self._articleid = articleid
- def _name(self):
- return self.fix_title(self._feed.getTitle(self._articleid))
- def _unread(self):
- return str(self._feed.isEntryRead(self._articleid))
- def _getarticleid(self):
- return self._articleid
- def _updatedDate(self):
- return self._feed.getDateStamp(self._articleid)
- def _path(self):
- return self._feed.getContentLink(self._articleid)
-
- changed = QtCore.Signal()
-
- title = QtCore.Property(unicode, _name, notify=changed)
- articleid = QtCore.Property(unicode, _getarticleid, notify=changed)
- unread = QtCore.Property(unicode, _unread, notify=changed)
- updatedDate= QtCore.Property(unicode, _updatedDate, notify=changed)
- path = QtCore.Property(unicode, _path, notify=changed)
-
-class ArticlesModel(QtCore.QAbstractListModel):
- COLUMNS = ('article', )
- _articles = []
- _key = None
- _feed = None
-
- def __init__(self,):
- QtCore.QAbstractListModel.__init__(self)
- self.setRoleNames(dict(enumerate(ArticlesModel.COLUMNS)))
-
- def updateModel(self, key):
- self._key = key
- self._feed = listing.getFeed(self._key)
- self._articles = self._feed.getIds()
-
- def rowCount(self, parent=QtCore.QModelIndex()):
- print "art " + str(len(self._articles))
- return len(self._articles)
-
- def data(self, index, role):
- print "data" + str(index) + " " + str(role)
- if index.isValid() and role == ArticlesModel.COLUMNS.index('article'):
- return ArticleWrapper(self._articles[index.row()])
- return None
-
class Controller(QtCore.QObject):
+ cachedList = None
def __init__(self, listing):
QtCore.QObject.__init__(self)
from XmlHandler import XmlHandler
self._handler = XmlHandler(listing)
+
+ def update_progress(self, percent_complete,
+ completed, in_progress, queued,
+ bytes_downloaded, bytes_updated, bytes_per_second,
+ feed_updated):
+ total = completed + in_progress + queued
+ root.updateProgress(int(total), int(completed))
+
+ def articleCountUpdated(self):
+ #print "article updated"
+ pass
+
+ def update_started(self):
+ root.updateStarted()
+
+ def update_finished(self):
+ root.updateFinished()
@QtCore.Slot(str,str, result=str)
def getArticle(self, key, article):
feed = listing.getFeed(key)
try:
- file = open(feed.getContentLink(article))
+ file = codecs.open(feed.getContentLink(article), "r", "utf-8")
html = file.read().replace("body", "body bgcolor='#ffffff'", 1)
file.close()
except:
- html = "<html><body>Error retrieving article</body></html>"
+ html = u"<html><body>Error retrieving article</body></html>"
return html
@QtCore.Slot(str, result=str)
@QtCore.Slot(str,result=str)
def getArticlesXml(self, key):
+ feed = listing.getFeed(key)
+ self.cachedList = feed.getIds(onlyUnread=True)
#onlyUnread = arguments.get("onlyUnread","False")
- return self._handler.generateArticlesXml(key, "False")
+ return self._handler.generateArticlesXml(key, config.getHideReadArticles())
+
+ @QtCore.Slot(str,str,bool,result=str)
+ def getNextId(self, key, articleid, onlyUnread):
+ if (onlyUnread):
+ #print self.cachedList, articleid
+ index = self.cachedList.index(articleid)
+ return self.cachedList[(index + 1) % len(self.cachedList)]
+ else:
+ feed = listing.getFeed(key)
+ return feed.getNextId(articleid)
+
+ @QtCore.Slot(str,str,bool,result=str)
+ def getPreviousId(self, key, articleid, onlyUnread):
+ if (onlyUnread):
+ #print self.cachedList, articleid
+ index = self.cachedList.index(articleid)
+ return self.cachedList[(index - 1) % len(self.cachedList)]
+ else:
+ feed = listing.getFeed(key)
+ return feed.getPreviousId(articleid)
@QtCore.Slot(result=str)
def getCategoryXml(self):
@QtCore.Slot(str)
def updateFeed(self, key):
- print 'updating feed ', key
listing.updateFeed(key)
@QtCore.Slot()
def updateAll(self):
- for feed in listing.getListOfFeeds("Manual"):
- listing.updateFeed(feed)
-
+ for catid in listing.getListOfCategories():
+ for feed in listing.getSortedListOfKeys("Manual", category=catid):
+ listing.updateFeed(feed)
+
+ @QtCore.Slot(str)
+ def updateCategory(self, catid):
+ for feed in listing.getSortedListOfKeys("Manual", category=catid):
+ listing.updateFeed(feed)
+
@QtCore.Slot(str,str,str)
def addFeed(self, title, url, catid):
listing.addFeed(title,url, category=catid)
listing.addCategory(name)
@QtCore.Slot(str)
+ def removeFeed(self, key):
+ listing.removeFeed(key)
+
+ @QtCore.Slot(str)
+ def removeCategory(self, catid):
+ listing.removeCategory(catid)
+
+ @QtCore.Slot(str)
def markAllAsRead(self, key):
feed = listing.getFeed(key)
feed.markAllAsRead()
+ listing.updateUnread(key)
@QtCore.Slot(str, str)
def setEntryRead(self, key, articleid):
if (item == "hideReadArticles"):
return "False"
return ""
+
+ @QtCore.Slot(str, str)
+ def populateFileDialog(self, path, type):
+ import glob
+ import os.path
+ for file in glob.glob(path+type):
+ logger.debug(file)
+ root.addFileNotification(file, os.path.basename(file))
+
+ @QtCore.Slot(str, result=int)
+ def importOpml(self, filename):
+ from opml_lib import parseOpml
+ file = open(filename, "r")
+ feeds = parseOpml(file.read())
+ file.close()
+ for (title, url) in feeds:
+ listing.addFeed(title, url)
+ return len(feeds)
+
+ @QtCore.Slot(str, result=str)
+ def exportOpml(self, filename="/home/user/MyDocs/feedingit-export.opml"):
+ logger.debug("ExportOpmlData: %s" % filename)
+ from opml_lib import getOpmlText
+ try:
+ str = getOpmlText(listing)
+ file = open(filename, "w")
+ file.write(str)
+ file.close()
+ return filename
+ except:
+ logger.debug("Error exporting: %s" % filename)
+ return "error"
+
+ @QtCore.Slot(str, result=bool)
+ def getBooleanSetting(self, setting):
+ if (setting == "theme"):
+ return config.getTheme()
+ elif (setting == "imageCache" ):
+ return config.getImageCache()
+ elif (setting == "hideReadFeeds"):
+ return config.getHideReadFeeds()
+ elif (setting == "hideReadArticles"):
+ return config.getHideReadArticles()
+ elif (setting == "autoupdate"):
+ return config.isAutoUpdateEnabled()
+ else:
+ return 'True'
+
+ @QtCore.Slot(str, result=int)
+ def getIntSetting(self, setting):
+ if (setting == "artFontSize"):
+ return config.getArtFontSize()
+ elif (setting == "fontSize" ):
+ return config.getFontSize()
+ else:
+ return -1
+
+ @QtCore.Slot(str, bool)
+ def setBooleanSetting(self, setting, value):
+ if (setting == "theme"):
+ config.setTheme(value)
+ elif (setting == "imageCache" ):
+ config.setImageCache(value)
+ elif (setting == "hideReadFeeds"):
+ config.setHideReadFeeds(value)
+ elif (setting == "hideReadArticles"):
+ config.setHideReadArticles(value)
+ elif (setting == "autoupdate"):
+ config.setAutoUpdateEnabled(value)
+ config.saveConfig()
+
+ @QtCore.Slot(str, int)
+ def setIntSetting(self, setting, value):
+ if (setting == "artFontSize"):
+ config.setArtFontSize(value)
+ elif (setting == "fontSize" ):
+ config.setFontSize(value)
+ config.saveConfig()
+
+ @QtCore.Slot(str, str)
+ def openSettings(self):
+ bus = dbus.SessionBus()
+ settingService = bus.get_object('com.nokia.DuiControlPanel', '/')
+ setting = shareService.get_dbus_method('appletPage', 'com.nokia.DuiControlPanelIf')
+ setting("FeedingIt")
-def main():
+ @QtCore.Slot(str, str)
+ def share(self, key, articleid):
+ feed = listing.getFeed(key)
+ title = feed.getTitle(articleid)
+ link = feed.getExternalLink(articleid)
+ description = 'Shared%20via%20FeedingIt%20on%20Meego'
+ import urllib
+ bus = dbus.SessionBus()
+ shareService = bus.get_object('com.nokia.ShareUi', '/')
+ share = shareService.get_dbus_method('share', 'com.nokia.maemo.meegotouch.ShareUiInterface')
+ #share([u'data:text/x-url;description=Support%20for%20Nokia%20Developers;title=Forum%20Nokia,http%3A%2F%2Fforum.nokia.com',])
+ share( ['data:text/x-url;title=%s;description=%s,%s' %(urllib.quote(title), description, urllib.quote(link)),] )
+
+ @QtCore.Slot(str, result=bool)
+ def getFeedEventStatus(self, key):
+ from gconf import client_get_defaults
+ return client_get_default().get_bool('/apps/ControlPanel/FeedingIt/EnableFeed/'+key)
+
+ @QtCore.Slot(str)
+ def switchEventFeedStatus(self, key):
+ from gconf import client_get_defaults
+ value = client_get_default().get_bool('/apps/ControlPanel/FeedingIt/EventFeed/Hide/'+key)
+ if value:
+ client_get_default().unset('/apps/ControlPanel/FeedingIt/EventFeed/Hide/'+key)
+ else:
+ client_get_default().set_bool('/apps/ControlPanel/FeedingIt/EventFeed/Hide/'+key, True)
+
+def main():
if not isdir(CONFIGDIR):
try:
mkdir(CONFIGDIR)
app = QtGui.QApplication(sys.argv)
view = QtDeclarative.QDeclarativeView()
- global articlesModel
- feedsModel = FeedsModel()
- articlesModel = ArticlesModel()
-
controller = Controller(listing)
+ # listen on dbus for download update progress
+ bus = dbus.SessionBus()
+
+ bus.add_signal_receiver(handler_function=controller.update_progress,
+ bus_name=None,
+ signal_name='UpdateProgress',
+ dbus_interface='org.marcoz.feedingit',
+ path='/org/marcoz/feedingit/update')
+
+ bus.add_signal_receiver(handler_function=controller.articleCountUpdated,
+ bus_name=None,
+ signal_name='ArticleCountUpdated',
+ dbus_interface='org.marcoz.feedingit',
+ path='/org/marcoz/feedingit/update')
+ bus.add_signal_receiver(handler_function=controller.update_started,
+ bus_name=None,
+ signal_name='UpdateStarted',
+ dbus_interface='org.marcoz.feedingit',
+ path='/org/marcoz/feedingit/update')
+ bus.add_signal_receiver(handler_function=controller.update_finished,
+ bus_name=None,
+ signal_name='UpdateFinished',
+ dbus_interface='org.marcoz.feedingit',
+ path='/org/marcoz/feedingit/update')
+
+ global root
rc = view.rootContext()
rc.setContextProperty('controller', controller)
- rc.setContextProperty('feedsModel', feedsModel)
- rc.setContextProperty('articlesModel', articlesModel)
# Comment the two lines below if you don't want to use OpenGL for QML rendering or if it is not supported
- glw = QtOpenGL.QGLWidget()
- view.setViewport(glw)
+ #glw = QtOpenGL.QGLWidget()
+ #view.setViewport(glw)
if os.path.exists('/usr/share/feedingit/qml'):
+ glw = QtOpenGL.QGLWidget()
+ view.setViewport(glw)
view.setSource('/usr/share/feedingit/qml/main.qml')
+ view.showFullScreen()
else:
- #view.setSource(os.path.join('qml','main.qml'))
- view.setSource(os.path.join('qml','FeedingIt.qml'))
+ view.setSource(os.path.join('qml','main.qml'))
+ view.show()
+ #view.setSource(os.path.join('qml','FeedingIt.qml'))
+ root = view.rootObject()
#view.showFullScreen()
- view.show()
+ #view.show()
sys.exit(app.exec_())
-if __name__ == "__main__":
-
+if __name__ == "__main__":
main()