5 from PySide import QtGui
6 from PySide import QtDeclarative
8 from os import mkdir, remove, stat, environ
9 from os.path import isfile, isdir, exists
11 # Comment the line below if you don't want to use OpenGL for QML rendering or if it is not supported
12 from PySide import QtOpenGL, QtCore
14 from rss_sqlite import Listing
15 CONFIGDIR = environ.get("HOME", "/home/user") + "/.feedingit"
16 #CONFIGDIR = "/home/user/.feedingit"
19 #logger = logging.getLogger(__name__)
22 debugging.init(dot_directory=".feedingit", program_name="feedingit-pyside")
24 from cgi import escape
27 class FeedWrapper(QtCore.QObject):
28 def __init__(self, key):
29 QtCore.QObject.__init__(self)
32 return listing.getFeedTitle(self._key)
34 return listing.getFeedNumberOfUnreadItems(self._key)
35 def _updatedDate(self):
36 return listing.getFeedUpdateTime(self._key)
38 return listing.getFavicon(self._key)
44 changed = QtCore.Signal()
46 title = QtCore.Property(unicode, _name, notify=changed)
47 feedid = QtCore.Property(unicode, _feedid, notify=changed)
48 unread = QtCore.Property(unicode, _unread, notify=changed)
49 updatedDate= QtCore.Property(unicode, _updatedDate, notify=changed)
50 icon = QtCore.Property(unicode, _icon, notify=changed)
51 updating = QtCore.Property(unicode, _icon, notify=changed)
53 class FeedsModel(QtCore.QAbstractListModel):
58 QtCore.QAbstractListModel.__init__(self)
59 self._feeds = listing.getListOfFeeds(self._category)
60 self.setRoleNames(dict(enumerate(FeedsModel.COLUMNS)))
62 def rowCount(self, parent=QtCore.QModelIndex()):
63 return len(self._feeds)
65 def data(self, index, role):
66 if index.isValid() and role == FeedsModel.COLUMNS.index('feed'):
67 print self._feeds[index.row()]
68 return FeedWrapper(self._feeds[index.row()])
71 class ArticleWrapper(QtCore.QObject):
72 def __init__(self, feed, articleid):
73 QtCore.QObject.__init__(self)
75 self._articleid = articleid
77 return self.fix_title(self._feed.getTitle(self._articleid))
79 return str(self._feed.isEntryRead(self._articleid))
80 def _getarticleid(self):
81 return self._articleid
82 def _updatedDate(self):
83 return self._feed.getDateStamp(self._articleid)
85 return self._feed.getContentLink(self._articleid)
87 changed = QtCore.Signal()
89 title = QtCore.Property(unicode, _name, notify=changed)
90 articleid = QtCore.Property(unicode, _getarticleid, notify=changed)
91 unread = QtCore.Property(unicode, _unread, notify=changed)
92 updatedDate= QtCore.Property(unicode, _updatedDate, notify=changed)
93 path = QtCore.Property(unicode, _path, notify=changed)
95 class ArticlesModel(QtCore.QAbstractListModel):
96 COLUMNS = ('article', )
102 QtCore.QAbstractListModel.__init__(self)
103 self.setRoleNames(dict(enumerate(ArticlesModel.COLUMNS)))
105 def updateModel(self, key):
107 self._feed = listing.getFeed(self._key)
108 self._articles = self._feed.getIds()
110 def rowCount(self, parent=QtCore.QModelIndex()):
111 print "art " + str(len(self._articles))
112 return len(self._articles)
114 def data(self, index, role):
115 print "data" + str(index) + " " + str(role)
116 if index.isValid() and role == ArticlesModel.COLUMNS.index('article'):
117 return ArticleWrapper(self._articles[index.row()])
120 class Controller(QtCore.QObject):
122 def __init__(self, listing):
123 QtCore.QObject.__init__(self)
124 from XmlHandler import XmlHandler
125 self._handler = XmlHandler(listing)
127 @QtCore.Slot(str,str, result=str)
128 def getArticle(self, key, article):
129 feed = listing.getFeed(key)
131 file = open(feed.getContentLink(article))
132 html = file.read().replace("body", "body bgcolor='#ffffff'", 1)
135 html = "<html><body>Error retrieving article</body></html>"
138 @QtCore.Slot(str, result=str)
139 def getFeedsXml(self, catid):
140 return self._handler.generateFeedsXml(catid)
142 @QtCore.Slot(str,result=str)
143 def getArticlesXml(self, key):
144 #onlyUnread = arguments.get("onlyUnread","False")
145 return self._handler.generateArticlesXml(key, "False")
147 @QtCore.Slot(result=str)
148 def getCategoryXml(self):
149 return self._handler.generateCategoryXml()
151 @QtCore.Slot(QtCore.QObject)
152 def feedClicked(self, wrapper):
153 #print 'User clicked on:', wrapper._key
154 #articlesModel.updateModel(wrapper._key)
158 def updateFeed(self, key):
159 print 'updating feed ', key
160 listing.updateFeed(key)
164 for feed in listing.getListOfFeeds("Manual"):
165 listing.updateFeed(feed)
167 @QtCore.Slot(str,str,str)
168 def addFeed(self, title, url, catid):
169 listing.addFeed(title,url, category=catid)
172 def addCategory(self, name):
173 listing.addCategory(name)
176 def markAllAsRead(self, key):
177 feed = listing.getFeed(key)
180 @QtCore.Slot(str, str)
181 def setEntryRead(self, key, articleid):
182 feed = listing.getFeed(key)
183 feed.setEntryRead(articleid)
184 listing.updateUnread(key)
186 @QtCore.Slot(str, result=str)
187 def getConfig(self, item):
188 if (item == "hideReadFeed"):
190 if (item == "hideReadArticles"):
196 if not isdir(CONFIGDIR):
200 logger.error("Error: Can't create configuration directory")
204 from config import Config
206 config = Config(None,CONFIGDIR+"config.ini")
209 listing = Listing(config, CONFIGDIR)
214 from jobmanager import JobManager
217 app = QtGui.QApplication(sys.argv)
218 view = QtDeclarative.QDeclarativeView()
221 feedsModel = FeedsModel()
222 articlesModel = ArticlesModel()
224 controller = Controller(listing)
226 rc = view.rootContext()
228 rc.setContextProperty('controller', controller)
229 rc.setContextProperty('feedsModel', feedsModel)
230 rc.setContextProperty('articlesModel', articlesModel)
232 # Comment the two lines below if you don't want to use OpenGL for QML rendering or if it is not supported
233 glw = QtOpenGL.QGLWidget()
234 view.setViewport(glw)
236 if os.path.exists('/usr/share/feedingit/qml'):
237 view.setSource('/usr/share/feedingit/qml/main.qml')
239 #view.setSource(os.path.join('qml','main.qml'))
240 view.setSource(os.path.join('qml','FeedingIt.qml'))
242 #view.showFullScreen()
244 sys.exit(app.exec_())
246 if __name__ == "__main__":