diff options
author | RaNaN <Mast3rRaNaN@hotmail.de> | 2012-01-08 14:44:59 +0100 |
---|---|---|
committer | RaNaN <Mast3rRaNaN@hotmail.de> | 2012-01-08 14:44:59 +0100 |
commit | bac28b7740aae772636d8b90e291d9c17dfd59a7 (patch) | |
tree | 08b6bd4f00cf27819f06d24f363d633b852f50a3 | |
parent | some cleanups (diff) | |
download | pyload-bac28b7740aae772636d8b90e291d9c17dfd59a7.tar.xz |
new MultiHoster hook
-rw-r--r-- | module/HookManager.py | 23 | ||||
-rw-r--r-- | module/PyFile.py | 7 | ||||
-rw-r--r-- | module/plugins/AccountManager.py | 18 | ||||
-rw-r--r-- | module/plugins/Hook.py | 4 | ||||
-rw-r--r-- | module/plugins/MultiHoster.py | 12 | ||||
-rw-r--r-- | module/plugins/PluginManager.py | 37 | ||||
-rw-r--r-- | module/plugins/accounts/RealdebridCom.py | 22 | ||||
-rw-r--r-- | module/plugins/hooks/ClickAndLoad.py | 2 | ||||
-rw-r--r-- | module/plugins/hooks/MultiHoster.py | 100 | ||||
-rw-r--r-- | module/plugins/hooks/RealdebridCom.py | 24 | ||||
-rw-r--r-- | module/plugins/hoster/RealdebridCom.py | 5 | ||||
-rw-r--r-- | module/plugins/internal/MultiHoster.py | 85 | ||||
-rw-r--r-- | module/threads/DownloadThread.py | 4 | ||||
-rw-r--r-- | module/threads/InfoThread.py | 4 | ||||
-rw-r--r-- | module/web/pyload_app.py | 4 |
15 files changed, 179 insertions, 172 deletions
diff --git a/module/HookManager.py b/module/HookManager.py index b915341e3..3691fe3ed 100644 --- a/module/HookManager.py +++ b/module/HookManager.py @@ -28,6 +28,9 @@ from module.threads.HookThread import HookThread from module.plugins.PluginManager import literal_eval from utils import lock, to_string +def class_name(p): + return p.rpartition(".")[2] + class HookManager: """ Manages hooks, loading, unloading. """ @@ -68,7 +71,7 @@ class HookManager: print_exc() def addRPC(self, plugin, func, doc): - plugin = plugin.rpartition(".")[2] + plugin = class_name(plugin) doc = doc.strip() if doc else "" if plugin in self.methods: @@ -141,6 +144,7 @@ class HookManager: # active the hook in new thread start_new_thread(plugin.activate, tuple()) + self.registerEvents() @lock def deactivateHook(self, plugin): @@ -168,6 +172,8 @@ class HookManager: if plugin.isActivated(): self.call(plugin, "activate") + self.registerEvents() + def deactivateHooks(self): """ Called when core is shutting down """ self.log.info(_("Deactivating Plugins...")) @@ -219,10 +225,21 @@ class HookManager: return info def addEventListener(self, plugin, func, event): - pass + plugin = class_name(plugin) + if plugin not in self.events: + self.events[plugin] = [] + self.events[plugin].append((func, event)) + + def registerEvents(self): + for name, plugin in self.plugins.iteritems(): + if name in self.events: + for func, event in self.events[name]: + self.addEvent(event, getattr(plugin, func)) + # clean up + del self.events[name] def addConfigHandler(self, plugin, func): - pass + pass #TODO def addEvent(self, *args): self.core.eventManager.addEvent(*args) diff --git a/module/PyFile.py b/module/PyFile.py index b446fde65..0c4c20705 100644 --- a/module/PyFile.py +++ b/module/PyFile.py @@ -51,7 +51,7 @@ class PyFile(object): """ __slots__ = ("m", "id", "url", "name", "size", "_size", "status", "pluginname", "packageid", "error", "order", "lock", "plugin", "waitUntil", "active", "abort", "statusname", - "reconnected", "progress", "maxprogress", "pluginmodule", "pluginclass") + "reconnected", "progress", "maxprogress", "pluginclass") def __init__(self, manager, id, url, name, size, status, error, pluginname, package, order): self.m = manager @@ -91,14 +91,13 @@ class PyFile(object): size = property(lambda self: self._size, setSize) def __repr__(self): - return "PyFile %s: %s@%s" % (self.id, self.name, self.pluginname) + return "<PyFile %s: %s@%s>" % (self.id, self.name, self.pluginname) @lock def initPlugin(self): """ inits plugin instance """ if not self.plugin: - self.pluginmodule = self.m.core.pluginManager.getPlugin(self.pluginname) - self.pluginclass = getattr(self.pluginmodule, self.m.core.pluginManager.getPluginName(self.pluginname)) + self.pluginclass = self.m.core.pluginManager.getPlugin(self.pluginname) self.plugin = self.pluginclass(self) @lock diff --git a/module/plugins/AccountManager.py b/module/plugins/AccountManager.py index 00dd2ccc6..c610d10e0 100644 --- a/module/plugins/AccountManager.py +++ b/module/plugins/AccountManager.py @@ -48,6 +48,12 @@ class AccountManager: return + def iterAccounts(self): + """ yields login, account for all accounts""" + for name, data in self.accounts.iteritems(): + for login, account in data.iteritems(): + yield login, account + def saveAccounts(self): """save all account information""" @@ -71,6 +77,9 @@ class AccountManager: self.accounts[plugin][loginname] = klass(self, loginname, password, options) + def getAccount(self, plugin, user): + return self.accounts[plugin].get(user, None) + @lock def updateAccount(self, plugin, user, password=None, options={}): """add or update account""" @@ -84,7 +93,7 @@ class AccountManager: self.createAccount(plugin, user, password, options) self.saveAccounts() - self.sendChange() + self.sendChange(plugin, user) @lock def removeAccount(self, plugin, user): @@ -92,7 +101,7 @@ class AccountManager: if plugin in self.accounts and user in self.accounts[plugin]: del self.accounts[plugin][user] self.core.db.removeAccount(plugin, user) - self.sendChange() + self.core.eventManager.dispatchEvent("accountDeleted", plugin, user) else: self.core.log.debug("Remove non existing account %s %s" % (plugin, user)) @@ -128,6 +137,5 @@ class AccountManager: for acc in p.itervalues(): acc.getAccountInfo(True) - - def sendChange(self): - self.core.eventManager.dispatchEvent("accountsUpdated")
\ No newline at end of file + def sendChange(self, plugin, name): + self.core.eventManager.dispatchEvent("accountUpdated", plugin, name)
\ No newline at end of file diff --git a/module/plugins/Hook.py b/module/plugins/Hook.py index 6e2057f03..c0ce7d99c 100644 --- a/module/plugins/Hook.py +++ b/module/plugins/Hook.py @@ -98,6 +98,7 @@ class Hook(Base): self.event_list = None self.initPeriodical() + self.init() self.setup() def initPeriodical(self): @@ -122,6 +123,9 @@ class Hook(Base): """ checks if hook is activated""" return self.getConfig("activated") + def init(self): + pass + def setup(self): """ more init stuff if needed """ pass diff --git a/module/plugins/MultiHoster.py b/module/plugins/MultiHoster.py index 047b9155e..abbc14466 100644 --- a/module/plugins/MultiHoster.py +++ b/module/plugins/MultiHoster.py @@ -33,7 +33,7 @@ class MultiHoster(Account): # Timestamp self.ts = 0 - Account.__init__(*args, **kwargs) + Account.__init__(self, *args, **kwargs) def loadHosterList(self, req): """Load list of supported hoster @@ -63,11 +63,11 @@ class MultiHoster(Account): req.close() for rep in self.replacements: - if rep[0] in self.hosters: - self.hosters.remove(rep[0]) - if rep[1] not in self.hosters: - self.hosters.append(rep[1]) + if rep[0] in self.hoster: + self.hoster.remove(rep[0]) + if rep[1] not in self.hoster: + self.hoster.append(rep[1]) self.ts = time() - return self.hosters
\ No newline at end of file + return self.hoster
\ No newline at end of file diff --git a/module/plugins/PluginManager.py b/module/plugins/PluginManager.py index e00c1e1f5..c345f765f 100644 --- a/module/plugins/PluginManager.py +++ b/module/plugins/PluginManager.py @@ -58,7 +58,6 @@ class PluginManager: self.plugins = {} self.modules = {} # cached modules - self.names = {} # overwritten names self.history = [] # match history to speedup parsing (type, name) self.createIndex() @@ -262,27 +261,19 @@ class PluginManager: return ptype, self.plugins[ptype][name] return None, None - def getPlugin(self, name, original=False): - """return plugin module from hoster|decrypter""" + def getPluginModule(self, name): + """ Decprecated: return plugin module from hoster|crypter""" + self.log.debug("Deprecated method: .getPluginModule()") type, plugin = self.findPlugin(name) - - if not plugin: - self.log.warning("Plugin %s not found." % name) - name = "BasePlugin" - - if (type, name) in self.modules and not original: - return self.modules[(type, name)] - return self.loadModule(type, name) - def getPluginName(self, name): - """ used to obtain new name if other plugin was injected""" + def getPluginClass(self, name): + """ return plugin class from hoster|crypter, always the not overwritten one """ type, plugin = self.findPlugin(name) + return self.loadClass(type, name) - if (type, name) in self.names: - return self.names[(type, name)] - - return name + # MultiHoster will overwrite this + getPlugin = getPluginClass def loadModule(self, type, name): """ Returns loaded module for plugin @@ -309,18 +300,6 @@ class PluginManager: module = self.loadModule(type, name) if module: return getattr(module, name) - def injectPlugin(self, type, name, module, new_name): - """ Overwrite a plugin with a other module. used by Multihoster """ - self.modules[(type, name)] = module - self.names[(type, name)] = new_name - - def restoreState(self, type, name): - """ Restore the state of a plugin after injecting """ - if (type, name) in self.modules: - del self.modules[(type, name)] - if (type, name) in self.names: - del self.names[(type, name)] - def find_module(self, fullname, path=None): #redirecting imports if necesarry if fullname.startswith(self.ROOT) or fullname.startswith(self.USERROOT): #seperate pyload plugins diff --git a/module/plugins/accounts/RealdebridCom.py b/module/plugins/accounts/RealdebridCom.py index 3137987a9..4a2cf9368 100644 --- a/module/plugins/accounts/RealdebridCom.py +++ b/module/plugins/accounts/RealdebridCom.py @@ -1,15 +1,18 @@ -from module.plugins.Account import Account
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from module.plugins.MultiHoster import MultiHoster
import xml.dom.minidom as dom
-class RealdebridCom(Account):
+class RealdebridCom(MultiHoster):
__name__ = "RealdebridCom"
- __version__ = "0.4"
+ __version__ = "0.5"
__type__ = "account"
__description__ = """Real-Debrid.com account plugin"""
__author_name__ = ("Devirex, Hazzard")
__author_mail__ = ("naibaf_11@yahoo.de")
- def loadAccountInfo(self, user, req):
+ def loadAccountInfo(self, req):
page = req.load("http://real-debrid.com/api/account.php")
xml = dom.parseString(page)
account_info = {"validuntil": int(xml.getElementsByTagName("expiration")[0].childNodes[0].nodeValue),
@@ -17,9 +20,16 @@ class RealdebridCom(Account): return account_info
- def login(self, user, data, req):
- page = req.load("https://real-debrid.com/ajax/login.php?user=%s&pass=%s" % (user, data["password"]))
+ def login(self, req):
+ page = req.load("https://real-debrid.com/ajax/login.php?user=%s&pass=%s" % (self.loginname, self.password))
#page = req.load("https://real-debrid.com/login.html", post={"user": user, "pass": data["password"]}, cookies=True)
if "Your login informations are incorrect" in page:
self.wrongPassword()
+
+
+ def loadHosterList(self, req):
+ https = "https" if self.getConfig("https") else "http"
+ page = req.load(https + "://real-debrid.com/api/hosters.php").replace("\"","").strip()
+
+ return[x.strip() for x in page.split(",") if x.strip()]
\ No newline at end of file diff --git a/module/plugins/hooks/ClickAndLoad.py b/module/plugins/hooks/ClickAndLoad.py index 97e5cd57d..fc32d0da8 100644 --- a/module/plugins/hooks/ClickAndLoad.py +++ b/module/plugins/hooks/ClickAndLoad.py @@ -32,7 +32,7 @@ class ClickAndLoad(Hook): __author_name__ = ("RaNaN", "mkaay") __author_mail__ = ("RaNaN@pyload.de", "mkaay@mkaay.de") - def coreReady(self): + def activate(self): self.port = int(self.core.config['webinterface']['port']) if self.core.config['webinterface']['activated']: try: diff --git a/module/plugins/hooks/MultiHoster.py b/module/plugins/hooks/MultiHoster.py new file mode 100644 index 000000000..1f40a4ddd --- /dev/null +++ b/module/plugins/hooks/MultiHoster.py @@ -0,0 +1,100 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import re +from types import MethodType + +from module.plugins.MultiHoster import MultiHoster as MultiHosterAccount, normalize +from module.plugins.Hook import Hook, AddEventListener +from module.plugins.PluginManager import PluginTuple + +class MultiHoster(Hook): + __version__ = "0.1" + __description__ = "Gives ability to use MultiHoster services. You need to add your account first." + __config__ = [("activated", "bool", "Activated", True)] + __author_mail__ = ("pyLoad Team",) + __author_mail__ = ("support@pyload.org",) + + #TODO: multiple accounts - multihoster / config options + + def init(self): + + # overwritten plugins + self.plugins = {} + + def addHoster(self, account): + + self.logDebug("New MultiHoster %s" % account.__name__) + + pluginMap = {} + for name in self.core.pluginManager.getPlugins("hoster").keys(): + pluginMap[name.lower()] = name + + supported = [] + new_supported = [] + + for hoster in account.getHosterList(): + name = normalize(hoster) + + if name in pluginMap: + supported.append(pluginMap[name]) + else: + new_supported.append(hoster) + + if not supported and not new_supported: + account.logError(_("No Hoster loaded")) + return + + klass = self.core.pluginManager.getPluginClass(account.__name__) + + # inject plugin plugin + account.logDebug("Overwritten Hosters: %s" % ", ".join(sorted(supported))) + for hoster in supported: + self.plugins[hoster] = klass + + account.logDebug("New Hosters: %s" % ", ".join(sorted(new_supported))) + + # create new regexp + regexp = r".*(%s).*" % "|".join([klass.__pattern__] + [x.replace(".", "\\.") for x in new_supported]) + + # recreate plugin tuple for new regexp + hoster = self.core.pluginManager.getPlugins("hoster") + p = hoster[account.__name__] + new = PluginTuple(p.version, re.compile(regexp), p.deps, p.user, p.path) + hoster[account.__name__] = new + + + + @AddEventListener("accountDeleted") + def refreshAccounts(self, plugin=None, user=None): + + self.plugins = {} + for name, account in self.core.accountManager.iterAccounts(): + if isinstance(account, MultiHosterAccount) and account.isUsable(): + self.addHoster(account) + + @AddEventListener("accountUpdated") + def refreshAccount(self, plugin, user): + + account = self.core.accountManager.getAccount(plugin, user) + if isinstance(account, MultiHosterAccount) and account.isUsable(): + self.addHoster(account) + + def activate(self): + self.refreshAccounts() + + # new method for plugin manager + def getPlugin(self2, name): + if name in self.plugins: + return self.plugins[name] + return self2.getPluginClass(name) + + pm = self.core.pluginManager + pm.getPlugin = MethodType(getPlugin, pm, object) + + + def deactivate(self): + #restore state + pm = self.core.pluginManager + pm.getPlugin = pm.getPluginClass + diff --git a/module/plugins/hooks/RealdebridCom.py b/module/plugins/hooks/RealdebridCom.py deleted file mode 100644 index c57e3de52..000000000 --- a/module/plugins/hooks/RealdebridCom.py +++ /dev/null @@ -1,24 +0,0 @@ -# -*- coding: utf-8 -*- - -from module.network.RequestFactory import getURL -from module.plugins.internal.MultiHoster import MultiHoster - -class RealdebridCom(MultiHoster): - __name__ = "RealdebridCom" - __version__ = "0.4" - __type__ = "hook" - - __config__ = [("activated", "bool", "Activated", "False"), - ("https", "bool", "Enable HTTPS", "False")] - - __description__ = """Real-Debrid.com hook plugin""" - __author_name__ = ("Devirex, Hazzard") - __author_mail__ = ("naibaf_11@yahoo.de") - - replacements = [("freakshare.net", "freakshare.com")] - - def getHoster(self): - https = "https" if self.getConfig("https") else "http" - page = getURL(https + "://real-debrid.com/api/hosters.php").replace("\"","").strip() - - return[x.strip() for x in page.split(",") if x.strip()]
\ No newline at end of file diff --git a/module/plugins/hoster/RealdebridCom.py b/module/plugins/hoster/RealdebridCom.py index 62c09aaa8..376ae3414 100644 --- a/module/plugins/hoster/RealdebridCom.py +++ b/module/plugins/hoster/RealdebridCom.py @@ -8,12 +8,11 @@ from random import randrange from module.plugins.Hoster import Hoster
class RealdebridCom(Hoster):
- __name__ = "RealdebridCom"
__version__ = "0.41"
- __type__ = "hoster"
-
__pattern__ = r"https?://.*real-debrid\..*"
__description__ = """Real-Debrid.com hoster plugin"""
+ __config__ = [("https", "bool", _("Enable HTTPS"), False)]
+
__author_name__ = ("Devirex, Hazzard")
__author_mail__ = ("naibaf_11@yahoo.de")
diff --git a/module/plugins/internal/MultiHoster.py b/module/plugins/internal/MultiHoster.py deleted file mode 100644 index 2252c4460..000000000 --- a/module/plugins/internal/MultiHoster.py +++ /dev/null @@ -1,85 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -import re - -from module.utils import remove_chars -from module.plugins.Hook import Hook -from module.plugins.PluginManager import PluginTuple - -class MultiHoster(Hook): - """ - Generic MultiHoster plugin - """ - - interval = 0 - hosters = [] - replacements = [] - supported = [] - - def getHosterCached(self): - if not self.hosters: - - try: - self.hosters = self.getHoster() - except Exception, e: - self.logError(e) - return [] - - for rep in self.replacements: - if rep[0] in self.hosters: - self.hosters.remove(rep[0]) - if rep[1] not in self.hosters: - self.hosters.append(rep[1]) - - return self.hosters - - - def getHoster(self): - """Load list of supported hoster - - :return: List of domain names - """ - raise NotImplementedError - - def coreReady(self): - pluginMap = {} - for name in self.core.pluginManager.getPlugins("hoster").keys(): - pluginMap[name.lower()] = name - - new_supported = [] - - for hoster in self.getHosterCached(): - name = remove_chars(hoster.lower(), "-.") - - if name in pluginMap: - self.supported.append(pluginMap[name]) - else: - new_supported.append(hoster) - - if not self.supported and not new_supported: - self.logError(_("No Hoster loaded")) - return - - module = self.core.pluginManager.getPlugin(self.__name__) - klass = getattr(module, self.__name__) - - # inject plugin plugin - self.logDebug("Overwritten Hosters: %s" % ", ".join(sorted(self.supported))) - for hoster in self.supported: - self.core.pluginManager.injectPlugin("hoster", hoster, module, self.__name__) - - self.logDebug("New Hosters: %s" % ", ".join(sorted(new_supported))) - - # create new regexp - regexp = r".*(%s).*" % "|".join([klass.__pattern__] + [x.replace(".", "\\.") for x in new_supported]) - - hoster = self.core.pluginManager.getPlugins("hoster") - p = hoster[self.__name__] - new = PluginTuple(p.version, re.compile(regexp), p.deps, p.user, p.path) - hoster[self.__name__] = new - - - def deactivate(self): - for hoster in self.supported: - self.core.pluginManager.restoreState("hoster", hoster)
\ No newline at end of file diff --git a/module/threads/DownloadThread.py b/module/threads/DownloadThread.py index e140703d5..c151831a3 100644 --- a/module/threads/DownloadThread.py +++ b/module/threads/DownloadThread.py @@ -156,7 +156,7 @@ class DownloadThread(BaseThread): self.log.error("pycurl error %s: %s" % (code, msg)) if self.core.debug: print_exc() - self.writeDebugReport(pyfile.pluginname, pyfile) + self.writeDebugReport(pyfile.plugin.__name__, pyfile) self.core.hookManager.downloadFailed(pyfile) @@ -186,7 +186,7 @@ class DownloadThread(BaseThread): if self.core.debug: print_exc() - self.writeDebugReport(pyfile.pluginname, pyfile) + self.writeDebugReport(pyfile.plugin.__name__, pyfile) self.core.hookManager.downloadFailed(pyfile) self.clean(pyfile) diff --git a/module/threads/InfoThread.py b/module/threads/InfoThread.py index 5f21d487c..7db85803a 100644 --- a/module/threads/InfoThread.py +++ b/module/threads/InfoThread.py @@ -40,8 +40,8 @@ class InfoThread(BaseThread): #directly write to database if self.pid > -1: for pluginname, urls in plugins.iteritems(): - plugin = self.m.core.pluginManager.getPlugin(pluginname, True) - klass = getattr(plugin, pluginname) + plugin = self.m.core.pluginManager.getPluginModule(pluginname) + klass = self.m.core.pluginManager.getPluginClass(pluginname) if has_method(klass, "getInfo"): self.fetchForPlugin(pluginname, klass, urls, self.updateDB) self.m.core.files.save() diff --git a/module/web/pyload_app.py b/module/web/pyload_app.py index f73defb45..fffa19b48 100644 --- a/module/web/pyload_app.py +++ b/module/web/pyload_app.py @@ -246,10 +246,10 @@ def config(): conf_menu = [] plugin_menu = [] - for section, data in conf.getBaseSections(): + for section, data in sorted(conf.getBaseSections()): conf_menu.append((section, data.name)) - for section, data in conf.getPluginSections(): + for section, data in sorted(conf.getPluginSections()): plugin_menu.append((section, data.name)) accs = PYLOAD.getAccounts(False) |