# -*- coding: utf-8 -*- """ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, see . @author: RaNaN """ from traceback import print_exc #from functools import wraps from module.utils import has_method, to_list from Base import Base def class_name(p): return p.rpartition(".")[2] def AddEventListener(event): """ Used to register method for events. Arguments needs to match parameter of event :param event: Name of event or list of them. """ class _klass(object): def __new__(cls, f, *args, **kwargs): for ev in to_list(event): addonManager.addEventListener(class_name(f.__module__), f.func_name, ev) return f return _klass def AddonHandler(desc, media=None): """ Register Handler for files, packages, or arbitrary callable methods. To let the method work on packages/files, media must be set and the argument named pid or fid. :param desc: verbose description :param media: if True or bits of media type """ pass def AddonInfo(desc): """ Called to retrieve information about the current state. Decorated method must return anything convertable into string. :param desc: verbose description """ pass def threaded(f): """ Decorator to run method in a thread. """ #@wraps(f) def run(*args,**kwargs): addonManager.startThread(f, *args, **kwargs) return run class Addon(Base): """ Base class for addon plugins. Use @threaded decorator for all longer running tasks. Decorate methods with @Expose, @AddEventListener, @ConfigHandler """ #: automatically register event listeners for functions, attribute will be deleted don't use it yourself event_map = None #: periodic call interval in seconds interval = 60 def __init__(self, core, manager, user=None): Base.__init__(self, core, user) #: Provide information in dict here, usable by API `getInfo` self.info = None #: Callback of periodical job task, used by addonmanager self.cb = None #: `AddonManager` self.manager = manager #register events if self.event_map: for event, funcs in self.event_map.iteritems(): if type(funcs) in (list, tuple): for f in funcs: self.evm.listenTo(event, getattr(self,f)) else: self.evm.listenTo(event, getattr(self,funcs)) #delete for various reasons self.event_map = None self.initPeriodical() self.init() def initPeriodical(self): if self.interval >=1: self.cb = self.core.scheduler.addJob(0, self._periodical, threaded=False) def _periodical(self): try: if self.isActivated(): self.periodical() except Exception, e: self.core.log.error(_("Error executing addons: %s") % str(e)) if self.core.debug: print_exc() self.cb = self.core.scheduler.addJob(self.interval, self._periodical, threaded=False) def __repr__(self): return "" % self.__name__ def isActivated(self): """ checks if addon is activated""" return True if self.__internal__ else self.getConfig("activated") def getCategory(self): return self.core.pluginManager.getCategory(self.__name__) def init(self): pass def activate(self): """ Used to activate the addon """ if has_method(self.__class__, "coreReady"): self.logDebug("Deprecated method .coreReady() use activate() instead") self.coreReady() def deactivate(self): """ Used to deactivate the addon. """ pass def periodical(self): pass def newInteractionTask(self, task): """ new interaction task for the plugin, it MUST set the handler and timeout or will be ignored """ pass def taskCorrect(self, task): pass def taskInvalid(self, task): pass # public events starts from here def downloadPreparing(self, pyfile): pass def downloadFinished(self, pyfile): pass def downloadFailed(self, pyfile): pass def packageFinished(self, pypack): pass