summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--module/Api.py13
-rw-r--r--module/HookManager.py55
-rw-r--r--module/database/FileDatabase.py9
-rw-r--r--module/plugins/Hook.py32
-rw-r--r--module/plugins/Plugin.py3
-rw-r--r--module/plugins/hooks/CaptchaTrader.py3
-rw-r--r--module/plugins/hooks/ExternalScripts.py5
-rw-r--r--module/plugins/hooks/IRCInterface.py4
-rw-r--r--module/plugins/hooks/XMPPInterface.py4
9 files changed, 98 insertions, 30 deletions
diff --git a/module/Api.py b/module/Api.py
index 2f6200950..832122ac5 100644
--- a/module/Api.py
+++ b/module/Api.py
@@ -185,8 +185,15 @@ class Api(Iface):
except:
return ['No log available']
- def checkURL(self, urls):
- raise NotImplemented #TODO
+ def parseURLs(self, html):
+ #TODO implement
+ pass
+
+ def checkURLs(self, urls):
+ pass
+
+ def checkOnlineStatus(self, urls):
+ pass
def isTimeDownload(self):
"""Checks if pyload will start new downloads according to time in config .
@@ -655,7 +662,7 @@ class Api(Iface):
:param username:
:param password:
- :param remoteip:
+ :param remoteip: Omit this argument, its only used internal
:return: bool indicating login was successful
"""
if self.core.config["remote"]["nolocalauth"] and remoteip == "127.0.0.1":
diff --git a/module/HookManager.py b/module/HookManager.py
index 8b039683f..13e8695c2 100644
--- a/module/HookManager.py
+++ b/module/HookManager.py
@@ -25,8 +25,11 @@ from time import time
from module.PluginThread import HookThread
from module.plugins.PluginManager import literal_eval
+from utils import lock
class HookManager:
+ """Manages hooks and delegates and handles Events"""
+
def __init__(self, core):
self.core = core
self.config = self.core.config
@@ -37,17 +40,11 @@ class HookManager:
self.plugins = []
self.pluginMap = {}
self.methods = {} #dict of names and list of methods usable by rpc
- self.lock = RLock()
- self.createIndex()
- def lock(func):
- def new(*args):
- args[0].lock.acquire()
- res = func(*args)
- args[0].lock.release()
- return res
+ self.events = {} # contains events
- return new
+ self.lock = RLock()
+ self.createIndex()
def try_catch(func):
def new(*args):
@@ -92,7 +89,7 @@ class HookManager:
#hookClass = getattr(plugin, plugin.__name__)
if self.core.config.getPlugin(pluginClass.__name__, "load"):
- plugin = pluginClass(self.core)
+ plugin = pluginClass(self.core, self)
plugins.append(plugin)
self.pluginMap[pluginClass.__name__] = plugin
if plugin.isActivated():
@@ -142,10 +139,13 @@ class HookManager:
@lock
def downloadStarts(self, pyfile):
+ #TODO: rename to downloadPreparing
for plugin in self.plugins:
if plugin.isActivated():
plugin.downloadStarts(pyfile)
+ self.dispatchEvent("downloadPreparing", pyfile)
+
@lock
def downloadFinished(self, pyfile):
for plugin in self.plugins:
@@ -155,6 +155,8 @@ class HookManager:
else:
plugin.downloadFinished(pyfile)
+ self.dispatchEvent("downloadFinished", pyfile)
+
@lock
def packageFinished(self, package):
for plugin in self.plugins:
@@ -164,22 +166,30 @@ class HookManager:
else:
plugin.packageFinished(package)
+ self.dispatchEvent("packageFinished", package)
+
@lock
def beforeReconnecting(self, ip):
for plugin in self.plugins:
plugin.beforeReconnecting(ip)
+ self.dispatchEvent("beforeReconnecting", ip)
+
@lock
def afterReconnecting(self, ip):
for plugin in self.plugins:
if plugin.isActivated():
plugin.afterReconnecting(ip)
+ self.dispatchEvent("afterReconnecting", ip)
+
@lock
def unrarFinished(self, folder, fname):
for plugin in self.plugins:
plugin.unrarFinished(folder, fname)
+ self.dispatchEvent("unrarFinished", folder, fname)
+
def startThread(self, function, pyfile):
t = HookThread(self.core.threadManager, function, pyfile)
@@ -193,6 +203,29 @@ class HookManager:
for name, plugin in self.pluginMap.iteritems():
if plugin.info:
#copy and convert so str
- info[name] = dict([(x, str(y)) for x, y in plugin.info.iteritems()])
+ info[name] = dict([(x, str(y) if type(y) != basestring else y) for x, y in plugin.info.iteritems()])
return info
+
+ def addEvent(self, event, func):
+ """Adds an event listener for event name"""
+ if self.events.has_key(event):
+ self.events[event].append(func)
+ else:
+ self.events[event] = [func]
+
+ def removeEvent(self, event, func):
+ """removes previously added event listener"""
+ if self.events.has_key(event):
+ self.events[event].remove(func)
+
+ def dispatchEvent(self, event, *args):
+ """dispatches event with args"""
+ if self.events.has_key(event):
+ for f in self.events[event]:
+ try:
+ f(*args)
+ except Exception, e:
+ self.log.debug("Error calling event handler %s: %s, %s, %s"
+ % (event, f, args, str(e)))
+ \ No newline at end of file
diff --git a/module/database/FileDatabase.py b/module/database/FileDatabase.py
index 0ed526240..c77bf5e95 100644
--- a/module/database/FileDatabase.py
+++ b/module/database/FileDatabase.py
@@ -115,12 +115,14 @@ class FileHandler:
@change
def addLinks(self, urls, package):
"""adds links"""
-
+
+ self.core.hookManager.dispatchEvent("linksAdded", urls, package)
+
data = self.core.pluginManager.parseUrls(urls)
self.db.addLinks(data, package)
self.core.threadManager.createInfoThread(data, package)
-
+
#@TODO change from reloadAll event to package update event
self.core.pullManager.addEvent(ReloadAllEvent("collector"))
@@ -158,6 +160,7 @@ class FileHandler:
self.db.deletePackage(p)
self.core.pullManager.addEvent(e)
+ self.core.hookManager.dispatchEvent("packageDeleted", id)
if self.packageCache.has_key(id):
del self.packageCache[id]
@@ -183,7 +186,7 @@ class FileHandler:
del self.cache[id]
self.db.deleteLink(f)
-
+
self.core.pullManager.addEvent(e)
p = self.getPackage(pid)
diff --git a/module/plugins/Hook.py b/module/plugins/Hook.py
index 5e4b192ea..47faba95a 100644
--- a/module/plugins/Hook.py
+++ b/module/plugins/Hook.py
@@ -51,16 +51,36 @@ class Hook():
__description__ = """interface for hook"""
__author_name__ = ("mkaay", "RaNaN")
__author_mail__ = ("mkaay@mkaay.de", "RaNaN@pyload.org")
-
- def __init__(self, core):
+
+ #: automatically register event listeners for functions, attribute will be deleted dont use it yourself
+ event_map = None
+
+ #: periodic call interval in secondc
+ interval = 60
+
+ def __init__(self, core, manager):
self.core = core
self.log = core.log
self.config = core.config
-
- self.interval = 60 #: periodic call interval in seconds
- self.info = None #: Provide information in dict here, usable by API `getInfo`
-
+ #: Provide information in dict here, usable by API `getInfo`
+ self.info = None
+
+ #: `HookManager`
+ 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.manager.addEvent(event, getattr(self,f))
+ else:
+ self.manager.addEvent(event, getattr(self,funcs))
+
+ #delete for various reasons
+ self.event_map = None
+
self.setup()
def __repr__(self):
diff --git a/module/plugins/Plugin.py b/module/plugins/Plugin.py
index 71a06c8b5..ec8a0151a 100644
--- a/module/plugins/Plugin.py
+++ b/module/plugins/Plugin.py
@@ -450,6 +450,9 @@ class Plugin(object):
name = removeChars(name, '/\\"')
filename = join(location, fs_encode(name))
+
+ self.core.hookManager.dispatchEvent("downloadStarts", self.pyfile, url, filename)
+
try:
newname = self.req.httpDownload(url, filename, get=get, post=post, ref=ref, cookies=cookies,
chunks=self.getChunkCount(), resume=self.resumeDownload,
diff --git a/module/plugins/hooks/CaptchaTrader.py b/module/plugins/hooks/CaptchaTrader.py
index 2bae9401a..62ac2c8cc 100644
--- a/module/plugins/hooks/CaptchaTrader.py
+++ b/module/plugins/hooks/CaptchaTrader.py
@@ -58,6 +58,8 @@ class CaptchaTrader(Hook):
RESPOND_URL = "http://captchatrader.com/api/respond"
GETCREDITS_URL = "http://captchatrader.com/api/get_credits/username:%(user)s/password:%(password)s/"
+ def setup(self):
+ self.info = {}
def getCredits(self):
json = getURL(CaptchaTrader.GETCREDITS_URL % {"user": self.getConfig("username"),
@@ -67,6 +69,7 @@ class CaptchaTrader(Hook):
raise CaptchaTraderException(response[1])
else:
self.logInfo(_("%s credits left") % response[1])
+ self.info["credits"] = response[1]
return response[1]
def submit(self, captcha, captchaType="file", match=None):
diff --git a/module/plugins/hooks/ExternalScripts.py b/module/plugins/hooks/ExternalScripts.py
index bbf5acde3..daffc1827 100644
--- a/module/plugins/hooks/ExternalScripts.py
+++ b/module/plugins/hooks/ExternalScripts.py
@@ -40,7 +40,6 @@ class ExternalScripts(Hook):
folders = ['download_preparing', 'download_finished', 'package_finished',
'before_reconnect', 'after_reconnect', 'unrar_finished']
-
for folder in folders:
self.scripts[folder] = []
@@ -52,6 +51,7 @@ class ExternalScripts(Hook):
if names:
self.logInfo(_("Installed scripts for %s : %s") % (script_type, ", ".join([basename(x) for x in names])))
+
def initPluginType(self, folder, path):
if not exists(path):
try:
@@ -91,8 +91,7 @@ class ExternalScripts(Hook):
def packageFinished(self, pypack):
for script in self.scripts['package_finished']:
folder = self.core.config['general']['download_folder']
- if self.core.config.get("general", "folder_per_package"):
- folder = save_join(folder. pypack.folder)
+ folder = save_join(folder. pypack.folder)
self.callScript(script, pypack.name, folder, pypack.id)
diff --git a/module/plugins/hooks/IRCInterface.py b/module/plugins/hooks/IRCInterface.py
index 6fdb7622f..8be84f863 100644
--- a/module/plugins/hooks/IRCInterface.py
+++ b/module/plugins/hooks/IRCInterface.py
@@ -49,9 +49,9 @@ class IRCInterface(Thread, Hook):
__author_name__ = ("Jeix")
__author_mail__ = ("Jeix@hasnomail.com")
- def __init__(self, core):
+ def __init__(self, core, manager):
Thread.__init__(self)
- Hook.__init__(self, core)
+ Hook.__init__(self, core, manager)
self.setDaemon(True)
self.sm = core.server_methods
diff --git a/module/plugins/hooks/XMPPInterface.py b/module/plugins/hooks/XMPPInterface.py
index ce937c5d6..a96adf524 100644
--- a/module/plugins/hooks/XMPPInterface.py
+++ b/module/plugins/hooks/XMPPInterface.py
@@ -43,8 +43,8 @@ class XMPPInterface(IRCInterface, JabberClient):
implements(IMessageHandlersProvider)
- def __init__(self, core):
- IRCInterface.__init__(self, core)
+ def __init__(self, core, manager):
+ IRCInterface.__init__(self, core, manager)
self.jid = JID(self.getConfig("jid"))
password = self.getConfig("pw")