psa: added progress bar for updates
[feedingit] / psa_harmattan / feedingit / deb_dist / feedingit-0.1.0 / pysrc / 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         logger.info(feed_updated)
45         total = completed + in_progress + queued
46         root.updateProgress(total, completed)
47     
48     def update_started(self):
49         root.updateStarted()
50     
51     def update_finished(self):
52         root.updateFinished()
53
54     @QtCore.Slot(str,str, result=str)
55     def getArticle(self, key, article):
56        feed = listing.getFeed(key)
57        try:
58           file = codecs.open(feed.getContentLink(article), "r", "utf-8")
59           html = file.read().replace("body", "body bgcolor='#ffffff'", 1)
60           file.close()
61        except:
62           html = u"<html><body>Error retrieving article</body></html>"
63        return html
64     
65     @QtCore.Slot(str, result=str)
66     def getFeedsXml(self, catid):
67         return self._handler.generateFeedsXml(catid)
68     
69     @QtCore.Slot(str,result=str)
70     def getArticlesXml(self, key):
71         #onlyUnread = arguments.get("onlyUnread","False")
72         return self._handler.generateArticlesXml(key, config.getHideReadArticles())
73     
74     @QtCore.Slot(result=str)
75     def getCategoryXml(self):
76         return self._handler.generateCategoryXml()
77     
78     @QtCore.Slot(QtCore.QObject)
79     def feedClicked(self, wrapper):
80         #print 'User clicked on:', wrapper._key
81         #articlesModel.updateModel(wrapper._key)
82         pass
83         
84     @QtCore.Slot(str)
85     def updateFeed(self, key):
86         listing.updateFeed(key)
87         
88     @QtCore.Slot()
89     def updateAll(self):
90         for catid in listing.getListOfCategories():
91             for feed in listing.getSortedListOfKeys("Manual", category=catid):
92                 listing.updateFeed(feed)
93
94     @QtCore.Slot(str)
95     def updateCategory(self, catid):
96         for feed in listing.getSortedListOfKeys("Manual", category=catid):
97             listing.updateFeed(feed)           
98
99     @QtCore.Slot(str,str,str)
100     def addFeed(self, title, url, catid):
101         listing.addFeed(title,url, category=catid)
102         
103     @QtCore.Slot(str)
104     def addCategory(self, name):
105         listing.addCategory(name)
106
107     @QtCore.Slot(str)
108     def removeFeed(self, key):
109         listing.removeFeed(key)
110
111     @QtCore.Slot(str)
112     def removeCategory(self, catid):
113         listing.removeCategory(catid)
114
115     @QtCore.Slot(str)
116     def markAllAsRead(self, key):
117         feed = listing.getFeed(key)
118         feed.markAllAsRead()
119         listing.updateUnread(key)
120
121     @QtCore.Slot(str, str)
122     def setEntryRead(self, key, articleid):
123         feed = listing.getFeed(key)
124         feed.setEntryRead(articleid)
125         listing.updateUnread(key)
126
127     @QtCore.Slot(str, result=str)
128     def getConfig(self, item):
129         if (item == "hideReadFeed"):
130             return "True"
131         if (item == "hideReadArticles"):
132             return "False"
133         return ""
134     
135     @QtCore.Slot(str, str)
136     def populateFileDialog(self, path, type):
137         import glob
138         import os.path
139         for file in glob.glob(path+type):
140             logger.debug(file)
141             root.addFileNotification(file, os.path.basename(file))
142     
143     @QtCore.Slot(str, result=int)
144     def importOpml(self, filename):
145         from opml_lib import parseOpml
146         file = open(filename, "r")
147         feeds = parseOpml(file.read())
148         file.close()
149         for (title, url) in feeds:
150             listing.addFeed(title, url)
151         return len(feeds)
152     
153     @QtCore.Slot(str, result=str)
154     def exportOpml(self, filename="/home/user/MyDocs/feedingit-export.opml"):
155         logger.debug("ExportOpmlData: %s" % filename)
156         from opml_lib import getOpmlText
157         try:
158             str = getOpmlText(listing)
159             file = open(filename, "w")
160             file.write(str)
161             file.close()
162             return filename
163         except:
164             logger.debug("Error exporting: %s" % filename)
165             return "error"
166         
167     @QtCore.Slot(str, result=bool)
168     def getBooleanSetting(self, setting):
169         if (setting == "theme"):
170             return config.getTheme()
171         elif (setting == "imageCache" ):
172             return config.getImageCache()
173         elif (setting == "hideReadFeeds"):
174             return config.getHideReadFeeds()
175         elif (setting == "hideReadArticles"):
176             return config.getHideReadArticles()
177         elif (setting == "autoupdate"):
178             return config.isAutoUpdateEnabled()
179         else:
180             return 'True'
181         
182     @QtCore.Slot(str, bool)
183     def setBooleanSetting(self, setting, value):
184         if (setting == "theme"):
185             config.setTheme(value)
186         elif (setting == "imageCache" ):
187             config.setImageCache(value)
188         elif (setting == "hideReadFeeds"):
189             config.setHideReadFeeds(value)
190         elif (setting == "hideReadArticles"):
191             config.setHideReadArticles(value)
192         elif (setting == "autoupdate"):
193             config.setAutoUpdateEnabled(value)
194         config.saveConfig()
195
196 def main():
197
198     if not isdir(CONFIGDIR):
199         try:
200             mkdir(CONFIGDIR)
201         except:
202             logger.error("Error: Can't create configuration directory")
203             from sys import exit
204             exit(1)
205             
206     from config import Config
207     global config
208     config = Config(None,CONFIGDIR+"config.ini")
209
210     global listing
211     listing = Listing(config, CONFIGDIR)
212     
213     import mainthread
214     mainthread.init()
215
216     from jobmanager import JobManager
217     JobManager(True)
218
219     app = QtGui.QApplication(sys.argv)
220     view = QtDeclarative.QDeclarativeView()
221
222     controller = Controller(listing)
223  
224     # listen on dbus for download update progress
225     bus = dbus.SessionBus()
226     bus.add_signal_receiver(handler_function=controller.update_progress,
227                             bus_name=None,
228                             signal_name='UpdateProgress',
229                             dbus_interface='org.marcoz.feedingit',
230                             path='/org/marcoz/feedingit/update')
231     bus.add_signal_receiver(handler_function=controller.update_started,
232                             bus_name=None,
233                             signal_name='UpdateStarted',
234                             dbus_interface='org.marcoz.feedingit',
235                             path='/org/marcoz/feedingit/update')
236     bus.add_signal_receiver(handler_function=controller.update_finished,
237                             bus_name=None,
238                             signal_name='UpdateFinished',
239                             dbus_interface='org.marcoz.feedingit',
240                             path='/org/marcoz/feedingit/update')
241  
242     global root
243     rc = view.rootContext()
244  
245     rc.setContextProperty('controller', controller)
246
247     # Comment the two lines below if you don't want to use OpenGL for QML rendering or if it is not supported
248     #glw = QtOpenGL.QGLWidget()
249     #view.setViewport(glw)
250
251     if os.path.exists('/usr/share/feedingit/qml'):
252         glw = QtOpenGL.QGLWidget()
253         view.setViewport(glw)
254         view.setSource('/usr/share/feedingit/qml/main.qml')
255         view.showFullScreen()
256     else:
257         view.setSource(os.path.join('qml','main.qml'))
258         view.show()
259         #view.setSource(os.path.join('qml','FeedingIt.qml'))
260     root = view.rootObject()
261
262     #view.showFullScreen()
263     #view.show()
264     sys.exit(app.exec_())
265
266 if __name__ == "__main__":
267     
268     main()