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
12 # import python dbus GLib mainloop support
13 import dbus.mainloop.glib
14 # Enable glib main loop support
15 dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
17 # Comment the line below if you don't want to use OpenGL for QML rendering or if it is not supported
18 from PySide import QtOpenGL, QtCore
20 from rss_sqlite import Listing
21 CONFIGDIR = environ.get("HOME", "/home/user") + "/.feedingit/"
22 #CONFIGDIR = "/home/user/.feedingit"
25 logger = logging.getLogger(__name__)
28 debugging.init(dot_directory=".feedingit", program_name="feedingit-pyside")
30 from cgi import escape
33 class Controller(QtCore.QObject):
35 def __init__(self, listing):
36 QtCore.QObject.__init__(self)
37 from XmlHandler import XmlHandler
38 self._handler = XmlHandler(listing)
40 def update_progress(self, percent_complete,
41 completed, in_progress, queued,
42 bytes_downloaded, bytes_updated, bytes_per_second,
44 total = completed + in_progress + queued
45 root.updateProgress(int(total), int(completed))
47 def articleCountUpdated(self):
48 print "article updated"
50 def update_started(self):
53 def update_finished(self):
56 @QtCore.Slot(str,str, result=str)
57 def getArticle(self, key, article):
58 feed = listing.getFeed(key)
60 file = codecs.open(feed.getContentLink(article), "r", "utf-8")
61 html = file.read().replace("body", "body bgcolor='#ffffff'", 1)
64 html = u"<html><body>Error retrieving article</body></html>"
67 @QtCore.Slot(str, result=str)
68 def getFeedsXml(self, catid):
69 return self._handler.generateFeedsXml(catid)
71 @QtCore.Slot(str,result=str)
72 def getArticlesXml(self, key):
73 #onlyUnread = arguments.get("onlyUnread","False")
74 return self._handler.generateArticlesXml(key, config.getHideReadArticles())
76 @QtCore.Slot(str,str,result=str)
77 def getNextId(self, key, articleid):
78 feed = listing.getFeed(key)
79 return feed.getNextId(articleid)
81 @QtCore.Slot(str,str,result=str)
82 def getPreviousId(self, key, articleid):
83 feed = listing.getFeed(key)
84 return feed.getPreviousId(articleid)
86 @QtCore.Slot(result=str)
87 def getCategoryXml(self):
88 return self._handler.generateCategoryXml()
90 @QtCore.Slot(QtCore.QObject)
91 def feedClicked(self, wrapper):
92 #print 'User clicked on:', wrapper._key
93 #articlesModel.updateModel(wrapper._key)
97 def updateFeed(self, key):
98 listing.updateFeed(key)
102 for catid in listing.getListOfCategories():
103 for feed in listing.getSortedListOfKeys("Manual", category=catid):
104 listing.updateFeed(feed)
107 def updateCategory(self, catid):
108 for feed in listing.getSortedListOfKeys("Manual", category=catid):
109 listing.updateFeed(feed)
111 @QtCore.Slot(str,str,str)
112 def addFeed(self, title, url, catid):
113 listing.addFeed(title,url, category=catid)
116 def addCategory(self, name):
117 listing.addCategory(name)
120 def removeFeed(self, key):
121 listing.removeFeed(key)
124 def removeCategory(self, catid):
125 listing.removeCategory(catid)
128 def markAllAsRead(self, key):
129 feed = listing.getFeed(key)
131 listing.updateUnread(key)
133 @QtCore.Slot(str, str)
134 def setEntryRead(self, key, articleid):
135 feed = listing.getFeed(key)
136 feed.setEntryRead(articleid)
137 listing.updateUnread(key)
139 @QtCore.Slot(str, result=str)
140 def getConfig(self, item):
141 if (item == "hideReadFeed"):
143 if (item == "hideReadArticles"):
147 @QtCore.Slot(str, str)
148 def populateFileDialog(self, path, type):
151 for file in glob.glob(path+type):
153 root.addFileNotification(file, os.path.basename(file))
155 @QtCore.Slot(str, result=int)
156 def importOpml(self, filename):
157 from opml_lib import parseOpml
158 file = open(filename, "r")
159 feeds = parseOpml(file.read())
161 for (title, url) in feeds:
162 listing.addFeed(title, url)
165 @QtCore.Slot(str, result=str)
166 def exportOpml(self, filename="/home/user/MyDocs/feedingit-export.opml"):
167 logger.debug("ExportOpmlData: %s" % filename)
168 from opml_lib import getOpmlText
170 str = getOpmlText(listing)
171 file = open(filename, "w")
176 logger.debug("Error exporting: %s" % filename)
179 @QtCore.Slot(str, result=bool)
180 def getBooleanSetting(self, setting):
181 if (setting == "theme"):
182 return config.getTheme()
183 elif (setting == "imageCache" ):
184 return config.getImageCache()
185 elif (setting == "hideReadFeeds"):
186 return config.getHideReadFeeds()
187 elif (setting == "hideReadArticles"):
188 return config.getHideReadArticles()
189 elif (setting == "autoupdate"):
190 return config.isAutoUpdateEnabled()
194 @QtCore.Slot(str, result=int)
195 def getIntSetting(self, setting):
196 if (setting == "artFontSize"):
197 return config.getArtFontSize()
198 elif (setting == "fontSize" ):
199 return config.getFontSize()
203 @QtCore.Slot(str, bool)
204 def setBooleanSetting(self, setting, value):
205 if (setting == "theme"):
206 config.setTheme(value)
207 elif (setting == "imageCache" ):
208 config.setImageCache(value)
209 elif (setting == "hideReadFeeds"):
210 config.setHideReadFeeds(value)
211 elif (setting == "hideReadArticles"):
212 config.setHideReadArticles(value)
213 elif (setting == "autoupdate"):
214 config.setAutoUpdateEnabled(value)
217 @QtCore.Slot(str, int)
218 def setIntSetting(self, setting, value):
219 if (setting == "artFontSize"):
220 config.setArtFontSize(value)
221 elif (setting == "fontSize" ):
222 config.setFontSize(value)
225 @QtCore.Slot(str, str)
226 def share(self, key, articleid):
227 feed = listing.getFeed(key)
228 title = feed.getTitle(articleid)
229 link = feed.getExternalLink(articleid)
230 description = 'Shared%20via%20FeedingIt%20on%20Meego'
232 bus = dbus.SessionBus()
233 shareService = bus.get_object('com.nokia.ShareUi', '/')
234 share = shareService.get_dbus_method('share', 'com.nokia.maemo.meegotouch.ShareUiInterface')
235 #share([u'data:text/x-url;description=Support%20for%20Nokia%20Developers;title=Forum%20Nokia,http%3A%2F%2Fforum.nokia.com',])
236 share( ['data:text/x-url;title=%s;description=%s,%s' %(urllib.quote(title), description, urllib.quote(link)),] )
239 if not isdir(CONFIGDIR):
243 logger.error("Error: Can't create configuration directory")
247 from config import Config
249 config = Config(None,CONFIGDIR+"config.ini")
252 listing = Listing(config, CONFIGDIR)
257 from jobmanager import JobManager
260 app = QtGui.QApplication(sys.argv)
261 view = QtDeclarative.QDeclarativeView()
263 controller = Controller(listing)
265 # listen on dbus for download update progress
266 bus = dbus.SessionBus()
268 bus.add_signal_receiver(handler_function=controller.update_progress,
270 signal_name='UpdateProgress',
271 dbus_interface='org.marcoz.feedingit',
272 path='/org/marcoz/feedingit/update')
274 bus.add_signal_receiver(handler_function=controller.articleCountUpdated,
276 signal_name='ArticleCountUpdated',
277 dbus_interface='org.marcoz.feedingit',
278 path='/org/marcoz/feedingit/update')
279 bus.add_signal_receiver(handler_function=controller.update_started,
281 signal_name='UpdateStarted',
282 dbus_interface='org.marcoz.feedingit',
283 path='/org/marcoz/feedingit/update')
284 bus.add_signal_receiver(handler_function=controller.update_finished,
286 signal_name='UpdateFinished',
287 dbus_interface='org.marcoz.feedingit',
288 path='/org/marcoz/feedingit/update')
291 rc = view.rootContext()
293 rc.setContextProperty('controller', controller)
295 # Comment the two lines below if you don't want to use OpenGL for QML rendering or if it is not supported
296 #glw = QtOpenGL.QGLWidget()
297 #view.setViewport(glw)
299 if os.path.exists('/usr/share/feedingit/qml'):
300 glw = QtOpenGL.QGLWidget()
301 view.setViewport(glw)
302 view.setSource('/usr/share/feedingit/qml/main.qml')
303 view.showFullScreen()
305 view.setSource(os.path.join('qml','main.qml'))
307 #view.setSource(os.path.join('qml','FeedingIt.qml'))
308 root = view.rootObject()
310 #view.showFullScreen()
312 sys.exit(app.exec_())
314 if __name__ == "__main__":