from portrait import FremantleRotation
from threading import Thread, activeCount
from feedingitdbus import ServerObject
-from updatedbus import UpdateServerObject, get_lock
from config import Config
from cgi import escape
import weakref
+import dbus
import debugging
import logging
logger = logging.getLogger(__name__)
from opml import GetOpmlData, ExportOpmlData
import mainthread
-from jobmanager import JobManager
from socket import setdefaulttimeout
timeout = 5
if hasattr (cls, 'class_init_done'):
return
- jm = JobManager ()
- jm.stats_hook_register (cls.update_progress,
- run_in_main_thread=True)
-
cls.downloadbars = []
# Total number of jobs we are monitoring.
cls.total = 0
cls.class_init_done = True
+ bus = dbus.SessionBus()
+ bus.add_signal_receiver(handler_function=cls.update_progress,
+ bus_name=None,
+ signal_name='UpdateProgress',
+ dbus_interface='org.marcoz.feedingit',
+ path='/org/marcoz/feedingit/update')
+
def __init__(self, parent):
self.class_init ()
@classmethod
def downloading(cls):
- return hasattr (cls, 'jobs_at_start')
+ cls.class_init ()
+ return cls.done != cls.total
@classmethod
- def update_progress(cls, jm, old_stats, new_stats, updated_feed):
- if not cls.downloading():
- cls.jobs_at_start = old_stats['jobs-completed']
-
+ def update_progress(cls, percent_complete,
+ completed, in_progress, queued,
+ bytes_downloaded, bytes_updated, bytes_per_second,
+ feed_updated):
if not cls.downloadbars:
return
- if new_stats['jobs-in-progress'] + new_stats['jobs-queued'] == 0:
- del cls.jobs_at_start
+ cls.total = completed + in_progress + queued
+ cls.done = completed
+ cls.progress = percent_complete / 100.
+ if cls.progress < 0: cls.progress = 0
+ if cls.progress > 1: cls.progress = 1
+
+ if feed_updated:
for ref in cls.downloadbars:
bar = ref ()
if bar is None:
# The download bar disappeared.
cls.downloadbars.remove (ref)
else:
- bar.emit("download-done", None)
- return
+ bar.emit("download-done", feed_updated)
- # This should never be called if new_stats['jobs'] is 0, but
- # just in case...
- cls.total = max (1, new_stats['jobs'] - cls.jobs_at_start)
- cls.done = new_stats['jobs-completed'] - cls.jobs_at_start
- cls.progress = 1 - (new_stats['jobs-in-progress'] / 2.
- + new_stats['jobs-queued']) / cls.total
- cls.update_bars()
-
- if updated_feed:
+ if in_progress == 0 and queued == 0:
for ref in cls.downloadbars:
bar = ref ()
if bar is None:
# The download bar disappeared.
cls.downloadbars.remove (ref)
else:
- bar.emit("download-done", updated_feed)
+ bar.emit("download-done", None)
+ return
+
+ cls.update_bars()
@classmethod
def update_bars(cls):
iface.open_new_window(link)
class DisplayFeed(hildon.StackableWindow):
- def __init__(self, listing, feed, title, key, config, updateDbusHandler):
+ def __init__(self, listing, feed, title, key, config):
hildon.StackableWindow.__init__(self)
self.listing = listing
self.feed = feed
self.key=key
self.current = list()
self.config = config
- self.updateDbusHandler = updateDbusHandler
self.downloadDialog = False
#self.feed.saveFeed(CONFIGDIR)
self.displayFeed()
- def button_update_clicked(self, button):
+
+ def do_update_feed(self):
self.listing.updateFeed (self.key, priority=-1)
+
+ def button_update_clicked(self, button):
+ gobject.idle_add(self.do_update_feed)
def show_download_bar(self):
if not type(self.downloadDialog).__name__=="DownloadBar":
self.show_all()
def onDownloadDone(self, widget, feed):
- if feed == self.feed or feed is None:
- self.downloadDialog.destroy()
- self.downloadDialog = False
+ if feed == self.feed:
self.feed = self.listing.getFeed(self.key)
self.displayFeed()
- self.updateDbusHandler.ArticleCountUpdated()
+
+ if feed is None:
+ self.downloadDialog.destroy()
+ self.downloadDialog = False
def buttonReadAllClicked(self, button):
#self.clear()
self.config = Config(self.window, CONFIGDIR+"config.ini")
gobject.idle_add(self.createWindow)
- # This is set to try when the user interacts with the program.
- # If, after an update is complete, we discover that the
- # environment variable DBUS_STARTED_ADDRESS is set and
- # self.had_interaction is False, we quit.
- self.had_interaction = False
-
def createWindow(self):
self.category = 0
-
- self.app_lock = get_lock("app_lock")
- if self.app_lock == None:
- try:
- self.stopButton.set_sensitive(True)
- except:
- self.stopButton = hildon.Button(gtk.HILDON_SIZE_AUTO_WIDTH | gtk.HILDON_SIZE_FINGER_HEIGHT, hildon.BUTTON_ARRANGEMENT_VERTICAL)
- self.stopButton.set_text("Stop update","")
- self.stopButton.connect("clicked", self.stop_running_update)
- self.mainVbox.pack_end(self.stopButton, expand=False, fill=False)
- self.window.show_all()
- self.introLabel.set_label("Update in progress, please wait.")
- gobject.timeout_add_seconds(3, self.createWindow)
- return False
- try:
- self.stopButton.destroy()
- except:
- pass
self.listing = Listing(self.config, CONFIGDIR)
self.downloadDialog = False
hildon.hildon_gtk_window_set_progress_indicator(self.window, 0)
gobject.idle_add(self.late_init)
- def job_manager_update(self, jm, old_stats, new_stats, updated_feed):
- if (not self.downloadDialog
- and new_stats['jobs-in-progress'] + new_stats['jobs-queued'] > 0):
- self.updateDbusHandler.UpdateStarted()
-
+ def update_progress(self, percent_complete,
+ completed, in_progress, queued,
+ bytes_downloaded, bytes_updated, bytes_per_second,
+ updated_feed):
+ if (in_progress or queued) and not self.downloadDialog:
self.downloadDialog = DownloadBar(self.window)
self.downloadDialog.connect("download-done", self.onDownloadDone)
self.mainVbox.pack_end(self.downloadDialog, expand=False, fill=False)
self.downloadDialog.destroy()
self.downloadDialog = False
self.displayListing()
- self.updateDbusHandler.UpdateFinished()
- self.updateDbusHandler.ArticleCountUpdated()
-
- if not self.had_interaction and 'DBUS_STARTER_ADDRESS' in environ:
- logger.info(
- "Update complete. No interaction, started by dbus: quitting.")
- self.quit()
- def stop_running_update(self, button):
- self.stopButton.set_sensitive(False)
- import dbus
- bus=dbus.SessionBus()
- remote_object = bus.get_object("org.marcoz.feedingit", # Connection name
- "/org/marcoz/feedingit/update" # Object's path
- )
- iface = dbus.Interface(remote_object, 'org.marcoz.feedingit')
- iface.StopUpdate()
-
- def increase_download_parallelism(self):
- # The system has been idle for a while. Enable parallel
- # downloads.
- JobManager().num_threads = 4
- gobject.source_remove (self.increase_download_parallelism_id)
- del self.increase_download_parallelism_id
- return False
-
- def system_inactivity_ind(self, idle):
- # The system's idle state changed.
- if (self.am_idle and idle) or (not self.am_idle and not idle):
- # No change.
- return
-
- if not idle:
- if hasattr (self, 'increase_download_parallelism_id'):
- gobject.source_remove (self.increase_download_parallelism_id)
- del self.increase_download_parallelism_id
- else:
- self.increase_download_parallelism_id = \
- gobject.timeout_add_seconds(
- 60, self.increase_download_parallelism)
-
- if not idle:
- JobManager().num_threads = 1
-
- self.am_idle = idle
def late_init(self):
self.dbusHandler = ServerObject(self)
- self.updateDbusHandler = UpdateServerObject(self)
-
- jm = JobManager()
- jm.stats_hook_register (self.job_manager_update,
- run_in_main_thread=True)
- jm.num_threads = 1
- self.am_idle = False
- JobManager(True)
-
- import dbus
- bus = dbus.SystemBus()
- proxy = bus.get_object('com.nokia.mce',
- '/com/nokia/mce/signal')
- iface = dbus.Interface(proxy, 'com.nokia.mce.signal')
- iface.connect_to_signal('system_inactivity_ind',
- self.system_inactivity_ind)
+ bus = dbus.SessionBus()
+ bus.add_signal_receiver(handler_function=self.update_progress,
+ bus_name=None,
+ signal_name='UpdateProgress',
+ dbus_interface='org.marcoz.feedingit',
+ path='/org/marcoz/feedingit/update')
def button_markAll(self, button):
- self.had_interaction = True
for key in self.listing.getListOfFeeds():
feed = self.listing.getFeed(key)
feed.markAllAsRead()
self.displayListing()
def button_about_clicked(self, button):
- self.had_interaction = True
HeAboutDialog.present(self.window, \
__appname__, \
ABOUT_ICON, \
ABOUT_DONATE)
def button_export_clicked(self, button):
- self.had_interaction = True
opml = ExportOpmlData(self.window, self.listing)
def button_import_clicked(self, button):
- self.had_interaction = True
opml = GetOpmlData(self.window)
feeds = opml.getData()
for (title, url) in feeds:
self.displayListing()
def addFeed(self, urlIn="http://"):
- self.had_interaction = True
wizard = AddWidgetWizard(self.window, self.listing, urlIn, self.listing.getListOfCategories())
ret = wizard.run()
if ret == 2:
self.displayListing()
def button_organize_clicked(self, button):
- self.had_interaction = True
def after_closing():
self.displayListing()
SortList(self.window, self.listing, self, after_closing)
- def button_update_clicked(self, button, key):
- self.had_interaction = True
+ def do_update_feeds(self):
for k in self.listing.getListOfFeeds():
self.listing.updateFeed (k)
- #self.displayListing()
+
+ def button_update_clicked(self, button, key):
+ gobject.idle_add(self.do_update_feeds)
def onDownloadsDone(self, *widget):
self.downloadDialog.destroy()
self.downloadDialog = False
self.displayListing()
- self.updateDbusHandler.UpdateFinished()
- self.updateDbusHandler.ArticleCountUpdated()
def button_preferences_clicked(self, button):
- self.had_interaction = True
dialog = self.config.createDialog()
dialog.connect("destroy", self.prefsClosed)
# pass
def on_feedList_row_activated(self, treeview, path, column):
- self.had_interaction = True
model = treeview.get_model()
iter = model.get_iter(path)
key = model.get_value(iter, COLUMN_KEY)
self.openFeed(key)
def openFeed(self, key):
- try:
- self.feed_lock
- except:
- # If feed_lock doesn't exist, we can open the feed, else we do nothing
- if key != None:
- self.feed_lock = get_lock(key)
- self.disp = DisplayFeed(self.listing, self.listing.getFeed(key), \
- self.listing.getFeedTitle(key), key, \
- self.config, self.updateDbusHandler)
- self.disp.connect("feed-closed", self.onFeedClosed)
+ if key != None:
+ self.disp = DisplayFeed(
+ self.listing, self.listing.getFeed(key),
+ self.listing.getFeedTitle(key), key,
+ self.config)
+ self.disp.connect("feed-closed", self.onFeedClosed)
def openArticle(self, key, id):
- try:
- self.feed_lock
- except:
- # If feed_lock doesn't exist, we can open the feed, else we do nothing
- if key != None:
- self.feed_lock = get_lock(key)
- self.disp = DisplayFeed(self.listing, self.listing.getFeed(key), \
- self.listing.getFeedTitle(key), key, \
- self.config, self.updateDbusHandler)
- self.disp.button_clicked(None, id)
- self.disp.connect("feed-closed", self.onFeedClosed)
-
+ if key != None:
+ self.openFeed(key)
+ self.disp.button_clicked(None, id)
def onFeedClosed(self, object, key):
- #self.listing.saveConfig()
- #del self.feed_lock
- gobject.idle_add(self.onFeedClosedTimeout)
self.displayListing()
- #self.updateDbusHandler.ArticleCountUpdated()
- def onFeedClosedTimeout(self):
- del self.feed_lock
- self.updateDbusHandler.ArticleCountUpdated()
-
def quit(self, *args):
self.window.hide()
-
- if hasattr (self, 'app_lock'):
- del self.app_lock
-
- # Wait until all slave threads have properly exited before
- # terminating the mainloop.
- jm = JobManager()
- jm.quit ()
- stats = jm.stats()
- if stats['jobs-in-progress'] == 0 and stats['jobs-queued'] == 0:
- gtk.main_quit ()
- else:
- gobject.timeout_add(500, self.quit)
-
- return False
+ gtk.main_quit ()
def run(self):
self.window.connect("destroy", self.quit)
self.button_update_clicked(None, None)
return True
- def stopUpdate(self):
- # Not implemented in the app (see update_feeds.py)
- try:
- JobManager().cancel ()
- except:
- pass
-
def getStatus(self):
status = ""
for key in self.listing.getListOfFeeds():