diff options
author | Walter Purcaro <vuolter@gmail.com> | 2014-11-26 22:19:01 +0100 |
---|---|---|
committer | Walter Purcaro <vuolter@gmail.com> | 2014-11-26 22:19:01 +0100 |
commit | 4a7f6177152d3c59c92291aa76fd7a36a1c8b044 (patch) | |
tree | 9796b6c6f4be98dd29dba0d9f92cc44756da8b3a | |
parent | Merge branch 'stable' into 0.4.10 (diff) | |
parent | [XFSHoster] Code improvements (diff) | |
download | pyload-4a7f6177152d3c59c92291aa76fd7a36a1c8b044.tar.xz |
Merge branch 'stable' into 0.4.10
Conflicts:
module/PluginThread.py
module/plugins/hoster/XFileSharingPro.py
module/plugins/internal/CaptchaService.py
pyload/api/__init__.py
pyload/manager/AccountManager.py
pyload/manager/AddonManager.py
pyload/manager/CaptchaManager.py
pyload/manager/PluginManager.py
pyload/network/HTTPRequest.py
pyload/network/XDCCRequest.py
pyload/plugins/Plugin.py
pyload/plugins/account/EasybytezCom.py
pyload/plugins/crypter/C1neonCom.py
pyload/plugins/crypter/CryptItCom.py
pyload/plugins/crypter/DuploadOrg.py
pyload/plugins/crypter/FilebeerInfo.py
pyload/plugins/crypter/FilesonicCom.py
pyload/plugins/crypter/FiredriveCom.py
pyload/plugins/crypter/HotfileCom.py
pyload/plugins/crypter/ILoadTo.py
pyload/plugins/crypter/LofCc.py
pyload/plugins/crypter/MBLinkInfo.py
pyload/plugins/crypter/MegauploadCom.py
pyload/plugins/crypter/Movie2kTo.py
pyload/plugins/crypter/MultiuploadCom.py
pyload/plugins/crypter/OronCom.py
pyload/plugins/crypter/RSLayerCom.py
pyload/plugins/crypter/SecuredIn.py
pyload/plugins/crypter/SharingmatrixCom.py
pyload/plugins/crypter/SpeedLoadOrg.py
pyload/plugins/crypter/StealthTo.py
pyload/plugins/crypter/TrailerzoneInfo.py
pyload/plugins/crypter/WiiReloadedOrg.py
pyload/plugins/crypter/WuploadCom.py
pyload/plugins/internal/Account.py
pyload/plugins/internal/Addon.py
pyload/plugins/internal/BasePlugin.py
pyload/plugins/internal/Container.py
pyload/plugins/internal/Crypter.py
pyload/plugins/internal/DeadCrypter.py
pyload/plugins/internal/DeadHoster.py
pyload/plugins/internal/Hoster.py
pyload/plugins/internal/SimpleCrypter.py
pyload/utils/__init__.py
47 files changed, 577 insertions, 172 deletions
diff --git a/module/plugins/hoster/XFileSharingPro.py b/module/plugins/hoster/XFileSharingPro.py new file mode 100644 index 000000000..0acad3dba --- /dev/null +++ b/module/plugins/hoster/XFileSharingPro.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- + +import re + +from module.plugins.internal.XFSHoster import XFSHoster, create_getInfo + + +class XFileSharingPro(XFSHoster): + __name__ = "XFileSharingPro" + __type__ = "hoster" + __version__ = "0.43" + + __pattern__ = r'^unmatchable$' + + __description__ = """XFileSharingPro dummy hoster plugin for hook""" + __license__ = "GPLv3" + __authors__ = [("Walter Purcaro", "vuolter@gmail.com")] + + + URL_REPLACEMENTS = [("/embed-", "/")] + + + def _log(self, type, args): + msg = " | ".join([str(a).strip() for a in args if a]) + logger = getattr(self.log, type) + logger("%s: %s: %s" % (self.__name__, self.HOSTER_NAME, msg or _("%s MARK" % type.upper()))) + + + def init(self): + super(XFileSharingPro, self).init() + + self.__pattern__ = self.core.pluginManager.hosterPlugins[self.__name__]['pattern'] + + self.HOSTER_DOMAIN = re.match(self.__pattern__, self.pyfile.url).group(1).lower() + self.HOSTER_NAME = "".join([str.capitalize() for str in self.HOSTER_DOMAIN.split('.')]) + + account = self.core.accountManager.getAccountPlugin(self.HOSTER_NAME) + + if account and account.canUse(): + self.account = account + elif self.account: + self.account.HOSTER_DOMAIN = self.HOSTER_DOMAIN + else: + return + + self.user, data = self.account.selectAccount() + self.req = self.account.getAccountRequest(self.user) + self.premium = self.account.isPremium(self.user) + + + def setup(self): + self.chunkLimit = 1 + self.resumeDownload = self.premium + self.multiDL = True + + +getInfo = create_getInfo(XFileSharingPro) diff --git a/module/plugins/hoster/ZShareNet.py b/module/plugins/hoster/ZShareNet.py new file mode 100644 index 000000000..dc96facbe --- /dev/null +++ b/module/plugins/hoster/ZShareNet.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- + +from module.plugins.internal.DeadHoster import DeadHoster, create_getInfo + + +class ZShareNet(DeadHoster): + __name__ = "ZShareNet" + __type__ = "hoster" + __version__ = "0.21" + + __pattern__ = r'https?://(?:ww[2w]\.)?zshares?\.net/.+' + + __description__ = """ZShare.net hoster plugin""" + __license__ = "GPLv3" + __authors__ = [("espes", None), + ("Cptn Sandwich", None)] + + +getInfo = create_getInfo(ZShareNet) diff --git a/module/plugins/internal/CaptchaService.py b/module/plugins/internal/CaptchaService.py new file mode 100644 index 000000000..7009e6986 --- /dev/null +++ b/module/plugins/internal/CaptchaService.py @@ -0,0 +1,213 @@ +# -*- coding: utf-8 -*- + +import re + +from random import random + + +class CaptchaService: + __name__ = "CaptchaService" + __version__ = "0.15" + + __description__ = """Base captcha service plugin""" + __license__ = "GPLv3" + __authors__ = [("pyLoad Team", "admin@pyload.org")] + + + KEY_PATTERN = None + + key = None #: last key detected + + + def __init__(self, plugin): + self.plugin = plugin + + + def detect_key(self, html=None): + if not html: + if hasattr(self.plugin, "html") and self.plugin.html: + html = self.plugin.html + else: + errmsg = _("%s html not found") % self.__name__ + self.plugin.fail(errmsg) #@TODO: replace all plugin.fail(errmsg) with plugin.error(errmsg) in 0.4.10 + raise TypeError(errmsg) + + m = re.search(self.KEY_PATTERN, html) + if m: + self.key = m.group("KEY") + self.plugin.logDebug("%s key: %s" % (self.__name__, self.key)) + return self.key + else: + self.plugin.logDebug("%s key not found" % self.__name__) + return None + + + def challenge(self, key=None): + raise NotImplementedError + + + def result(self, server, challenge): + raise NotImplementedError + + +class ReCaptcha(CaptchaService): + __name__ = "ReCaptcha" + __version__ = "0.08" + + __description__ = """ReCaptcha captcha service plugin""" + __license__ = "GPLv3" + __authors__ = [("pyLoad Team", "admin@pyload.org")] + + + KEY_PATTERN = r'recaptcha(/api|\.net)/(challenge|noscript)\?k=(?P<KEY>[\w-]+)' + KEY_AJAX_PATTERN = r'Recaptcha\.create\s*\(\s*["\'](?P<KEY>[\w-]+)' + + + def detect_key(self, html=None): + if not html: + if hasattr(self.plugin, "html") and self.plugin.html: + html = self.plugin.html + else: + errmsg = _("ReCaptcha html not found") + self.plugin.fail(errmsg) + raise TypeError(errmsg) + + m = re.search(self.KEY_PATTERN, html) or re.search(self.KEY_AJAX_PATTERN, html) + if m: + self.key = m.group("KEY") + self.plugin.logDebug("ReCaptcha key: %s" % self.key) + return self.key + else: + self.plugin.logDebug("ReCaptcha key not found") + return None + + + def challenge(self, key=None): + if not key: + if self.detect_key(): + key = self.key + else: + errmsg = _("ReCaptcha key not found") + self.plugin.fail(errmsg) + raise TypeError(errmsg) + + js = self.plugin.req.load("http://www.google.com/recaptcha/api/challenge", get={'k': key}) + try: + challenge = re.search("challenge : '(.+?)',", js).group(1) + server = re.search("server : '(.+?)',", js).group(1) + except: + self.plugin.error("ReCaptcha challenge pattern not found") + + result = self.result(server, challenge) + + self.plugin.logDebug("ReCaptcha result: %s" % result, "challenge: %s" % challenge) + + return challenge, result + + + def result(self, server, challenge): + return self.plugin.decryptCaptcha("%simage" % server, get={'c': challenge}, + cookies=True, forceUser=True, imgtype="jpg") + + +class AdsCaptcha(CaptchaService): + __name__ = "AdsCaptcha" + __version__ = "0.05" + + __description__ = """AdsCaptcha captcha service plugin""" + __license__ = "GPLv3" + __authors__ = [("pyLoad Team", "admin@pyload.org")] + + + ID_PATTERN = r'api\.adscaptcha\.com/Get\.aspx\?[^"\']*CaptchaId=(?P<ID>\d+)' + KEY_PATTERN = r'api\.adscaptcha\.com/Get\.aspx\?[^"\']*PublicKey=(?P<KEY>[\w-]+)' + + + def detect_key(self, html=None): + if not html: + if hasattr(self.plugin, "html") and self.plugin.html: + html = self.plugin.html + else: + errmsg = _("AdsCaptcha html not found") + self.plugin.fail(errmsg) + raise TypeError(errmsg) + + m = re.search(self.ID_PATTERN, html) + n = re.search(self.KEY_PATTERN, html) + if m and n: + self.key = (m.group("ID"), m.group("KEY")) + self.plugin.logDebug("AdsCaptcha id|key: %s | %s" % self.key) + return self.key + else: + self.plugin.logDebug("AdsCaptcha id or key not found") + return None + + + def challenge(self, key=None): #: key is a tuple(CaptchaId, PublicKey) + if not key: + if self.detect_key(): + key = self.key + else: + errmsg = _("AdsCaptcha key not found") + self.plugin.fail(errmsg) + raise TypeError(errmsg) + + CaptchaId, PublicKey = key + + js = self.plugin.req.load("http://api.adscaptcha.com/Get.aspx", get={'CaptchaId': CaptchaId, 'PublicKey': PublicKey}) + try: + challenge = re.search("challenge: '(.+?)',", js).group(1) + server = re.search("server: '(.+?)',", js).group(1) + except: + self.plugin.error("AdsCaptcha challenge pattern not found") + + result = self.result(server, challenge) + + self.plugin.logDebug("AdsCaptcha result: %s" % result, "challenge: %s" % challenge) + + return challenge, result + + + def result(self, server, challenge): + return self.plugin.decryptCaptcha("%sChallenge.aspx" % server, get={'cid': challenge, 'dummy': random()}, + cookies=True, imgtype="jpg") + + +class SolveMedia(CaptchaService): + __name__ = "SolveMedia" + __version__ = "0.06" + + __description__ = """SolveMedia captcha service plugin""" + __license__ = "GPLv3" + __authors__ = [("pyLoad Team", "admin@pyload.org")] + + + KEY_PATTERN = r'api\.solvemedia\.com/papi/challenge\.(no)?script\?k=(?P<KEY>.+?)["\']' + + + def challenge(self, key=None): + if not key: + if self.detect_key(): + key = self.key + else: + errmsg = _("SolveMedia key not found") + self.plugin.fail(errmsg) + raise TypeError(errmsg) + + html = self.plugin.req.load("http://api.solvemedia.com/papi/challenge.noscript", get={'k': key}) + try: + challenge = re.search(r'<input type=hidden name="adcopy_challenge" id="adcopy_challenge" value="([^"]+)">', + html).group(1) + server = "http://api.solvemedia.com/papi/media" + except: + self.plugin.error("SolveMedia challenge pattern not found") + + result = self.result(server, challenge) + + self.plugin.logDebug("SolveMedia result: %s" % result, "challenge: %s" % challenge) + + return challenge, result + + + def result(self, server, challenge): + return self.plugin.decryptCaptcha(server, get={'c': challenge}, imgtype="gif") diff --git a/pyload/plugins/account/EasybytezCom.py b/pyload/plugins/account/EasybytezCom.py index b1fb6a213..2ffcd5392 100644 --- a/pyload/plugins/account/EasybytezCom.py +++ b/pyload/plugins/account/EasybytezCom.py @@ -2,10 +2,7 @@ import re -from time import mktime, strptime, gmtime - from pyload.plugins.internal.XFSAccount import XFSAccount -from pyload.utils import parseFileSize class EasybytezCom(XFSAccount): diff --git a/pyload/plugins/crypter/C1neonCom.py b/pyload/plugins/crypter/C1neonCom.py index 91a22ea39..cf1d2a211 100644 --- a/pyload/plugins/crypter/C1neonCom.py +++ b/pyload/plugins/crypter/C1neonCom.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from pyload.plugins.internal.DeadCrypter import DeadCrypter +from module.plugins.internal.DeadCrypter import DeadCrypter, create_getInfo class C1neonCom(DeadCrypter): @@ -14,3 +14,6 @@ class C1neonCom(DeadCrypter): __description__ = """C1neon.com decrypter plugin""" __license__ = "GPLv3" __authors__ = [("godofdream", "soilfiction@gmail.com")] + + +getInfo = create_getInfo(C1neonCom) diff --git a/pyload/plugins/crypter/CryptItCom.py b/pyload/plugins/crypter/CryptItCom.py index 9ca6f2bc3..2cf4e9f62 100644 --- a/pyload/plugins/crypter/CryptItCom.py +++ b/pyload/plugins/crypter/CryptItCom.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from pyload.plugins.internal.DeadCrypter import DeadCrypter +from module.plugins.internal.DeadCrypter import DeadCrypter, create_getInfo class CryptItCom(DeadCrypter): @@ -14,3 +14,6 @@ class CryptItCom(DeadCrypter): __description__ = """Crypt-it.com decrypter plugin""" __license__ = "GPLv3" __authors__ = [("jeix", "jeix@hasnomail.de")] + + +getInfo = create_getInfo(CryptItCom) diff --git a/pyload/plugins/crypter/DdlstorageCom.py b/pyload/plugins/crypter/DdlstorageCom.py index b4a8d07b4..95f771c9e 100644 --- a/pyload/plugins/crypter/DdlstorageCom.py +++ b/pyload/plugins/crypter/DdlstorageCom.py @@ -17,4 +17,4 @@ class DdlstorageCom(DeadCrypter): ("stickell", "l.stickell@yahoo.it")] -getInfo = create_getInfo(SpeedLoadOrg) +getInfo = create_getInfo(DdlstorageCom) diff --git a/pyload/plugins/crypter/DuploadOrg.py b/pyload/plugins/crypter/DuploadOrg.py index fdb51021b..48978577e 100644 --- a/pyload/plugins/crypter/DuploadOrg.py +++ b/pyload/plugins/crypter/DuploadOrg.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from pyload.plugins.internal.DeadCrypter import DeadCrypter +from module.plugins.internal.DeadCrypter import DeadCrypter, create_getInfo class DuploadOrg(DeadCrypter): @@ -14,3 +14,6 @@ class DuploadOrg(DeadCrypter): __description__ = """Dupload.org folder decrypter plugin""" __license__ = "GPLv3" __authors__ = [("stickell", "l.stickell@yahoo.it")] + + +getInfo = create_getInfo(DuploadOrg) diff --git a/pyload/plugins/crypter/FilebeerInfo.py b/pyload/plugins/crypter/FilebeerInfo.py index 75714c81a..8b09cc8cb 100644 --- a/pyload/plugins/crypter/FilebeerInfo.py +++ b/pyload/plugins/crypter/FilebeerInfo.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from pyload.plugins.internal.DeadCrypter import DeadCrypter +from module.plugins.internal.DeadCrypter import DeadCrypter, create_getInfo class FilebeerInfo(DeadCrypter): @@ -14,3 +14,6 @@ class FilebeerInfo(DeadCrypter): __description__ = """Filebeer.info folder decrypter plugin""" __license__ = "GPLv3" __authors__ = [("zoidberg", "zoidberg@mujmail.cz")] + + +getInfo = create_getInfo(FilebeerInfo) diff --git a/pyload/plugins/crypter/FilecryptCc.py b/pyload/plugins/crypter/FilecryptCc.py index db4a8c4ab..dedd284b3 100644 --- a/pyload/plugins/crypter/FilecryptCc.py +++ b/pyload/plugins/crypter/FilecryptCc.py @@ -12,7 +12,7 @@ from module.plugins.Crypter import Crypter class FilecryptCc(Crypter): __name__ = "FilecryptCc" __type__ = "crypter" - __version__ = "0.04" + __version__ = "0.05" __pattern__ = r'https?://(?:www\.)?filecrypt\.cc/Container/\w+' @@ -58,7 +58,7 @@ class FilecryptCc(Crypter): mirror = re.findall(self.MIRROR_PAGE_PATTERN, self.siteWithLinks) - self.logInfo(_("Found %d mirrors") % len(m)) + self.logInfo(_("Found %d mirrors") % len(mirror)) for i in mirror[1:]: self.siteWithLinks = self.siteWithLinks + self.load(i, cookies=True).decode("utf-8", "replace") diff --git a/pyload/plugins/crypter/FilesonicCom.py b/pyload/plugins/crypter/FilesonicCom.py index 33a99f0d5..7e436440d 100644 --- a/pyload/plugins/crypter/FilesonicCom.py +++ b/pyload/plugins/crypter/FilesonicCom.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from pyload.plugins.internal.DeadCrypter import DeadCrypter +from module.plugins.internal.DeadCrypter import DeadCrypter, create_getInfo class FilesonicCom(DeadCrypter): @@ -13,3 +13,6 @@ class FilesonicCom(DeadCrypter): __description__ = """Filesonic.com folder decrypter plugin""" __license__ = "GPLv3" __authors__ = [("zoidberg", "zoidberg@mujmail.cz")] + + +getInfo = create_getInfo(FilesonicCom) diff --git a/pyload/plugins/crypter/FiredriveCom.py b/pyload/plugins/crypter/FiredriveCom.py index 7ef84c8ff..bc88b974c 100644 --- a/pyload/plugins/crypter/FiredriveCom.py +++ b/pyload/plugins/crypter/FiredriveCom.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from pyload.plugins.internal.DeadCrypter import DeadCrypter +from module.plugins.internal.DeadCrypter import DeadCrypter, create_getInfo class FiredriveCom(DeadCrypter): @@ -14,3 +14,6 @@ class FiredriveCom(DeadCrypter): __description__ = """Firedrive.com folder decrypter plugin""" __license__ = "GPLv3" __authors__ = [("Walter Purcaro", "vuolter@gmail.com")] + + +getInfo = create_getInfo(FiredriveCom) diff --git a/pyload/plugins/crypter/HotfileCom.py b/pyload/plugins/crypter/HotfileCom.py index 1c1dcb76b..79922f62f 100644 --- a/pyload/plugins/crypter/HotfileCom.py +++ b/pyload/plugins/crypter/HotfileCom.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from pyload.plugins.internal.DeadCrypter import DeadCrypter +from module.plugins.internal.DeadCrypter import DeadCrypter, create_getInfo class HotfileCom(DeadCrypter): @@ -14,3 +14,6 @@ class HotfileCom(DeadCrypter): __description__ = """Hotfile.com folder decrypter plugin""" __license__ = "GPLv3" __authors__ = [("RaNaN", "RaNaN@pyload.org")] + + +getInfo = create_getInfo(HotfileCom) diff --git a/pyload/plugins/crypter/ILoadTo.py b/pyload/plugins/crypter/ILoadTo.py index e04e43a00..f3415706d 100644 --- a/pyload/plugins/crypter/ILoadTo.py +++ b/pyload/plugins/crypter/ILoadTo.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from pyload.plugins.internal.DeadCrypter import DeadCrypter +from module.plugins.internal.DeadCrypter import DeadCrypter, create_getInfo class ILoadTo(DeadCrypter): @@ -14,3 +14,6 @@ class ILoadTo(DeadCrypter): __description__ = """Iload.to decrypter plugin""" __license__ = "GPLv3" __authors__ = [("hzpz", None)] + + +getInfo = create_getInfo(ILoadTo) diff --git a/pyload/plugins/crypter/LofCc.py b/pyload/plugins/crypter/LofCc.py index 955ae56d7..65c9b18bd 100644 --- a/pyload/plugins/crypter/LofCc.py +++ b/pyload/plugins/crypter/LofCc.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from pyload.plugins.internal.DeadCrypter import DeadCrypter +from module.plugins.internal.DeadCrypter import DeadCrypter, create_getInfo class LofCc(DeadCrypter): @@ -14,3 +14,6 @@ class LofCc(DeadCrypter): __description__ = """Lof.cc decrypter plugin""" __license__ = "GPLv3" __authors__ = [("mkaay", "mkaay@mkaay.de")] + + +getInfo = create_getInfo(LofCc) diff --git a/pyload/plugins/crypter/MBLinkInfo.py b/pyload/plugins/crypter/MBLinkInfo.py index 98d4c09e6..82c2d9719 100644 --- a/pyload/plugins/crypter/MBLinkInfo.py +++ b/pyload/plugins/crypter/MBLinkInfo.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from pyload.plugins.internal.DeadCrypter import DeadCrypter +from module.plugins.internal.DeadCrypter import DeadCrypter, create_getInfo class MBLinkInfo(DeadCrypter): @@ -15,3 +15,6 @@ class MBLinkInfo(DeadCrypter): __license__ = "GPLv3" __authors__ = [("Gummibaer", "Gummibaer@wiki-bierkiste.de"), ("stickell", "l.stickell@yahoo.it")] + + +getInfo = create_getInfo(MBLinkInfo) diff --git a/pyload/plugins/crypter/MegauploadCom.py b/pyload/plugins/crypter/MegauploadCom.py index 57c08bd53..d052b7c61 100644 --- a/pyload/plugins/crypter/MegauploadCom.py +++ b/pyload/plugins/crypter/MegauploadCom.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from pyload.plugins.internal.DeadCrypter import DeadCrypter +from module.plugins.internal.DeadCrypter import DeadCrypter, create_getInfo class MegauploadCom(DeadCrypter): @@ -13,3 +13,6 @@ class MegauploadCom(DeadCrypter): __description__ = """Megaupload.com folder decrypter plugin""" __license__ = "GPLv3" __authors__ = [("zoidberg", "zoidberg@mujmail.cz")] + + +getInfo = create_getInfo(MegauploadCom) diff --git a/pyload/plugins/crypter/Movie2kTo.py b/pyload/plugins/crypter/Movie2kTo.py index bb00e2eed..0be7eb7eb 100644 --- a/pyload/plugins/crypter/Movie2kTo.py +++ b/pyload/plugins/crypter/Movie2kTo.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from pyload.plugins.internal.DeadCrypter import DeadCrypter +from module.plugins.internal.DeadCrypter import DeadCrypter, create_getInfo class Movie2kTo(DeadCrypter): @@ -14,3 +14,6 @@ class Movie2kTo(DeadCrypter): __description__ = """Movie2k.to decrypter plugin""" __license__ = "GPLv3" __authors__ = [("4Christopher", "4Christopher@gmx.de")] + + +getInfo = create_getInfo(Movie2kTo) diff --git a/pyload/plugins/crypter/MultiuploadCom.py b/pyload/plugins/crypter/MultiuploadCom.py index 713d67c18..03275477d 100644 --- a/pyload/plugins/crypter/MultiuploadCom.py +++ b/pyload/plugins/crypter/MultiuploadCom.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from pyload.plugins.internal.DeadCrypter import DeadCrypter +from module.plugins.internal.DeadCrypter import DeadCrypter, create_getInfo class MultiuploadCom(DeadCrypter): @@ -13,3 +13,6 @@ class MultiuploadCom(DeadCrypter): __description__ = """MultiUpload.com decrypter plugin""" __license__ = "GPLv3" __authors__ = [("zoidberg", "zoidberg@mujmail.cz")] + + +getInfo = create_getInfo(MultiuploadCom) diff --git a/pyload/plugins/crypter/OronCom.py b/pyload/plugins/crypter/OronCom.py index c92666a5b..f466492b3 100644 --- a/pyload/plugins/crypter/OronCom.py +++ b/pyload/plugins/crypter/OronCom.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from pyload.plugins.internal.DeadCrypter import DeadCrypter +from module.plugins.internal.DeadCrypter import DeadCrypter, create_getInfo class OronCom(DeadCrypter): @@ -14,3 +14,6 @@ class OronCom(DeadCrypter): __description__ = """Oron.com folder decrypter plugin""" __license__ = "GPLv3" __authors__ = [("DHMH", "webmaster@pcProfil.de")] + + +getInfo = create_getInfo(OronCom) diff --git a/pyload/plugins/crypter/RSLayerCom.py b/pyload/plugins/crypter/RSLayerCom.py index 70c04a10c..cc3b23bbc 100644 --- a/pyload/plugins/crypter/RSLayerCom.py +++ b/pyload/plugins/crypter/RSLayerCom.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from pyload.plugins.internal.DeadCrypter import DeadCrypter +from module.plugins.internal.DeadCrypter import DeadCrypter, create_getInfo class RSLayerCom(DeadCrypter): @@ -14,3 +14,6 @@ class RSLayerCom(DeadCrypter): __description__ = """RS-Layer.com decrypter plugin""" __license__ = "GPLv3" __authors__ = [("hzpz", None)] + + +getInfo = create_getInfo(RSLayerCom) diff --git a/pyload/plugins/crypter/SecuredIn.py b/pyload/plugins/crypter/SecuredIn.py index 21ebff060..cbfa919ac 100644 --- a/pyload/plugins/crypter/SecuredIn.py +++ b/pyload/plugins/crypter/SecuredIn.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from pyload.plugins.internal.DeadCrypter import DeadCrypter +from module.plugins.internal.DeadCrypter import DeadCrypter, create_getInfo class SecuredIn(DeadCrypter): @@ -14,3 +14,6 @@ class SecuredIn(DeadCrypter): __description__ = """Secured.in decrypter plugin""" __license__ = "GPLv3" __authors__ = [("mkaay", "mkaay@mkaay.de")] + + +getInfo = create_getInfo(SecuredIn) diff --git a/pyload/plugins/crypter/SharingmatrixCom.py b/pyload/plugins/crypter/SharingmatrixCom.py index 28906ae7b..c875631f4 100644 --- a/pyload/plugins/crypter/SharingmatrixCom.py +++ b/pyload/plugins/crypter/SharingmatrixCom.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from pyload.plugins.internal.DeadCrypter import DeadCrypter +from module.plugins.internal.DeadCrypter import DeadCrypter, create_getInfo class SharingmatrixCom(DeadCrypter): @@ -13,3 +13,6 @@ class SharingmatrixCom(DeadCrypter): __description__ = """Sharingmatrix.com folder decrypter plugin""" __license__ = "GPLv3" __authors__ = [("zoidberg", "zoidberg@mujmail.cz")] + + +getInfo = create_getInfo(SharingmatrixCom) diff --git a/pyload/plugins/crypter/SpeedLoadOrg.py b/pyload/plugins/crypter/SpeedLoadOrg.py index 46c9b8552..3c1b1af22 100644 --- a/pyload/plugins/crypter/SpeedLoadOrg.py +++ b/pyload/plugins/crypter/SpeedLoadOrg.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from pyload.plugins.internal.DeadCrypter import DeadCrypter +from module.plugins.internal.DeadCrypter import DeadCrypter, create_getInfo class SpeedLoadOrg(DeadCrypter): @@ -14,3 +14,6 @@ class SpeedLoadOrg(DeadCrypter): __description__ = """Speedload decrypter plugin""" __license__ = "GPLv3" __authors__ = [("stickell", "l.stickell@yahoo.it")] + + +getInfo = create_getInfo(SpeedLoadOrg) diff --git a/pyload/plugins/crypter/StealthTo.py b/pyload/plugins/crypter/StealthTo.py index 6177a116a..e4da3e7e4 100644 --- a/pyload/plugins/crypter/StealthTo.py +++ b/pyload/plugins/crypter/StealthTo.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from pyload.plugins.internal.DeadCrypter import DeadCrypter +from module.plugins.internal.DeadCrypter import DeadCrypter, create_getInfo class StealthTo(DeadCrypter): @@ -14,3 +14,6 @@ class StealthTo(DeadCrypter): __description__ = """Stealth.to decrypter plugin""" __license__ = "GPLv3" __authors__ = [("spoob", "spoob@pyload.org")] + + +getInfo = create_getInfo(StealthTo) diff --git a/pyload/plugins/crypter/TrailerzoneInfo.py b/pyload/plugins/crypter/TrailerzoneInfo.py index deee3e23b..abdb2307e 100644 --- a/pyload/plugins/crypter/TrailerzoneInfo.py +++ b/pyload/plugins/crypter/TrailerzoneInfo.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from pyload.plugins.internal.DeadCrypter import DeadCrypter +from module.plugins.internal.DeadCrypter import DeadCrypter, create_getInfo class TrailerzoneInfo(DeadCrypter): @@ -14,3 +14,6 @@ class TrailerzoneInfo(DeadCrypter): __description__ = """TrailerZone.info decrypter plugin""" __license__ = "GPLv3" __authors__ = [("godofdream", "soilfiction@gmail.com")] + + +getInfo = create_getInfo(TrailerzoneInfo) diff --git a/pyload/plugins/crypter/TusfilesNet.py b/pyload/plugins/crypter/TusfilesNet.py index d8f0b604a..ef00ba440 100644 --- a/pyload/plugins/crypter/TusfilesNet.py +++ b/pyload/plugins/crypter/TusfilesNet.py @@ -10,7 +10,7 @@ from pyload.plugins.internal.XFSCrypter import XFSCrypter class TusfilesNet(XFSCrypter): __name__ = "TusfilesNet" __type__ = "crypter" - __version__ = "0.06" + __version__ = "0.07" __pattern__ = r'https?://(?:www\.)?tusfiles\.net/go/(?P<ID>\w+)' __config__ = [("use_subfolder", "bool", "Save package to subfolder", True), @@ -26,7 +26,7 @@ class TusfilesNet(XFSCrypter): PAGES_PATTERN = r'>\((\d+) \w+\)<' - URL_REPLACEMENTS = [(__pattern__, r'https://www.tusfiles.net/go/\g<ID>/')] + URL_REPLACEMENTS = [(__pattern__ + ".*", r'https://www.tusfiles.net/go/\g<ID>/')] def loadPage(self, page_n): diff --git a/pyload/plugins/crypter/WiiReloadedOrg.py b/pyload/plugins/crypter/WiiReloadedOrg.py index 3c48044b0..c3c5b8222 100644 --- a/pyload/plugins/crypter/WiiReloadedOrg.py +++ b/pyload/plugins/crypter/WiiReloadedOrg.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from pyload.plugins.internal.DeadCrypter import DeadCrypter +from module.plugins.internal.DeadCrypter import DeadCrypter, create_getInfo class WiiReloadedOrg(DeadCrypter): @@ -14,3 +14,6 @@ class WiiReloadedOrg(DeadCrypter): __description__ = """Wii-Reloaded.org decrypter plugin""" __license__ = "GPLv3" __authors__ = [("hzpz", None)] + + +getInfo = create_getInfo(WiiReloadedOrg) diff --git a/pyload/plugins/crypter/WuploadCom.py b/pyload/plugins/crypter/WuploadCom.py index dd1c4a168..4a004be66 100644 --- a/pyload/plugins/crypter/WuploadCom.py +++ b/pyload/plugins/crypter/WuploadCom.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from pyload.plugins.internal.DeadCrypter import DeadCrypter +from module.plugins.internal.DeadCrypter import DeadCrypter, create_getInfo class WuploadCom(DeadCrypter): @@ -13,3 +13,6 @@ class WuploadCom(DeadCrypter): __description__ = """Wupload.com folder decrypter plugin""" __license__ = "GPLv3" __authors__ = [("zoidberg", "zoidberg@mujmail.cz")] + + +getInfo = create_getInfo(WuploadCom) diff --git a/pyload/plugins/hook/XFileSharingPro.py b/pyload/plugins/hook/XFileSharingPro.py index 520e30964..268e91909 100644 --- a/pyload/plugins/hook/XFileSharingPro.py +++ b/pyload/plugins/hook/XFileSharingPro.py @@ -8,11 +8,11 @@ from pyload.plugins.internal.Addon import Hook class XFileSharingPro(Hook): __name__ = "XFileSharingPro" __type__ = "hook" - __version__ = "0.22" + __version__ = "0.24" __config__ = [("activated", "bool", "Activated", True), - ("use_hoster_list", "bool", "Load listed hosters only", False), - ("use_crypter_list", "bool", "Load listed crypters only", False), + ("use_hoster_list", "bool", "Load listed hosters only", True), + ("use_crypter_list", "bool", "Load listed crypters only", True), ("use_builtin_list", "bool", "Load built-in plugin list", True), ("hoster_list", "str", "Hoster list (comma separated)", ""), ("crypter_list", "str", "Crypter list (comma separated)", "")] @@ -23,8 +23,8 @@ class XFileSharingPro(Hook): # event_list = ["pluginConfigChanged"] - regexp = {'hoster' : (r'https?://(?:www\.)?([\w^_]+(?:\.[a-zA-Z]{2,})+(?:\:\d+)?)/(?:embed-)?\w{12}', - r'https?://(?:[^/]+\.)?(%s)/(?:embed-)?\w{12}\W?'), + regexp = {'hoster' : (r'https?://(?:www\.)?([\w^_]+(?:\.[a-zA-Z]{2,})+(?:\:\d+)?)/(?:embed-)?\w{12}(?:\W|$)', + r'https?://(?:[^/]+\.)?(%s)/(?:embed-)?\w+'), 'crypter': (r'https?://(?:www\.)?([\w^_]+(?:\.[a-zA-Z]{2,})+(?:\:\d+)?)/(?:user|folder)s?/\w+', r'https?://(?:[^/]+\.)?(%s)/(?:user|folder)s?/\w+')} diff --git a/pyload/plugins/hoster/DataportCz.py b/pyload/plugins/hoster/DataportCz.py index 174bd04af..65ae38ff1 100644 --- a/pyload/plugins/hoster/DataportCz.py +++ b/pyload/plugins/hoster/DataportCz.py @@ -6,7 +6,7 @@ from pyload.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo class DataportCz(SimpleHoster): __name__ = "DataportCz" __type__ = "hoster" - __version__ = "0.39" + __version__ = "0.40" __pattern__ = r'http://(?:www\.)?dataport\.cz/file/(.*)' @@ -19,8 +19,6 @@ class DataportCz(SimpleHoster): SIZE_PATTERN = r'<td class="fil">Velikost</td>\s*<td>(?P<S>[^<]+)</td>' OFFLINE_PATTERN = r'<h2>Soubor nebyl nalezen</h2>' - URL_REPLACEMENTS = [(__pattern__, r'http://www.dataport.cz/file/\1')] - CAPTCHA_PATTERN = r'<section id="captcha_bg">\s*<img src="(.*?)"' FREE_SLOTS_PATTERN = ur'Počet volných slotů: <span class="darkblue">(\d+)</span><br />' diff --git a/pyload/plugins/hoster/DepositfilesCom.py b/pyload/plugins/hoster/DepositfilesCom.py index ee84195b6..ca26ebc47 100644 --- a/pyload/plugins/hoster/DepositfilesCom.py +++ b/pyload/plugins/hoster/DepositfilesCom.py @@ -11,7 +11,7 @@ from pyload.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo class DepositfilesCom(SimpleHoster): __name__ = "DepositfilesCom" __type__ = "hoster" - __version__ = "0.50" + __version__ = "0.51" __pattern__ = r'https?://(?:www\.)?(depositfiles\.com|dfiles\.(eu|ru))(/\w{1,3})?/files/(?P<ID>\w+)' @@ -22,18 +22,18 @@ class DepositfilesCom(SimpleHoster): ("Walter Purcaro", "vuolter@gmail.com")] - NAME_PATTERN = r'<script type="text/javascript">eval\( unescape\(\'(?P<N>.*?)\'' - SIZE_PATTERN = r': <b>(?P<S>[\d.,]+) (?P<U>[\w^_]+)</b>' + NAME_PATTERN = r'<script type="text/javascript">eval\( unescape\(\'(?P<N>.*?)\'' + SIZE_PATTERN = r': <b>(?P<S>[\d.,]+) (?P<U>[\w^_]+)</b>' OFFLINE_PATTERN = r'<span class="html_download_api-not_exists"></span>' NAME_REPLACEMENTS = [(r'\%u([0-9A-Fa-f]{4})', lambda m: unichr(int(m.group(1), 16))), (r'.*<b title="(?P<N>[^"]+).*', "\g<N>")] - URL_REPLACEMENTS = [(__pattern__, "https://dfiles.eu/files/\g<ID>")] + URL_REPLACEMENTS = [(__pattern__ + ".*", "https://dfiles.eu/files/\g<ID>")] COOKIES = [("dfiles.eu", "lang_current", "en")] - FREE_LINK_PATTERN = r'<form id="downloader_file_form" action="(http://.+?\.(dfiles\.eu|depositfiles\.com)/.+?)" method="post"' - PREMIUM_LINK_PATTERN = r'class="repeat"><a href="(.+?)"' + FREE_LINK_PATTERN = r'<form id="downloader_file_form" action="(http://.+?\.(dfiles\.eu|depositfiles\.com)/.+?)" method="post"' + PREMIUM_LINK_PATTERN = r'class="repeat"><a href="(.+?)"' PREMIUM_MIRROR_PATTERN = r'class="repeat_mirror"><a href="(.+?)"' diff --git a/pyload/plugins/hoster/FilerioCom.py b/pyload/plugins/hoster/FilerioCom.py index f4582b876..afa1356fc 100644 --- a/pyload/plugins/hoster/FilerioCom.py +++ b/pyload/plugins/hoster/FilerioCom.py @@ -6,7 +6,7 @@ from pyload.plugins.internal.XFSHoster import XFSHoster, create_getInfo class FilerioCom(XFSHoster): __name__ = "FilerioCom" __type__ = "hoster" - __version__ = "0.06" + __version__ = "0.07" __pattern__ = r'http://(?:www\.)?(filerio\.(in|com)|filekeen\.com)/\w{12}' @@ -17,8 +17,9 @@ class FilerioCom(XFSHoster): HOSTER_DOMAIN = "filerio.in" + URL_REPLACEMENTS = [(r'filekeen\.com', "filerio.in")] + OFFLINE_PATTERN = r'>"File Not Found|File has been removed' - URL_REPLACEMENTS = [(r'/(?:embed-)?(\w{12}).*', r'/\1'), (r'filekeen\.com', "filerio.in")] getInfo = create_getInfo(FilerioCom) diff --git a/pyload/plugins/hoster/HugefilesNet.py b/pyload/plugins/hoster/HugefilesNet.py index e955d53cc..1c32b7378 100644 --- a/pyload/plugins/hoster/HugefilesNet.py +++ b/pyload/plugins/hoster/HugefilesNet.py @@ -1,7 +1,6 @@ # -*- coding: utf-8 -*- -# -# Test links: -# http://hugefiles.net/prthf9ya4w6s + +import re from pyload.plugins.internal.XFSHoster import XFSHoster, create_getInfo @@ -9,7 +8,7 @@ from pyload.plugins.internal.XFSHoster import XFSHoster, create_getInfo class HugefilesNet(XFSHoster): __name__ = "HugefilesNet" __type__ = "hoster" - __version__ = "0.04" + __version__ = "0.05" __pattern__ = r'http://(?:www\.)?hugefiles\.net/\w{12}' @@ -22,5 +21,7 @@ class HugefilesNet(XFSHoster): SIZE_PATTERN = r'File Size:</span>\s*<span[^>]*>(?P<S>[^<]+)</span></div>' + FORM_INPUTS_MAP = {'ctype': re.compile(r'\d+')} + getInfo = create_getInfo(HugefilesNet) diff --git a/pyload/plugins/hoster/JunocloudMe.py b/pyload/plugins/hoster/JunocloudMe.py index dc5620e0e..908402775 100644 --- a/pyload/plugins/hoster/JunocloudMe.py +++ b/pyload/plugins/hoster/JunocloudMe.py @@ -6,7 +6,7 @@ from pyload.plugins.internal.XFSHoster import XFSHoster, create_getInfo class JunocloudMe(XFSHoster): __name__ = "JunocloudMe" __type__ = "hoster" - __version__ = "0.03" + __version__ = "0.04" __pattern__ = r'http://(?:\w+\.)?junocloud\.me/\w{12}' @@ -17,7 +17,7 @@ class JunocloudMe(XFSHoster): HOSTER_DOMAIN = "junocloud.me" - URL_REPLACEMENTS = [(r'/(?:embed-)?(\w{12}).*', r'/\1'), (r'//www\.', "//dl3.")] + URL_REPLACEMENTS = [(r'//www\.', "//dl3.")] NAME_PATTERN = r'<p class="request_file">http://junocloud.me/w{12}/(?P<N>.+?)</p>' SIZE_PATTERN = r'<p class="request_filesize">Size: (?P<S>[\d.,]+) (?P<U>[\w^_]+)</p>' diff --git a/pyload/plugins/hoster/NowVideoAt.py b/pyload/plugins/hoster/NowVideoAt.py index e17e2e256..1ac9d19a3 100644 --- a/pyload/plugins/hoster/NowVideoAt.py +++ b/pyload/plugins/hoster/NowVideoAt.py @@ -8,7 +8,7 @@ from pyload.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo class NowVideoAt(SimpleHoster): __name__ = "NowVideoAt" __type__ = "hoster" - __version__ = "0.05" + __version__ = "0.06" __pattern__ = r'http://(?:www\.)?nowvideo\.(at|ch|co|eu|sx)/(video|mobile/#/videos)/(?P<ID>\w+)' @@ -17,7 +17,7 @@ class NowVideoAt(SimpleHoster): __authors__ = [("Walter Purcaro", "vuolter@gmail.com")] - URL_REPLACEMENTS = [(__pattern__, r'http://www.nowvideo.at/video/\g<ID>')] + URL_REPLACEMENTS = [(__pattern__ + ".*", r'http://www.nowvideo.at/video/\g<ID>')] NAME_PATTERN = r'<h4>(?P<N>.+?)<' OFFLINE_PATTERN = r'>This file no longer exists' diff --git a/pyload/plugins/hoster/TurbobitNet.py b/pyload/plugins/hoster/TurbobitNet.py index b069e7a84..e0691942c 100644 --- a/pyload/plugins/hoster/TurbobitNet.py +++ b/pyload/plugins/hoster/TurbobitNet.py @@ -17,7 +17,7 @@ from pyload.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo, t class TurbobitNet(SimpleHoster): __name__ = "TurbobitNet" __type__ = "hoster" - __version__ = "0.14" + __version__ = "0.15" __pattern__ = r'http://(?:www\.)?turbobit\.net/(?:download/free/)?(?P<ID>\w+)' @@ -27,7 +27,7 @@ class TurbobitNet(SimpleHoster): ("prOq", None)] - URL_REPLACEMENTS = [(__pattern__, "http://turbobit.net/\g<ID>.html")] + URL_REPLACEMENTS = [(__pattern__ + ".*", "http://turbobit.net/\g<ID>.html")] COOKIES = [("turbobit.net", "user_lang", "en")] diff --git a/pyload/plugins/hoster/UpleaCom.py b/pyload/plugins/hoster/UpleaCom.py index 7a7dd4870..395f71bbf 100644 --- a/pyload/plugins/hoster/UpleaCom.py +++ b/pyload/plugins/hoster/UpleaCom.py @@ -10,7 +10,7 @@ from pyload.plugins.internal.XFSHoster import XFSHoster, create_getInfo class UpleaCom(XFSHoster): __name__ = "UpleaCom" __type__ = "hoster" - __version__ = "0.04" + __version__ = "0.05" __pattern__ = r'https?://(?:www\.)?uplea\.com/dl/\w{15}' @@ -28,7 +28,7 @@ class UpleaCom(XFSHoster): LINK_PATTERN = r'"(http?://\w+\.uplea\.com/anonym/.*?)"' WAIT_PATTERN = r'timeText:([\d.]+),' - VARS_PATTERN = r'class="cel_tbl_step1_foot">\s<a href="(/step/.+)">' + STEP_PATTERN = r'<a href="(/step/.+)">' def setup(self): @@ -38,11 +38,11 @@ class UpleaCom(XFSHoster): def handleFree(self): - m = re.search(self.VARS_PATTERN, self.html) + m = re.search(self.STEP_PATTERN, self.html) if m is None: - self.error("VARS_PATTERN not found") + self.error("STEP_PATTERN not found") - self.html = self.load(urljoin("http://uplea.com/", m.groups(1))) + self.html = self.load(urljoin("http://uplea.com/", m.group(1))) m = re.search(self.WAIT_PATTERN, self.html) if m: diff --git a/pyload/plugins/hoster/VeohCom.py b/pyload/plugins/hoster/VeohCom.py index 0f756211c..a1aa9896f 100644 --- a/pyload/plugins/hoster/VeohCom.py +++ b/pyload/plugins/hoster/VeohCom.py @@ -8,7 +8,7 @@ from pyload.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo class VeohCom(SimpleHoster): __name__ = "VeohCom" __type__ = "hoster" - __version__ = "0.2" + __version__ = "0.21" __pattern__ = r'http://(?:www\.)?veoh\.com/(tv/)?(watch|videos)/(?P<ID>v\w+)' __config__ = [("quality", "Low;High;Auto", "Quality", "Auto")] @@ -18,10 +18,10 @@ class VeohCom(SimpleHoster): __authors__ = [("Walter Purcaro", "vuolter@gmail.com")] - NAME_PATTERN = r'<meta name="title" content="(?P<N>.*?)"' + NAME_PATTERN = r'<meta name="title" content="(?P<N>.*?)"' OFFLINE_PATTERN = r'>Sorry, we couldn\'t find the video you were looking for' - URL_REPLACEMENTS = [(__pattern__, r'http://www.veoh.com/watch/\g<ID>')] + URL_REPLACEMENTS = [(__pattern__ + ".*", r'http://www.veoh.com/watch/\g<ID>')] COOKIES = [("veoh.com", "lassieLocale", "en")] diff --git a/pyload/plugins/hoster/VimeoCom.py b/pyload/plugins/hoster/VimeoCom.py index 5bd1b9afb..bfa2cbb79 100644 --- a/pyload/plugins/hoster/VimeoCom.py +++ b/pyload/plugins/hoster/VimeoCom.py @@ -8,7 +8,7 @@ from pyload.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo class VimeoCom(SimpleHoster): __name__ = "VimeoCom" __type__ = "hoster" - __version__ = "0.02" + __version__ = "0.03" __pattern__ = r'https?://(?:www\.)?(player\.)?vimeo\.com/(video/)?(?P<ID>\d+)' __config__ = [("quality", "Lowest;Mobile;SD;HD;Highest", "Quality", "Highest"), @@ -19,11 +19,11 @@ class VimeoCom(SimpleHoster): __authors__ = [("Walter Purcaro", "vuolter@gmail.com")] - NAME_PATTERN = r'<title>(?P<N>.+) on Vimeo<' - OFFLINE_PATTERN = r'class="exception_header"' + NAME_PATTERN = r'<title>(?P<N>.+) on Vimeo<' + OFFLINE_PATTERN = r'class="exception_header"' TEMP_OFFLINE_PATTERN = r'Please try again in a few minutes.<' - URL_REPLACEMENTS = [(__pattern__, r'https://www.vimeo.com/\g<ID>')] + URL_REPLACEMENTS = [(__pattern__ + ".*", r'https://www.vimeo.com/\g<ID>')] COOKIES = [("vimeo.com", "language", "en")] diff --git a/pyload/plugins/internal/BasePlugin.py b/pyload/plugins/internal/BasePlugin.py index dd8540578..f4abc1a15 100644 --- a/pyload/plugins/internal/BasePlugin.py +++ b/pyload/plugins/internal/BasePlugin.py @@ -6,20 +6,26 @@ from urllib import unquote from urlparse import urlparse from pyload.network.HTTPRequest import BadHeader +from pyload.plugins.internal.SimpleHoster import create_getInfo from pyload.plugins.internal.Hoster import Hoster -from pyload.utils import html_unescape, remove_chars class BasePlugin(Hoster): __name__ = "BasePlugin" __type__ = "hoster" - __version__ = "0.20" + __version__ = "0.23" __pattern__ = r'^unmatchable$' __description__ = """Base Plugin when any other didnt fit""" __license__ = "GPLv3" - __authors__ = [("RaNaN", "RaNaN@pyload.org")] + __authors__ = [("RaNaN", "RaNaN@pyload.org"), + ("Walter Purcaro", "vuolter@gmail.com")] + + + @classmethod + def getInfo(cls, url="", html=""): #@TODO: Move to hoster class in 0.4.10 + return {'name': urlparse(url).path.split('/')[-1] or _("Unknown"), 'size': 0, 'status': 3, 'url': url or ""} def setup(self): @@ -30,40 +36,45 @@ class BasePlugin(Hoster): def process(self, pyfile): """main function""" - #: debug part, for api exerciser - if pyfile.url.startswith("DEBUG_API"): - self.multiDL = False - return + pyfile.name = self.getInfo(pyfile.url)['name'] if pyfile.url.startswith("http"): + for _i in xrange(2): + try: + self.downloadFile(pyfile) - try: - self.downloadFile(pyfile) - except BadHeader, e: - if e.code in (401, 403): - self.logDebug("Auth required") + except BadHeader, e: + if e.code is 404: + self.offline() - account = self.core.accountManager.getAccountPlugin('Http') - servers = [x['login'] for x in account.getAllAccounts()] - server = urlparse(pyfile.url).netloc + elif e.code in (401, 403): + self.logDebug("Auth required") - if server in servers: - self.logDebug("Logging on to %s" % server) - self.req.addAuth(account.accounts[server]['password']) - else: - for pwd in pyfile.package().password.splitlines(): - if ":" in pwd: - self.req.addAuth(pwd.strip()) - break - else: - self.fail(_("Authorization required (username:password)")) + account = self.core.accountManager.getAccountPlugin('Http') + servers = [x['login'] for x in account.getAllAccounts()] + server = urlparse(pyfile.url).netloc - self.downloadFile(pyfile) + if server in servers: + self.logDebug("Logging on to %s" % server) + self.req.addAuth(account.accounts[server]['password']) + else: + for pwd in pyfile.package().password.splitlines(): + if ":" in pwd: + self.req.addAuth(pwd.strip()) + break + else: + self.fail(_("Authorization required (username:password)")) + else: + self.fail(e) else: - raise - + break + else: + self.fail(_("No file downloaded")) #@TODO: Move to hoster class (check if self.lastDownload) in 0.4.10 else: - self.fail(_("No Plugin matched and not a downloadable url")) + self.fail(_("No plugin matched")) + + # if self.checkDownload({'empty': re.compile(r"^$")}) is "empty": + # self.fail(_("Empty file")) def downloadFile(self, pyfile): @@ -78,31 +89,18 @@ class BasePlugin(Hoster): if 'location' in header: self.logDebug("Location: " + header['location']) + base = re.match(r'https?://[^/]+', url).group(0) + if header['location'].startswith("http"): url = header['location'] + elif header['location'].startswith("/"): url = base + unquote(header['location']) + else: url = '%s/%s' % (base, unquote(header['location'])) else: break - name = html_unescape(unquote(urlparse(url).path.split("/")[-1])) - - if 'content-disposition' in header: - self.logDebug("Content-Disposition: " + header['content-disposition']) - m = re.search("filename(?P<type>=|\*=(?P<enc>.+)'')(?P<name>.*)", header['content-disposition']) - if m: - disp = m.groupdict() - self.logDebug(disp) - if not disp['enc']: - disp['enc'] = 'utf-8' - name = remove_chars(disp['name'], "\"';").strip() - name = unicode(unquote(name), disp['enc']) - - if not name: - name = url - pyfile.name = name - self.logDebug("Filename: %s" % pyfile.name) self.download(url, disposition=True) diff --git a/pyload/plugins/internal/DeadCrypter.py b/pyload/plugins/internal/DeadCrypter.py index bf150f3d5..3510e1466 100644 --- a/pyload/plugins/internal/DeadCrypter.py +++ b/pyload/plugins/internal/DeadCrypter.py @@ -1,12 +1,15 @@ # -*- coding: utf-8 -*- +from urlparse import urlparse + from pyload.plugins.internal.Crypter import Crypter as _Crypter +from pyload.plugins.internal.SimpleCrypter import create_getInfo class DeadCrypter(_Crypter): __name__ = "DeadCrypter" __type__ = "crypter" - __version__ = "0.02" + __version__ = "0.03" __pattern__ = r'^unmatchable$' @@ -15,5 +18,14 @@ class DeadCrypter(_Crypter): __authors__ = [("stickell", "l.stickell@yahoo.it")] + @classmethod + def getInfo(cls, url="", html=""): + return {'name': urlparse(url).path.split('/')[-1] or _("Unknown"), 'size': 0, 'status': 1, 'url': url or ""} + + def setup(self): - self.offline("Crypter is no longer available") + self.pyfile.error = "Crypter is no longer available" + self.offline() #@TODO: self.offline("Crypter is no longer available") + + +getInfo = create_getInfo(DeadCrypter) diff --git a/pyload/plugins/internal/DeadHoster.py b/pyload/plugins/internal/DeadHoster.py index 036ed3cb6..a7e5093d3 100644 --- a/pyload/plugins/internal/DeadHoster.py +++ b/pyload/plugins/internal/DeadHoster.py @@ -1,20 +1,15 @@ # -*- coding: utf-8 -*- -from pyload.plugins.internal.Hoster import Hoster as _Hoster - - -def create_getInfo(plugin): +from urlparse import urlparse - def getInfo(urls): - yield map(lambda url: ('#N/A: ' + url, 0, 1, url), urls) - - return getInfo +from pyload.plugins.internal.Hoster import Hoster as _Hoster +from pyload.plugins.internal.SimpleHoster import create_getInfo class DeadHoster(_Hoster): __name__ = "DeadHoster" __type__ = "hoster" - __version__ = "0.12" + __version__ = "0.13" __pattern__ = r'^unmatchable$' @@ -23,5 +18,14 @@ class DeadHoster(_Hoster): __authors__ = [("zoidberg", "zoidberg@mujmail.cz")] + @classmethod + def getInfo(cls, url="", html=""): + return {'name': urlparse(url).path.split('/')[-1] or _("Unknown"), 'size': 0, 'status': 1, 'url': url or ""} + + def setup(self): - self.offline("Hoster is no longer available") + self.pyfile.error = "Hoster is no longer available" + self.offline() #@TODO: self.offline("Hoster is no longer available") + + +getInfo = create_getInfo(DeadHoster) diff --git a/pyload/plugins/internal/SimpleCrypter.py b/pyload/plugins/internal/SimpleCrypter.py index ead5cefba..090cf2e9f 100644 --- a/pyload/plugins/internal/SimpleCrypter.py +++ b/pyload/plugins/internal/SimpleCrypter.py @@ -5,14 +5,14 @@ import re from urlparse import urlparse from pyload.plugins.internal.Crypter import Crypter -from pyload.plugins.internal.SimpleHoster import SimpleHoster, replace_patterns, set_cookies +from pyload.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo, replace_patterns, set_cookies from pyload.utils import fixup class SimpleCrypter(Crypter, SimpleHoster): __name__ = "SimpleCrypter" __type__ = "crypter" - __version__ = "0.31" + __version__ = "0.32" __pattern__ = r'^unmatchable$' __config__ = [("use_subfolder", "bool", "Save package to subfolder", True), #: Overrides core.config['general']['folder_per_package'] diff --git a/pyload/plugins/internal/SimpleHoster.py b/pyload/plugins/internal/SimpleHoster.py index 4e9db7f73..a33e48bdf 100644 --- a/pyload/plugins/internal/SimpleHoster.py +++ b/pyload/plugins/internal/SimpleHoster.py @@ -37,12 +37,13 @@ def parseHtmlTagAttrValue(attr_name, tag): return m.group(2) if m else None -def parseHtmlForm(attr_str, html, input_names=None): - for form in re.finditer(r"(?P<tag><form[^>]*%s[^>]*>)(?P<content>.*?)</?(form|body|html)[^>]*>" % attr_str, +def parseHtmlForm(attr_str, html, input_names={}): + for form in re.finditer(r"(?P<TAG><form[^>]*%s[^>]*>)(?P<CONTENT>.*?)</?(form|body|html)[^>]*>" % attr_str, html, re.S | re.I): inputs = {} - action = parseHtmlTagAttrValue("action", form.group('tag')) - for inputtag in re.finditer(r'(<(input|textarea)[^>]*>)([^<]*(?=</\2)|)', form.group('content'), re.S | re.I): + action = parseHtmlTagAttrValue("action", form.group('TAG')) + + for inputtag in re.finditer(r'(<(input|textarea)[^>]*>)([^<]*(?=</\2)|)', form.group('CONTENT'), re.S | re.I): name = parseHtmlTagAttrValue("name", inputtag.group(1)) if name: value = parseHtmlTagAttrValue("value", inputtag.group(1)) @@ -51,7 +52,7 @@ def parseHtmlForm(attr_str, html, input_names=None): else: inputs[name] = value - if isinstance(input_names, dict): + if input_names: # check input attributes for key, val in input_names.iteritems(): if key in inputs: @@ -80,6 +81,7 @@ def parseFileInfo(plugin, url="", html=""): #@TODO: Remove in 0.4.10 +#@NOTE: Every plugin must have own parseInfo classmethod to work with 0.4.10 def create_getInfo(plugin): return lambda urls: [(info['name'], info['size'], info['status'], info['url']) for info in plugin.parseInfo(urls)] @@ -90,23 +92,21 @@ def timestamp(): #@TODO: Move to hoster class in 0.4.10 def _getDirectLink(self, url): - self.req.http.c.setopt(FOLLOWLOCATION, 0) + header = self.load(url, ref=True, just_header=True, decode=True) - html = self.load(url, ref=True, decode=True) + if not 'location' in header or not header['location']: + return "" - self.req.http.c.setopt(FOLLOWLOCATION, 1) + if header['code'] != 302 or 'content-type' not in header or header['content-type'] != "text/plain": + return "" - if self.getInfo(url, html)['status'] is not 2: - try: - return re.search(r'Location\s*:\s*(.+)', self.req.http.header, re.I).group(1).rstrip() #@TODO: Remove .rstrip() in 0.4.10 - except: - pass + return header['location'] class SimpleHoster(Hoster): __name__ = "SimpleHoster" __type__ = "hoster" - __version__ = "0.60" + __version__ = "0.62" __pattern__ = r'^unmatchable$' @@ -177,7 +177,7 @@ class SimpleHoster(Hoster): @classmethod def getInfo(cls, url="", html=""): - info = {'name': url or _("Unknown"), 'size': 0, 'status': 3, 'url': url} + info = {'name': urlparse(url).path.split('/')[-1] or _("Unknown"), 'size': 0, 'status': 3, 'url': url or ""} if not html: if url: @@ -391,14 +391,15 @@ class SimpleHoster(Hoster): def handleDirect(self): - self.link = _getDirectLink(self, self.pyfile.url) + link = _getDirectLink(self, self.pyfile.url) - if self.link: + if link: self.logInfo(_("Direct download link detected")) + self.link = link + self._updateInfo(self.getInfo(self.pyfile.url)) self.checkNameSize() - else: self.logDebug(_("Direct download link not found")) @@ -452,7 +453,7 @@ class SimpleHoster(Hoster): self.retry(max_tries=max_tries, reason=_("Download limit reached")) - def parseHtmlForm(self, attr_str='', input_names=None): + def parseHtmlForm(self, attr_str="", input_names={}): return parseHtmlForm(attr_str, self.html, input_names) diff --git a/pyload/plugins/internal/XFSAccount.py b/pyload/plugins/internal/XFSAccount.py index 1e18c09bd..168c4f903 100644 --- a/pyload/plugins/internal/XFSAccount.py +++ b/pyload/plugins/internal/XFSAccount.py @@ -12,7 +12,7 @@ from pyload.plugins.internal.SimpleHoster import parseHtmlForm, set_cookies class XFSAccount(Account): __name__ = "XFSAccount" __type__ = "account" - __version__ = "0.26" + __version__ = "0.30" __description__ = """XFileSharing account plugin""" __license__ = "GPLv3" @@ -32,6 +32,9 @@ class XFSAccount(Account): TRAFFIC_LEFT_PATTERN = r'>Traffic available today:.*?<b>\s*(?P<S>[\d.,]+|[Uu]nlimited)\s*(?:(?P<U>[\w^_]+)\s*)?</b>' TRAFFIC_LEFT_UNIT = "MB" #: used only if no group <U> was found + LEECH_TRAFFIC_PATTERN = r'Leech Traffic left:<b>.*?(?P<S>[\d.,]+|[Uu]nlimited)\s*(?:(?P<U>[\w^_]+)\s*)?</b>' + LEECH_TRAFFIC_UNIT = "MB" #: used only if no group <U> was found + LOGIN_FAIL_PATTERN = r'>(Incorrect Login or Password|Error<)' @@ -44,9 +47,10 @@ class XFSAccount(Account): def loadAccountInfo(self, user, req): - validuntil = None - trafficleft = None - premium = None + validuntil = None + trafficleft = None + leechtraffic = None + premium = None html = req.load(self.HOSTER_URL, get={'op': "my_account"}, decode=True) @@ -64,17 +68,22 @@ class XFSAccount(Account): self.logError(e) else: + self.logDebug("Valid until: %s" % validuntil) + if validuntil > mktime(gmtime()): premium = True + trafficleft = -1 else: premium = False validuntil = None #: registered account type (not premium) + else: + self.logDebug("VALID_UNTIL_PATTERN not found") m = re.search(self.TRAFFIC_LEFT_PATTERN, html) if m: try: traffic = m.groupdict() - size = traffic['S'] + size = traffic['S'] if "nlimited" in size: trafficleft = -1 @@ -93,10 +102,36 @@ class XFSAccount(Account): except Exception, e: self.logError(e) else: - if premium: - trafficleft = -1 + self.logDebug("TRAFFIC_LEFT_PATTERN not found") + + m = re.finditer(self.LEECH_TRAFFIC_PATTERN, html) + if m: + leechtraffic = 0 + try: + for leech in m: + size = leech['S'] + + if "nlimited" in size: + leechtraffic = -1 + if validuntil is None: + validuntil = -1 + break + else: + if 'U' in leech: + unit = leech['U'] + elif isinstance(self.LEECH_TRAFFIC_UNIT, basestring): + unit = self.LEECH_TRAFFIC_UNIT + else: + unit = "" + + leechtraffic += self.parseTraffic(size + unit) + + except Exception, e: + self.logError(e) + else: + self.logDebug("LEECH_TRAFFIC_PATTERN not found") - return {'validuntil': validuntil, 'trafficleft': trafficleft, 'premium': premium} + return {'validuntil': validuntil, 'trafficleft': trafficleft, 'leechtraffic': leechtraffic, 'premium': premium} def login(self, user, data, req): diff --git a/pyload/plugins/internal/XFSHoster.py b/pyload/plugins/internal/XFSHoster.py index 3ae9ee05a..4d3c848b9 100644 --- a/pyload/plugins/internal/XFSHoster.py +++ b/pyload/plugins/internal/XFSHoster.py @@ -16,7 +16,7 @@ from pyload.utils import html_unescape class XFSHoster(SimpleHoster): __name__ = "XFSHoster" __type__ = "hoster" - __version__ = "0.22" + __version__ = "0.26" __pattern__ = r'^unmatchable$' @@ -30,15 +30,13 @@ class XFSHoster(SimpleHoster): HOSTER_DOMAIN = None HOSTER_NAME = None - URL_REPLACEMENTS = [(r'/(?:embed-)?(\w{12}).*', r'/\1')] #: plus support embedded files - TEXT_ENCODING = False COOKIES = [(HOSTER_DOMAIN, "lang", "english")] CHECK_DIRECT_LINK = None - MULTI_HOSTER = False + MULTI_HOSTER = True #@NOTE: Should be default to False for safe, but I'm lazy... INFO_PATTERN = r'<tr><td align=right><b>Filename:</b></td><td nowrap>(?P<N>[^<]+)</td></tr>\s*.*?<small>\((?P<S>[^<]+)\)</small>' - NAME_PATTERN = r'(>Filename:</b></td><td nowrap>|name="fname" value="|<span class="name">|<[Tt]itle>.*?Download )(?P<N>.+?)(\s*<|")' + NAME_PATTERN = r'(>Filename:</b></td><td nowrap>|name="fname" value="|<span class="name">)(?P<N>.+?)(\s*<|")' SIZE_PATTERN = r'(>Size:</b></td><td>|>File:.*>|<span class="size">)(?P<S>[\d.,]+)\s*(?P<U>[\w^_]+)' OFFLINE_PATTERN = r'>\s*\w+ (Not Found|file (was|has been) removed)' @@ -48,14 +46,17 @@ class XFSHoster(SimpleHoster): PREMIUM_ONLY_PATTERN = r'>This file is available for Premium Users only' ERROR_PATTERN = r'(?:class=["\']err["\'].*?>|<[Cc]enter><b>|>Error</td>|>\(ERROR:)(?:\s*<.+?>\s*)*(.+?)(?:["\']|<|\))' - OVR_LINK_PATTERN = r'<h2>Download Link</h2>\s*<textarea[^>]*>([^<]+)' - LINK_PATTERN = None #: final download url pattern + LEECH_LINK_PATTERN = r'<h2>Download Link</h2>\s*<textarea[^>]*>([^<]+)' + LINK_PATTERN = None #: final download url pattern CAPTCHA_PATTERN = r'(https?://[^"\']+?/captchas?/[^"\']+)' CAPTCHA_DIV_PATTERN = r'>Enter code.*?<div.*?>(.+?)</div>' RECAPTCHA_PATTERN = None SOLVEMEDIA_PATTERN = None + FORM_PATTERN = None + FORM_INPUTS_MAP = None #: dict passed as input_names to parseHtmlForm + def setup(self): self.chunkLimit = 1 @@ -108,7 +109,7 @@ class XFSHoster(SimpleHoster): def getDownloadLink(self): - for i in xrange(1, 5): + for i in xrange(1, 6): self.logDebug("Getting download link: #%d" % i) self.checkErrors() @@ -145,7 +146,7 @@ class XFSHoster(SimpleHoster): #only tested with easybytez.com self.html = self.load("http://www.%s/" % self.HOSTER_DOMAIN) - action, inputs = self.parseHtmlForm('') + action, inputs = self.parseHtmlForm() upload_id = "%012d" % int(random() * 10 ** 12) action += upload_id + "&js_on=1&utype=prem&upload_type=url" @@ -186,9 +187,9 @@ class XFSHoster(SimpleHoster): self.fail(stmsg) #get easybytez.com link for uploaded file - m = re.search(self.OVR_LINK_PATTERN, self.html) + m = re.search(self.LEECH_LINK_PATTERN, self.html) if m is None: - self.error(_("OVR_LINK_PATTERN not found")) + self.error(_("LEECH_LINK_PATTERN not found")) header = self.load(m.group(1), just_header=True, decode=True) @@ -259,10 +260,10 @@ class XFSHoster(SimpleHoster): def getPostParameters(self): - if hasattr(self, "FORM_PATTERN"): - action, inputs = self.parseHtmlForm(self.FORM_PATTERN) + if self.FORM_PATTERN or self.FORM_INPUTS_MAP: + action, inputs = self.parseHtmlForm(self.FORM_PATTERN or "", self.FORM_INPUTS_MAP or {}) else: - action, inputs = self.parseHtmlForm(input_names={"op": re.compile("^download")}) + action, inputs = self.parseHtmlForm(input_names={'op': re.compile(r'^download')}) if not inputs: action, inputs = self.parseHtmlForm('F1') @@ -313,8 +314,8 @@ class XFSHoster(SimpleHoster): m = re.search(self.CAPTCHA_DIV_PATTERN, self.html, re.S) if m: captcha_div = m.group(1) + numerals = re.findall(r'<span.*?padding-left\s*:\s*(\d+).*?>(\d)</span>', html_unescape(captcha_div)) self.logDebug(captcha_div) - numerals = re.findall(r'<span.*?padding-left\s*:\s*(\d+).*?>(\d)</span>', html_unescape(captcha_div)) inputs['code'] = "".join([a[1] for a in sorted(numerals, key=lambda num: int(num[0]))]) self.logDebug("Captcha code: %s" % inputs['code'], numerals) return 2 @@ -324,9 +325,10 @@ class XFSHoster(SimpleHoster): captcha_key = re.search(self.RECAPTCHA_PATTERN, self.html).group(1) except: captcha_key = recaptcha.detect_key() + else: + self.logDebug("ReCaptcha key: %s" % captcha_key) if captcha_key: - self.logDebug("ReCaptcha key: %s" % captcha_key) inputs['recaptcha_challenge_field'], inputs['recaptcha_response_field'] = recaptcha.challenge(captcha_key) return 3 @@ -335,9 +337,10 @@ class XFSHoster(SimpleHoster): captcha_key = re.search(self.SOLVEMEDIA_PATTERN, self.html).group(1) except: captcha_key = solvemedia.detect_key() + else: + self.logDebug("SolveMedia key: %s" % captcha_key) if captcha_key: - self.logDebug("SolveMedia key: %s" % captcha_key) inputs['adcopy_challenge'], inputs['adcopy_response'] = solvemedia.challenge(captcha_key) return 4 |