def notify_done(status, ex = None, redirect = None): step.status = status step.redirect = redirect def wake_up_main(): child.join() thread_blocker.trigger(ex) return False tasks.get_loop().call_soon_threadsafe(wake_up_main)
def download(self, step, timeout = None): """ Queue up this download. If it takes too long, trigger step.dl.timeout (if any), but only count time spent actually downloading, not time spent queuing. @type step: L{DownloadStep}""" if self.active == MAX_DOWNLOADS_PER_SITE: # Too busy to start a new download now. Queue this one and wait. ticket = tasks.Blocker('queued download for ' + step.url) self.queue.append(ticket) yield ticket, step.dl._aborted if step.dl._aborted.happened: raise download.DownloadAborted() in_progress = [True] if isinstance(timeout, str): slave.start_timeout(timeout) elif timeout is not None: def timeout_cb(): if in_progress: step.dl.timeout.trigger() tasks.get_loop().call_later(timeout, timeout_cb) # Start a new thread for the download thread_blocker = _spawn_thread(step) self.active += 1 # Wait for thread to complete download. yield thread_blocker, step.dl._aborted del in_progress[0] self.active -= 1 if self.active < MAX_DOWNLOADS_PER_SITE: self.process_next() # Start next queued download, if any if step.dl._aborted.happened: # Don't wait for child to finish (might be stuck doing IO) raise download.DownloadAborted() tasks.check(thread_blocker) if step.status == download.RESULT_REDIRECT: assert step.redirect return # DownloadScheduler will handle it assert not step.redirect, step.redirect step.dl._finish(step.status)
def download(self, step, timeout=None): """ Queue up this download. If it takes too long, trigger step.dl.timeout (if any), but only count time spent actually downloading, not time spent queuing. @type step: L{DownloadStep}""" if self.active == MAX_DOWNLOADS_PER_SITE: # Too busy to start a new download now. Queue this one and wait. ticket = tasks.Blocker('queued download for ' + step.url) self.queue.append(ticket) yield ticket, step.dl._aborted if step.dl._aborted.happened: raise download.DownloadAborted() in_progress = [True] if timeout is not None: def timeout_cb(): if in_progress: step.dl.timeout.trigger() tasks.get_loop().call_later(timeout, timeout_cb) # Start a new thread for the download thread_blocker = _spawn_thread(step) self.active += 1 # Wait for thread to complete download. yield thread_blocker, step.dl._aborted del in_progress[0] self.active -= 1 if self.active < MAX_DOWNLOADS_PER_SITE: self.process_next() # Start next queued download, if any if step.dl._aborted.happened: # Don't wait for child to finish (might be stuck doing IO) raise download.DownloadAborted() tasks.check(thread_blocker) if step.status == download.RESULT_REDIRECT: assert step.redirect return # DownloadScheduler will handle it assert not step.redirect, step.redirect step.dl._finish(step.status)
def downloads_changed(self): if self.monitored_downloads and self.update is None: if self.screen_width is None: try: import curses curses.setupterm() self.screen_width = curses.tigetnum('cols') or 80 except Exception as ex: logger.info("Failed to initialise curses library: %s", ex) self.screen_width = 80 self.show_progress() self.original_print = print builtins.print = self.print self.update = tasks.get_loop().call_repeatedly(0.2, self.show_progress) elif len(self.monitored_downloads) == 0: if self.update: self.update.cancel() self.update = None builtins.print = self.original_print self.original_print = None self.clear_display()
def get_feed(self, master_feed_url, package_impls): """Generate a feed containing information about distribution packages. This should immediately return a feed containing an implementation for the package if it's already installed. Information about versions that could be installed using the distribution's package manager can be added asynchronously later (see L{fetch_candidates}). @rtype: L{model.ZeroInstallFeed}""" feed = model.ZeroInstallFeed(None) feed.url = 'distribution:' + master_feed_url for item, item_attrs, _depends in package_impls: package = item_attrs.get('package', None) if package is None: raise model.InvalidInterface(_("Missing 'package' attribute on %s") % item) new_impls = [] def factory(id, only_if_missing = False, installed = True): assert id.startswith('package:') if id in feed.implementations: if only_if_missing: return None logger.warning(_("Duplicate ID '%s' for DistributionImplementation"), id) impl = model.DistributionImplementation(feed, id, self, item) feed.implementations[id] = impl new_impls.append(impl) impl.installed = installed impl.metadata = item_attrs if impl.main is None: item_main = item_attrs.get('main', None) if item_main: impl.main = item_main impl.upstream_stability = model.packaged return impl self.get_package_info(package, factory) for impl in new_impls: self.fixup(package, impl) if impl.installed: self.installed_fixup(impl) if master_feed_url == _PYTHON_URI and os.name != "nt": # Hack: we can support Python on platforms with unsupported package managers # by adding the implementation of Python running us now to the list. python_version = '.'.join([str(v) for v in sys.version_info if isinstance(v, int)]) impl_id = 'package:host:python:' + python_version assert impl_id not in feed.implementations impl = model.DistributionImplementation(feed, impl_id, self, distro_name = 'host') impl.installed = True impl.version = model.parse_version(python_version) impl.main = sys.executable or '/usr/bin/python' impl.upstream_stability = model.packaged impl.machine = host_machine # (hopefully) _set_quick_test(impl, sys.executable) feed.implementations[impl_id] = impl elif master_feed_url == 'http://repo.roscidus.com/python/python-gobject' and os.name != "nt": gobject = get_loop().gobject if gobject: # Likewise, we know that there is a native python-gobject available for our Python impl_id = 'package:host:python-gobject:' + '.'.join(str(x) for x in gobject.pygobject_version) assert impl_id not in feed.implementations impl = model.DistributionImplementation(feed, impl_id, self, distro_name = 'host') impl.installed = True impl.version = [list(gobject.pygobject_version)] impl.upstream_stability = model.packaged impl.machine = host_machine # (hopefully) if gobject.__file__.startswith('<'): _set_quick_test(impl, gobject.__path__) # Python 3 else: _set_quick_test(impl, gobject.__file__) # Python 2 feed.implementations[impl_id] = impl return feed
# Copyright (C) 2009, Thomas Leonard # See the README file for details, or visit http://0install.net. from zeroinstall import _ import os import gtk from zeroinstall.gtkui import gtkutils from zeroinstall.support.tasks import get_loop from zeroinstall import SafeException from zeroinstall.injector import model from zeroinstall.injector.namespaces import XMLNS_IFACE from zeroinstall.injector.iface_cache import iface_cache glib = get_loop().glib _RESPONSE_PREV = 0 _RESPONSE_NEXT = 1 def N_(message): return message categories = [ N_('AudioVideo'), N_('Audio'), N_('Video'), N_('Development'), N_('Education'), N_('Game'), N_('Graphics'), N_('Network'),
# Copyright (C) 2009, Thomas Leonard # See the README file for details, or visit http://0install.net. from zeroinstall import _ import os import gtk from zeroinstall.gtkui import gtkutils from zeroinstall.support.tasks import get_loop from zeroinstall import SafeException from zeroinstall.injector import model from zeroinstall.injector.namespaces import XMLNS_IFACE from zeroinstall.injector.iface_cache import iface_cache gobject = get_loop().gobject _RESPONSE_PREV = 0 _RESPONSE_NEXT = 1 def N_(message): return message categories = [ N_('AudioVideo'), N_('Audio'), N_('Video'), N_('Development'), N_('Education'), N_('Game'), N_('Graphics'), N_('Network'),
# Copyright (C) 2009, Thomas Leonard # See the README file for details, or visit http://0install.net. from __future__ import print_function from zeroinstall import _ import os, sys import gtk from zeroinstall.injector import namespaces, model from zeroinstall.zerostore import BadDigest, manifest from zeroinstall import support from zeroinstall.support import basedir, tasks from zeroinstall.gtkui import help_box, gtkutils gobject = tasks.get_loop().gobject __all__ = ['CacheExplorer'] ROX_IFACE = 'http://rox.sourceforge.net/2005/interfaces/ROX-Filer' def escape(tooltip): return tooltip.replace('<', '<').strip() # Tree view columns class Column(object): columns = [] def __init__(self, name, column_type, resizable=False, props={}, hide=False, markup=False): self.idx = len(self.columns) self.columns.append(self) self.name = name
# Copyright (C) 2009, Thomas Leonard # See the README file for details, or visit http://0install.net. from zeroinstall import _ from zeroinstall.support import tasks from zeroinstall.injector import handler, download gobject = tasks.get_loop().gobject glib = tasks.get_loop().glib version = '2.3.3' class GUIHandler(handler.Handler): dl_callbacks = None # Download -> [ callback ] pulse = None mainwindow = None def _reset_counters(self): if not self.monitored_downloads: self.n_completed_downloads = 0 self.total_bytes_downloaded = 0 return False def abort_all_downloads(self): for dl in self.monitored_downloads: dl.abort() def downloads_changed(self): if self.monitored_downloads and self.pulse is None: def pulse(): self.mainwindow.update_download_status(only_update_visible = True)
"""A GTK dialog which displays a list of Zero Install applications in the menu.""" # Copyright (C) 2009, Thomas Leonard # See the README file for details, or visit http://0install.net. from zeroinstall import _ from zeroinstall.support.tasks import get_loop import os, sys import gtk, pango import subprocess from zeroinstall import support from zeroinstall.gtkui import icon, xdgutils, gtkutils from zeroinstall.injector import reader, model, namespaces gobject = get_loop().gobject gtk2 = sys.version_info[0] < 3 def _pango_escape(s): return s.replace('&', '&').replace('<', '<') class AppList(object): """A list of applications which can be displayed in an L{AppListBox}. For example, a program might implement this to display a list of plugins. This default implementation lists applications in the freedesktop.org menus. """ def get_apps(self): """Return a list of application URIs.""" self.apps = xdgutils.discover_existing_apps()
# Copyright (C) 2009, Thomas Leonard # See the README file for details, or visit http://0install.net. from zeroinstall import _ from zeroinstall.support import tasks from zeroinstall.injector import handler, download gobject = tasks.get_loop().gobject glib = tasks.get_loop().glib version = '2.3.3' class GUIHandler(handler.Handler): dl_callbacks = None # Download -> [ callback ] pulse = None mainwindow = None def _reset_counters(self): if not self.monitored_downloads: self.n_completed_downloads = 0 self.total_bytes_downloaded = 0 return False def abort_all_downloads(self): for dl in self.monitored_downloads: dl.abort() def downloads_changed(self): if self.monitored_downloads and self.pulse is None:
# Copyright (C) 2009, Thomas Leonard # See the README file for details, or visit http://0install.net. from zeroinstall import _ import os import gtk from zeroinstall.gtkui import gtkutils from zeroinstall.support.tasks import get_loop from zeroinstall import SafeException from zeroinstall.injector import model from zeroinstall.injector.namespaces import XMLNS_IFACE from zeroinstall.injector.iface_cache import iface_cache glib = get_loop().glib _RESPONSE_PREV = 0 _RESPONSE_NEXT = 1 def N_(message): return message categories = [ N_('AudioVideo'), N_('Audio'), N_('Video'), N_('Development'), N_('Education'),