Beispiel #1
0
    def __init__(self, plugin_name):

        RT.logger.setLevel(logging.INFO)
        if __debug__: RT.register(self)

        super(GtkUI, self).__init__(plugin_name)

        self.initialized = False

        self.config = None

        self.store = LabelStore()
        self.last_updated = None
        self._tries = 0
        self._calls = []

        self._extensions = []

        self._update_funcs = []
        self._cleanup_funcs = []
Beispiel #2
0
  def __init__(self, plugin_name):

    RT.logger.setLevel(logging.INFO)
    if __debug__: RT.register(self)

    super(GtkUI, self).__init__(plugin_name)

    self.initialized = False

    self.config = None

    self.store = LabelStore()
    self.last_updated = None
    self._tries = 0
    self._calls = []

    self._extensions = []

    self._update_funcs = []
    self._cleanup_funcs = []
Beispiel #3
0
class GtkUI(Gtk3PluginBase):

    # Section: Initialization

    def __init__(self, plugin_name):

        RT.logger.setLevel(logging.INFO)
        if __debug__: RT.register(self)

        super(GtkUI, self).__init__(plugin_name)

        self.initialized = False

        self.config = None

        self.store = LabelStore()
        self.last_updated = None
        self._tries = 0
        self._calls = []

        self._extensions = []

        self._update_funcs = []
        self._cleanup_funcs = []

    def enable(self):

        log.info("Initializing %s...", self.__class__.__name__)

        self._poll_init()

    def _poll_init(self):

        client.labelplus.is_initialized().addCallback(self._check_init)

    def _check_init(self, result):

        log.debug("Waiting for core to be initialized...")

        if result == True:
            client.labelplus.get_label_updates_dict().addCallback(
                self._finish_init)
        else:
            twisted.internet.reactor.callLater(INIT_POLLING_INTERVAL,
                                               self._poll_init)

    def _finish_init(self, result):

        log.debug("Resuming initialization...")

        try:
            info = client.connection_info()
            self.daemon = "%s@%s:%s" % (info[2], info[0], info[1])

            self._load_config()
            self._update_store(result)

            self.initialized = True

            self._load_extensions()

            log.info("%s initialized", self.__class__.__name__)
        except:
            log.error("Error initializing %s", self.__class__.__name__)
            raise

        twisted.internet.reactor.callLater(0, self._update_loop)

    def _load_extensions(self):

        log.info("Loading extensions...")

        for ext in EXTENSIONS:
            try:
                log.debug("Initializing %s", ext.__name__)
                instance = ext(self)
                self._extensions.append(instance)
                if __debug__: RT.register(instance, ext.__name__)
                log.info("%s initialized", ext.__name__)
            except:
                log.exception("Error initializing %s", ext.__name__)

    # Section: Deinitialization

    def disable(self):

        log.info("Deinitializing %s...", self.__class__.__name__)

        labelplus.common.cancel_calls(self._calls)

        self._run_cleanup_funcs()
        self._unload_extensions()
        self._update_funcs = []

        self._close_config()
        self._destroy_store()

        self.initialized = False

        if __debug__: RT.report()

        log.info("%s deinitialized", self.__class__.__name__)

    def _run_cleanup_funcs(self):

        while self._cleanup_funcs:
            func = self._cleanup_funcs.pop()
            try:
                func()
            except:
                log.exception("Failed to run %s()", func.__name__)

    def _unload_extensions(self):

        log.info("Unloading extensions...")

        while self._extensions:
            ext = self._extensions.pop()
            try:
                ext.unload()
                log.info("%s deinitialized", ext.__class__.__name__)
            except:
                log.exception("Error deinitializing %s",
                              ext.__class__.__name__)

    def _destroy_store(self):

        if self.store:
            self.store.destroy()
            self.store = None

    # Section: Public

    def get_extension(self, name):

        for ext in self._extensions:
            if ext.__class__.__name__ == name:
                return ext

        return None

    def register_update_func(self, func):

        if func not in self._update_funcs:
            self._update_funcs.append(func)

    def deregister_update_func(self, func):

        if func in self._update_funcs:
            self._update_funcs.remove(func)

    def register_cleanup_func(self, func):

        if func not in self._cleanup_funcs:
            self._cleanup_funcs.append(func)

    def deregister_cleanup_func(self, func):

        if func in self._cleanup_funcs:
            self._cleanup_funcs.remove(func)

    # Section: Config

    def _load_config(self):

        config = deluge.configmanager.ConfigManager(GTKUI_CONFIG)

        # Workaround for 0.2.19.x that didn't use header
        if config.config.get("version") == 2:
            labelplus.common.config.set_version(config, 2)

        labelplus.common.config.init_config(
            config, labelplus.gtkui.config.CONFIG_DEFAULTS,
            labelplus.gtkui.config.CONFIG_VERSION,
            labelplus.gtkui.config.convert.CONFIG_SPECS)

        self._update_daemon_config(config)
        self._normalize_config(config)

        self.config = config

    def _close_config(self):

        if self.config:
            if self.initialized:
                self.config.save()

            deluge.configmanager.close(GTKUI_CONFIG)

    def _update_daemon_config(self, config):

        saved_daemons = deluge.component.get(
            "ConnectionManager").hostlist.get_hosts_info()
        if not saved_daemons:
            config["daemon"] = {}
        else:
            daemons = ["%s@%s:%s" % (x[3], x[1], x[2]) for x in saved_daemons]

            # Remove daemons from config if not in ConnectionManager hosts
            for daemon in list(config["daemon"].keys()):
                if "@localhost:" in daemon or "@127.0.0.1:" in daemon:
                    continue

                if daemon not in daemons and daemon != self.daemon:
                    del config["daemon"][daemon]

        if self.daemon not in config["daemon"]:
            config["daemon"][self.daemon] = copy.deepcopy(
                labelplus.gtkui.config.DAEMON_DEFAULTS)

    def _normalize_config(self, config):

        labelplus.common.normalize_dict(config.config,
                                        labelplus.gtkui.config.CONFIG_DEFAULTS)

        labelplus.common.normalize_dict(
            config["common"], labelplus.gtkui.config.CONFIG_DEFAULTS["common"])

        for daemon in config["daemon"]:
            labelplus.common.normalize_dict(
                config["daemon"][daemon],
                labelplus.gtkui.config.DAEMON_DEFAULTS)

    # Section: Update

    def _update_loop(self):
        def on_timeout():

            log.error("%s: %s", STR_UPDATE, LabelPlusError(ERR_TIMED_OUT))

            if self.initialized:
                self._tries += 1
                if self._tries < MAX_TRIES:
                    self._calls.append(
                        twisted.internet.reactor.callLater(
                            THROTTLED_INTERVAL, self._update_loop))
                else:
                    log.error("%s: %s", STR_UPDATE,
                              LabelPlusError(ERR_MAX_RETRY))

        def process_result(result):

            if isinstance(result, Failure):
                if failure.check(LabelPlusError):
                    log.error("%s: %s", STR_UPDATE,
                              LabelPlusError(result.value.message))
                    interval = THROTTLED_INTERVAL
                else:
                    return result
            else:
                self._tries = 0
                interval = UPDATE_INTERVAL
                self._update_store(result)

            if self.initialized:
                self._calls.append(
                    twisted.internet.reactor.callLater(interval,
                                                       self._update_loop))

        labelplus.common.clean_calls(self._calls)

        if self.initialized:
            iso_time = serialize_datetime(self.last_updated)
            deferred = client.labelplus.get_label_updates_dict(iso_time)
            labelplus.common.deferred_timeout(deferred, REQUEST_TIMEOUT,
                                              on_timeout, process_result,
                                              process_result)

    def _update_store(self, result):

        if not result:
            return

        update = result

        log.debug("Update: Type: %s, Timestamp: %s", update['type'],
                  update['timestamp'])

        self.last_updated = deserialize_datetime(update['timestamp'])
        self.store.update(update['data'])

        for func in list(self._update_funcs):
            try:
                func(self.store)
            except:
                log.exception("Failed to run %s()", func.__name__)
