From 4e918edba6c3808b095eab1bad137a2a8cab970d Mon Sep 17 00:00:00 2001 From: RaNaN Date: Sat, 17 Dec 2011 21:53:57 +0100 Subject: updated plugin api and plugin manager --- module/plugins/hooks/UpdateManager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'module/plugins/hooks') diff --git a/module/plugins/hooks/UpdateManager.py b/module/plugins/hooks/UpdateManager.py index 920a88060..8cbc56c42 100644 --- a/module/plugins/hooks/UpdateManager.py +++ b/module/plugins/hooks/UpdateManager.py @@ -129,10 +129,10 @@ class UpdateManager(Hook): else: type = prefix - plugins = getattr(self.core.pluginManager, "%sPlugins" % type) + plugins = self.core.pluginManager.getPlugins(type) if name in plugins: - if float(plugins[name]["v"]) >= float(version): + if float(plugins[name].version) >= float(version): continue if name in IGNORE or (type, name) in IGNORE: -- cgit v1.2.3 From 6eae782f13953dd0ba2bbe1b582cf33fd4d7d90a Mon Sep 17 00:00:00 2001 From: RaNaN Date: Mon, 19 Dec 2011 23:10:49 +0100 Subject: configparser v2, warning CONFIG will be DELETED. --- module/plugins/hooks/UpdateManager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'module/plugins/hooks') diff --git a/module/plugins/hooks/UpdateManager.py b/module/plugins/hooks/UpdateManager.py index 8cbc56c42..4324a96ba 100644 --- a/module/plugins/hooks/UpdateManager.py +++ b/module/plugins/hooks/UpdateManager.py @@ -24,7 +24,7 @@ from os import stat from os.path import join, exists from time import time -from module.ConfigParser import IGNORE +from module.plugins.PluginManager import IGNORE from module.network.RequestFactory import getURL from module.plugins.Hook import threaded, Expose, Hook -- cgit v1.2.3 From d35c003cc53d4723d1dfe0d81eeb9bea78cee594 Mon Sep 17 00:00:00 2001 From: RaNaN Date: Sat, 31 Dec 2011 16:01:24 +0100 Subject: new crypter plugin API, now decrypting possible for now. --- module/plugins/hooks/UpdateManager.py | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'module/plugins/hooks') diff --git a/module/plugins/hooks/UpdateManager.py b/module/plugins/hooks/UpdateManager.py index 4324a96ba..d0c7f213d 100644 --- a/module/plugins/hooks/UpdateManager.py +++ b/module/plugins/hooks/UpdateManager.py @@ -61,6 +61,11 @@ class UpdateManager(Hook): @threaded def periodical(self): + + if self.core.version.endswith("-dev"): + self.logDebug("No update check performed on dev version.") + return + update = self.checkForUpdate() if update: self.info["pyload"] = True -- cgit v1.2.3 From e370517032aeb5f8305d9e0fdc26f643ff30f883 Mon Sep 17 00:00:00 2001 From: zoidberg10 Date: Wed, 4 Jan 2012 17:52:43 +0100 Subject: filesonic pattern fix (thanx Lino24), fix mu life account, closed #463 easybytez --- module/plugins/hooks/EasybytezCom.py | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 module/plugins/hooks/EasybytezCom.py (limited to 'module/plugins/hooks') diff --git a/module/plugins/hooks/EasybytezCom.py b/module/plugins/hooks/EasybytezCom.py new file mode 100644 index 000000000..4dd39cca6 --- /dev/null +++ b/module/plugins/hooks/EasybytezCom.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- + +from module.network.RequestFactory import getURL +from module.plugins.internal.MultiHoster import MultiHoster +import re + +def getConfigSet(option): + s = set(option.lower().replace(',','|').split('|')) + s.discard(u'') + return s + +class EasybytezCom(MultiHoster): + __name__ = "EasybytezCom" + __version__ = "0.01" + __type__ = "hook" + __config__ = [("activated", "bool", "Activated", "False"), + ("includeHoster", "str", "Use only for downloads from (comma-separated hosters)", ""), + ("excludeHoster", "str", "Do not use for downloads from (comma-separated hosters)", "")] + __description__ = """EasyBytez.com hook plugin""" + __author_name__ = ("zoidberg") + __author_mail__ = ("zoidberg@mujmail.cz") + + def getHoster(self): + + hoster = set(['2shared.com', 'easy-share.com', 'filefactory.com', 'fileserve.com', 'filesonic.com', 'hotfile.com', 'mediafire.com', 'megaupload.com', 'netload.in', 'rapidshare.com', 'uploading.com', 'wupload.com', 'oron.com', 'uploadstation.com', 'ul.to', 'uploaded.to']) + + option = self.getConfig('includeHoster').strip() + if option: hoster &= getConfigSet(option) + option = self.getConfig('excludeHoster').strip() + if option: hoster -= getConfigSet(option) + + return list(hoster) \ No newline at end of file -- cgit v1.2.3 From 2fc8bdf0f306297995afbbd757211ab8629092c2 Mon Sep 17 00:00:00 2001 From: Wieland Hoffmann Date: Thu, 5 Jan 2012 20:31:06 +0100 Subject: XMPPInterface: handle subscribe requests Owners get a subscription, other people don't This could probably be extended to unsubscribe people deleted from the owner list --- module/plugins/hooks/XMPPInterface.py | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) (limited to 'module/plugins/hooks') diff --git a/module/plugins/hooks/XMPPInterface.py b/module/plugins/hooks/XMPPInterface.py index a96adf524..fad98beb7 100644 --- a/module/plugins/hooks/XMPPInterface.py +++ b/module/plugins/hooks/XMPPInterface.py @@ -19,7 +19,7 @@ """ from pyxmpp import streamtls -from pyxmpp.all import JID, Message +from pyxmpp.all import JID, Message, Presence from pyxmpp.jabber.client import JabberClient from pyxmpp.interface import implements from pyxmpp.interfaces import * @@ -121,7 +121,26 @@ class XMPPInterface(IRCInterface, JabberClient): in a client session.""" return [ ("normal", self.message), - ] + ] + + def presence_control(self, stanza): + from_jid = unicode(stanza.get_from_jid()) + stanza_type = stanza.get_type() + self.log.debug("pyLoad XMPP: %s stanza from %s" % (stanza_type, + from_jid)) + + if from_jid in self.getConfig("owners"): + return stanza.make_accept_response() + + return stanza.make_deny_response() + + def session_started(self): + self.stream.send(Presence()) + + self.stream.set_presence_handler("subscribe", self.presence_control) + self.stream.set_presence_handler("subscribed", self.presence_control) + self.stream.set_presence_handler("unsubscribe", self.presence_control) + self.stream.set_presence_handler("unsubscribed", self.presence_control) def message(self, stanza): """Message handler for the component.""" @@ -248,4 +267,4 @@ class VersionHandler(object): q.newTextChild(q.ns(), "name", "Echo component") q.newTextChild(q.ns(), "version", "1.0") return iq - \ No newline at end of file + -- cgit v1.2.3 From ce6229a82f6952d5ae1e57a08cc6ed9fdef3c760 Mon Sep 17 00:00:00 2001 From: Wieland Hoffmann Date: Thu, 5 Jan 2012 20:39:46 +0100 Subject: Unbreak Ev0InFetcher --- module/plugins/hooks/Ev0InFetcher.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'module/plugins/hooks') diff --git a/module/plugins/hooks/Ev0InFetcher.py b/module/plugins/hooks/Ev0InFetcher.py index 5941cf38c..0cd3f3226 100644 --- a/module/plugins/hooks/Ev0InFetcher.py +++ b/module/plugins/hooks/Ev0InFetcher.py @@ -40,7 +40,7 @@ class Ev0InFetcher(Hook): results = self.core.pluginManager.parseUrls(links) sortedLinks = {} - for url, hoster in results: + for url, hoster in results[0]: if hoster not in sortedLinks: sortedLinks[hoster] = [] sortedLinks[hoster].append(url) -- cgit v1.2.3 From 800eafec5a0ff63a461cc4f2348d6e695ba9ba12 Mon Sep 17 00:00:00 2001 From: Wieland Hoffmann Date: Thu, 5 Jan 2012 20:58:52 +0100 Subject: xmpp: disconnect on unload / deactivate --- module/plugins/hooks/XMPPInterface.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'module/plugins/hooks') diff --git a/module/plugins/hooks/XMPPInterface.py b/module/plugins/hooks/XMPPInterface.py index fad98beb7..de87433cf 100644 --- a/module/plugins/hooks/XMPPInterface.py +++ b/module/plugins/hooks/XMPPInterface.py @@ -267,4 +267,10 @@ class VersionHandler(object): q.newTextChild(q.ns(), "name", "Echo component") q.newTextChild(q.ns(), "version", "1.0") return iq - + + def unload(self): + self.log.debug("pyLoad XMPP: unloading") + self.disconnect() + + def deactivate(self): + self.unload() -- cgit v1.2.3 From bac28b7740aae772636d8b90e291d9c17dfd59a7 Mon Sep 17 00:00:00 2001 From: RaNaN Date: Sun, 8 Jan 2012 14:44:59 +0100 Subject: new MultiHoster hook --- module/plugins/hooks/ClickAndLoad.py | 2 +- module/plugins/hooks/MultiHoster.py | 100 ++++++++++++++++++++++++++++++++++ module/plugins/hooks/RealdebridCom.py | 24 -------- 3 files changed, 101 insertions(+), 25 deletions(-) create mode 100644 module/plugins/hooks/MultiHoster.py delete mode 100644 module/plugins/hooks/RealdebridCom.py (limited to 'module/plugins/hooks') 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 -- cgit v1.2.3 From 1ecdd9f6b53fec45e1d48592e3ff56aa7a576bec Mon Sep 17 00:00:00 2001 From: RaNaN Date: Sun, 8 Jan 2012 16:47:52 +0100 Subject: some cleanups, closed #490 --- module/plugins/hooks/ExternalScripts.py | 9 ++++----- module/plugins/hooks/ExtractArchive.py | 4 ++-- module/plugins/hooks/MultiHoster.py | 1 + 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'module/plugins/hooks') diff --git a/module/plugins/hooks/ExternalScripts.py b/module/plugins/hooks/ExternalScripts.py index 2e77f1dae..39fe2b9f0 100644 --- a/module/plugins/hooks/ExternalScripts.py +++ b/module/plugins/hooks/ExternalScripts.py @@ -14,16 +14,15 @@ You should have received a copy of the GNU General Public License along with this program; if not, see . - @author: mkaay - @interface-version: 0.1 + @author: RaNaN """ import subprocess -from os import listdir, access, X_OK, makedirs -from os.path import join, exists, basename +from os import access, X_OK, makedirs +from os.path import basename from module.plugins.Hook import Hook -from module.utils import save_join +from module.utils.fs import save_join, exists, join, listdir class ExternalScripts(Hook): __name__ = "ExternalScripts" diff --git a/module/plugins/hooks/ExtractArchive.py b/module/plugins/hooks/ExtractArchive.py index 82e9c1d36..d9c2e57bb 100644 --- a/module/plugins/hooks/ExtractArchive.py +++ b/module/plugins/hooks/ExtractArchive.py @@ -4,7 +4,7 @@ import sys import os from os import remove, chmod, makedirs -from os.path import exists, basename, isfile, isdir, join +from os.path import basename, isfile, isdir, join from traceback import print_exc from copy import copy @@ -48,7 +48,7 @@ if os.name != "nt": from pwd import getpwnam from grp import getgrnam -from module.utils import save_join, fs_encode +from module.utils.fs import save_join, fs_encode, exists from module.plugins.Hook import Hook, threaded, Expose from module.plugins.internal.AbstractExtractor import ArchiveError, CRCError, WrongPassword diff --git a/module/plugins/hooks/MultiHoster.py b/module/plugins/hooks/MultiHoster.py index 1f40a4ddd..749f2c104 100644 --- a/module/plugins/hooks/MultiHoster.py +++ b/module/plugins/hooks/MultiHoster.py @@ -69,6 +69,7 @@ class MultiHoster(Hook): 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) -- cgit v1.2.3 From a2ab9ced6ffb038a051e465f06d8b5ca6512a79b Mon Sep 17 00:00:00 2001 From: RaNaN Date: Sun, 22 Jan 2012 13:59:46 +0100 Subject: try to fix unrar encoding issues --- module/plugins/hooks/ExtractArchive.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'module/plugins/hooks') diff --git a/module/plugins/hooks/ExtractArchive.py b/module/plugins/hooks/ExtractArchive.py index d9c2e57bb..53f88b3a5 100644 --- a/module/plugins/hooks/ExtractArchive.py +++ b/module/plugins/hooks/ExtractArchive.py @@ -3,7 +3,6 @@ import sys import os -from os import remove, chmod, makedirs from os.path import basename, isfile, isdir, join from traceback import print_exc from copy import copy @@ -48,7 +47,7 @@ if os.name != "nt": from pwd import getpwnam from grp import getgrnam -from module.utils.fs import save_join, fs_encode, exists +from module.utils.fs import save_join, fs_encode, exists, remove, chmod, makedirs from module.plugins.Hook import Hook, threaded, Expose from module.plugins.internal.AbstractExtractor import ArchiveError, CRCError, WrongPassword -- cgit v1.2.3 From d7eef2c28eae2e43e3ade4441810ecc0cdea6fd7 Mon Sep 17 00:00:00 2001 From: RaNaN Date: Sun, 5 Feb 2012 21:21:36 +0100 Subject: option for internal plugins --- module/plugins/hooks/MultiHoster.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'module/plugins/hooks') diff --git a/module/plugins/hooks/MultiHoster.py b/module/plugins/hooks/MultiHoster.py index 749f2c104..2a567cce4 100644 --- a/module/plugins/hooks/MultiHoster.py +++ b/module/plugins/hooks/MultiHoster.py @@ -10,8 +10,9 @@ from module.plugins.PluginManager import PluginTuple class MultiHoster(Hook): __version__ = "0.1" + __internal__ = True __description__ = "Gives ability to use MultiHoster services. You need to add your account first." - __config__ = [("activated", "bool", "Activated", True)] + __config__ = [] __author_mail__ = ("pyLoad Team",) __author_mail__ = ("support@pyload.org",) -- cgit v1.2.3 From 4df2b77fdf42046fe19bd371be7c7255986b5980 Mon Sep 17 00:00:00 2001 From: RaNaN Date: Tue, 6 Mar 2012 13:36:39 +0100 Subject: renamed hooks to addons, new filemanager and database, many new api methods you will loose ALL your LINKS, webinterface will NOT work --- module/plugins/hooks/CaptchaTrader.py | 159 ------------ module/plugins/hooks/ClickAndLoad.py | 89 ------- module/plugins/hooks/EasybytezCom.py | 32 --- module/plugins/hooks/Ev0InFetcher.py | 87 ------- module/plugins/hooks/ExternalScripts.py | 118 --------- module/plugins/hooks/ExtractArchive.py | 314 ----------------------- module/plugins/hooks/HotFolder.py | 85 ------- module/plugins/hooks/IRCInterface.py | 425 -------------------------------- module/plugins/hooks/MergeFiles.py | 94 ------- module/plugins/hooks/MultiHome.py | 82 ------ module/plugins/hooks/MultiHoster.py | 102 -------- module/plugins/hooks/MultishareCz.py | 36 --- module/plugins/hooks/Premium4Me.py | 46 ---- module/plugins/hooks/RehostTo.py | 39 --- module/plugins/hooks/UpdateManager.py | 199 --------------- module/plugins/hooks/XMPPInterface.py | 276 --------------------- module/plugins/hooks/__init__.py | 0 17 files changed, 2183 deletions(-) delete mode 100644 module/plugins/hooks/CaptchaTrader.py delete mode 100644 module/plugins/hooks/ClickAndLoad.py delete mode 100644 module/plugins/hooks/EasybytezCom.py delete mode 100644 module/plugins/hooks/Ev0InFetcher.py delete mode 100644 module/plugins/hooks/ExternalScripts.py delete mode 100644 module/plugins/hooks/ExtractArchive.py delete mode 100644 module/plugins/hooks/HotFolder.py delete mode 100644 module/plugins/hooks/IRCInterface.py delete mode 100644 module/plugins/hooks/MergeFiles.py delete mode 100644 module/plugins/hooks/MultiHome.py delete mode 100644 module/plugins/hooks/MultiHoster.py delete mode 100644 module/plugins/hooks/MultishareCz.py delete mode 100644 module/plugins/hooks/Premium4Me.py delete mode 100644 module/plugins/hooks/RehostTo.py delete mode 100644 module/plugins/hooks/UpdateManager.py delete mode 100644 module/plugins/hooks/XMPPInterface.py delete mode 100644 module/plugins/hooks/__init__.py (limited to 'module/plugins/hooks') diff --git a/module/plugins/hooks/CaptchaTrader.py b/module/plugins/hooks/CaptchaTrader.py deleted file mode 100644 index 889eb83c0..000000000 --- a/module/plugins/hooks/CaptchaTrader.py +++ /dev/null @@ -1,159 +0,0 @@ -# -*- 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: mkaay, RaNaN -""" - -try: - from json import loads -except ImportError: - from simplejson import loads - -from thread import start_new_thread -from pycurl import FORM_FILE, LOW_SPEED_TIME - -from module.network.RequestFactory import getURL, getRequest -from module.network.HTTPRequest import BadHeader - -from module.plugins.Hook import Hook - -PYLOAD_KEY = "9f65e7f381c3af2b076ea680ae96b0b7" - -class CaptchaTraderException(Exception): - def __init__(self, err): - self.err = err - - def getCode(self): - return self.err - - def __str__(self): - return "" % self.err - - def __repr__(self): - return "" % self.err - -class CaptchaTrader(Hook): - __name__ = "CaptchaTrader" - __version__ = "0.13" - __description__ = """send captchas to captchatrader.com""" - __config__ = [("activated", "bool", "Activated", True), - ("username", "str", "Username", ""), - ("force", "bool", "Force CT even if client is connected", False), - ("passkey", "password", "Password", ""),] - __author_name__ = ("RaNaN") - __author_mail__ = ("RaNaN@pyload.org") - - SUBMIT_URL = "http://captchatrader.com/api/submit" - 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"), - "password": self.getConfig("passkey")}) - response = loads(json) - if response[0] < 0: - 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): - if not PYLOAD_KEY: - raise CaptchaTraderException("No API Key Specified!") - - #if type(captcha) == str and captchaType == "file": - # raise CaptchaTraderException("Invalid Type") - assert captchaType in ("file", "url-jpg", "url-jpeg", "url-png", "url-bmp") - - req = getRequest() - - #raise timeout threshold - req.c.setopt(LOW_SPEED_TIME, 80) - - try: - json = req.load(CaptchaTrader.SUBMIT_URL, post={"api_key": PYLOAD_KEY, - "username": self.getConfig("username"), - "password": self.getConfig("passkey"), - "value": (FORM_FILE, captcha), - "type": captchaType}, multipart=True) - finally: - req.close() - - response = loads(json) - if response[0] < 0: - raise CaptchaTraderException(response[1]) - - ticket = response[0] - result = response[1] - self.logDebug("result %s : %s" % (ticket,result)) - - return ticket, result - - def respond(self, ticket, success): - try: - json = getURL(CaptchaTrader.RESPOND_URL, post={"is_correct": 1 if success else 0, - "username": self.getConfig("username"), - "password": self.getConfig("passkey"), - "ticket": ticket}) - - response = loads(json) - if response[0] < 0: - raise CaptchaTraderException(response[1]) - - except BadHeader, e: - self.logError(_("Could not send response."), str(e)) - - def newCaptchaTask(self, task): - if not task.isTextual(): - return False - - if not self.getConfig("username") or not self.getConfig("passkey"): - return False - - if self.core.isClientConnected() and not self.getConfig("force"): - return False - - if self.getCredits() > 10: - task.handler.append(self) - task.setWaiting(100) - start_new_thread(self.processCaptcha, (task,)) - - else: - self.logInfo(_("Your CaptchaTrader Account has not enough credits")) - - def captchaCorrect(self, task): - if "ticket" in task.data: - ticket = task.data["ticket"] - self.respond(ticket, True) - - def captchaInvalid(self, task): - if "ticket" in task.data: - ticket = task.data["ticket"] - self.respond(ticket, False) - - def processCaptcha(self, task): - c = task.captchaFile - try: - ticket, result = self.submit(c) - except CaptchaTraderException, e: - task.error = e.getCode() - return - - task.data["ticket"] = ticket - task.setResult(result) diff --git a/module/plugins/hooks/ClickAndLoad.py b/module/plugins/hooks/ClickAndLoad.py deleted file mode 100644 index fc32d0da8..000000000 --- a/module/plugins/hooks/ClickAndLoad.py +++ /dev/null @@ -1,89 +0,0 @@ -# -*- 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 - @interface-version: 0.2 -""" - -import socket -import thread - -from module.plugins.Hook import Hook - -class ClickAndLoad(Hook): - __name__ = "ClickAndLoad" - __version__ = "0.2" - __description__ = """Gives abillity to use jd's click and load. depends on webinterface""" - __config__ = [("activated", "bool", "Activated", "True"), - ("extern", "bool", "Allow external link adding", "False")] - __author_name__ = ("RaNaN", "mkaay") - __author_mail__ = ("RaNaN@pyload.de", "mkaay@mkaay.de") - - def activate(self): - self.port = int(self.core.config['webinterface']['port']) - if self.core.config['webinterface']['activated']: - try: - if self.getConfig("extern"): - ip = "0.0.0.0" - else: - ip = "127.0.0.1" - - thread.start_new_thread(proxy, (self, ip, self.port, 9666)) - except: - self.log.error("ClickAndLoad port already in use.") - - -def proxy(self, *settings): - thread.start_new_thread(server, (self,) + settings) - lock = thread.allocate_lock() - lock.acquire() - lock.acquire() - - -def server(self, *settings): - try: - dock_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - dock_socket.bind((settings[0], settings[2])) - dock_socket.listen(5) - while True: - client_socket = dock_socket.accept()[0] - server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - server_socket.connect(("127.0.0.1", settings[1])) - thread.start_new_thread(forward, (client_socket, server_socket)) - thread.start_new_thread(forward, (server_socket, client_socket)) - except socket.error, e: - if hasattr(e, "errno"): - errno = e.errno - else: - errno = e.args[0] - - if errno == 98: - self.core.log.warning(_("Click'N'Load: Port 9666 already in use")) - return - thread.start_new_thread(server, (self,) + settings) - except: - thread.start_new_thread(server, (self,) + settings) - - -def forward(source, destination): - string = ' ' - while string: - string = source.recv(1024) - if string: - destination.sendall(string) - else: - #source.shutdown(socket.SHUT_RD) - destination.shutdown(socket.SHUT_WR) diff --git a/module/plugins/hooks/EasybytezCom.py b/module/plugins/hooks/EasybytezCom.py deleted file mode 100644 index 4dd39cca6..000000000 --- a/module/plugins/hooks/EasybytezCom.py +++ /dev/null @@ -1,32 +0,0 @@ -# -*- coding: utf-8 -*- - -from module.network.RequestFactory import getURL -from module.plugins.internal.MultiHoster import MultiHoster -import re - -def getConfigSet(option): - s = set(option.lower().replace(',','|').split('|')) - s.discard(u'') - return s - -class EasybytezCom(MultiHoster): - __name__ = "EasybytezCom" - __version__ = "0.01" - __type__ = "hook" - __config__ = [("activated", "bool", "Activated", "False"), - ("includeHoster", "str", "Use only for downloads from (comma-separated hosters)", ""), - ("excludeHoster", "str", "Do not use for downloads from (comma-separated hosters)", "")] - __description__ = """EasyBytez.com hook plugin""" - __author_name__ = ("zoidberg") - __author_mail__ = ("zoidberg@mujmail.cz") - - def getHoster(self): - - hoster = set(['2shared.com', 'easy-share.com', 'filefactory.com', 'fileserve.com', 'filesonic.com', 'hotfile.com', 'mediafire.com', 'megaupload.com', 'netload.in', 'rapidshare.com', 'uploading.com', 'wupload.com', 'oron.com', 'uploadstation.com', 'ul.to', 'uploaded.to']) - - option = self.getConfig('includeHoster').strip() - if option: hoster &= getConfigSet(option) - option = self.getConfig('excludeHoster').strip() - if option: hoster -= getConfigSet(option) - - return list(hoster) \ No newline at end of file diff --git a/module/plugins/hooks/Ev0InFetcher.py b/module/plugins/hooks/Ev0InFetcher.py deleted file mode 100644 index 0cd3f3226..000000000 --- a/module/plugins/hooks/Ev0InFetcher.py +++ /dev/null @@ -1,87 +0,0 @@ -# -*- 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: mkaay -""" -from module.lib import feedparser -from time import mktime, time - -from module.plugins.Hook import Hook - -class Ev0InFetcher(Hook): - __name__ = "Ev0InFetcher" - __version__ = "0.2" - __description__ = """checks rss feeds for ev0.in""" - __config__ = [("activated", "bool", "Activated", "False"), - ("interval", "int", "Check interval in minutes", "10"), - ("queue", "bool", "Move new shows directly to Queue", False), - ("shows", "str", "Shows to check for (comma seperated)", ""), - ("quality", "xvid;x264;rmvb", "Video Format", "xvid"), - ("hoster", "str", "Hoster to use (comma seperated)", "NetloadIn,RapidshareCom,MegauploadCom,HotfileCom")] - __author_name__ = ("mkaay") - __author_mail__ = ("mkaay@mkaay.de") - - def setup(self): - self.interval = self.getConfig("interval") * 60 - - def filterLinks(self, links): - results = self.core.pluginManager.parseUrls(links) - sortedLinks = {} - - for url, hoster in results[0]: - if hoster not in sortedLinks: - sortedLinks[hoster] = [] - sortedLinks[hoster].append(url) - - for h in self.getConfig("hoster").split(","): - try: - return sortedLinks[h.strip()] - except: - continue - return [] - - def periodical(self): - def normalizefiletitle(filename): - filename = filename.replace('.', ' ') - filename = filename.replace('_', ' ') - filename = filename.lower() - return filename - - shows = [s.strip() for s in self.getConfig("shows").split(",")] - - feed = feedparser.parse("http://feeds.feedburner.com/ev0in/%s?format=xml" % self.getConfig("quality")) - - showStorage = {} - for show in shows: - showStorage[show] = int(self.getStorage("show_%s_lastfound" % show, 0)) - - found = False - for item in feed['items']: - for show, lastfound in showStorage.iteritems(): - if show.lower() in normalizefiletitle(item['title']) and lastfound < int(mktime(item.date_parsed)): - links = self.filterLinks(item['description'].split("
")) - packagename = item['title'].encode("utf-8") - self.core.log.info("Ev0InFetcher: new episode '%s' (matched '%s')" % (packagename, show)) - self.core.api.addPackage(packagename, links, 1 if self.getConfig("queue") else 0) - self.setStorage("show_%s_lastfound" % show, int(mktime(item.date_parsed))) - found = True - if not found: - #self.core.log.debug("Ev0InFetcher: no new episodes found") - pass - - for show, lastfound in self.getStorage().iteritems(): - if int(lastfound) > 0 and int(lastfound) + (3600*24*30) < int(time()): - self.delStorage("show_%s_lastfound" % show) - self.core.log.debug("Ev0InFetcher: cleaned '%s' record" % show) diff --git a/module/plugins/hooks/ExternalScripts.py b/module/plugins/hooks/ExternalScripts.py deleted file mode 100644 index 39fe2b9f0..000000000 --- a/module/plugins/hooks/ExternalScripts.py +++ /dev/null @@ -1,118 +0,0 @@ -# -*- 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 -""" - -import subprocess -from os import access, X_OK, makedirs -from os.path import basename - -from module.plugins.Hook import Hook -from module.utils.fs import save_join, exists, join, listdir - -class ExternalScripts(Hook): - __name__ = "ExternalScripts" - __version__ = "0.21" - __description__ = """Run external scripts""" - __config__ = [("activated", "bool", "Activated", "True")] - __author_name__ = ("mkaay", "RaNaN", "spoob") - __author_mail__ = ("mkaay@mkaay.de", "ranan@pyload.org", "spoob@pyload.org") - - event_list = ["unrarFinished", "allDownloadsFinished", "allDownloadsProcessed"] - - def setup(self): - self.scripts = {} - - folders = ['download_preparing', 'download_finished', 'package_finished', - 'before_reconnect', 'after_reconnect', 'unrar_finished', - 'all_dls_finished', 'all_dls_processed'] - - for folder in folders: - - self.scripts[folder] = [] - - self.initPluginType(folder, join(pypath, 'scripts', folder)) - self.initPluginType(folder, join('scripts', folder)) - - for script_type, names in self.scripts.iteritems(): - if names: - self.logInfo((_("Installed scripts for %s: ") % script_type ) + ", ".join([basename(x) for x in names])) - - - def initPluginType(self, folder, path): - if not exists(path): - try: - makedirs(path) - except : - self.logDebug("Script folder %s not created" % folder) - return - - for f in listdir(path): - if f.startswith("#") or f.startswith(".") or f.startswith("_") or f.endswith("~") or f.endswith(".swp"): - continue - - if not access(join(path,f), X_OK): - self.logWarning(_("Script not executable:") + " %s/%s" % (folder, f)) - - self.scripts[folder].append(join(path, f)) - - def callScript(self, script, *args): - try: - cmd = [script] + [str(x) if not isinstance(x, basestring) else x for x in args] - #output goes to pyload - subprocess.Popen(cmd, bufsize=-1) - except Exception, e: - self.logError(_("Error in %(script)s: %(error)s") % { "script" :basename(script), "error": str(e)}) - - def downloadPreparing(self, pyfile): - for script in self.scripts['download_preparing']: - self.callScript(script, pyfile.pluginname, pyfile.url, pyfile.id) - - def downloadFinished(self, pyfile): - for script in self.scripts['download_finished']: - self.callScript(script, pyfile.pluginname, pyfile.url, pyfile.name, pyfile.id, - save_join(self.core.config['general']['download_folder'], pyfile.package().folder, pyfile.name), - pyfile.id) - - - def packageFinished(self, pypack): - for script in self.scripts['package_finished']: - folder = self.core.config['general']['download_folder'] - folder = save_join(folder, pypack.folder) - - self.callScript(script, pypack.name, folder, pypack.id) - - def beforeReconnecting(self, ip): - for script in self.scripts['before_reconnect']: - self.callScript(script, ip) - - def afterReconnecting(self, ip): - for script in self.scripts['after_reconnect']: - self.callScript(script, ip) - - def unrarFinished(self, folder, fname): - for script in self.scripts["unrar_finished"]: - self.callScript(script, folder, fname) - - def allDownloadsFinished(self): - for script in self.scripts["all_dls_finished"]: - self.callScript(script) - - def allDownloadsProcessed(self): - for script in self.scripts["all_dls_processed"]: - self.callScript(script) - diff --git a/module/plugins/hooks/ExtractArchive.py b/module/plugins/hooks/ExtractArchive.py deleted file mode 100644 index 12bd40d1b..000000000 --- a/module/plugins/hooks/ExtractArchive.py +++ /dev/null @@ -1,314 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -import sys -import os -from os.path import basename, isfile, isdir, join -from traceback import print_exc -from copy import copy - -# monkey patch bug in python 2.6 and lower -# see http://bugs.python.org/issue6122 -# http://bugs.python.org/issue1236 -# http://bugs.python.org/issue1731717 -if sys.version_info < (2, 7) and os.name != "nt": - from subprocess import Popen - import errno - - def _eintr_retry_call(func, *args): - while True: - try: - return func(*args) - except OSError, e: - if e.errno == errno.EINTR: - continue - raise - - # unsued timeout option for older python version - def wait(self, timeout=0): - """Wait for child process to terminate. Returns returncode - attribute.""" - if self.returncode is None: - try: - pid, sts = _eintr_retry_call(os.waitpid, self.pid, 0) - except OSError, e: - if e.errno != errno.ECHILD: - raise - # This happens if SIGCLD is set to be ignored or waiting - # for child processes has otherwise been disabled for our - # process. This child is dead, we can't get the status. - sts = 0 - self._handle_exitstatus(sts) - return self.returncode - - Popen.wait = wait - -if os.name != "nt": - from os import chown - from pwd import getpwnam - from grp import getgrnam - -from module.utils.fs import save_join, fs_encode, exists, remove, chmod, makedirs -from module.plugins.Hook import Hook, threaded, Expose -from module.plugins.internal.AbstractExtractor import ArchiveError, CRCError, WrongPassword - -class ExtractArchive(Hook): - """ - Provides: unrarFinished (folder, filename) - """ - __name__ = "ExtractArchive" - __version__ = "0.12" - __description__ = "Extract different kind of archives" - __config__ = [("activated", "bool", "Activated", True), - ("fullpath", "bool", "Extract full path", True), - ("overwrite", "bool", "Overwrite files", True), - ("passwordfile", "file", "password file", "unrar_passwords.txt"), - ("deletearchive", "bool", "Delete archives when done", False), - ("subfolder", "bool", "Create subfolder for each package", False), - ("destination", "folder", "Extract files to", ""), - ("recursive", "bool", "Extract archives in archvies", True), - ("queue", "bool", "Wait for all downloads to be finished", True), - ("renice", "int", "CPU Priority", 0), ] - __author_name__ = ("pyload Team") - __author_mail__ = ("adminpyload.org") - - event_list = ["allDownloadsProcessed"] - - def setup(self): - self.plugins = [] - self.passwords = [] - names = [] - - for p in ("UnRar", "UnZip"): - try: - module = self.core.pluginManager.loadModule("internal", p) - klass = getattr(module, p) - if klass.checkDeps(): - names.append(p) - self.plugins.append(klass) - - except OSError, e: - if e.errno == 2: - self.logInfo(_("No %s installed") % p) - else: - self.logWarning(_("Could not activate %s") % p, str(e)) - if self.core.debug: - print_exc() - - except Exception, e: - self.logWarning(_("Could not activate %s") % p, str(e)) - if self.core.debug: - print_exc() - - if names: - self.logInfo(_("Activated") + " " + " ".join(names)) - else: - self.logInfo(_("No Extract plugins activated")) - - # queue with package ids - self.queue = [] - - @Expose - def extractPackage(self, id): - """ Extract package with given id""" - self.manager.startThread(self.extract, [id]) - - def packageFinished(self, pypack): - if self.getConfig("queue"): - self.logInfo(_("Package %s queued for later extracting") % pypack.name) - self.queue.append(pypack.id) - else: - self.manager.startThread(self.extract, [pypack.id]) - - - @threaded - def allDownloadsProcessed(self, thread): - local = copy(self.queue) - del self.queue[:] - self.extract(local, thread) - - - def extract(self, ids, thread=None): - # reload from txt file - self.reloadPasswords() - - # dl folder - dl = self.config['general']['download_folder'] - - extracted = [] - - #iterate packages -> plugins -> targets - for pid in ids: - p = self.core.files.getPackage(pid) - self.logInfo(_("Check package %s") % p.name) - if not p: continue - - # determine output folder - out = save_join(dl, p.folder, "") - # force trailing slash - - if self.getConfig("destination") and self.getConfig("destination").lower() != "none": - - out = save_join(dl, p.folder, self.getConfig("destination"), "") - #relative to package folder if destination is relative, otherwise absolute path overwrites them - - if self.getConf("subfolder"): - out = join(out, fs_encode(p.folder)) - - if not exists(out): - makedirs(out) - - files_ids = [(save_join(dl, p.folder, x["name"]), x["id"]) for x in p.getChildren().itervalues()] - matched = False - - # check as long there are unseen files - while files_ids: - new_files_ids = [] - - for plugin in self.plugins: - targets = plugin.getTargets(files_ids) - if targets: - self.logDebug("Targets for %s: %s" % (plugin.__name__, targets)) - matched = True - for target, fid in targets: - if target in extracted: - self.logDebug(basename(target), "skipped") - continue - extracted.append(target) #prevent extracting same file twice - - klass = plugin(self, target, out, self.getConfig("fullpath"), self.getConfig("overwrite"), - self.getConfig("renice")) - klass.init() - - self.logInfo(basename(target), _("Extract to %s") % out) - new_files = self.startExtracting(klass, fid, p.password.strip().splitlines(), thread) - self.logDebug("Extracted: %s" % new_files) - self.setPermissions(new_files) - - for file in new_files: - if not exists(file): - self.logDebug("new file %s does not exists" % file) - continue - if self.getConfig("recursive") and isfile(file): - new_files_ids.append((file, fid)) #append as new target - - files_ids = new_files_ids # also check extracted files - - if not matched: self.logInfo(_("No files found to extract")) - - - - def startExtracting(self, plugin, fid, passwords, thread): - pyfile = self.core.files.getFile(fid) - if not pyfile: return [] - - pyfile.setCustomStatus(_("extracting")) - thread.addActive(pyfile) #keep this file until everything is done - - try: - progress = lambda x: pyfile.setProgress(x) - success = False - - if not plugin.checkArchive(): - plugin.extract(progress) - success = True - else: - self.logInfo(basename(plugin.file), _("Password protected")) - self.logDebug("Passwords: %s" % str(passwords)) - - pwlist = copy(self.getPasswords()) - #remove already supplied pws from list (only local) - for pw in passwords: - if pw in pwlist: pwlist.remove(pw) - - for pw in passwords + pwlist: - try: - self.logDebug("Try password: %s" % pw) - if plugin.checkPassword(pw): - plugin.extract(progress, pw) - self.addPassword(pw) - success = True - break - except WrongPassword: - self.logDebug("Password was wrong") - - if not success: - self.logError(basename(plugin.file), _("Wrong password")) - return [] - - if self.core.debug: - self.logDebug("Would delete: %s" % ", ".join(plugin.getDeleteFiles())) - - if self.getConfig("deletearchive"): - files = plugin.getDeleteFiles() - self.logInfo(_("Deleting %s files") % len(files)) - for f in files: - if exists(f): remove(f) - else: self.logDebug("%s does not exists" % f) - - self.logInfo(basename(plugin.file), _("Extracting finished")) - self.manager.dispatchEvent("unrarFinished", plugin.out, plugin.file) - - return plugin.getExtractedFiles() - - - except ArchiveError, e: - self.logError(basename(plugin.file), _("Archive Error"), str(e)) - except CRCError: - self.logError(basename(plugin.file), _("CRC Mismatch")) - except Exception, e: - if self.core.debug: - print_exc() - self.logError(basename(plugin.file), _("Unknown Error"), str(e)) - - return [] - - @Expose - def getPasswords(self): - """ List of saved passwords """ - return self.passwords - - - def reloadPasswords(self): - pwfile = self.getConfig("passwordfile") - if not exists(pwfile): - open(pwfile, "wb").close() - - passwords = [] - f = open(pwfile, "rb") - for pw in f.read().splitlines(): - passwords.append(pw) - f.close() - - self.passwords = passwords - - - @Expose - def addPassword(self, pw): - """ Adds a password to saved list""" - pwfile = self.getConfig("passwordfile") - - if pw in self.passwords: self.passwords.remove(pw) - self.passwords.insert(0, pw) - - f = open(pwfile, "wb") - for pw in self.passwords: - f.write(pw + "\n") - f.close() - - def setPermissions(self, files): - for f in files: - if not exists(f): continue - try: - if self.core.config["permission"]["change_file"]: - if isfile(f): - chmod(f, int(self.core.config["permission"]["file"], 8)) - elif isdir(f): - chmod(f, int(self.core.config["permission"]["folder"], 8)) - - if self.core.config["permission"]["change_dl"] and os.name != "nt": - uid = getpwnam(self.config["permission"]["user"])[2] - gid = getgrnam(self.config["permission"]["group"])[2] - chown(f, uid, gid) - except Exception, e: - self.log.warning(_("Setting User and Group failed"), e) diff --git a/module/plugins/hooks/HotFolder.py b/module/plugins/hooks/HotFolder.py deleted file mode 100644 index ee1031ad5..000000000 --- a/module/plugins/hooks/HotFolder.py +++ /dev/null @@ -1,85 +0,0 @@ -# -*- 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 - @interface-version: 0.2 -""" - -from os import makedirs -from os import listdir -from os.path import exists -from os.path import join -from os.path import isfile -from shutil import move -import time - -from module.plugins.Hook import Hook - -class HotFolder(Hook): - __name__ = "HotFolder" - __version__ = "0.1" - __description__ = """observe folder and file for changes and add container and links""" - __config__ = [ ("activated", "bool", "Activated" , "False"), - ("folder", "str", "Folder to observe", "container"), - ("watch_file", "bool", "Observe link file", "False"), - ("keep", "bool", "Keep added containers", "True"), - ("file", "str", "Link file", "links.txt")] - __threaded__ = [] - __author_name__ = ("RaNaN") - __author_mail__ = ("RaNaN@pyload.de") - - def setup(self): - self.interval = 10 - - def periodical(self): - - if not exists(join(self.getConfig("folder"), "finished")): - makedirs(join(self.getConfig("folder"), "finished")) - - if self.getConfig("watch_file"): - - if not exists(self.getConfig("file")): - f = open(self.getConfig("file"), "wb") - f.close() - - - f = open(self.getConfig("file"), "rb") - content = f.read().strip() - f.close() - f = open(self.getConfig("file"), "wb") - f.close() - if content: - name = "%s_%s.txt" % (self.getConfig("file"), time.strftime("%H-%M-%S_%d%b%Y") ) - - f = open(join(self.getConfig("folder"), "finished", name), "wb") - f.write(content) - f.close() - - self.core.api.addPackage(f.name, [f.name], 1) - - for f in listdir(self.getConfig("folder")): - path = join(self.getConfig("folder"), f) - - if not isfile(path) or f.endswith("~") or f.startswith("#") or f.startswith("."): - continue - - newpath = join(self.getConfig("folder"), "finished", f if self.getConfig("keep") else "tmp_"+f) - move(path, newpath) - - self.log.info(_("Added %s from HotFolder") % f) - self.core.api.addPackage(f, [newpath], 1) - - \ No newline at end of file diff --git a/module/plugins/hooks/IRCInterface.py b/module/plugins/hooks/IRCInterface.py deleted file mode 100644 index e2737dc3a..000000000 --- a/module/plugins/hooks/IRCInterface.py +++ /dev/null @@ -1,425 +0,0 @@ -# -*- 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 - @author: jeix - @interface-version: 0.2 -""" - -from select import select -import socket -from threading import Thread -import time -from time import sleep -from traceback import print_exc -import re - -from module.plugins.Hook import Hook -from module.network.RequestFactory import getURL -from module.utils import formatSize - -from pycurl import FORM_FILE - -class IRCInterface(Thread, Hook): - __name__ = "IRCInterface" - __version__ = "0.1" - __description__ = """connect to irc and let owner perform different tasks""" - __config__ = [("activated", "bool", "Activated", "False"), - ("host", "str", "IRC-Server Address", "Enter your server here!"), - ("port", "int", "IRC-Server Port", "6667"), - ("ident", "str", "Clients ident", "pyload-irc"), - ("realname", "str", "Realname", "pyload-irc"), - ("nick", "str", "Nickname the Client will take", "pyLoad-IRC"), - ("owner", "str", "Nickname the Client will accept commands from", "Enter your nick here!"), - ("info_file", "bool", "Inform about every file finished", "False"), - ("info_pack", "bool", "Inform about every package finished", "True"), - ("captcha", "bool", "Send captcha requests", "True")] - __author_name__ = ("Jeix") - __author_mail__ = ("Jeix@hasnomail.com") - - def __init__(self, core, manager): - Thread.__init__(self) - Hook.__init__(self, core, manager) - self.setDaemon(True) - # self.sm = core.server_methods - self.api = core.api #todo, only use api - - def coreReady(self): - self.new_package = {} - - self.abort = False - - self.links_added = 0 - self.more = [] - - self.start() - - - def packageFinished(self, pypack): - try: - if self.getConfig("info_pack"): - self.response(_("Package finished: %s") % pypack.name) - except: - pass - - def downloadFinished(self, pyfile): - try: - if self.getConfig("info_file"): - self.response(_("Download finished: %(name)s @ %(plugin)s ") % { "name" : pyfile.name, "plugin": pyfile.pluginname} ) - except: - pass - - def newCaptchaTask(self, task): - if self.getConfig("captcha") and task.isTextual(): - task.handler.append(self) - task.setWaiting(60) - - page = getURL("http://www.freeimagehosting.net/upload.php", post={"attached" : (FORM_FILE, task.captchaFile)}, multipart=True) - - url = re.search(r"\[img\]([^\[]+)\[/img\]\[/url\]", page).group(1) - self.response(_("New Captcha Request: %s") % url) - self.response(_("Answer with 'c %s text on the captcha'") % task.id) - - def run(self): - # connect to IRC etc. - self.sock = socket.socket() - host = self.getConfig("host") - self.sock.connect((host, self.getConfig("port"))) - nick = self.getConfig("nick") - self.sock.send("NICK %s\r\n" % nick) - self.sock.send("USER %s %s bla :%s\r\n" % (nick, host, nick)) - for t in self.getConfig("owner").split(): - if t.strip().startswith("#"): - self.sock.send("JOIN %s\r\n" % t.strip()) - self.log.info("pyLoad IRC: Connected to %s!" % host) - self.log.info("pyLoad IRC: Switching to listening mode!") - try: - self.main_loop() - - except IRCError, ex: - self.sock.send("QUIT :byebye\r\n") - print_exc() - self.sock.close() - - - def main_loop(self): - readbuffer = "" - while True: - sleep(1) - fdset = select([self.sock], [], [], 0) - if self.sock not in fdset[0]: - continue - - if self.abort: - raise IRCError("quit") - - readbuffer += self.sock.recv(1024) - temp = readbuffer.split("\n") - readbuffer = temp.pop() - - for line in temp: - line = line.rstrip() - first = line.split() - - if first[0] == "PING": - self.sock.send("PONG %s\r\n" % first[1]) - - if first[0] == "ERROR": - raise IRCError(line) - - msg = line.split(None, 3) - if len(msg) < 4: - continue - - msg = { - "origin":msg[0][1:], - "action":msg[1], - "target":msg[2], - "text":msg[3][1:] - } - - self.handle_events(msg) - - - def handle_events(self, msg): - if not msg["origin"].split("!", 1)[0] in self.getConfig("owner").split(): - return - - if msg["target"].split("!", 1)[0] != self.getConfig("nick"): - return - - if msg["action"] != "PRIVMSG": - return - - # HANDLE CTCP ANTI FLOOD/BOT PROTECTION - if msg["text"] == "\x01VERSION\x01": - self.log.debug("Sending CTCP VERSION.") - self.sock.send("NOTICE %s :%s\r\n" % (msg['origin'], "pyLoad! IRC Interface")) - return - elif msg["text"] == "\x01TIME\x01": - self.log.debug("Sending CTCP TIME.") - self.sock.send("NOTICE %s :%d\r\n" % (msg['origin'], time.time())) - return - elif msg["text"] == "\x01LAG\x01": - self.log.debug("Received CTCP LAG.") # don't know how to answer - return - - trigger = "pass" - args = None - - try: - temp = msg["text"].split() - trigger = temp[0] - if len(temp) > 1: - args = temp[1:] - except: - pass - - handler = getattr(self, "event_%s" % trigger, self.event_pass) - try: - res = handler(args) - for line in res: - self.response(line, msg["origin"]) - except Exception, e: - self.log.error("pyLoad IRC: "+ repr(e)) - - - def response(self, msg, origin=""): - if origin == "": - for t in self.getConfig("owner").split(): - self.sock.send("PRIVMSG %s :%s\r\n" % (t.strip(), msg)) - else: - self.sock.send("PRIVMSG %s :%s\r\n" % (origin.split("!", 1)[0], msg)) - - -#### Events - def event_pass(self, args): - return [] - - def event_status(self, args): - downloads = self.api.statusDownloads() - if not downloads: - return ["INFO: There are no active downloads currently."] - - temp_progress = "" - lines = ["ID - Name - Status - Speed - ETA - Progress"] - for data in downloads: - - if data.status == 5: - temp_progress = data.format_wait - else: - temp_progress = "%d%% (%s)" % (data.percent, data.format_size) - - lines.append("#%d - %s - %s - %s - %s - %s" % - ( - data.fid, - data.name, - data.statusmsg, - "%s/s" % formatSize(data.speed), - "%s" % data.format_eta, - temp_progress - ) - ) - return lines - - def event_queue(self, args): - ps = self.api.getQueue() - - if not ps: - return ["INFO: There are no packages in queue."] - - lines = [] - for pack in ps: - lines.append('PACKAGE #%s: "%s" with %d links.' % (pack.pid, pack.name, len(pack.fids) )) - - return lines - - def event_collector(self, args): - ps = self.api.getCollector() - if not ps: - return ["INFO: No packages in collector!"] - - lines = [] - for pack in ps: - lines.append('PACKAGE #%s: "%s" with %d links.' % (pack.pid, pack.name, len(pack.fids) )) - - return lines - - def event_info(self, args): - if not args: - return ['ERROR: Use info like this: info '] - - info = self.api.getFileData(int(args[0])) - - if not info: - return ["ERROR: Link doesn't exists."] - - return ['LINK #%s: %s (%s) [%s][%s]' % (info.fid, info.name, info.format_size, info.status_msg, - info.plugin)] - - def event_packinfo(self, args): - if not args: - return ['ERROR: Use packinfo like this: packinfo '] - - lines = [] - pack = self.api.getPackageData(int(args[0])) - - if not pack: - return ["ERROR: Package doesn't exists."] - - id = args[0] - - self.more = [] - - lines.append('PACKAGE #%s: "%s" with %d links' % (id, pack.name, len(pack.links)) ) - for pyfile in pack.links: - self.more.append('LINK #%s: %s (%s) [%s][%s]' % (pyfile.fid, pyfile.name, pyfile.format_size, - pyfile.statusmsg, pyfile.plugin)) - - if len(self.more) < 6: - lines.extend(self.more) - self.more = [] - else: - lines.extend(self.more[:6]) - self.more = self.more[6:] - lines.append("%d more links do display." % len(self.more)) - - - return lines - - def event_more(self, args): - if not self.more: - return ["No more information to display."] - - lines = self.more[:6] - self.more = self.more[6:] - lines.append("%d more links do display." % len(self.more)) - - return lines - - def event_start(self, args): - - self.api.unpauseServer() - return ["INFO: Starting downloads."] - - def event_stop(self, args): - - self.api.pauseServer() - return ["INFO: No new downloads will be started."] - - - def event_add(self, args): - if len(args) < 2: - return ['ERROR: Add links like this: "add links". ', - 'This will add the link to to the package / the package with id !'] - - - - pack = args[0].strip() - links = [x.strip() for x in args[1:]] - - count_added = 0 - count_failed = 0 - try: - id = int(pack) - pack = self.api.getPackageData(id) - if not pack: - return ["ERROR: Package doesn't exists."] - - #TODO add links - - return ["INFO: Added %d links to Package %s [#%d]" % (len(links), pack["name"], id)] - - except: - # create new package - id = self.api.addPackage(pack, links, 1) - return ["INFO: Created new Package %s [#%d] with %d links." % (pack, id, len(links))] - - - def event_del(self, args): - if len(args) < 2: - return ["ERROR: Use del command like this: del -p|-l [...] (-p indicates that the ids are from packages, -l indicates that the ids are from links)"] - - if args[0] == "-p": - ret = self.api.deletePackages(map(int, args[1:])) - return ["INFO: Deleted %d packages!" % len(args[1:])] - - elif args[0] == "-l": - ret = self.api.delLinks(map(int, args[1:])) - return ["INFO: Deleted %d links!" % len(args[1:])] - - else: - return ["ERROR: Use del command like this: del <-p|-l> [...] (-p indicates that the ids are from packages, -l indicates that the ids are from links)"] - - def event_push(self, args): - if not args: - return ["ERROR: Push package to queue like this: push "] - - id = int(args[0]) - if not self.api.getPackage_data(id): - return ["ERROR: Package #%d does not exist." % id] - - self.api.pushToQueue(id) - return ["INFO: Pushed package #%d to queue." % id] - - def event_pull(self, args): - if not args: - return ["ERROR: Pull package from queue like this: pull ."] - - id = int(args[0]) - if not self.api.getPackageData(id): - return ["ERROR: Package #%d does not exist." % id] - - self.api.pullFromQueue(id) - return ["INFO: Pulled package #%d from queue to collector." % id] - - def event_c(self, args): - """ captcha answer """ - if not args: - return ["ERROR: Captcha ID missing."] - - task = self.core.captchaManager.getTaskByID(args[0]) - if not task: - return ["ERROR: Captcha Task with ID %s does not exists." % args[0]] - - task.setResult(" ".join(args[1:])) - return ["INFO: Result %s saved." % " ".join(args[1:])] - - - def event_help(self, args): - lines = ["The following commands are available:", - "add [...] Adds link to package. (creates new package if it does not exist)", - "queue Shows all packages in the queue", - "collector Shows all packages in collector", - "del -p|-l [...] Deletes all packages|links with the ids specified", - "info Shows info of the link with id ", - "packinfo Shows info of the package with id ", - "more Shows more info when the result was truncated", - "start Starts all downloads", - "stop Stops the download (but not abort active downloads)", - "push Push package to queue", - "pull Pull package from queue", - "status Show general download status", - "help Shows this help message"] - return lines - - -class IRCError(Exception): - def __init__(self, value): - Exception.__init__(value) - self.value = value - def __str__(self): - return repr(self.value) diff --git a/module/plugins/hooks/MergeFiles.py b/module/plugins/hooks/MergeFiles.py deleted file mode 100644 index 02d343096..000000000 --- a/module/plugins/hooks/MergeFiles.py +++ /dev/null @@ -1,94 +0,0 @@ -# -*- 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: and9000 -""" - -import os -import re -import sys -import traceback - -from os.path import join -from module.utils import save_join, fs_encode -from module.plugins.Hook import Hook - -BUFFER_SIZE = 4096 - -class MergeFiles(Hook): - __name__ = "MergeFiles" - __version__ = "0.1" - __description__ = "Merges parts splitted with hjsplit" - __config__ = [ - ("activated" , "bool" , "Activated" , "False"), - ] - __threaded__ = ["packageFinished"] - __author_name__ = ("and9000") - __author_mail__ = ("me@has-no-mail.com") - - def setup(self): - # nothing to do - pass - - def packageFinished(self, pack): - files = {} - fid_dict = {} - for fid, data in pack.getChildren().iteritems(): - if re.search("\.[0-9]{3}$", data["name"]): - if data["name"][:-4] not in files: - files[data["name"][:-4]] = [] - files[data["name"][:-4]].append(data["name"]) - files[data["name"][:-4]].sort() - fid_dict[data["name"]] = fid - - download_folder = self.core.config['general']['download_folder'] - - if self.core.config['general']['folder_per_package']: - download_folder = save_join(download_folder, pack.folder) - - for name, file_list in files.iteritems(): - self.core.log.info("Starting merging of %s" % name) - final_file = open(join(download_folder, fs_encode(name)), "wb") - - for splitted_file in file_list: - self.core.log.debug("Merging part %s" % splitted_file) - pyfile = self.core.files.getFile(fid_dict[splitted_file]) - pyfile.setStatus("processing") - try: - s_file = open(os.path.join(download_folder, splitted_file), "rb") - size_written = 0 - s_file_size = int(os.path.getsize(os.path.join(download_folder, splitted_file))) - while True: - f_buffer = s_file.read(BUFFER_SIZE) - if f_buffer: - final_file.write(f_buffer) - size_written += BUFFER_SIZE - pyfile.setProgress((size_written*100)/s_file_size) - else: - break - s_file.close() - self.core.log.debug("Finished merging part %s" % splitted_file) - except Exception, e: - print traceback.print_exc() - finally: - pyfile.setProgress(100) - pyfile.setStatus("finished") - pyfile.release() - - final_file.close() - self.core.log.info("Finished merging of %s" % name) - - diff --git a/module/plugins/hooks/MultiHome.py b/module/plugins/hooks/MultiHome.py deleted file mode 100644 index f15148538..000000000 --- a/module/plugins/hooks/MultiHome.py +++ /dev/null @@ -1,82 +0,0 @@ -# -*- 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: mkaay -""" - -from module.plugins.Hook import Hook -from time import time - -class MultiHome(Hook): - __name__ = "MultiHome" - __version__ = "0.1" - __description__ = """ip address changer""" - __config__ = [ ("activated", "bool", "Activated" , "False"), - ("interfaces", "str", "Interfaces" , "None") ] - __author_name__ = ("mkaay") - __author_mail__ = ("mkaay@mkaay.de") - - def setup(self): - self.register = {} - self.interfaces = [] - self.parseInterfaces(self.getConfig("interfaces").split(";")) - if not self.interfaces: - self.parseInterfaces([self.config["download"]["interface"]]) - self.setConfig("interfaces", self.toConfig()) - - def toConfig(self): - return ";".join([i.adress for i in self.interfaces]) - - def parseInterfaces(self, interfaces): - for interface in interfaces: - if not interface or str(interface).lower() == "none": - continue - self.interfaces.append(Interface(interface)) - - def coreReady(self): - requestFactory = self.core.requestFactory - oldGetRequest = requestFactory.getRequest - def getRequest(pluginName, account=None): - iface = self.bestInterface(pluginName, account) - if iface: - iface.useFor(pluginName, account) - requestFactory.iface = lambda: iface.adress - self.log.debug("Multihome: using address: "+iface.adress) - return oldGetRequest(pluginName, account) - requestFactory.getRequest = getRequest - - def bestInterface(self, pluginName, account): - best = None - for interface in self.interfaces: - if not best or interface.lastPluginAccess(pluginName, account) < best.lastPluginAccess(pluginName, account): - best = interface - return best - -class Interface(object): - def __init__(self, adress): - self.adress = adress - self.history = {} - - def lastPluginAccess(self, pluginName, account): - if (pluginName, account) in self.history: - return self.history[(pluginName, account)] - return 0 - - def useFor(self, pluginName, account): - self.history[(pluginName, account)] = time() - - def __repr__(self): - return "" % self.adress diff --git a/module/plugins/hooks/MultiHoster.py b/module/plugins/hooks/MultiHoster.py deleted file mode 100644 index 2a567cce4..000000000 --- a/module/plugins/hooks/MultiHoster.py +++ /dev/null @@ -1,102 +0,0 @@ -#!/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" - __internal__ = True - __description__ = "Gives ability to use MultiHoster services. You need to add your account first." - __config__ = [] - __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/MultishareCz.py b/module/plugins/hooks/MultishareCz.py deleted file mode 100644 index a934f43ef..000000000 --- a/module/plugins/hooks/MultishareCz.py +++ /dev/null @@ -1,36 +0,0 @@ -# -*- coding: utf-8 -*- - -from module.network.RequestFactory import getURL -from module.plugins.internal.MultiHoster import MultiHoster -import re - -def getConfigSet(option): - s = set(option.lower().split('|')) - s.discard(u'') - return s - -class MultishareCz(MultiHoster): - __name__ = "MultishareCz" - __version__ = "0.01" - __type__ = "hook" - __config__ = [("activated", "bool", "Activated", "False"), - ("includeHoster", "str", "Use only for downloads from (bar-separated hosters)", ""), - ("excludeHoster", "str", "Do not use for downloads from (bar-separated hosters)", "rapidshare.com|uloz.to")] - __description__ = """MultiShare.cz hook plugin""" - __author_name__ = ("zoidberg") - __author_mail__ = ("zoidberg@mujmail.cz") - - #replacements = [("freakshare.net", "freakshare.com")] - HOSTER_PATTERN = r']*alt="([^"]+)">\s*OK' - - def getHoster(self): - - page = getURL("http://www.multishare.cz/monitoring/") - hoster = set(m.group(1).lower() for m in re.finditer(self.HOSTER_PATTERN, page)) - - option = self.getConfig('includeHoster').strip() - if option: hoster &= getConfigSet(option) - option = self.getConfig('excludeHoster').strip() - if option: hoster -= getConfigSet(option) - - return list(hoster) \ No newline at end of file diff --git a/module/plugins/hooks/Premium4Me.py b/module/plugins/hooks/Premium4Me.py deleted file mode 100644 index fc3ce2343..000000000 --- a/module/plugins/hooks/Premium4Me.py +++ /dev/null @@ -1,46 +0,0 @@ -# -*- coding: utf-8 -*- - -from module.network.RequestFactory import getURL -from module.plugins.internal.MultiHoster import MultiHoster - -class Premium4Me(MultiHoster): - __name__ = "Premium4Me" - __version__ = "0.02" - __type__ = "hook" - - __config__ = [("activated", "bool", "Activated", "False"), - ("hosterListMode", "all;listed;unlisted", "Use for downloads from supported hosters:", "all"), - ("hosterList", "str", "Hoster list (comma separated)", "")] - __description__ = """premium4.me hook plugin""" - __author_name__ = ("RaNaN", "zoidberg") - __author_mail__ = ("RaNaN@pyload.org", "zoidberg@mujmail.cz") - - replacements = [("freakshare.net", "freakshare.com")] - - def getHoster(self): - - page = getURL("http://premium4.me/api/hosters.php?authcode=%s" % self.account.authcode) - hosters = set([x.strip() for x in page.replace("\"", "").split(";")]) - - configMode = self.getConfig('hosterListMode') - if configMode in ("listed", "unlisted"): - configList = set(self.getConfig('hosterList').strip().lower().replace(',','|').split('|')) - configList.discard(u'') - if configMode == "listed": - hosters &= configList - elif configMode == "unlisted": - hosters -= configList - - return list(hosters) - - def coreReady(self): - - self.account = self.core.accountManager.getAccountPlugin("Premium4Me") - - user = self.account.selectAccount()[0] - - if not user: - self.logError(_("Please add your premium4.me account first and restart pyLoad")) - return - - return MultiHoster.coreReady(self) \ No newline at end of file diff --git a/module/plugins/hooks/RehostTo.py b/module/plugins/hooks/RehostTo.py deleted file mode 100644 index b16987f5c..000000000 --- a/module/plugins/hooks/RehostTo.py +++ /dev/null @@ -1,39 +0,0 @@ -# -*- coding: utf-8 -*- - -from module.network.RequestFactory import getURL -from module.plugins.internal.MultiHoster import MultiHoster - -class RehostTo(MultiHoster): - __name__ = "RehostTo" - __version__ = "0.41" - __type__ = "hook" - - __config__ = [("activated", "bool", "Activated", "False")] - - __description__ = """rehost.to hook plugin""" - __author_name__ = ("RaNaN") - __author_mail__ = ("RaNaN@pyload.org") - - replacements = [("freakshare.net", "freakshare.com")] - - def getHoster(self): - - page = getURL("http://rehost.to/api.php?cmd=get_supported_och_dl&long_ses=%s" % self.long_ses) - return [x.strip() for x in page.replace("\"", "").split(",")] - - - def coreReady(self): - - self.account = self.core.accountManager.getAccountPlugin("RehostTo") - - user = self.account.selectAccount()[0] - - if not user: - self.log.error("Rehost.to: "+ _("Please add your rehost.to account first and restart pyLoad")) - return - - data = self.account.getAccountInfo(user) - self.ses = data["ses"] - self.long_ses = data["long_ses"] - - return MultiHoster.coreReady(self) diff --git a/module/plugins/hooks/UpdateManager.py b/module/plugins/hooks/UpdateManager.py deleted file mode 100644 index 230a6e858..000000000 --- a/module/plugins/hooks/UpdateManager.py +++ /dev/null @@ -1,199 +0,0 @@ -# -*- 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 -""" - -import sys -import re -from os import stat -from os.path import join, exists -from time import time - -from module.plugins.PluginManager import IGNORE -from module.network.RequestFactory import getURL -from module.plugins.Hook import threaded, Expose, Hook - -class UpdateManager(Hook): - __name__ = "UpdateManager" - __version__ = "0.12" - __description__ = """checks for updates""" - __config__ = [("activated", "bool", "Activated", "True"), - ("interval", "int", "Check interval in minutes", "360"), - ("debug", "bool", "Check for plugin changes when in debug mode", False)] - __author_name__ = ("RaNaN") - __author_mail__ = ("ranan@pyload.org") - - @property - def debug(self): - return self.core.debug and self.getConfig("debug") - - - def setup(self): - if self.debug: - self.logDebug("Monitoring file changes") - self.interval = 4 - self.last_check = 0 #timestamp of updatecheck - self.old_periodical = self.periodical - self.periodical = self.checkChanges - self.mtimes = {} #recordes times - else: - self.interval = self.getConfig("interval") * 60 - - self.updated = False - self.reloaded = True - - self.info = {"pyload": False, "plugins": False} - - @threaded - def periodical(self): - - if self.core.version.endswith("-dev"): - self.logDebug("No update check performed on dev version.") - return - - update = self.checkForUpdate() - if update: - self.info["pyload"] = True - else: - self.log.info(_("No Updates for pyLoad")) - self.checkPlugins() - - if self.updated and not self.reloaded: - self.info["plugins"] = True - self.log.info(_("*** Plugins have been updated, please restart pyLoad ***")) - elif self.updated and self.reloaded: - self.log.info(_("Plugins updated and reloaded")) - self.updated = False - else: - self.log.info(_("No plugin updates available")) - - @Expose - def recheckForUpdates(self): - """recheck if updates are available""" - self.periodical() - - def checkForUpdate(self): - """checks if an update is available""" - - try: - version_check = getURL("http://get.pyload.org/check/%s/" % self.core.api.getServerVersion()) - if version_check == "": - return False - else: - self.log.info(_("*** New pyLoad Version %s available ***") % version_check) - self.log.info(_("*** Get it here: http://pyload.org/download ***")) - return True - except: - self.log.warning(_("Not able to connect server for updates")) - return False - - - def checkPlugins(self): - """ checks for plugins updates""" - - # plugins were already updated - if self.info["plugins"]: return - - try: - updates = getURL("http://get.pyload.org/plugins/check/") - except: - self.log.warning(_("Not able to connect server for updates")) - return False - - updates = updates.splitlines() - reloads = [] - - vre = re.compile(r'__version__.*=.*("|\')([0-9.]+)') - - for plugin in updates: - path, version = plugin.split(":") - prefix, filename = path.split("/") - - if filename.endswith(".pyc"): - name = filename[:filename.find("_")] - else: - name = filename.replace(".py", "") - - #TODO: obsolete - if prefix.endswith("s"): - type = prefix[:-1] - else: - type = prefix - - plugins = self.core.pluginManager.getPlugins(type) - - if name in plugins: - if float(plugins[name].version) >= float(version): - continue - - if name in IGNORE or (type, name) in IGNORE: - continue - - self.log.info(_("New version of %(type)s|%(name)s : %(version).2f") % { - "type": type, - "name": name, - "version": float(version) - }) - - try: - content = getURL("http://get.pyload.org/plugins/get/" + path) - except Exception, e: - self.logWarning(_("Error when updating %s") % filename, str(e)) - continue - - m = vre.search(content) - if not m or m.group(2) != version: - self.logWarning(_("Error when updating %s") % name, _("Version mismatch")) - continue - - f = open(join("userplugins", prefix, filename), "wb") - f.write(content) - f.close() - self.updated = True - - reloads.append((prefix, name)) - - self.reloaded = self.core.pluginManager.reloadPlugins(reloads) - - def checkChanges(self): - - if self.last_check + self.getConfig("interval") * 60 < time(): - self.old_periodical() - self.last_check = time() - - modules = filter( - lambda m: m and (m.__name__.startswith("module.plugins.") or m.__name__.startswith("userplugins.")) and m.__name__.count(".") >= 2, - sys.modules.itervalues()) - - reloads = [] - - for m in modules: - root, type, name = m.__name__.rsplit(".", 2) - id = (type, name) - if type in self.core.pluginManager.plugins: - f = m.__file__.replace(".pyc", ".py") - if not exists(f): continue - - mtime = stat(f).st_mtime - - if id not in self.mtimes: - self.mtimes[id] = mtime - elif self.mtimes[id] < mtime: - reloads.append(id) - self.mtimes[id] = mtime - - self.core.pluginManager.reloadPlugins(reloads) diff --git a/module/plugins/hooks/XMPPInterface.py b/module/plugins/hooks/XMPPInterface.py deleted file mode 100644 index de87433cf..000000000 --- a/module/plugins/hooks/XMPPInterface.py +++ /dev/null @@ -1,276 +0,0 @@ -# -*- 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 - @interface-version: 0.2 -""" - -from pyxmpp import streamtls -from pyxmpp.all import JID, Message, Presence -from pyxmpp.jabber.client import JabberClient -from pyxmpp.interface import implements -from pyxmpp.interfaces import * - -from module.plugins.hooks.IRCInterface import IRCInterface - -class XMPPInterface(IRCInterface, JabberClient): - __name__ = "XMPPInterface" - __version__ = "0.1" - __description__ = """connect to jabber and let owner perform different tasks""" - __config__ = [("activated", "bool", "Activated", "False"), - ("jid", "str", "Jabber ID", "user@exmaple-jabber-server.org"), - ("pw", "str", "Password", ""), - ("tls", "bool", "Use TLS", False), - ("owners", "str", "List of JIDs accepting commands from", "me@icq-gateway.org;some@msn-gateway.org"), - ("info_file", "bool", "Inform about every file finished", "False"), - ("info_pack", "bool", "Inform about every package finished", "True"), - ("captcha", "bool", "Send captcha requests", "True")] - __author_name__ = ("RaNaN") - __author_mail__ = ("RaNaN@pyload.org") - - implements(IMessageHandlersProvider) - - def __init__(self, core, manager): - IRCInterface.__init__(self, core, manager) - - self.jid = JID(self.getConfig("jid")) - password = self.getConfig("pw") - - # if bare JID is provided add a resource -- it is required - if not self.jid.resource: - self.jid = JID(self.jid.node, self.jid.domain, "pyLoad") - - if self.getConfig("tls"): - tls_settings = streamtls.TLSSettings(require=True, verify_peer=False) - auth = ("sasl:PLAIN", "sasl:DIGEST-MD5") - else: - tls_settings = None - auth = ("sasl:DIGEST-MD5", "digest") - - # setup client with provided connection information - # and identity data - JabberClient.__init__(self, self.jid, password, - disco_name="pyLoad XMPP Client", disco_type="bot", - tls_settings=tls_settings, auth_methods=auth) - - self.interface_providers = [ - VersionHandler(self), - self, - ] - - def coreReady(self): - self.new_package = {} - - self.start() - - def packageFinished(self, pypack): - try: - if self.getConfig("info_pack"): - self.announce(_("Package finished: %s") % pypack.name) - except: - pass - - def downloadFinished(self, pyfile): - try: - if self.getConfig("info_file"): - self.announce( - _("Download finished: %(name)s @ %(plugin)s") % {"name": pyfile.name, "plugin": pyfile.pluginname}) - except: - pass - - def run(self): - # connect to IRC etc. - self.connect() - try: - self.loop() - except Exception, ex: - self.core.log.error("pyLoad XMPP: %s" % str(ex)) - - def stream_state_changed(self, state, arg): - """This one is called when the state of stream connecting the component - to a server changes. This will usually be used to let the user - know what is going on.""" - self.log.debug("pyLoad XMPP: *** State changed: %s %r ***" % (state, arg)) - - def disconnected(self): - self.log.debug("pyLoad XMPP: Client was disconnected") - - def stream_closed(self, stream): - self.log.debug("pyLoad XMPP: Stream was closed | %s" % stream) - - def stream_error(self, err): - self.log.debug("pyLoad XMPP: Stream Error: %s" % err) - - def get_message_handlers(self): - """Return list of (message_type, message_handler) tuples. - - The handlers returned will be called when matching message is received - in a client session.""" - return [ - ("normal", self.message), - ] - - def presence_control(self, stanza): - from_jid = unicode(stanza.get_from_jid()) - stanza_type = stanza.get_type() - self.log.debug("pyLoad XMPP: %s stanza from %s" % (stanza_type, - from_jid)) - - if from_jid in self.getConfig("owners"): - return stanza.make_accept_response() - - return stanza.make_deny_response() - - def session_started(self): - self.stream.send(Presence()) - - self.stream.set_presence_handler("subscribe", self.presence_control) - self.stream.set_presence_handler("subscribed", self.presence_control) - self.stream.set_presence_handler("unsubscribe", self.presence_control) - self.stream.set_presence_handler("unsubscribed", self.presence_control) - - def message(self, stanza): - """Message handler for the component.""" - subject = stanza.get_subject() - body = stanza.get_body() - t = stanza.get_type() - self.log.debug(u'pyLoad XMPP: Message from %s received.' % (unicode(stanza.get_from(), ))) - self.log.debug(u'pyLoad XMPP: Body: %s Subject: %s Type: %s' % (body, subject, t)) - - if t == "headline": - # 'headline' messages should never be replied to - return True - if subject: - subject = u"Re: " + subject - - to_jid = stanza.get_from() - from_jid = stanza.get_to() - - #j = JID() - to_name = to_jid.as_utf8() - from_name = from_jid.as_utf8() - - names = self.getConfig("owners").split(";") - - if to_name in names or to_jid.node + "@" + to_jid.domain in names: - messages = [] - - trigger = "pass" - args = None - - try: - temp = body.split() - trigger = temp[0] - if len(temp) > 1: - args = temp[1:] - except: - pass - - handler = getattr(self, "event_%s" % trigger, self.event_pass) - try: - res = handler(args) - for line in res: - m = Message( - to_jid=to_jid, - from_jid=from_jid, - stanza_type=stanza.get_type(), - subject=subject, - body=line) - - messages.append(m) - except Exception, e: - self.log.error("pyLoad XMPP: " + repr(e)) - - return messages - - else: - return True - - def response(self, msg, origin=""): - return self.announce(msg) - - def announce(self, message): - """ send message to all owners""" - for user in self.getConfig("owners").split(";"): - self.log.debug("pyLoad XMPP: Send message to %s" % user) - - to_jid = JID(user) - - m = Message(from_jid=self.jid, - to_jid=to_jid, - stanza_type="chat", - body=message) - - stream = self.get_stream() - if not stream: - self.connect() - stream = self.get_stream() - - stream.send(m) - - def beforeReconnecting(self, ip): - self.disconnect() - - def afterReconnecting(self, ip): - self.connect() - - -class VersionHandler(object): - """Provides handler for a version query. - - This class will answer version query and announce 'jabber:iq:version' namespace - in the client's disco#info results.""" - - implements(IIqHandlersProvider, IFeaturesProvider) - - def __init__(self, client): - """Just remember who created this.""" - self.client = client - - def get_features(self): - """Return namespace which should the client include in its reply to a - disco#info query.""" - return ["jabber:iq:version"] - - def get_iq_get_handlers(self): - """Return list of tuples (element_name, namespace, handler) describing - handlers of stanzas""" - return [ - ("query", "jabber:iq:version", self.get_version), - ] - - def get_iq_set_handlers(self): - """Return empty list, as this class provides no stanza handler.""" - return [] - - def get_version(self, iq): - """Handler for jabber:iq:version queries. - - jabber:iq:version queries are not supported directly by PyXMPP, so the - XML node is accessed directly through the libxml2 API. This should be - used very carefully!""" - iq = iq.make_result_response() - q = iq.new_query("jabber:iq:version") - q.newTextChild(q.ns(), "name", "Echo component") - q.newTextChild(q.ns(), "version", "1.0") - return iq - - def unload(self): - self.log.debug("pyLoad XMPP: unloading") - self.disconnect() - - def deactivate(self): - self.unload() diff --git a/module/plugins/hooks/__init__.py b/module/plugins/hooks/__init__.py deleted file mode 100644 index e69de29bb..000000000 -- cgit v1.2.3