# -*- 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