psa: using 2 flickables
[feedingit] / psa_harmattan / feedingit / deb_dist / feedingit-0.1.0 / debian / feedingit / usr / share / feedingit / feedingit.py
1 #!/usr/bin/python
2
3 import sys
4
5 from PySide import QtGui
6 from PySide import QtDeclarative
7 import os
8 from os import mkdir, remove, stat, environ
9 from os.path import isfile, isdir, exists
10 import codecs
11 import dbus
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)
16
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
19
20 from rss_sqlite import Listing
21 CONFIGDIR = environ.get("HOME", "/home/user") + "/.feedingit/"
22 #CONFIGDIR = "/home/user/.feedingit"
23
24 import logging
25 logger = logging.getLogger(__name__)
26
27 import debugging
28 debugging.init(dot_directory=".feedingit", program_name="feedingit-pyside")
29
30 from cgi import escape
31 from re import sub
32
33 class Controller(QtCore.QObject):
34     
35     def __init__(self, listing):
36         QtCore.QObject.__init__(self)
37         from XmlHandler import XmlHandler
38         self._handler = XmlHandler(listing)
39         
40     def update_progress(self, percent_complete,
41                         completed, in_progress, queued,
42                         bytes_downloaded, bytes_updated, bytes_per_second,
43                         feed_updated):
44         total = completed + in_progress + queued
45         root.updateProgress(int(total), int(completed))
46         
47     def articleCountUpdated(self):
48         print "article updated"
49     
50     def update_started(self):
51         root.updateStarted()
52     
53     def update_finished(self):
54         root.updateFinished()
55
56     @QtCore.Slot(str,str, result=str)
57     def getArticle(self, key, article):
58        feed = listing.getFeed(key)
59        try:
60           file = codecs.open(feed.getContentLink(article), "r", "utf-8")
61           html = file.read().replace("body", "body bgcolor='#ffffff'", 1)
62           file.close()
63        except:
64           html = u"<html><body>Error retrieving article</body></html>"
65        return html
66     
67     @QtCore.Slot(str, result=str)
68     def getFeedsXml(self, catid):
69         return self._handler.generateFeedsXml(catid)
70     
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())
75     
76     @QtCore.Slot(str,str,result=str)
77     def getNextId(self, key, articleid):
78         feed = listing.getFeed(key)
79         return feed.getNextId(articleid)
80         
81     @QtCore.Slot(str,str,result=str)
82     def getPreviousId(self, key, articleid):
83         feed = listing.getFeed(key)
84         return feed.getPreviousId(articleid)
85     
86     @QtCore.Slot(result=str)
87     def getCategoryXml(self):
88         return self._handler.generateCategoryXml()
89     
90     @QtCore.Slot(QtCore.QObject)
91     def feedClicked(self, wrapper):
92         #print 'User clicked on:', wrapper._key
93         #articlesModel.updateModel(wrapper._key)
94         pass
95         
96     @QtCore.Slot(str)
97     def updateFeed(self, key):
98         listing.updateFeed(key)
99         
100     @QtCore.Slot()
101     def updateAll(self):
102         for catid in listing.getListOfCategories():
103             for feed in listing.getSortedListOfKeys("Manual", category=catid):
104                 listing.updateFeed(feed)
105
106     @QtCore.Slot(str)
107     def updateCategory(self, catid):
108         for feed in listing.getSortedListOfKeys("Manual", category=catid):
109             listing.updateFeed(feed)           
110
111     @QtCore.Slot(str,str,str)
112     def addFeed(self, title, url, catid):
113         listing.addFeed(title,url, category=catid)
114         
115     @QtCore.Slot(str)
116     def addCategory(self, name):
117         listing.addCategory(name)
118
119     @QtCore.Slot(str)
120     def removeFeed(self, key):
121         listing.removeFeed(key)
122
123     @QtCore.Slot(str)
124     def removeCategory(self, catid):
125         listing.removeCategory(catid)
126
127     @QtCore.Slot(str)
128     def markAllAsRead(self, key):
129         feed = listing.getFeed(key)
130         feed.markAllAsRead()
131         listing.updateUnread(key)
132
133     @QtCore.Slot(str, str)
134     def setEntryRead(self, key, articleid):
135         feed = listing.getFeed(key)
136         feed.setEntryRead(articleid)
137         listing.updateUnread(key)
138
139     @QtCore.Slot(str, result=str)
140     def getConfig(self, item):
141         if (item == "hideReadFeed"):
142             return "True"
143         if (item == "hideReadArticles"):
144             return "False"
145         return ""
146     
147     @QtCore.Slot(str, str)
148     def populateFileDialog(self, path, type):
149         import glob
150         import os.path
151         for file in glob.glob(path+type):
152             logger.debug(file)
153             root.addFileNotification(file, os.path.basename(file))
154     
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())
160         file.close()
161         for (title, url) in feeds:
162             listing.addFeed(title, url)
163         return len(feeds)
164     
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
169         try:
170             str = getOpmlText(listing)
171             file = open(filename, "w")
172             file.write(str)
173             file.close()
174             return filename
175         except:
176             logger.debug("Error exporting: %s" % filename)
177             return "error"
178         
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()
191         else:
192             return 'True'
193         
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()
200         else:
201             return -1
202         
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)
215         config.saveConfig()
216         
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)
223         config.saveConfig()
224
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'
231         import urllib
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)),] )
237
238 def main():
239     if not isdir(CONFIGDIR):
240         try:
241             mkdir(CONFIGDIR)
242         except:
243             logger.error("Error: Can't create configuration directory")
244             from sys import exit
245             exit(1)
246             
247     from config import Config
248     global config
249     config = Config(None,CONFIGDIR+"config.ini")
250
251     global listing
252     listing = Listing(config, CONFIGDIR)
253     
254     import mainthread
255     mainthread.init()
256
257     from jobmanager import JobManager
258     JobManager(True)
259
260     app = QtGui.QApplication(sys.argv)
261     view = QtDeclarative.QDeclarativeView()
262
263     controller = Controller(listing)
264  
265     # listen on dbus for download update progress
266     bus = dbus.SessionBus()
267     
268     bus.add_signal_receiver(handler_function=controller.update_progress,
269                             bus_name=None,
270                             signal_name='UpdateProgress',
271                             dbus_interface='org.marcoz.feedingit',
272                             path='/org/marcoz/feedingit/update')
273     
274     bus.add_signal_receiver(handler_function=controller.articleCountUpdated,
275                             bus_name=None,
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,
280                             bus_name=None,
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,
285                             bus_name=None,
286                             signal_name='UpdateFinished',
287                             dbus_interface='org.marcoz.feedingit',
288                             path='/org/marcoz/feedingit/update')
289  
290     global root
291     rc = view.rootContext()
292  
293     rc.setContextProperty('controller', controller)
294
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)
298
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()
304     else:
305         view.setSource(os.path.join('qml','main.qml'))
306         view.show()
307         #view.setSource(os.path.join('qml','FeedingIt.qml'))
308     root = view.rootObject()
309
310     #view.showFullScreen()
311     #view.show()
312     sys.exit(app.exec_())
313
314 if __name__ == "__main__": 
315     main()