Beispiel #4
0
class GtkUI(GtkPluginBase):

  # Section: Initialization

  def __init__(self, plugin_name):

    RT.logger.setLevel(logging.INFO)
    if __debug__: RT.register(self)

    super(GtkUI, self).__init__(plugin_name)

    self.initialized = False

    self.config = None

    self.store = LabelStore()
    self.last_updated = None
    self._tries = 0
    self._calls = []

    self._extensions = []

    self._update_funcs = []
    self._cleanup_funcs = []


  def enable(self):

    log.info("Initializing %s...", self.__class__.__name__)

    self._poll_init()


  def _poll_init(self):

    client.labelplus.is_initialized().addCallback(self._check_init)


  def _check_init(self, result):

    log.debug("Waiting for core to be initialized...")

    if result == True:
      client.labelplus.get_label_updates().addCallback(self._finish_init)
    else:
      twisted.internet.reactor.callLater(INIT_POLLING_INTERVAL,
        self._poll_init)


  def _finish_init(self, result):

    log.debug("Resuming initialization...")

    try:
      info = client.connection_info()
      self.daemon = "%s@%s:%s" % (info[2], info[0], info[1])

      self._load_config()
      self._update_store(result)

      self.initialized = True

      self._load_extensions()

      log.info("%s initialized", self.__class__.__name__)
    except:
      log.error("Error initializing %s", self.__class__.__name__)
      raise

    twisted.internet.reactor.callLater(0, self._update_loop)


  def _load_extensions(self):

    log.info("Loading extensions...")

    for ext in EXTENSIONS:
      try:
        log.debug("Initializing %s", ext.__name__)
        instance = ext(self)
        self._extensions.append(instance)
        if __debug__: RT.register(instance, ext.__name__)
        log.info("%s initialized", ext.__name__)
      except:
        log.exception("Error initializing %s", ext.__name__)


  # Section: Deinitialization

  def disable(self):

    log.info("Deinitializing %s...", self.__class__.__name__)

    labelplus.common.cancel_calls(self._calls)

    self._run_cleanup_funcs()
    self._unload_extensions()
    self._update_funcs = []

    self._close_config()
    self._destroy_store()

    self.initialized = False

    if __debug__: RT.report()

    log.info("%s deinitialized", self.__class__.__name__)


  def _run_cleanup_funcs(self):

    while self._cleanup_funcs:
      func = self._cleanup_funcs.pop()
      try:
        func()
      except:
        log.exception("Failed to run %s()", func.func_name)


  def _unload_extensions(self):

    log.info("Unloading extensions...")

    while self._extensions:
      ext = self._extensions.pop()
      try:
        ext.unload()
        log.info("%s deinitialized", ext.__class__.__name__)
      except:
        log.exception("Error deinitializing %s", ext.__class__.__name__)


  def _destroy_store(self):

    if self.store:
      self.store.destroy()
      self.store = None


  # Section: Public

  def get_extension(self, name):

    for ext in self._extensions:
      if ext.__class__.__name__ == name:
        return ext

    return None


  def register_update_func(self, func):

    if func not in self._update_funcs:
      self._update_funcs.append(func)


  def deregister_update_func(self, func):

    if func in self._update_funcs:
      self._update_funcs.remove(func)


  def register_cleanup_func(self, func):

    if func not in self._cleanup_funcs:
      self._cleanup_funcs.append(func)


  def deregister_cleanup_func(self, func):

    if func in self._cleanup_funcs:
      self._cleanup_funcs.remove(func)


  # Section: Config

  def _load_config(self):

    config = deluge.configmanager.ConfigManager(GTKUI_CONFIG)

    # Workaround for 0.2.19.x that didn't use header
    if config.config.get("version") == 2:
      labelplus.common.config.set_version(config, 2)

    labelplus.common.config.init_config(config,
      labelplus.gtkui.config.CONFIG_DEFAULTS,
      labelplus.gtkui.config.CONFIG_VERSION,
      labelplus.gtkui.config.convert.CONFIG_SPECS)

    self._update_daemon_config(config)
    self._normalize_config(config)

    self.config = config


  def _close_config(self):

    if self.config:
      if self.initialized:
        self.config.save()

      deluge.configmanager.close(GTKUI_CONFIG)


  def _update_daemon_config(self, config):

    saved_daemons = deluge.component.get("ConnectionManager").config["hosts"]
    if not saved_daemons:
      config["daemon"] = {}
    else:
      daemons = ["%s@%s:%s" % (x[3], x[1], x[2]) for x in saved_daemons]

      # Remove daemons from config if not in ConnectionManager hosts
      for daemon in config["daemon"].keys():
        if "@localhost:" in daemon or "@127.0.0.1:" in daemon:
          continue

        if daemon not in daemons and daemon != self.daemon:
          del config["daemon"][daemon]

    if self.daemon not in config["daemon"]:
      config["daemon"][self.daemon] = copy.deepcopy(
        labelplus.gtkui.config.DAEMON_DEFAULTS)


  def _normalize_config(self, config):

    labelplus.common.normalize_dict(config.config,
      labelplus.gtkui.config.CONFIG_DEFAULTS)

    labelplus.common.normalize_dict(config["common"],
      labelplus.gtkui.config.CONFIG_DEFAULTS["common"])

    for daemon in config["daemon"]:
      labelplus.common.normalize_dict(config["daemon"][daemon],
        labelplus.gtkui.config.DAEMON_DEFAULTS)


  # Section: Update

  def _update_loop(self):

    def on_timeout():

      log.error("%s: %s", STR_UPDATE, LabelPlusError(ERR_TIMED_OUT))

      if self.initialized:
        self._tries += 1
        if self._tries < MAX_TRIES:
          self._calls.append(twisted.internet.reactor.callLater(
            THROTTLED_INTERVAL, self._update_loop))
        else:
          log.error("%s: %s", STR_UPDATE, LabelPlusError(ERR_MAX_RETRY))


    def process_result(result):

      if isinstance(result, Failure):
        if (isinstance(result.value, DelugeRPCError) and
            result.value.exception_type == "LabelPlusError"):
          log.error("%s: %s", STR_UPDATE,
            LabelPlusError(result.value.exception_msg))
          interval = THROTTLED_INTERVAL
        else:
          return result
      else:
        self._tries = 0
        interval = UPDATE_INTERVAL
        self._update_store(result)

      if self.initialized:
        self._calls.append(twisted.internet.reactor.callLater(interval,
          self._update_loop))


    labelplus.common.clean_calls(self._calls)

    if self.initialized:
      pickled_time = cPickle.dumps(self.last_updated)
      deferred = client.labelplus.get_label_updates(pickled_time)
      labelplus.common.deferred_timeout(deferred, REQUEST_TIMEOUT, on_timeout,
        process_result, process_result)


  def _update_store(self, result):

    if not result:
      return

    update = cPickle.loads(result)

    log.debug("Update: Type: %s, Timestamp: %s", update.type,
      update.timestamp)

    self.last_updated = update.timestamp
    self.store.update(update.data)

    for func in list(self._update_funcs):
      try:
        func(self.store)
      except:
        log.exception("Failed to run %s()", func.func_name)