diff options
| author | 2014-12-13 15:56:57 +0100 | |
|---|---|---|
| committer | 2014-12-13 15:56:57 +0100 | |
| commit | acc46fc3497a66a427b795b4a22c6e71d69185a1 (patch) | |
| tree | 2d315b838a76435fc456b972c99c28d1732b2f70 /pyload/plugin/crypter | |
| parent | Code fixes (diff) | |
| download | pyload-acc46fc3497a66a427b795b4a22c6e71d69185a1.tar.xz | |
Update
Diffstat (limited to 'pyload/plugin/crypter')
84 files changed, 4307 insertions, 0 deletions
diff --git a/pyload/plugin/crypter/BitshareCom.py b/pyload/plugin/crypter/BitshareCom.py new file mode 100644 index 000000000..dfa7b71df --- /dev/null +++ b/pyload/plugin/crypter/BitshareCom.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- + +from pyload.plugin.internal.SimpleCrypter import SimpleCrypter + + +class BitshareCom(SimpleCrypter): +    __name    = "BitshareCom" +    __type    = "crypter" +    __version = "0.03" + +    __pattern = r'http://(?:www\.)?bitshare\.com/\?d=\w+' +    __config  = [("use_subfolder", "bool", "Save package to subfolder", True), +                   ("subfolder_per_package", "bool", "Create a subfolder for each package", True)] + +    __description = """Bitshare.com folder decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("stickell", "l.stickell@yahoo.it")] + + +    LINK_PATTERN = r'<a href="(http://bitshare\.com/files/.+)">.+</a></td>' +    NAME_PATTERN = r'View public folder "(?P<N>.+)"</h1>' diff --git a/pyload/plugin/crypter/C1neonCom.py b/pyload/plugin/crypter/C1neonCom.py new file mode 100644 index 000000000..ad428f6dd --- /dev/null +++ b/pyload/plugin/crypter/C1neonCom.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- + +from pyload.plugin.internal.DeadCrypter import DeadCrypter, create_getInfo + + +class C1neonCom(DeadCrypter): +    __name    = "C1neonCom" +    __type    = "crypter" +    __version = "0.05" + +    __pattern = r'http://(?:www\.)?c1neon\.com/.*?' +    __config  = [] + +    __description = """C1neon.com decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("godofdream", "soilfiction@gmail.com")] + + +getInfo = create_getInfo(C1neonCom) diff --git a/pyload/plugin/crypter/ChipDe.py b/pyload/plugin/crypter/ChipDe.py new file mode 100644 index 000000000..36735fd13 --- /dev/null +++ b/pyload/plugin/crypter/ChipDe.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- + +import re +from pyload.plugin.Crypter import Crypter + + +class ChipDe(Crypter): +    __name    = "ChipDe" +    __type    = "crypter" +    __version = "0.10" + +    __pattern = r'http://(?:www\.)?chip\.de/video/.*\.html' +    __config  = [("use_subfolder", "bool", "Save package to subfolder", True), +                   ("subfolder_per_package", "bool", "Create a subfolder for each package", True)] + +    __description = """Chip.de decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("4Christopher", "4Christopher@gmx.de")] + + +    def decrypt(self, pyfile): +        self.html = self.load(pyfile.url) +        try: +            f = re.search(r'"(http://video\.chip\.de/.+)"', self.html) +        except Exception: +            self.fail(_("Failed to find the URL")) +        else: +            self.urls = [f.group(1)] +            self.logDebug("The file URL is %s" % self.urls[0]) diff --git a/pyload/plugin/crypter/CrockoCom.py b/pyload/plugin/crypter/CrockoCom.py new file mode 100644 index 000000000..8782c86e6 --- /dev/null +++ b/pyload/plugin/crypter/CrockoCom.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- + +from pyload.plugin.internal.SimpleCrypter import SimpleCrypter + + +class CrockoCom(SimpleCrypter): +    __name    = "CrockoCom" +    __type    = "crypter" +    __version = "0.01" + +    __pattern = r'http://(?:www\.)?crocko\.com/f/.*' +    __config  = [("use_subfolder", "bool", "Save package to subfolder", True), +                   ("subfolder_per_package", "bool", "Create a subfolder for each package", True)] + +    __description = """Crocko.com folder decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("zoidberg", "zoidberg@mujmail.cz")] + + +    LINK_PATTERN = r'<td class="last"><a href="([^"]+)">download</a>' diff --git a/pyload/plugin/crypter/CryptItCom.py b/pyload/plugin/crypter/CryptItCom.py new file mode 100644 index 000000000..dfb6be954 --- /dev/null +++ b/pyload/plugin/crypter/CryptItCom.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- + +from pyload.plugin.internal.DeadCrypter import DeadCrypter, create_getInfo + + +class CryptItCom(DeadCrypter): +    __name    = "CryptItCom" +    __type    = "crypter" +    __version = "0.11" + +    __pattern = r'http://(?:www\.)?crypt-it\.com/(s|e|d|c)/\w+' +    __config  = [] + +    __description = """Crypt-it.com decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("jeix", "jeix@hasnomail.de")] + + +getInfo = create_getInfo(CryptItCom) diff --git a/pyload/plugin/crypter/CzshareCom.py b/pyload/plugin/crypter/CzshareCom.py new file mode 100644 index 000000000..e36394426 --- /dev/null +++ b/pyload/plugin/crypter/CzshareCom.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- + +import re +from pyload.plugin.Crypter import Crypter + + +class CzshareCom(Crypter): +    __name    = "CzshareCom" +    __type    = "crypter" +    __version = "0.20" + +    __pattern = r'http://(?:www\.)?(czshare|sdilej)\.(com|cz)/folders/.*' +    __config  = [("use_subfolder", "bool", "Save package to subfolder", True), +                   ("subfolder_per_package", "bool", "Create a subfolder for each package", True)] + +    __description = """Czshare.com folder decrypter plugin, now Sdilej.cz""" +    __license     = "GPLv3" +    __authors     = [("zoidberg", "zoidberg@mujmail.cz")] + + +    FOLDER_PATTERN = r'<tr class="subdirectory">\s*<td>\s*<table>(.*?)</table>' +    LINK_PATTERN = r'<td class="col2"><a href="([^"]+)">info</a></td>' + + +    def decrypt(self, pyfile): +        html = self.load(pyfile.url) + +        m = re.search(self.FOLDER_PATTERN, html, re.S) +        if m is None: +            self.error(_("FOLDER_PATTERN not found")) + +        self.urls.extend(re.findall(self.LINK_PATTERN, m.group(1))) diff --git a/pyload/plugin/crypter/DDLMusicOrg.py b/pyload/plugin/crypter/DDLMusicOrg.py new file mode 100644 index 000000000..a24cac22d --- /dev/null +++ b/pyload/plugin/crypter/DDLMusicOrg.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- + +import re + +from time import sleep + +from pyload.plugin.Crypter import Crypter + + +class DDLMusicOrg(Crypter): +    __name    = "DDLMusicOrg" +    __type    = "crypter" +    __version = "0.30" + +    __pattern = r'http://(?:www\.)?ddl-music\.org/captcha/ddlm_cr\d\.php\?\d+\?\d+' +    __config  = [("use_subfolder", "bool", "Save package to subfolder", True), +                   ("subfolder_per_package", "bool", "Create a subfolder for each package", True)] + +    __description = """Ddl-music.org decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("mkaay", "mkaay@mkaay.de")] + + +    def setup(self): +        self.multiDL = False + + +    def decrypt(self, pyfile): +        html = self.load(pyfile.url, cookies=True) + +        if re.search(r"Wer dies nicht rechnen kann", html) is not None: +            self.offline() + +        math = re.search(r"(\d+) ([+-]) (\d+) =\s+<inp", self.html) +        id = re.search(r"name=\"id\" value=\"(\d+)\"", self.html).group(1) +        linknr = re.search(r"name=\"linknr\" value=\"(\d+)\"", self.html).group(1) + +        solve = "" +        if math.group(2) == "+": +            solve = int(math.group(1)) + int(math.group(3)) +        else: +            solve = int(math.group(1)) - int(math.group(3)) +        sleep(3) +        htmlwithlink = self.load(pyfile.url, cookies=True, +                                     post={"calc%s" % linknr: solve, "send%s" % linknr: "Send", "id": id, +                                           "linknr": linknr}) +        m = re.search(r"<form id=\"ff\" action=\"(.*?)\" method=\"post\">", htmlwithlink) +        if m: +            self.urls = [m.group(1)] +        else: +            self.retry() diff --git a/pyload/plugin/crypter/DailymotionBatch.py b/pyload/plugin/crypter/DailymotionBatch.py new file mode 100644 index 000000000..4b5b7106c --- /dev/null +++ b/pyload/plugin/crypter/DailymotionBatch.py @@ -0,0 +1,106 @@ +# -*- coding: utf-8 -*- + +import re + +from urlparse import urljoin + +from pyload.utils import json_loads +from pyload.plugin.Crypter import Crypter +from pyload.utils import safe_join + + +class DailymotionBatch(Crypter): +    __name    = "DailymotionBatch" +    __type    = "crypter" +    __version = "0.01" + +    __pattern = r'https?://(?:www\.)?dailymotion\.com/((playlists/)?(?P<TYPE>playlist|user)/)?(?P<ID>[\w^_]+)(?(TYPE)|#)' +    __config  = [("use_subfolder", "bool", "Save package to subfolder", True), +                   ("subfolder_per_package", "bool", "Create a subfolder for each package", True)] + +    __description = """Dailymotion.com channel & playlist decrypter""" +    __license     = "GPLv3" +    __authors     = [("Walter Purcaro", "vuolter@gmail.com")] + + +    def api_response(self, ref, req=None): +        url = urljoin("https://api.dailymotion.com/", ref) +        page = self.load(url, get=req) +        return json_loads(page) + + +    def getPlaylistInfo(self, id): +        ref = "playlist/" + id +        req = {"fields": "name,owner.screenname"} +        playlist = self.api_response(ref, req) + +        if "error" in playlist: +            return + +        name = playlist['name'] +        owner = playlist['owner.screenname'] +        return name, owner + + +    def _getPlaylists(self, user_id, page=1): +        ref = "user/%s/playlists" % user_id +        req = {"fields": "id", "page": page, "limit": 100} +        user = self.api_response(ref, req) + +        if "error" in user: +            return + +        for playlist in user['list']: +            yield playlist['id'] + +        if user['has_more']: +            for item in self._getPlaylists(user_id, page + 1): +                yield item + + +    def getPlaylists(self, user_id): +        return [(id,) + self.getPlaylistInfo(id) for id in self._getPlaylists(user_id)] + + +    def _getVideos(self, id, page=1): +        ref = "playlist/%s/videos" % id +        req = {"fields": "url", "page": page, "limit": 100} +        playlist = self.api_response(ref, req) + +        if "error" in playlist: +            return + +        for video in playlist['list']: +            yield video['url'] + +        if playlist['has_more']: +            for item in self._getVideos(id, page + 1): +                yield item + + +    def getVideos(self, playlist_id): +        return list(self._getVideos(playlist_id))[::-1] + + +    def decrypt(self, pyfile): +        m = re.match(self.__pattern, pyfile.url) +        m_id = m.group("ID") +        m_type = m.group("TYPE") + +        if m_type == "playlist": +            self.logDebug("Url recognized as Playlist") +            p_info = self.getPlaylistInfo(m_id) +            playlists = [(m_id,) + p_info] if p_info else None +        else: +            self.logDebug("Url recognized as Channel") +            playlists = self.getPlaylists(m_id) +            self.logDebug("%s playlist\s found on channel \"%s\"" % (len(playlists), m_id)) + +        if not playlists: +            self.fail(_("No playlist available")) + +        for p_id, p_name, p_owner in playlists: +            p_videos = self.getVideos(p_id) +            p_folder = safe_join(self.config['general']['download_folder'], p_owner, p_name) +            self.logDebug("%s video\s found on playlist \"%s\"" % (len(p_videos), p_name)) +            self.packages.append((p_name, p_videos, p_folder))  #: folder is NOT recognized by pyload 0.4.9! diff --git a/pyload/plugin/crypter/DataHu.py b/pyload/plugin/crypter/DataHu.py new file mode 100644 index 000000000..bc677253a --- /dev/null +++ b/pyload/plugin/crypter/DataHu.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- + +import re + +from pyload.plugin.internal.SimpleCrypter import SimpleCrypter + + +class DataHu(SimpleCrypter): +    __name    = "DataHu" +    __type    = "crypter" +    __version = "0.06" + +    __pattern = r'http://(?:www\.)?data\.hu/dir/\w+' +    __config  = [("use_subfolder", "bool", "Save package to subfolder", True), +                   ("subfolder_per_package", "bool", "Create a subfolder for each package", True)] + +    __description = """Data.hu folder decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("crash", ""), +                       ("stickell", "l.stickell@yahoo.it")] + + +    LINK_PATTERN = r'<a href=\'(http://data\.hu/get/.+)\' target=\'_blank\'>\1</a>' +    NAME_PATTERN = ur'<title>(?P<N>.+) Let\xf6lt\xe9se</title>' + + +    def prepare(self): +        super(DataHu, self).prepare() + +        if u'K\xe9rlek add meg a jelsz\xf3t' in self.html:  # Password protected +            password = self.getPassword() +            if not password: +                self.fail(_("Password required")) + +            self.logDebug("The folder is password protected', 'Using password: " + password) + +            self.html = self.load(self.pyfile.url, post={'mappa_pass': password}, decode=True) + +            if u'Hib\xe1s jelsz\xf3' in self.html:  # Wrong password +                self.fail(_("Wrong password")) diff --git a/pyload/plugin/crypter/DdlstorageCom.py b/pyload/plugin/crypter/DdlstorageCom.py new file mode 100644 index 000000000..c6f423bb6 --- /dev/null +++ b/pyload/plugin/crypter/DdlstorageCom.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- + +from pyload.plugin.internal.DeadCrypter import DeadCrypter, create_getInfo + + +class DdlstorageCom(DeadCrypter): +    __name    = "DdlstorageCom" +    __type    = "crypter" +    __version = "0.03" + +    __pattern = r'https?://(?:www\.)?ddlstorage\.com/folder/\w+' +    __config  = [] + +    __description = """DDLStorage.com folder decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("godofdream", "soilfiction@gmail.com"), +                       ("stickell", "l.stickell@yahoo.it")] + + +getInfo = create_getInfo(DdlstorageCom) diff --git a/pyload/plugin/crypter/DepositfilesCom.py b/pyload/plugin/crypter/DepositfilesCom.py new file mode 100644 index 000000000..8ecbb6f8d --- /dev/null +++ b/pyload/plugin/crypter/DepositfilesCom.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- + +from pyload.plugin.internal.SimpleCrypter import SimpleCrypter + + +class DepositfilesCom(SimpleCrypter): +    __name    = "DepositfilesCom" +    __type    = "crypter" +    __version = "0.01" + +    __pattern = r'http://(?:www\.)?depositfiles\.com/folders/\w+' +    __config  = [("use_subfolder", "bool", "Save package to subfolder", True), +                   ("subfolder_per_package", "bool", "Create a subfolder for each package", True)] + +    __description = """Depositfiles.com folder decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("zoidberg", "zoidberg@mujmail.cz")] + + +    LINK_PATTERN = r'<div class="progressName"[^>]*>\s*<a href="([^"]+)" title="[^"]*" target="_blank">' diff --git a/pyload/plugin/crypter/Dereferer.py b/pyload/plugin/crypter/Dereferer.py new file mode 100644 index 000000000..ec7f48a52 --- /dev/null +++ b/pyload/plugin/crypter/Dereferer.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- + +import re + +from urllib import unquote + +from pyload.plugin.Crypter import Crypter + + +class Dereferer(Crypter): +    __name    = "Dereferer" +    __type    = "crypter" +    __version = "0.10" + +    __pattern = r'https?://([^/]+)/.*?(?P<url>(ht|f)tps?(://|%3A%2F%2F).*)' +    __config  = [("use_subfolder", "bool", "Save package to subfolder", True), +                   ("subfolder_per_package", "bool", "Create a subfolder for each package", True)] + +    __description = """Crypter for dereferers""" +    __license     = "GPLv3" +    __authors     = [("zoidberg", "zoidberg@mujmail.cz")] + + +    def decrypt(self, pyfile): +        link = re.match(self.__pattern, pyfile.url).group('url') +        self.urls = [unquote(link).rstrip('+')] diff --git a/pyload/plugin/crypter/DevhostStFolder.py b/pyload/plugin/crypter/DevhostStFolder.py new file mode 100644 index 000000000..aa00fe60e --- /dev/null +++ b/pyload/plugin/crypter/DevhostStFolder.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# +# Test links: +# http://d-h.st/users/shine/?fld_id=37263#files + +import re + +from urlparse import urljoin + +from pyload.plugin.internal.SimpleCrypter import SimpleCrypter + + +class DevhostStFolder(SimpleCrypter): +    __name    = "DevhostStFolder" +    __type    = "crypter" +    __version = "0.03" + +    __pattern = r'http://(?:www\.)?d-h\.st/users/(?P<USER>\w+)(/\?fld_id=(?P<ID>\d+))?' +    __config  = [("use_subfolder", "bool", "Save package to subfolder", True), +                   ("subfolder_per_package", "bool", "Create a subfolder for each package", True)] + +    __description = """d-h.st folder decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("zapp-brannigan", "fuerst.reinje@web.de"), +                       ("Walter Purcaro", "vuolter@gmail.com")] + + +    LINK_PATTERN = r'(?:/> |;">)<a href="(.+?)"(?!>Back to \w+<)' +    OFFLINE_PATTERN = r'"/cHP">test\.png<' + + +    def getFileInfo(self): +        if re.search(self.OFFLINE_PATTERN, self.html): +            self.offline() + +        try: +            id = re.match(self.__pattern, self.pyfile.url).group('ID') +            if id == "0": +                raise + +            p = r'href="(.+?)">Back to \w+<' +            m = re.search(p, self.html) +            html = self.load(urljoin("http://d-h.st", m.group(1)), +                             cookies=False) + +            p = '\?fld_id=%s.*?">(.+?)<' % id +            m = re.search(p, html) +            name = folder = m.group(1) + +        except Exception, e: +            self.logDebug(e) +            name = folder = re.match(self.__pattern, self.pyfile.url).group('USER') + +        return {'name': name, 'folder': folder} + + +    def getLinks(self): +        return [urljoin("http://d-h.st", link) for link in re.findall(self.LINK_PATTERN, self.html)] diff --git a/pyload/plugin/crypter/DlProtectCom.py b/pyload/plugin/crypter/DlProtectCom.py new file mode 100644 index 000000000..0a9f00cc4 --- /dev/null +++ b/pyload/plugin/crypter/DlProtectCom.py @@ -0,0 +1,65 @@ +# -*- coding: utf-8 -*- + +import re + +from base64 import urlsafe_b64encode +from time import time + +from pyload.plugin.internal.SimpleCrypter import SimpleCrypter + + +class DlProtectCom(SimpleCrypter): +    __name    = "DlProtectCom" +    __type    = "crypter" +    __version = "0.01" + +    __pattern = r'http://(?:www\.)?dl-protect\.com/((en|fr)/)?(?P<ID>\w+)' +    __config  = [("use_subfolder", "bool", "Save package to subfolder", True), +                   ("subfolder_per_package", "bool", "Create a subfolder for each package", True)] + +    __description = """Dl-protect.com decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("Walter Purcaro", "vuolter@gmail.com")] + + +    OFFLINE_PATTERN = r'>Unfortunately, the link you are looking for is not found' + + +    def getLinks(self): +        # Direct link with redirect +        if not re.match(r"http://(?:www\.)?dl-protect\.com", self.req.http.lastEffectiveURL): +            return [self.req.http.lastEffectiveURL] + +        #id = re.match(self.__pattern, self.pyfile.url).group("ID") +        key = re.search(r'name="id_key" value="(.+?)"', self.html).group(1) + +        post_req = {"id_key": key, "submitform": ""} + +        if self.OFFLINE_PATTERN in self.html: +            self.offline() +        elif ">Please click on continue to see the content" in self.html: +            post_req.update({"submitform": "Continue"}) +        else: +            mstime = int(round(time() * 1000)) +            b64time = "_" + urlsafe_b64encode(str(mstime)).replace("=", "%3D") + +            post_req.update({"i": b64time, "submitform": "Decrypt+link"}) + +            if ">Password :" in self.html: +                post_req['pwd'] = self.getPassword() + +            if ">Security Code" in self.html: +                captcha_id = re.search(r'/captcha\.php\?uid=(.+?)"', self.html).group(1) +                captcha_url = "http://www.dl-protect.com/captcha.php?uid=" + captcha_id +                captcha_code = self.decryptCaptcha(captcha_url, imgtype="gif") + +                post_req['secure'] = captcha_code + +        self.html = self.load(self.pyfile.url, post=post_req) + +        for errmsg in (">The password is incorrect", ">The security code is incorrect"): +            if errmsg in self.html: +                self.fail(_(errmsg[1:])) + +        pattern = r'<a href="([^/].+?)" target="_blank">' +        return re.findall(pattern, self.html) diff --git a/pyload/plugin/crypter/DontKnowMe.py b/pyload/plugin/crypter/DontKnowMe.py new file mode 100644 index 000000000..7fc1c87e4 --- /dev/null +++ b/pyload/plugin/crypter/DontKnowMe.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- + +import re + +from urllib import unquote + +from pyload.plugin.Crypter import Crypter + + +class DontKnowMe(Crypter): +    __name    = "DontKnowMe" +    __type    = "crypter" +    __version = "0.10" + +    __pattern = r'http://(?:www\.)?dontknow\.me/at/\?.+$' +    __config  = [("use_subfolder", "bool", "Save package to subfolder", True), +                   ("subfolder_per_package", "bool", "Create a subfolder for each package", True)] + +    __description = """DontKnow.me decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("selaux", "")] + + +    LINK_PATTERN = r'http://dontknow\.me/at/\?(.+)$' + + +    def decrypt(self, pyfile): +        link = re.findall(self.LINK_PATTERN, pyfile.url)[0] +        self.urls = [unquote(link)] diff --git a/pyload/plugin/crypter/DuckCryptInfo.py b/pyload/plugin/crypter/DuckCryptInfo.py new file mode 100644 index 000000000..28f9a1505 --- /dev/null +++ b/pyload/plugin/crypter/DuckCryptInfo.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- + +import re + +from BeautifulSoup import BeautifulSoup + +from pyload.plugin.Crypter import Crypter + + +class DuckCryptInfo(Crypter): +    __name    = "DuckCryptInfo" +    __type    = "crypter" +    __version = "0.02" + +    __pattern = r'http://(?:www\.)?duckcrypt\.info/(folder|wait|link)/(\w+)/?(\w*)' +    __config  = [("use_subfolder", "bool", "Save package to subfolder", True), +                   ("subfolder_per_package", "bool", "Create a subfolder for each package", True)] + +    __description = """DuckCrypt.info decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("godofdream", "soilfiction@gmail.com")] + + +    TIMER_PATTERN = r'<span id="timer">(.*)</span>' + + +    def decrypt(self, pyfile): +        url = pyfile.url + +        m = re.match(self.__pattern, url) +        if m is None: +            self.fail(_("Weird error in link")) +        if str(m.group(1)) == "link": +            self.handleLink(url) +        else: +            self.handleFolder(m) + + +    def handleFolder(self, m): +        html = self.load("http://duckcrypt.info/ajax/auth.php?hash=" + str(m.group(2))) +        m = re.match(self.__pattern, html) +        self.logDebug("Redirectet to " + str(m.group(0))) +        html = self.load(str(m.group(0))) +        soup = BeautifulSoup(html) +        cryptlinks = soup.findAll("div", attrs={"class": "folderbox"}) +        self.logDebug("Redirectet to " + str(cryptlinks)) +        if not cryptlinks: +            self.error(_("No link found")) +        for clink in cryptlinks: +            if clink.find("a"): +                self.handleLink(clink.find("a")['href']) + + +    def handleLink(self, url): +        html = self.load(url) +        soup = BeautifulSoup(html) +        self.urls = [soup.find("iframe")['src']] +        if not self.urls: +            self.logInfo(_("No link found")) diff --git a/pyload/plugin/crypter/DuploadOrg.py b/pyload/plugin/crypter/DuploadOrg.py new file mode 100644 index 000000000..d5839bce0 --- /dev/null +++ b/pyload/plugin/crypter/DuploadOrg.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- + +from pyload.plugin.internal.DeadCrypter import DeadCrypter, create_getInfo + + +class DuploadOrg(DeadCrypter): +    __name    = "DuploadOrg" +    __type    = "crypter" +    __version = "0.02" + +    __pattern = r'http://(?:www\.)?dupload\.org/folder/\d+' +    __config  = [] + +    __description = """Dupload.org folder decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("stickell", "l.stickell@yahoo.it")] + + +getInfo = create_getInfo(DuploadOrg) diff --git a/pyload/plugin/crypter/EasybytezCom.py b/pyload/plugin/crypter/EasybytezCom.py new file mode 100644 index 000000000..2e7e37537 --- /dev/null +++ b/pyload/plugin/crypter/EasybytezCom.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- + +from pyload.plugin.internal.XFSCrypter import XFSCrypter + + +class EasybytezCom(XFSCrypter): +    __name    = "EasybytezCom" +    __type    = "crypter" +    __version = "0.10" + +    __pattern = r'http://(?:www\.)?easybytez\.com/users/\d+/\d+' +    __config  = [("use_subfolder", "bool", "Save package to subfolder", True), +                   ("subfolder_per_package", "bool", "Create a subfolder for each package", True)] + +    __description = """Easybytez.com folder decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("stickell", "l.stickell@yahoo.it")] + + +    HOSTER_DOMAIN = "easybytez.com" + +    LOGIN_ACCOUNT = True diff --git a/pyload/plugin/crypter/EmbeduploadCom.py b/pyload/plugin/crypter/EmbeduploadCom.py new file mode 100644 index 000000000..88f6db50b --- /dev/null +++ b/pyload/plugin/crypter/EmbeduploadCom.py @@ -0,0 +1,60 @@ +# -*- coding: utf-8 -*- + +import re +from pyload.plugin.Crypter import Crypter +from pyload.network.HTTPRequest import BadHeader + + +class EmbeduploadCom(Crypter): +    __name    = "EmbeduploadCom" +    __type    = "crypter" +    __version = "0.02" + +    __pattern = r'http://(?:www\.)?embedupload\.com/\?d=.*' +    __config = [("use_subfolder", "bool", "Save package to subfolder", True), +                ("subfolder_per_package", "bool", "Create a subfolder for each package", True), +                ("preferedHoster", "str", "Prefered hoster list (bar-separated)", "embedupload"), +                ("ignoredHoster", "str", "Ignored hoster list (bar-separated)", "")] + +    __description = """EmbedUpload.com decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("zoidberg", "zoidberg@mujmail.cz")] + + +    LINK_PATTERN = r'<div id="([^"]+)"[^>]*>\s*<a href="([^"]+)" target="_blank" (?:class="DownloadNow"|style="color:red")>' + + +    def decrypt(self, pyfile): +        self.html = self.load(pyfile.url, decode=True) +        tmp_links = [] + +        m = re.findall(self.LINK_PATTERN, self.html) +        if m: +            prefered_set = set(self.getConfig("preferedHoster").split('|')) +            prefered_set = map(lambda s: s.lower().split('.')[0], prefered_set) + +            self.logDebug("PF: %s" % prefered_set) + +            tmp_links.extend([x[1] for x in m if x[0] in prefered_set]) +            self.urls = self.getLocation(tmp_links) + +            if not self.urls: +                ignored_set = set(self.getConfig("ignoredHoster").split('|')) +                ignored_set = map(lambda s: s.lower().split('.')[0], ignored_set) + +                self.logDebug("IG: %s" % ignored_set) + +                tmp_links.extend([x[1] for x in m if x[0] not in ignored_set]) +                self.urls = self.getLocation(tmp_links) + + +    def getLocation(self, tmp_links): +        new_links = [] +        for link in tmp_links: +            try: +                header = self.load(link, just_header=True) +                if 'location' in header: +                    new_links.append(header['location']) +            except BadHeader: +                pass +        return new_links diff --git a/pyload/plugin/crypter/FilebeerInfo.py b/pyload/plugin/crypter/FilebeerInfo.py new file mode 100644 index 000000000..294f57451 --- /dev/null +++ b/pyload/plugin/crypter/FilebeerInfo.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- + +from pyload.plugin.internal.DeadCrypter import DeadCrypter, create_getInfo + + +class FilebeerInfo(DeadCrypter): +    __name    = "FilebeerInfo" +    __type    = "crypter" +    __version = "0.02" + +    __pattern = r'http://(?:www\.)?filebeer\.info/(\d+~f).*' +    __config  = [] + +    __description = """Filebeer.info folder decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("zoidberg", "zoidberg@mujmail.cz")] + + +getInfo = create_getInfo(FilebeerInfo) diff --git a/pyload/plugin/crypter/FilecloudIo.py b/pyload/plugin/crypter/FilecloudIo.py new file mode 100644 index 000000000..1926d04bb --- /dev/null +++ b/pyload/plugin/crypter/FilecloudIo.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- + +from pyload.plugin.internal.SimpleCrypter import SimpleCrypter + + +class FilecloudIo(SimpleCrypter): +    __name    = "FilecloudIo" +    __type    = "crypter" +    __version = "0.03" + +    __pattern = r'https?://(?:www\.)?(filecloud\.io|ifile\.it)/_\w+' +    __config  = [("use_subfolder", "bool", "Save package to subfolder", True), +                   ("subfolder_per_package", "bool", "Create a subfolder for each package", True)] + +    __description = """Filecloud.io folder decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("Walter Purcaro", "vuolter@gmail.com")] + + +    LINK_PATTERN = r'href="(http://filecloud\.io/\w+)" title' +    NAME_PATTERN = r'>(?P<N>.+?) - filecloud\.io<' diff --git a/pyload/plugin/crypter/FilecryptCc.py b/pyload/plugin/crypter/FilecryptCc.py new file mode 100644 index 000000000..7db82f24c --- /dev/null +++ b/pyload/plugin/crypter/FilecryptCc.py @@ -0,0 +1,148 @@ +# -*- coding: utf-8 -*- + +import base64 +import binascii +import re + +from Crypto.Cipher import AES + +from pyload.plugin.Crypter import Crypter + + +class FilecryptCc(Crypter): +    __name    = "FilecryptCc" +    __type    = "crypter" +    __version = "0.05" + +    __pattern = r'https?://(?:www\.)?filecrypt\.cc/Container/\w+' + +    __description = """Filecrypt.cc decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("zapp-brannigan", "fuerst.reinje@web.de")] + + +    # URL_REPLACEMENTS  = [(r'.html$', ""), (r'$', ".html")]  #@TODO: Extend SimpleCrypter + +    DLC_LINK_PATTERN = r'<button class="dlcdownload" type="button" title="Download \*.dlc" onclick="DownloadDLC\(\'(.+)\'\);"><i></i><span>dlc<' +    WEBLINK_PATTERN = r"openLink.?'([\w_-]*)'," + +    CAPTCHA_PATTERN = r'<img id="nc" src="(.+?)"' + +    MIRROR_PAGE_PATTERN = r'"[\w]*" href="(http://filecrypt.cc/Container/\w+\.html\?mirror=\d+)">' + + +    def setup(self): +        self.links = [] + + +    def decrypt(self, pyfile): +        self.html = self.load(pyfile.url, cookies=True) + +        if "content not found" in self.html: +            self.offline() + +        self.handlePasswordProtection() +        self.handleCaptcha() +        self.handleMirrorPages() + +        for handle in (self.handleCNL, self.handleWeblinks, self.handleDlcContainer): +            handle() +            if self.links: +                self.packages = [(pyfile.package().name, self.links, pyfile.package().name)] +                return + + +    def handleMirrorPages(self): +        if "mirror=" not in self.siteWithLinks: +            return + +        mirror = re.findall(self.MIRROR_PAGE_PATTERN, self.siteWithLinks) + +        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") + + +    def handlePasswordProtection(self): +        if '<input type="text" name="password"' not in self.html: +            return + +        self.logInfo(_("Folder is password protected")) + +        if not self.pyfile.package().password: +            self.fail(_("Please enter the password in package section and try again")) + +        self.html = self.load(self.pyfile.url, post={"password": self.password}, cookies=True) + + +    def handleCaptcha(self): +        m = re.search(self.CAPTCHA_PATTERN, self.html) + +        if m: +            self.logDebug("Captcha-URL: %s" % m.group(1)) +            captcha_code = self.decryptCaptcha("http://filecrypt.cc" + m.group(1), forceUser=True, imgtype="gif") +            self.siteWithLinks = self.load(self.pyfile.url, post={"recaptcha_response_field":captcha_code}, decode=True, cookies=True) +        else: +            self.logDebug("No captcha found") +            self.siteWithLinks = self.html + +        if "recaptcha_response_field" in self.siteWithLinks: +            self.invalidCaptcha() +            self.retry() + + +    def handleDlcContainer(self): +        dlc = re.findall(self.DLC_LINK_PATTERN, self.siteWithLinks) + +        if not dlc: +            return + +        for i in dlc: +            self.links.append("http://filecrypt.cc/DLC/%s.dlc" % i) + + +    def handleWeblinks(self): +        try: +            weblinks = re.findall(self.WEBLINK_PATTERN, self.siteWithLinks) + +            for link in weblinks: +                res   = self.load("http://filecrypt.cc/Link/%s.html" % link, cookies=True) +                link2 = re.search('<iframe noresize src="(.*)"></iframe>', res) +                res2  = self.load(link2.group(1), just_header=True, cookies=True) +                self.links.append(res2['location']) + +        except Exception, e: +            self.logDebug("Error decrypting weblinks: %s" % e) + + +    def handleCNL(self): +        try: +            vjk = re.findall('<input type="hidden" name="jk" value="function f\(\){ return \'(.*)\';}">', self.siteWithLinks) +            vcrypted = re.findall('<input type="hidden" name="crypted" value="(.*)">', self.siteWithLinks) + +            for i in xrange(len(vcrypted)): +                self.links.extend(self._getLinks(vcrypted[i], vjk[i])) + +        except Exception, e: +            self.logDebug("Error decrypting CNL: %s" % e) + + +    def _getLinks(self, crypted, jk): +        # Get key +        key = binascii.unhexlify(str(jk)) + +        # Decode crypted +        crypted = base64.standard_b64decode(crypted) + +        # Decrypt +        Key  = key +        IV   = key +        obj  = AES.new(Key, AES.MODE_CBC, IV) +        text = obj.decrypt(crypted) + +        # Extract links +        links = filter(lambda x: x != "", +                       text.replace("\x00", "").replace("\r", "").split("\n")) + +        return links diff --git a/pyload/plugin/crypter/FilefactoryCom.py b/pyload/plugin/crypter/FilefactoryCom.py new file mode 100644 index 000000000..5b2d242cb --- /dev/null +++ b/pyload/plugin/crypter/FilefactoryCom.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- + +from pyload.plugin.internal.SimpleCrypter import SimpleCrypter + + +class FilefactoryCom(SimpleCrypter): +    __name    = "FilefactoryCom" +    __type    = "crypter" +    __version = "0.31" + +    __pattern = r'https?://(?:www\.)?filefactory\.com/(?:f|folder)/\w+' +    __config  = [("use_subfolder", "bool", "Save package to subfolder", True), +                   ("subfolder_per_package", "bool", "Create a subfolder for each package", True)] + +    __description = """Filefactory.com folder decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("stickell", "l.stickell@yahoo.it")] + + +    LINK_PATTERN = r'<td><a href="([^"]+)">' +    NAME_PATTERN = r'<h1>Files in <span>(?P<N>.+)</span></h1>' +    PAGES_PATTERN = r'data-paginator-totalPages="(\d+)"' + +    COOKIES = [("filefactory.com", "locale", "en_US.utf8")] + + +    def loadPage(self, page_n): +        return self.load(self.pyfile.url, get={'page': page_n}) diff --git a/pyload/plugin/crypter/FilerNet.py b/pyload/plugin/crypter/FilerNet.py new file mode 100644 index 000000000..950012b46 --- /dev/null +++ b/pyload/plugin/crypter/FilerNet.py @@ -0,0 +1,26 @@ +import re + +from pyload.plugin.internal.SimpleCrypter import SimpleCrypter + + +class FilerNet(SimpleCrypter): +    __name    = "FilerNet" +    __type    = "crypter" +    __version = "0.41" + +    __pattern = r'https?://filer\.net/folder/\w{16}' +    __config  = [("use_subfolder", "bool", "Save package to subfolder", True), +                   ("subfolder_per_package", "bool", "Create a subfolder for each package", True)] + +    __description = """Filer.net decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("nath_schwarz", "nathan.notwhite@gmail.com"), +                       ("stickell", "l.stickell@yahoo.it")] + + +    LINK_PATTERN = r'href="(/get/\w{16})">(?!<)' +    NAME_PATTERN = r'<h3>(?P<N>.+?) - <small' + + +    def getLinks(self): +        return ['http://filer.net%s' % link for link in re.findall(self.LINK_PATTERN, self.html)] diff --git a/pyload/plugin/crypter/FileserveCom.py b/pyload/plugin/crypter/FileserveCom.py new file mode 100644 index 000000000..a9f766b81 --- /dev/null +++ b/pyload/plugin/crypter/FileserveCom.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- + +import re + +from pyload.plugin.Crypter import Crypter + + +class FileserveCom(Crypter): +    __name    = "FileserveCom" +    __type    = "crypter" +    __version = "0.11" + +    __pattern = r'http://(?:www\.)?fileserve\.com/list/\w+' +    __config  = [("use_subfolder", "bool", "Save package to subfolder", True), +                   ("subfolder_per_package", "bool", "Create a subfolder for each package", True)] + +    __description = """FileServe.com folder decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("fionnc", "fionnc@gmail.com")] + + +    FOLDER_PATTERN = r'<table class="file_list">(.*?)</table>' +    LINK_PATTERN = r'<a href="([^"]+)" class="sheet_icon wbold">' + + +    def decrypt(self, pyfile): +        html = self.load(pyfile.url) + +        new_links = [] + +        folder = re.search(self.FOLDER_PATTERN, html, re.S) +        if folder is None: +            self.error(_("FOLDER_PATTERN not found")) + +        new_links.extend(re.findall(self.LINK_PATTERN, folder.group(1))) + +        if new_links: +            self.urls = [map(lambda s: "http://fileserve.com%s" % s, new_links)] diff --git a/pyload/plugin/crypter/FilesonicCom.py b/pyload/plugin/crypter/FilesonicCom.py new file mode 100644 index 000000000..6dded6c04 --- /dev/null +++ b/pyload/plugin/crypter/FilesonicCom.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- + +from pyload.plugin.internal.DeadCrypter import DeadCrypter, create_getInfo + + +class FilesonicCom(DeadCrypter): +    __name    = "FilesonicCom" +    __type    = "crypter" +    __version = "0.12" + +    __pattern = r'http://(?:www\.)?filesonic\.com/folder/\w+' + +    __description = """Filesonic.com folder decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("zoidberg", "zoidberg@mujmail.cz")] + + +getInfo = create_getInfo(FilesonicCom) diff --git a/pyload/plugin/crypter/FilestubeCom.py b/pyload/plugin/crypter/FilestubeCom.py new file mode 100644 index 000000000..5238899b0 --- /dev/null +++ b/pyload/plugin/crypter/FilestubeCom.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- + +from pyload.plugin.internal.SimpleCrypter import SimpleCrypter + + +class FilestubeCom(SimpleCrypter): +    __name    = "FilestubeCom" +    __type    = "crypter" +    __version = "0.05" + +    __pattern = r'http://(?:www\.)?filestube\.(?:com|to)/\w+' +    __config  = [("use_subfolder", "bool", "Save package to subfolder", True), +                   ("subfolder_per_package", "bool", "Create a subfolder for each package", True)] + +    __description = """Filestube.com decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("stickell", "l.stickell@yahoo.it")] + + +    LINK_PATTERN = r'<a class=\"file-link-main(?: noref)?\" [^>]* href=\"(http://[^\"]+)' +    NAME_PATTERN = r'<h1\s*> (?P<N>.+)  download\s*</h1>' diff --git a/pyload/plugin/crypter/FiletramCom.py b/pyload/plugin/crypter/FiletramCom.py new file mode 100644 index 000000000..28e38e30e --- /dev/null +++ b/pyload/plugin/crypter/FiletramCom.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- + +from pyload.plugin.internal.SimpleCrypter import SimpleCrypter + + +class FiletramCom(SimpleCrypter): +    __name    = "FiletramCom" +    __type    = "crypter" +    __version = "0.03" + +    __pattern = r'http://(?:www\.)?filetram\.com/[^/]+/.+' +    __config  = [("use_subfolder", "bool", "Save package to subfolder", True), +                   ("subfolder_per_package", "bool", "Create a subfolder for each package", True)] + +    __description = """Filetram.com decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("igel", "igelkun@myopera.com"), +                       ("stickell", "l.stickell@yahoo.it")] + + +    LINK_PATTERN = r'\s+(http://.+)' +    NAME_PATTERN = r'<title>(?P<N>.+?) - Free Download' diff --git a/pyload/plugin/crypter/FiredriveCom.py b/pyload/plugin/crypter/FiredriveCom.py new file mode 100644 index 000000000..27b81c006 --- /dev/null +++ b/pyload/plugin/crypter/FiredriveCom.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- + +from pyload.plugin.internal.DeadCrypter import DeadCrypter, create_getInfo + + +class FiredriveCom(DeadCrypter): +    __name    = "FiredriveCom" +    __type    = "crypter" +    __version = "0.03" + +    __pattern = r'https?://(?:www\.)?(firedrive|putlocker)\.com/share/.+' +    __config  = [] + +    __description = """Firedrive.com folder decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("Walter Purcaro", "vuolter@gmail.com")] + + +getInfo = create_getInfo(FiredriveCom) diff --git a/pyload/plugin/crypter/FourChanOrg.py b/pyload/plugin/crypter/FourChanOrg.py new file mode 100644 index 000000000..97d21ddeb --- /dev/null +++ b/pyload/plugin/crypter/FourChanOrg.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +# +# Based on 4chandl by Roland Beermann (https://gist.github.com/enkore/3492599) + +import re + +from pyload.plugin.Crypter import Crypter + + +class FourChanOrg(Crypter): +    __name    = "FourChanOrg" +    __type    = "crypter" +    __version = "0.30" + +    __pattern = r'http://(?:www\.)?boards\.4chan\.org/\w+/res/(\d+)' +    __config  = [("use_subfolder", "bool", "Save package to subfolder", True), +                   ("subfolder_per_package", "bool", "Create a subfolder for each package", True)] + +    __description = """4chan.org folder decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [] + + +    def decrypt(self, pyfile): +        pagehtml = self.load(pyfile.url) +        images = set(re.findall(r'(images\.4chan\.org/[^/]*/src/[^"<]*)', pagehtml)) +        self.urls = ["http://" + image for image in images] diff --git a/pyload/plugin/crypter/FreakhareCom.py b/pyload/plugin/crypter/FreakhareCom.py new file mode 100644 index 000000000..9df8ef200 --- /dev/null +++ b/pyload/plugin/crypter/FreakhareCom.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- + +import re + +from pyload.plugin.internal.SimpleCrypter import SimpleCrypter + + +class FreakhareCom(SimpleCrypter): +    __name    = "FreakhareCom" +    __type    = "crypter" +    __version = "0.03" + +    __pattern = r'http://(?:www\.)?freakshare\.com/folder/.+' +    __config  = [("use_subfolder", "bool", "Save package to subfolder", True), +                   ("subfolder_per_package", "bool", "Create a subfolder for each package", True)] + +    __description = """Freakhare.com folder decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("stickell", "l.stickell@yahoo.it")] + + +    LINK_PATTERN = r'<a href="(http://freakshare\.com/files/[^"]+)" target="_blank">' +    NAME_PATTERN = r'Folder:</b> (?P<N>.+)' +    PAGES_PATTERN = r'Pages: +(\d+)' + + +    def loadPage(self, page_n): +        if not hasattr(self, 'f_id') and not hasattr(self, 'f_md5'): +            m = re.search(r'http://freakshare.com/\?x=folder&f_id=(\d+)&f_md5=(\w+)', self.html) +            if m: +                self.f_id = m.group(1) +                self.f_md5 = m.group(2) +        return self.load('http://freakshare.com/', get={'x': 'folder', +                                                        'f_id': self.f_id, +                                                        'f_md5': self.f_md5, +                                                        'entrys': '20', +                                                        'page': page_n - 1, +                                                        'order': ''}, decode=True) diff --git a/pyload/plugin/crypter/FreetexthostCom.py b/pyload/plugin/crypter/FreetexthostCom.py new file mode 100644 index 000000000..db97a8003 --- /dev/null +++ b/pyload/plugin/crypter/FreetexthostCom.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- + +import re + +from pyload.plugin.internal.SimpleCrypter import SimpleCrypter + + +class FreetexthostCom(SimpleCrypter): +    __name    = "FreetexthostCom" +    __type    = "crypter" +    __version = "0.01" + +    __pattern = r'http://(?:www\.)?freetexthost\.com/\w+' +    __config  = [("use_subfolder", "bool", "Save package to subfolder", True), +                   ("subfolder_per_package", "bool", "Create a subfolder for each package", True)] + +    __description = """Freetexthost.com decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("stickell", "l.stickell@yahoo.it")] + + +    def getLinks(self): +        m = re.search(r'<div id="contentsinner">\s*(.+)<div class="viewcount">', self.html, re.S) +        if m is None: +            self.error(_("Unable to extract links")) +        links = m.group(1) +        return links.strip().split("<br />\r\n") diff --git a/pyload/plugin/crypter/FshareVn.py b/pyload/plugin/crypter/FshareVn.py new file mode 100644 index 000000000..895a4d258 --- /dev/null +++ b/pyload/plugin/crypter/FshareVn.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- + +from pyload.plugin.internal.SimpleCrypter import SimpleCrypter + + +class FshareVn(SimpleCrypter): +    __name    = "FshareVn" +    __type    = "crypter" +    __version = "0.01" + +    __pattern = r'http://(?:www\.)?fshare\.vn/folder/.*' +    __config  = [("use_subfolder", "bool", "Save package to subfolder", True), +                   ("subfolder_per_package", "bool", "Create a subfolder for each package", True)] + +    __description = """Fshare.vn folder decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("zoidberg", "zoidberg@mujmail.cz")] + + +    LINK_PATTERN = r'<li class="w_80pc"><a href="([^"]+)" target="_blank">' diff --git a/pyload/plugin/crypter/Go4UpCom.py b/pyload/plugin/crypter/Go4UpCom.py new file mode 100644 index 000000000..8652c3825 --- /dev/null +++ b/pyload/plugin/crypter/Go4UpCom.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- + +import re + +from urlparse import urljoin + +from pyload.plugin.internal.SimpleCrypter import SimpleCrypter, create_getInfo + + +class Go4UpCom(SimpleCrypter): +    __name    = "Go4UpCom" +    __type    = "crypter" +    __version = "0.11" + +    __pattern = r'http://go4up\.com/(dl/\w{12}|rd/\w{12}/\d+)' + +    __description = """Go4Up.com decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("rlindner81", "rlindner81@gmail.com"), +                       ("Walter Purcaro", "vuolter@gmail.com")] + + +    LINK_PATTERN = r'(http://go4up\.com/rd/.+?)<' + +    NAME_PATTERN = r'<title>Download (.+?)<' + +    OFFLINE_PATTERN = r'>\s*(404 Page Not Found|File not Found|Mirror does not exist)' + + +    def getLinks(self +        links = [] + +        m = re.search(r'(/download/gethosts/.+?)"') +        if m: +            self.html = self.load(urljoin("http://go4up.com/", m.group(1))) +            pages = [self.load(url) for url in re.findall(self.LINK_PATTERN, self.html)] +        else: +            pages = [self.html] + +        for html in pages: +            try: +                links.append(re.search(r'<b><a href="(.+?)"', html).group(1)) +            except Exception: +                continue + +        return links + + +getInfo = create_getInfo(Go4UpCom) diff --git a/pyload/plugin/crypter/GooGl.py b/pyload/plugin/crypter/GooGl.py new file mode 100644 index 000000000..d1c47935d --- /dev/null +++ b/pyload/plugin/crypter/GooGl.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- + +from pyload.plugin.Crypter import Crypter +from pyload.utils import json_loads + + +class GooGl(Crypter): +    __name    = "GooGl" +    __type    = "crypter" +    __version = "0.01" + +    __pattern = r'https?://(?:www\.)?goo\.gl/\w+' +    __config  = [("use_subfolder", "bool", "Save package to subfolder", True), +                   ("subfolder_per_package", "bool", "Create a subfolder for each package", True)] + +    __description = """Goo.gl decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("stickell", "l.stickell@yahoo.it")] + + +    API_URL = "https://www.googleapis.com/urlshortener/v1/url" + + +    def decrypt(self, pyfile): +        rep = self.load(self.API_URL, get={'shortUrl': pyfile.url}) +        self.logDebug("JSON data: " + rep) +        rep = json_loads(rep) + +        if 'longUrl' in rep: +            self.urls = [rep['longUrl']] +        else: +            self.fail(_("Unable to expand shortened link")) diff --git a/pyload/plugin/crypter/HoerbuchIn.py b/pyload/plugin/crypter/HoerbuchIn.py new file mode 100644 index 000000000..a809e756c --- /dev/null +++ b/pyload/plugin/crypter/HoerbuchIn.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- + +import re + +from BeautifulSoup import BeautifulSoup, BeautifulStoneSoup + +from pyload.plugin.Crypter import Crypter + + +class HoerbuchIn(Crypter): +    __name    = "HoerbuchIn" +    __type    = "crypter" +    __version = "0.60" + +    __pattern = r'http://(?:www\.)?hoerbuch\.in/(wp/horbucher/\d+/.+/|tp/out\.php\?.+|protection/folder_\d+\.html)' +    __config  = [("use_subfolder", "bool", "Save package to subfolder", True), +                   ("subfolder_per_package", "bool", "Create a subfolder for each package", True)] + +    __description = """Hoerbuch.in decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("spoob", "spoob@pyload.org"), +                       ("mkaay", "mkaay@mkaay.de")] + + +    article = re.compile("http://(?:www\.)?hoerbuch\.in/wp/horbucher/\d+/.+/") +    protection = re.compile("http://(?:www\.)?hoerbuch\.in/protection/folder_\d+.html") + + +    def decrypt(self, pyfile): +        self.pyfile = pyfile + +        if self.article.match(pyfile.url): +            html = self.load(pyfile.url) +            soup = BeautifulSoup(html, convertEntities=BeautifulStoneSoup.HTML_ENTITIES) + +            abookname = soup.find("a", attrs={"rel": "bookmark"}).text +            for a in soup.findAll("a", attrs={"href": self.protection}): +                package = "%s (%s)" % (abookname, a.previousSibling.previousSibling.text[:-1]) +                links = self.decryptFolder(a['href']) + +                self.packages.append((package, links, package)) +        else: +            self.urls = self.decryptFolder(pyfile.url) + + +    def decryptFolder(self, url): +        m = self.protection.search(url) +        if m is None: +            self.fail(_("Bad URL")) +        url = m.group(0) + +        self.pyfile.url = url +        html = self.load(url, post={"viewed": "adpg"}) + +        links = [] +        pattern = re.compile("http://www\.hoerbuch\.in/protection/(\w+)/(.*?)\"") +        for hoster, lid in pattern.findall(html): +            self.req.lastURL = url +            self.load("http://www.hoerbuch.in/protection/%s/%s" % (hoster, lid)) +            links.append(self.req.lastEffectiveURL) + +        return links diff --git a/pyload/plugin/crypter/HotfileCom.py b/pyload/plugin/crypter/HotfileCom.py new file mode 100644 index 000000000..11e0008c5 --- /dev/null +++ b/pyload/plugin/crypter/HotfileCom.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- + +from pyload.plugin.internal.DeadCrypter import DeadCrypter, create_getInfo + + +class HotfileCom(DeadCrypter): +    __name    = "HotfileCom" +    __type    = "crypter" +    __version = "0.30" + +    __pattern = r'https?://(?:www\.)?hotfile\.com/list/\w+/\w+' +    __config  = [] + +    __description = """Hotfile.com folder decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("RaNaN", "RaNaN@pyload.org")] + + +getInfo = create_getInfo(HotfileCom) diff --git a/pyload/plugin/crypter/ILoadTo.py b/pyload/plugin/crypter/ILoadTo.py new file mode 100644 index 000000000..d012c9bfd --- /dev/null +++ b/pyload/plugin/crypter/ILoadTo.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- + +from pyload.plugin.internal.DeadCrypter import DeadCrypter, create_getInfo + + +class ILoadTo(DeadCrypter): +    __name    = "ILoadTo" +    __type    = "crypter" +    __version = "0.11" + +    __pattern = r'http://(?:www\.)?iload\.to/go/\d+-[\w.-]+/' +    __config  = [] + +    __description = """Iload.to decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("hzpz", "")] + + +getInfo = create_getInfo(ILoadTo) diff --git a/pyload/plugin/crypter/ImgurComAlbum.py b/pyload/plugin/crypter/ImgurComAlbum.py new file mode 100644 index 000000000..e7df57cb6 --- /dev/null +++ b/pyload/plugin/crypter/ImgurComAlbum.py @@ -0,0 +1,27 @@ +import re + +from pyload.plugin.internal.SimpleCrypter import SimpleCrypter +from pyload.utils import uniqify + + +class ImgurComAlbum(SimpleCrypter): +    __name    = "ImgurComAlbum" +    __type    = "crypter" +    __version = "0.51" + +    __pattern = r'https?://(?:www\.|m\.)?imgur\.com/(a|gallery|)/?\w{5,7}' +    __config  = [("use_subfolder", "bool", "Save package to subfolder", True), +                   ("subfolder_per_package", "bool", "Create a subfolder for each package", True)] + +    __description = """Imgur.com decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("nath_schwarz", "nathan.notwhite@gmail.com")] + + +    NAME_PATTERN = r'(?P<N>.+?) - Imgur' +    LINK_PATTERN = r'i\.imgur\.com/\w{7}s?\.(?:jpeg|jpg|png|gif|apng)' + + +    def getLinks(self): +        f = lambda url: "http://" + re.sub(r'(\w{7})s\.', r'\1.', url) +        return uniqify(map(f, re.findall(self.LINK_PATTERN, self.html))) diff --git a/pyload/plugin/crypter/JunocloudMe.py b/pyload/plugin/crypter/JunocloudMe.py new file mode 100644 index 000000000..b47a5fc58 --- /dev/null +++ b/pyload/plugin/crypter/JunocloudMe.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- + +from pyload.plugin.internal.XFSCrypter import XFSCrypter + + +class JunocloudMe(XFSCrypter): +    __name    = "JunocloudMe" +    __type    = "crypter" +    __version = "0.03" + +    __pattern = r'http://(?:www\.)?junocloud\.me/folders/(?P<ID>\d+/\w+)' +    __config  = [("use_subfolder", "bool", "Save package to subfolder", True), +                   ("subfolder_per_package", "bool", "Create a subfolder for each package", True)] + +    __description = """Junocloud.me folder decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("guidobelix", "guidobelix@hotmail.it")] + + +    HOSTER_DOMAIN = "junocloud.me" diff --git a/pyload/plugin/crypter/LetitbitNet.py b/pyload/plugin/crypter/LetitbitNet.py new file mode 100644 index 000000000..ca787e31a --- /dev/null +++ b/pyload/plugin/crypter/LetitbitNet.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- + +import re +from pyload.plugin.Crypter import Crypter + + +class LetitbitNet(Crypter): +    __name    = "LetitbitNet" +    __type    = "crypter" +    __version = "0.10" + +    __pattern = r'http://(?:www\.)?letitbit\.net/folder/\w+' +    __config  = [("use_subfolder", "bool", "Save package to subfolder", True), +                   ("subfolder_per_package", "bool", "Create a subfolder for each package", True)] + +    __description = """Letitbit.net folder decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("DHMH", "webmaster@pcProfil.de"), +                       ("z00nx", "z00nx0@gmail.com")] + + +    FOLDER_PATTERN = r'<table>(.*)</table>' +    LINK_PATTERN = r'<a href="([^"]+)" target="_blank">' + + +    def decrypt(self, pyfile): +        html = self.load(pyfile.url) + +        folder = re.search(self.FOLDER_PATTERN, html, re.S) +        if folder is None: +            self.error(_("FOLDER_PATTERN not found")) + +        self.urls.extend(re.findall(self.LINK_PATTERN, folder.group(0))) diff --git a/pyload/plugin/crypter/LinkCryptWs.py b/pyload/plugin/crypter/LinkCryptWs.py new file mode 100644 index 000000000..2bd7b4c17 --- /dev/null +++ b/pyload/plugin/crypter/LinkCryptWs.py @@ -0,0 +1,327 @@ +# -*- coding: utf-8 -*- + +import base64 +import binascii +import re + +import pycurl + +from Crypto.Cipher import AES + +from pyload.plugin.Crypter import Crypter +from pyload.utils import html_unescape + + +class LinkCryptWs(Crypter): +    __name    = "LinkCryptWs" +    __type    = "crypter" +    __version = "0.07" + +    __pattern = r'http://(?:www\.)?linkcrypt\.ws/(dir|container)/(?P<ID>\w+)' + +    __description = """LinkCrypt.ws decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("kagenoshin", "kagenoshin[AT]gmx[DOT]ch"), +                       ("glukgluk", ""), +                       ("Gummibaer", "")] + + +    CRYPTED_KEY = "crypted" +    JK_KEY = "jk" + + +    def setup(self): +        self.captcha = False +        self.links   = [] +        self.sources = ['cnl', 'web', 'dlc', 'rsdf', 'ccf'] + + +    def prepare(self): +        # Init +        self.fileid = re.match(self.__pattern, self.pyfile.url).group('ID') + +        self.req.cj.setCookie("linkcrypt.ws", "language", "en") + +        # Request package +        self.req.http.c.setopt(pycurl.USERAGENT, "Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko")  #: better chance to not get those key-captchas +        self.html = self.load(self.pyfile.url) + + +    def decrypt(self, pyfile): +        if not self.js: +            self.fail(_("Missing JS Engine")) + +        self.prepare() + +        if not self.isOnline(): +            self.offline() + +        if self.isKeyCaptchaProtected(): +            self.retry(4, 30, _("Can't handle Key-Captcha")) + +        if self.isCaptchaProtected(): +            self.captcha = True +            self.unlockCaptchaProtection() +            self.handleCaptchaErrors() + +        # Check for protection +        if self.isPasswordProtected(): +            self.unlockPasswordProtection() +            self.handleErrors() + +        # get unrar password +        self.getunrarpw() + +        # Get package name and folder +        package_name, folder_name = self.getPackageInfo() + +        #get the container definitions from script section +        self.get_container_html() + +        # Extract package links +        for type in self.sources: +            links = self.handleLinkSource(type) + +            if links: +                self.links.extend(links) +                break + +        if self.links: +            self.packages = [(package_name, self.links, folder_name)] + + +    def isOnline(self): +        if "<title>Linkcrypt.ws // Error 404</title>" in self.html: +            self.logDebug("folder doesen't exist anymore") +            return False +        else: +            return True + + +    def isPasswordProtected(self): +        if "Authorizing" in self.html: +            self.logDebug("Links are password protected") +            return True +        else: +            return False + + +    def isCaptchaProtected(self): +        if 'id="captcha">' in self.html: +            self.logDebug("Links are captcha protected") +            return True +        else: +            return False + + +    def isKeyCaptchaProtected(self): +        if re.search(r'Key[ -]', self.html, re.I): +            return True +        else: +            return False + + +    def unlockPasswordProtection(self): +        password = self.getPassword() + +        if password: +            self.logDebug("Submitting password [%s] for protected links" % password) +            self.html = self.load(self.pyfile.url, post={"password": password, 'x': "0", 'y': "0"}) +        else: +            self.fail(_("Folder is password protected")) + + +    def unlockCaptchaProtection(self): +        captcha_url  = re.search(r'<form.*?id\s*?=\s*?"captcha"[^>]*?>.*?<\s*?input.*?src="([^"]*?)"', self.html, re.I | re.S).group(1) +        captcha_code = self.decryptCaptcha(captcha_url, forceUser=True, imgtype="gif", result_type='positional') + +        self.html = self.load(self.pyfile.url, post={"x": captcha_code[0], "y": captcha_code[1]}) + + +    def getPackageInfo(self): +        name   = self.pyfile.package().name +        folder = self.pyfile.package().folder + +        self.logDebug("Defaulting to pyfile name [%s] and folder [%s] for package" % (name, folder)) + +        return name, folder + + +    def getunrarpw(self): +        sitein = self.html +        indexi = sitein.find("|source|") + 8 +        indexe = sitein.find("|",indexi) + +        unrarpw = sitein[indexi:indexe] + +        if not (unrarpw == "Password" or "Dateipasswort") : +            self.logDebug("File password set to: [%s]"% unrarpw) +            self.pyfile.package().password = unrarpw + + +    def handleErrors(self): +        if self.isPasswordProtected(): +            self.fail(_("Incorrect password")) + + +    def handleCaptchaErrors(self): +        if self.captcha: +            if "Your choice was wrong!" in self.html: +                self.invalidCaptcha() +                self.retry() +            else: +                self.correctCaptcha() + + +    def handleLinkSource(self, type): +        if type == 'cnl': +                return self.handleCNL2() + +        elif type == 'web': +                return self.handleWebLinks() + +        elif type in ('rsdf', 'ccf', 'dlc'): +                return self.handleContainer(type) + +        else: +            self.fail(_("Unknown source type: %s") % type)  #@TODO: Replace with self.error in 0.4.10 + + +    def handleWebLinks(self): +        self.logDebug("Search for Web links ") + +        package_links = [] +        pattern = r'<form action="http://linkcrypt.ws/out.html"[^>]*?>.*?<input[^>]*?value="([^"]*?)"[^>]*?name="file"' +        ids = re.findall(pattern, self.html, re.I | re.S) + +        self.logDebug("Decrypting %d Web links" % len(ids)) + +        for idx, weblink_id in enumerate(ids): +            try: +                self.logDebug("Decrypting Web link %d, %s" % (idx + 1, weblink_id)) + +                res = self.load("http://linkcrypt.ws/out.html", post = {'file':weblink_id}) + +                indexs = res.find("window.location =") + 19 +                indexe = res.find('"', indexs) + +                link2 = res[indexs:indexe] + +                self.logDebug(link2) + +                link2 = html_unescape(link2) +                package_links.append(link2) + +            except Exception, detail: +                self.logDebug("Error decrypting Web link %s, %s" % (weblink_id, detail)) + +        return package_links + + +    def get_container_html(self): +        self.container_html = [] + +        script = re.search(r'<div.*?id="ad_cont".*?<script.*?javascrip[^>]*?>(.*?)</script', self.html, re.I | re.S) + +        if script: +            container_html_text = script.group(1) +            container_html_text.strip() +            self.container_html = container_html_text.splitlines() + + +    def handle_javascript(self, line): +        return self.js.eval(line.replace('{}))',"{}).replace('document.open();document.write','').replace(';document.close();',''))")) + + +    def handleContainer(self, type): +        package_links = [] +        type = type.lower() + +        self.logDebug('Search for %s Container links' % type.upper()) + +        if not type.isalnum():  # check to prevent broken re-pattern (cnl2,rsdf,ccf,dlc,web are all alpha-numeric) +            self.fail(_("Unknown container type: %s") % type)  #@TODO: Replace with self.error in 0.4.10 + +        for line in self.container_html: +            if type in line: +                jseval = self.handle_javascript(line) +                clink = re.search(r'href=["\']([^"\']*?)["\']',jseval,re.I) + +                if not clink: +                    continue + +                self.logDebug("clink avaible") + +                package_name, folder_name = self.getPackageInfo() +                self.logDebug("Added package with name %s.%s and container link %s" %( package_name, type, clink.group(1))) +                self.core.api.uploadContainer( "%s.%s" %(package_name, type), self.load(clink.group(1))) +                return "Found it" + +        return package_links + + +    def handleCNL2(self): +        self.logDebug("Search for CNL links") + +        package_links = [] +        cnl_line = None + +        for line in self.container_html: +            if "cnl" in line: +                cnl_line = line +                break + +        if cnl_line: +            self.logDebug("cnl_line gefunden") + +        try: +            cnl_section = self.handle_javascript(cnl_line) +            (vcrypted, vjk) = self._getCipherParams(cnl_section) +            for (crypted, jk) in zip(vcrypted, vjk): +                package_links.extend(self._getLinks(crypted, jk)) +        except Exception: +            self.logError(_("Unable to decrypt CNL links (JS Error) try to get over links")) +            return self.handleWebLinks() + +        return package_links + + +    def _getCipherParams(self, cnl_section): +        # Get jk +        jk_re = r'<INPUT.*?NAME="%s".*?VALUE="(.*?)"' % LinkCryptWs.JK_KEY +        vjk = re.findall(jk_re, cnl_section) + +        # Get crypted +        crypted_re = r'<INPUT.*?NAME="%s".*?VALUE="(.*?)"' % LinkCryptWs.CRYPTED_KEY +        vcrypted = re.findall(crypted_re, cnl_section) + +        # Log and return +        self.logDebug("Detected %d crypted blocks" % len(vcrypted)) +        return vcrypted, vjk + + +    def _getLinks(self, crypted, jk): +        # Get key +        jreturn = self.js.eval("%s f()" % jk) +        key     = binascii.unhexlify(jreturn) + +        self.logDebug("JsEngine returns value [%s]" % jreturn) + +        # Decode crypted +        crypted = base64.standard_b64decode(crypted) + +        # Decrypt +        Key  = key +        IV   = key +        obj  = AES.new(Key, AES.MODE_CBC, IV) +        text = obj.decrypt(crypted) + +        # Extract links +        text  = text.replace("\x00", "").replace("\r", "") +        links = text.split("\n") +        links = filter(lambda x: x != "", links) + +        # Log and return +        self.logDebug("Package has %d links" % len(links)) + +        return links diff --git a/pyload/plugin/crypter/LinkSaveIn.py b/pyload/plugin/crypter/LinkSaveIn.py new file mode 100644 index 000000000..3d5a989eb --- /dev/null +++ b/pyload/plugin/crypter/LinkSaveIn.py @@ -0,0 +1,246 @@ +# -*- coding: utf-8 -*- +# +# * cnl2 and web links are skipped if JS is not available (instead of failing the package) +# * only best available link source is used (priority: cnl2>rsdf>ccf>dlc>web + +import base64 +import binascii +import re + +from Crypto.Cipher import AES + +from pyload.plugin.internal.SimpleCrypter import SimpleCrypter +from pyload.utils import html_unescape + + +class LinkSaveIn(SimpleCrypter): +    __name    = "LinkSaveIn" +    __type    = "crypter" +    __version = "2.02" + +    __pattern = r'http://(?:www\.)?linksave\.in/(?P<id>\w+)$' +    __config  = [("use_subfolder", "bool", "Save package to subfolder", True), +                   ("subfolder_per_package", "bool", "Create a subfolder for each package", True)] + +    __description = """LinkSave.in decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("fragonib", "fragonib[AT]yahoo[DOT]es")] + + +    COOKIES = [("linksave.in", "Linksave_Language", "english")] + +    # Constants +    _JK_KEY_ = "jk" +    _CRYPTED_KEY_ = "crypted" + + +    def setup(self): +        self.fileid = None +        self.captcha = False +        self.package = None +        self.preferred_sources = ["cnl2", "rsdf", "ccf", "dlc", "web"] + + +    def decrypt(self, pyfile): +        # Init +        self.package = pyfile.package() +        self.fileid = re.match(self.__pattern, pyfile.url).group('id') + +        # Request package +        self.html = self.load(pyfile.url) +        if not self.isOnline(): +            self.offline() + +        # Check for protection +        if self.isPasswordProtected(): +            self.unlockPasswordProtection() +            self.handleErrors() + +        if self.isCaptchaProtected(): +            self.captcha = True +            self.unlockCaptchaProtection() +            self.handleErrors() + +        # Get package name and folder +        (package_name, folder_name) = self.getPackageInfo() + +        # Extract package links +        package_links = [] +        for type_ in self.preferred_sources: +            package_links.extend(self.handleLinkSource(type_)) +            if package_links:  # use only first source which provides links +                break +        package_links = set(package_links) + +        # Pack +        if package_links: +            self.packages = [(package_name, package_links, folder_name)] + + +    def isOnline(self): +        if "<big>Error 404 - Folder not found!</big>" in self.html: +            self.logDebug("File not found") +            return False +        return True + + +    def isPasswordProtected(self): +        if re.search(r'''<input.*?type="password"''', self.html): +            self.logDebug("Links are password protected") +            return True + + +    def isCaptchaProtected(self): +        if "<b>Captcha:</b>" in self.html: +            self.logDebug("Links are captcha protected") +            return True +        return False + + +    def unlockPasswordProtection(self): +        password = self.getPassword() +        self.logDebug("Submitting password [%s] for protected links" % password) +        post = {"id": self.fileid, "besucherpasswort": password, 'login': 'submit'} +        self.html = self.load(self.pyfile.url, post=post) + + +    def unlockCaptchaProtection(self): +        captcha_hash = re.search(r'name="hash" value="([^"]+)', self.html).group(1) +        captcha_url = re.search(r'src=".(/captcha/cap.php\?hsh=[^"]+)', self.html).group(1) +        captcha_code = self.decryptCaptcha("http://linksave.in" + captcha_url, forceUser=True) +        self.html = self.load(self.pyfile.url, post={"id": self.fileid, "hash": captcha_hash, "code": captcha_code}) + + +    def getPackageInfo(self): +        name = self.pyfile.package().name +        folder = self.pyfile.package().folder +        self.logDebug("Defaulting to pyfile name [%s] and folder [%s] for package" % (name, folder)) +        return name, folder + + +    def handleErrors(self): +        if "The visitorpassword you have entered is wrong" in self.html: +            self.logDebug("Incorrect password, please set right password on 'Edit package' form and retry") +            self.fail(_("Incorrect password, please set right password on 'Edit package' form and retry")) + +        if self.captcha: +            if "Wrong code. Please retry" in self.html: +                self.invalidCaptcha() +                self.retry() +            else: +                self.correctCaptcha() + + +    def handleLinkSource(self, type_): +        if type_ == "cnl2": +            return self.handleCNL2() +        elif type_ in ("rsdf", "ccf", "dlc"): +            return self.handleContainer(type_) +        elif type_ == "web": +            return self.handleWebLinks() +        else: +            self.error('Unknown source type "%s" (this is probably a bug)' % type_) + + +    def handleWebLinks(self): +        package_links = [] +        self.logDebug("Search for Web links") +        if not self.js: +            self.logDebug("No JS -> skip Web links") +        else: +            #@TODO: Gather paginated web links +            pattern = r'<a href="http://linksave\.in/(\w{43})"' +            ids = re.findall(pattern, self.html) +            self.logDebug("Decrypting %d Web links" % len(ids)) +            for i, weblink_id in enumerate(ids): +                try: +                    webLink = "http://linksave.in/%s" % weblink_id + +                    self.logDebug("Decrypting Web link %d, %s" % (i + 1, webLink)) + +                    fwLink = "http://linksave.in/fw-%s" % weblink_id +                    res = self.load(fwLink) + +                    jscode = re.findall(r'<script type="text/javascript">(.*)</script>', res)[-1] +                    jseval = self.js.eval("document = { write: function(e) { return e; } }; %s" % jscode) +                    dlLink = re.search(r'http://linksave\.in/dl-\w+', jseval).group(0) +                    self.logDebug("JsEngine returns value [%s] for redirection link" % dlLink) + +                    res = self.load(dlLink) +                    link = html_unescape(re.search(r'<iframe src="(.+?)"', res).group(1)) + +                    package_links.append(link) + +                except Exception, detail: +                    self.logDebug("Error decrypting Web link %s, %s" % (webLink, detail)) + +        return package_links + + +    def handleContainer(self, type_): +        package_links = [] +        type_ = type_.lower() +        self.logDebug("Seach for %s Container links" % type_.upper()) +        if not type_.isalnum():  # check to prevent broken re-pattern (cnl2,rsdf,ccf,dlc,web are all alpha-numeric) +            self.error('Unknown container type "%s" (this is probably a bug)' % type_) +        pattern = r'\(\'%s_link\'\).href=unescape\(\'(.*?\.%s)\'\)' % (type_, type_) +        containersLinks = re.findall(pattern, self.html) +        self.logDebug("Found %d %s Container links" % (len(containersLinks), type_.upper())) +        for containerLink in containersLinks: +            link = "http://linksave.in/%s" % html_unescape(containerLink) +            package_links.append(link) +        return package_links + + +    def handleCNL2(self): +        package_links = [] +        self.logDebug("Search for CNL2 links") +        if not self.js: +            self.logDebug("No JS -> skip CNL2 links") +        elif 'cnl2_load' in self.html: +            try: +                (vcrypted, vjk) = self._getCipherParams() +                for (crypted, jk) in zip(vcrypted, vjk): +                    package_links.extend(self._getLinks(crypted, jk)) +            except Exception: +                self.fail(_("Unable to decrypt CNL2 links")) +        return package_links + + +    def _getCipherParams(self): +        # Get jk +        jk_re = r'<INPUT.*?NAME="%s".*?VALUE="(.*?)"' % LinkSaveIn._JK_KEY_ +        vjk = re.findall(jk_re, self.html) + +        # Get crypted +        crypted_re = r'<INPUT.*?NAME="%s".*?VALUE="(.*?)"' % LinkSaveIn._CRYPTED_KEY_ +        vcrypted = re.findall(crypted_re, self.html) + +        # Log and return +        self.logDebug("Detected %d crypted blocks" % len(vcrypted)) +        return vcrypted, vjk + + +    def _getLinks(self, crypted, jk): +        # Get key +        jreturn = self.js.eval("%s f()" % jk) +        self.logDebug("JsEngine returns value [%s]" % jreturn) +        key = binascii.unhexlify(jreturn) + +        # Decode crypted +        crypted = base64.standard_b64decode(crypted) + +        # Decrypt +        Key = key +        IV = key +        obj = AES.new(Key, AES.MODE_CBC, IV) +        text = obj.decrypt(crypted) + +        # Extract links +        text = text.replace("\x00", "").replace("\r", "") +        links = text.split("\n") +        links = filter(lambda x: x != "", links) + +        # Log and return +        self.logDebug("Package has %d links" % len(links)) +        return links diff --git a/pyload/plugin/crypter/LinkdecrypterCom.py b/pyload/plugin/crypter/LinkdecrypterCom.py new file mode 100644 index 000000000..349e8b2d3 --- /dev/null +++ b/pyload/plugin/crypter/LinkdecrypterCom.py @@ -0,0 +1,92 @@ +# -*- coding: utf-8 -*- + +import re +from pyload.plugin.Crypter import Crypter + + +class LinkdecrypterCom(Crypter): +    __name    = "LinkdecrypterCom" +    __type    = "crypter" +    __version = "0.27" + +    __pattern = r'^unmatchable$' +    __config  = [("use_subfolder", "bool", "Save package to subfolder", True), +                   ("subfolder_per_package", "bool", "Create a subfolder for each package", True)] + +    __description = """Linkdecrypter.com""" +    __license     = "GPLv3" +    __authors     = [("zoidberg", "zoidberg@mujmail.cz"), +                       ("flowlee", "")] + + +    TEXTAREA_PATTERN = r'<textarea name="links" wrap="off" readonly="1" class="caja_des">(.+)</textarea>' +    PASSWORD_PATTERN = r'<input type="text" name="password"' +    CAPTCHA_PATTERN = r'<img class="captcha" src="(.+?)"(.*?)>' +    REDIR_PATTERN = r'<i>(Click <a href="./">here</a> if your browser does not redirect you).</i>' + + +    def decrypt(self, pyfile): +        self.passwords = self.getPassword().splitlines() + +        # API not working anymore +        self.urls = self.decryptHTML() + + +    def decryptAPI(self): +        get_dict = {"t": "link", "url": self.pyfile.url, "lcache": "1"} +        self.html = self.load('http://linkdecrypter.com/api', get=get_dict) +        if self.html.startswith('http://'): +            return self.html.splitlines() + +        if self.html == 'INTERRUPTION(PASSWORD)': +            for get_dict['pass'] in self.passwords: +                self.html = self.load('http://linkdecrypter.com/api', get=get_dict) +                if self.html.startswith('http://'): +                    return self.html.splitlines() + +        self.logError("API", self.html) +        if self.html == 'INTERRUPTION(PASSWORD)': +            self.fail(_("No or incorrect password")) + +        return None + + +    def decryptHTML(self): +        retries = 5 + +        post_dict = {"link_cache": "on", "pro_links": self.pyfile.url, "modo_links": "text"} +        self.html = self.load('http://linkdecrypter.com/', post=post_dict, cookies=True, decode=True) + +        while self.passwords or retries: +            m = re.search(self.TEXTAREA_PATTERN, self.html, flags=re.S) +            if m: +                return [x for x in m.group(1).splitlines() if '[LINK-ERROR]' not in x] + +            m = re.search(self.CAPTCHA_PATTERN, self.html) +            if m: +                captcha_url = 'http://linkdecrypter.com/' + m.group(1) +                result_type = "positional" if "getPos" in m.group(2) else "textual" + +                m = re.search(r"<p><i><b>([^<]+)</b></i></p>", self.html) +                msg = m.group(1) if m else "" +                self.logInfo(_("Captcha protected link"), result_type, msg) + +                captcha = self.decryptCaptcha(captcha_url, result_type=result_type) +                if result_type == "positional": +                    captcha = "%d|%d" % captcha +                self.html = self.load('http://linkdecrypter.com/', post={"captcha": captcha}, decode=True) +                retries -= 1 + +            elif self.PASSWORD_PATTERN in self.html: +                if self.passwords: +                    password = self.passwords.pop(0) +                    self.logInfo(_("Password protected link, trying ") + password) +                    self.html = self.load('http://linkdecrypter.com/', post={'password': password}, decode=True) +                else: +                    self.fail(_("No or incorrect password")) + +            else: +                retries -= 1 +                self.html = self.load('http://linkdecrypter.com/', cookies=True, decode=True) + +        return None diff --git a/pyload/plugin/crypter/LixIn.py b/pyload/plugin/crypter/LixIn.py new file mode 100644 index 000000000..f992d38fd --- /dev/null +++ b/pyload/plugin/crypter/LixIn.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- + +import re + +from pyload.plugin.Crypter import Crypter + + +class LixIn(Crypter): +    __name    = "LixIn" +    __type    = "crypter" +    __version = "0.22" + +    __pattern = r'http://(?:www\.)?lix\.in/(?P<ID>.+)' +    __config  = [("use_subfolder", "bool", "Save package to subfolder", True), +                   ("subfolder_per_package", "bool", "Create a subfolder for each package", True)] + +    __description = """Lix.in decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("spoob", "spoob@pyload.org")] + + +    CAPTCHA_PATTERN = r'<img src="(?P<image>captcha_img\.php\?.*?)"' +    SUBMIT_PATTERN = r'value=\'continue.*?\'' +    LINK_PATTERN = r'name="ifram" src="(?P<link>.*?)"' + + +    def decrypt(self, pyfile): +        url = pyfile.url + +        m = re.match(self.__pattern, url) +        if m is None: +            self.error(_("Unable to identify file ID")) + +        id = m.group("ID") +        self.logDebug("File id is %s" % id) + +        self.html = self.load(url, decode=True) + +        m = re.search(self.SUBMIT_PATTERN, self.html) +        if m is None: +            self.error(_("Link doesn't seem valid")) + +        m = re.search(self.CAPTCHA_PATTERN, self.html) +        if m: +            for _i in xrange(5): +                m = re.search(self.CAPTCHA_PATTERN, self.html) +                if m: +                    self.logDebug("Trying captcha") +                    captcharesult = self.decryptCaptcha("http://lix.in/" + m.group("image")) +                self.html = self.load(url, decode=True, +                                          post={"capt": captcharesult, "submit": "submit", "tiny": id}) +            else: +                self.logDebug("No captcha/captcha solved") +        else: +            self.html = self.load(url, decode=True, post={"submit": "submit", "tiny": id}) + +        m = re.search(self.LINK_PATTERN, self.html) +        if m is None: +            self.error(_("Unable to find destination url")) +        else: +            self.urls = [m.group("link")] +            self.logDebug("Found link %s, adding to package" % self.urls[0]) diff --git a/pyload/plugin/crypter/LofCc.py b/pyload/plugin/crypter/LofCc.py new file mode 100644 index 000000000..f1f4d1680 --- /dev/null +++ b/pyload/plugin/crypter/LofCc.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- + +from pyload.plugin.internal.DeadCrypter import DeadCrypter, create_getInfo + + +class LofCc(DeadCrypter): +    __name    = "LofCc" +    __type    = "crypter" +    __version = "0.21" + +    __pattern = r'http://(?:www\.)?lof\.cc/(.*)' +    __config  = [] + +    __description = """Lof.cc decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("mkaay", "mkaay@mkaay.de")] + + +getInfo = create_getInfo(LofCc) diff --git a/pyload/plugin/crypter/MBLinkInfo.py b/pyload/plugin/crypter/MBLinkInfo.py new file mode 100644 index 000000000..64eb57167 --- /dev/null +++ b/pyload/plugin/crypter/MBLinkInfo.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- + +from pyload.plugin.internal.DeadCrypter import DeadCrypter, create_getInfo + + +class MBLinkInfo(DeadCrypter): +    __name    = "MBLinkInfo" +    __type    = "crypter" +    __version = "0.03" + +    __pattern = r'http://(?:www\.)?mblink\.info/?\?id=(\d+)' +    __config  = [] + +    __description = """MBLink.info decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("Gummibaer", "Gummibaer@wiki-bierkiste.de"), +                       ("stickell", "l.stickell@yahoo.it")] + + +getInfo = create_getInfo(MBLinkInfo) diff --git a/pyload/plugin/crypter/MediafireCom.py b/pyload/plugin/crypter/MediafireCom.py new file mode 100644 index 000000000..036c41233 --- /dev/null +++ b/pyload/plugin/crypter/MediafireCom.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- + +import re +from pyload.plugin.Crypter import Crypter +from pyload.plugin.hoster.MediafireCom import checkHTMLHeader +from pyload.utils import json_loads + + +class MediafireCom(Crypter): +    __name    = "MediafireCom" +    __type    = "crypter" +    __version = "0.14" + +    __pattern = r'http://(?:www\.)?mediafire\.com/(folder/|\?sharekey=|\?\w{13}($|[/#]))' +    __config  = [("use_subfolder", "bool", "Save package to subfolder", True), +                   ("subfolder_per_package", "bool", "Create a subfolder for each package", True)] + +    __description = """Mediafire.com folder decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("zoidberg", "zoidberg@mujmail.cz")] + + +    FOLDER_KEY_PATTERN = r'var afI= \'(\w+)' +    LINK_PATTERN = r'<meta property="og:url" content="http://www\.mediafire\.com/\?(\w+)"/>' + + +    def decrypt(self, pyfile): +        url, result = checkHTMLHeader(pyfile.url) +        self.logDebug("Location (%d): %s" % (result, url)) + +        if result == 0: +            # load and parse html +            html = self.load(pyfile.url) +            m = re.search(self.LINK_PATTERN, html) +            if m: +                # file page +                self.urls.append("http://www.mediafire.com/file/%s" % m.group(1)) +            else: +                # folder page +                m = re.search(self.FOLDER_KEY_PATTERN, html) +                if m: +                    folder_key = m.group(1) +                    self.logDebug("FOLDER KEY: %s" % folder_key) + +                    json_resp = json_loads(self.load("http://www.mediafire.com/api/folder/get_info.php", +                                                     get={'folder_key'     : folder_key, +                                                          'response_format': "json", +                                                          'version'        : 1})) +                    #self.logInfo(json_resp) +                    if json_resp['response']['result'] == "Success": +                        for link in json_resp['response']['folder_info']['files']: +                            self.urls.append("http://www.mediafire.com/file/%s" % link['quickkey']) +                    else: +                        self.fail(json_resp['response']['message']) +        elif result == 1: +            self.offline() +        else: +            self.urls.append(url) diff --git a/pyload/plugin/crypter/MegaRapidCz.py b/pyload/plugin/crypter/MegaRapidCz.py new file mode 100644 index 000000000..2cedfec09 --- /dev/null +++ b/pyload/plugin/crypter/MegaRapidCz.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- + +from pyload.plugin.internal.SimpleCrypter import SimpleCrypter + + +class MegaRapidCz(SimpleCrypter): +    __name    = "MegaRapidCz" +    __type    = "crypter" +    __version = "0.02" + +    __pattern = r'http://(?:www\.)?(share|mega)rapid\.cz/slozka/\d+/\w+' +    __config  = [("use_subfolder", "bool", "Save package to subfolder", True), +                   ("subfolder_per_package", "bool", "Create a subfolder for each package", True)] + +    __description = """Share-Rapid.com folder decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("zoidberg", "zoidberg@mujmail.cz")] + + +    LINK_PATTERN = r'<td class="soubor"[^>]*><a href="([^"]+)">' diff --git a/pyload/plugin/crypter/MegauploadCom.py b/pyload/plugin/crypter/MegauploadCom.py new file mode 100644 index 000000000..5a4b2349e --- /dev/null +++ b/pyload/plugin/crypter/MegauploadCom.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- + +from pyload.plugin.internal.DeadCrypter import DeadCrypter, create_getInfo + + +class MegauploadCom(DeadCrypter): +    __name    = "MegauploadCom" +    __type    = "crypter" +    __version = "0.02" + +    __pattern = r'http://(?:www\.)?megaupload\.com/(\?f|xml/folderfiles\.php\?.*&?folderid)=\w+' + +    __description = """Megaupload.com folder decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("zoidberg", "zoidberg@mujmail.cz")] + + +getInfo = create_getInfo(MegauploadCom) diff --git a/pyload/plugin/crypter/Movie2kTo.py b/pyload/plugin/crypter/Movie2kTo.py new file mode 100644 index 000000000..b481ead73 --- /dev/null +++ b/pyload/plugin/crypter/Movie2kTo.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- + +from pyload.plugin.internal.DeadCrypter import DeadCrypter, create_getInfo + + +class Movie2kTo(DeadCrypter): +    __name    = "Movie2kTo" +    __type    = "crypter" +    __version = "0.51" + +    __pattern = r'http://(?:www\.)?movie2k\.to/(.*)\.html' +    __config  = [] + +    __description = """Movie2k.to decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("4Christopher", "4Christopher@gmx.de")] + + +getInfo = create_getInfo(Movie2kTo) diff --git a/pyload/plugin/crypter/MultiUpOrg.py b/pyload/plugin/crypter/MultiUpOrg.py new file mode 100644 index 000000000..1b3116ad5 --- /dev/null +++ b/pyload/plugin/crypter/MultiUpOrg.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- + +import re +from urlparse import urljoin + +from pyload.plugin.internal.SimpleCrypter import SimpleCrypter + + +class MultiUpOrg(SimpleCrypter): +    __name    = "MultiUpOrg" +    __type    = "crypter" +    __version = "0.03" + +    __pattern = r'http://(?:www\.)?multiup\.org/(en|fr)/(?P<TYPE>project|download|miror)/\w+(/\w+)?' +    __config  = [("use_subfolder", "bool", "Save package to subfolder", True), +                   ("subfolder_per_package", "bool", "Create a subfolder for each package", True)] + +    __description = """MultiUp.org decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("Walter Purcaro", "vuolter@gmail.com")] + + +    NAME_PATTERN = r'<title>.*(?:Project|Projet|ownload|élécharger) (?P<N>.+?) (\(|- )' + + +    def getLinks(self): +        m_type = re.match(self.__pattern, self.pyfile.url).group("TYPE") + +        if m_type == "project": +            pattern = r'\n(http://www\.multiup\.org/(?:en|fr)/download/.*)' +        else: +            pattern = r'style="width:97%;text-align:left".*\n.*href="(.*)"' +            if m_type == "download": +                dl_pattern = r'href="(.*)">.*\n.*<h5>DOWNLOAD</h5>' +                miror_page = urljoin("http://www.multiup.org", re.search(dl_pattern, self.html).group(1)) +                self.html = self.load(miror_page) + +        return re.findall(pattern, self.html) diff --git a/pyload/plugin/crypter/MultiloadCz.py b/pyload/plugin/crypter/MultiloadCz.py new file mode 100644 index 000000000..a94c53d42 --- /dev/null +++ b/pyload/plugin/crypter/MultiloadCz.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- + +import re +from pyload.plugin.Crypter import Crypter + + +class MultiloadCz(Crypter): +    __name    = "MultiloadCz" +    __type    = "crypter" +    __version = "0.40" + +    __pattern = r'http://(?:[^/]*\.)?multiload\.cz/(stahnout|slozka)/.*' +    __config = [("use_subfolder", "bool", "Save package to subfolder", True), +                ("subfolder_per_package", "bool", "Create a subfolder for each package", True), +                ("usedHoster", "str", "Prefered hoster list (bar-separated)", ""), +                ("ignoredHoster", "str", "Ignored hoster list (bar-separated)", "")] + +    __description = """Multiload.cz decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("zoidberg", "zoidberg@mujmail.cz")] + + +    FOLDER_PATTERN = r'<form action="" method="get"><textarea[^>]*>([^>]*)</textarea></form>' +    LINK_PATTERN = r'<p class="manager-server"><strong>([^<]+)</strong></p><p class="manager-linky"><a href="([^"]+)">' + + +    def decrypt(self, pyfile): +        self.html = self.load(pyfile.url, decode=True) + +        if re.match(self.__pattern, pyfile.url).group(1) == "slozka": +            m = re.search(self.FOLDER_PATTERN, self.html) +            if m: +                self.urls.extend(m.group(1).split()) +        else: +            m = re.findall(self.LINK_PATTERN, self.html) +            if m: +                prefered_set = set(self.getConfig("usedHoster").split('|')) +                self.urls.extend([x[1] for x in m if x[0] in prefered_set]) + +                if not self.urls: +                    ignored_set = set(self.getConfig("ignoredHoster").split('|')) +                    self.urls.extend([x[1] for x in m if x[0] not in ignored_set]) diff --git a/pyload/plugin/crypter/MultiuploadCom.py b/pyload/plugin/crypter/MultiuploadCom.py new file mode 100644 index 000000000..44c449d72 --- /dev/null +++ b/pyload/plugin/crypter/MultiuploadCom.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- + +from pyload.plugin.internal.DeadCrypter import DeadCrypter, create_getInfo + + +class MultiuploadCom(DeadCrypter): +    __name    = "MultiuploadCom" +    __type    = "crypter" +    __version = "0.02" + +    __pattern = r'http://(?:www\.)?multiupload\.(com|nl)/\w+' + +    __description = """MultiUpload.com decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("zoidberg", "zoidberg@mujmail.cz")] + + +getInfo = create_getInfo(MultiuploadCom) diff --git a/pyload/plugin/crypter/NCryptIn.py b/pyload/plugin/crypter/NCryptIn.py new file mode 100644 index 000000000..22d8020f2 --- /dev/null +++ b/pyload/plugin/crypter/NCryptIn.py @@ -0,0 +1,315 @@ +# -*- coding: utf-8 -*- + +import base64 +import binascii +import re + +from Crypto.Cipher import AES + +from pyload.plugin.Crypter import Crypter +from pyload.plugin.internal.captcha import ReCaptcha + + +class NCryptIn(Crypter): +    __name    = "NCryptIn" +    __type    = "crypter" +    __version = "1.33" + +    __pattern = r'http://(?:www\.)?ncrypt\.in/(?P<type>folder|link|frame)-([^/\?]+)' +    __config  = [("use_subfolder", "bool", "Save package to subfolder", True), +                   ("subfolder_per_package", "bool", "Create a subfolder for each package", True)] + +    __description = """NCrypt.in decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("fragonib", "fragonib[AT]yahoo[DOT]es"), +                       ("stickell", "l.stickell@yahoo.it")] + + +    JK_KEY = "jk" +    CRYPTED_KEY = "crypted" + +    NAME_PATTERN = r'<meta name="description" content="(?P<N>[^"]+)"' + + +    def setup(self): +        self.package = None +        self.cleanedHtml = None +        self.links_source_order = ["cnl2", "rsdf", "ccf", "dlc", "web"] +        self.protection_type = None + + +    def decrypt(self, pyfile): +        # Init +        self.package = pyfile.package() +        package_links = [] +        package_name = self.package.name +        folder_name = self.package.folder + +        # Deal with single links +        if self.isSingleLink(): +            package_links.extend(self.handleSingleLink()) + +        # Deal with folders +        else: + +            # Request folder home +            self.html = self.requestFolderHome() +            self.cleanedHtml = self.removeHtmlCrap(self.html) +            if not self.isOnline(): +                self.offline() + +            # Check for folder protection +            if self.isProtected(): +                self.html = self.unlockProtection() +                self.cleanedHtml = self.removeHtmlCrap(self.html) +                self.handleErrors() + +            # Prepare package name and folder +            (package_name, folder_name) = self.getPackageInfo() + +            # Extract package links +            for link_source_type in self.links_source_order: +                package_links.extend(self.handleLinkSource(link_source_type)) +                if package_links:  # use only first source which provides links +                    break +            package_links = set(package_links) + +        # Pack and return links +        if package_links: +            self.packages = [(package_name, package_links, folder_name)] + + +    def isSingleLink(self): +        link_type = re.match(self.__pattern, self.pyfile.url).group('type') +        return link_type in ("link", "frame") + + +    def requestFolderHome(self): +        return self.load(self.pyfile.url, decode=True) + + +    def removeHtmlCrap(self, content): +        patterns = (r'(type="hidden".*?(name=".*?")?.*?value=".*?")', +                    r'display:none;">(.*?)</(div|span)>', +                    r'<div\s+class="jdownloader"(.*?)</div>', +                    r'<table class="global">(.*?)</table>', +                    r'<iframe\s+style="display:none(.*?)</iframe>') +        for pattern in patterns: +            rexpr = re.compile(pattern, re.S) +            content = re.sub(rexpr, "", content) +        return content + + +    def isOnline(self): +        if "Your folder does not exist" in self.cleanedHtml: +            self.logDebug("File not m") +            return False +        return True + + +    def isProtected(self): +        form = re.search(r'<form.*?name.*?protected.*?>(.*?)</form>', self.cleanedHtml, re.S) +        if form is not None: +            content = form.group(1) +            for keyword in ("password", "captcha"): +                if keyword in content: +                    self.protection_type = keyword +                    self.logDebug("Links are %s protected" % self.protection_type) +                    return True +        return False + + +    def getPackageInfo(self): +        m = re.search(self.NAME_PATTERN, self.html) +        if m: +            name = folder = m.group('N').strip() +            self.logDebug("Found name [%s] and folder [%s] in package info" % (name, folder)) +        else: +            name = self.package.name +            folder = self.package.folder +            self.logDebug("Package info not m, defaulting to pyfile name [%s] and folder [%s]" % (name, folder)) +        return name, folder + + +    def unlockProtection(self): +        postData = {} + +        form = re.search(r'<form name="protected"(.*?)</form>', self.cleanedHtml, re.S).group(1) + +        # Submit package password +        if "password" in form: +            password = self.getPassword() +            self.logDebug("Submitting password [%s] for protected links" % password) +            postData['password'] = password + +        # Resolve anicaptcha +        if "anicaptcha" in form: +            self.logDebug("Captcha protected") +            captchaUri = re.search(r'src="(/temp/anicaptcha/[^"]+)', form).group(1) +            captcha = self.decryptCaptcha("http://ncrypt.in" + captchaUri) +            self.logDebug("Captcha resolved [%s]" % captcha) +            postData['captcha'] = captcha + +        # Resolve recaptcha +        if "recaptcha" in form: +            self.logDebug("ReCaptcha protected") +            captcha_key = re.search(r'\?k=(.*?)"', form).group(1) +            self.logDebug("Resolving ReCaptcha with key [%s]" % captcha_key) +            recaptcha = ReCaptcha(self) +            challenge, response = recaptcha.challenge(captcha_key) +            postData['recaptcha_challenge_field'] = challenge +            postData['recaptcha_response_field']  = response + +        # Resolve circlecaptcha +        if "circlecaptcha" in form: +            self.logDebug("CircleCaptcha protected") +            captcha_img_url = "http://ncrypt.in/classes/captcha/circlecaptcha.php" +            coords = self.decryptCaptcha(captcha_img_url, forceUser=True, imgtype="png", result_type='positional') +            self.logDebug("Captcha resolved, coords [%s]" % str(coords)) +            postData['circle.x'] = coords[0] +            postData['circle.y'] = coords[1] + +        # Unlock protection +        postData['submit_protected'] = 'Continue to folder' +        return self.load(self.pyfile.url, post=postData, decode=True) + + +    def handleErrors(self): +        if self.protection_type == "password": +            if "This password is invalid!" in self.cleanedHtml: +                self.logDebug("Incorrect password, please set right password on 'Edit package' form and retry") +                self.fail(_("Incorrect password, please set right password on 'Edit package' form and retry")) + +        if self.protection_type == "captcha": +            if "The securitycheck was wrong!" in self.cleanedHtml: +                self.invalidCaptcha() +                self.retry() +            else: +                self.correctCaptcha() + + +    def handleLinkSource(self, link_source_type): +        # Check for JS engine +        require_js_engine = link_source_type in ("cnl2", "rsdf", "ccf", "dlc") +        if require_js_engine and not self.js: +            self.logDebug("No JS engine available, skip %s links" % link_source_type) +            return [] + +        # Select suitable handler +        if link_source_type == 'single': +            return self.handleSingleLink() +        if link_source_type == 'cnl2': +            return self.handleCNL2() +        elif link_source_type in ("rsdf", "ccf", "dlc"): +            return self.handleContainer(link_source_type) +        elif link_source_type == "web": +            return self.handleWebLinks() +        else: +            self.error('Unknown source type "%s" (this is probably a bug)' % link_source_type) + + +    def handleSingleLink(self): +        self.logDebug("Handling Single link") +        package_links = [] + +        # Decrypt single link +        decrypted_link = self.decryptLink(self.pyfile.url) +        if decrypted_link: +            package_links.append(decrypted_link) + +        return package_links + + +    def handleCNL2(self): +        self.logDebug("Handling CNL2 links") +        package_links = [] + +        if 'cnl2_output' in self.cleanedHtml: +            try: +                (vcrypted, vjk) = self._getCipherParams() +                for (crypted, jk) in zip(vcrypted, vjk): +                    package_links.extend(self._getLinks(crypted, jk)) +            except Exception: +                self.fail(_("Unable to decrypt CNL2 links")) + +        return package_links + + +    def handleContainers(self): +        self.logDebug("Handling Container links") +        package_links = [] + +        pattern = r'/container/(rsdf|dlc|ccf)/(\w+)' +        containersLinks = re.findall(pattern, self.html) +        self.logDebug("Decrypting %d Container links" % len(containersLinks)) +        for containerLink in containersLinks: +            link = "http://ncrypt.in/container/%s/%s.%s" % (containerLink[0], containerLink[1], containerLink[0]) +            package_links.append(link) + +        return package_links + + +    def handleWebLinks(self): +        self.logDebug("Handling Web links") +        pattern = r'(http://ncrypt\.in/link-.*?=)' +        links = re.findall(pattern, self.html) + +        package_links = [] +        self.logDebug("Decrypting %d Web links" % len(links)) +        for i, link in enumerate(links): +            self.logDebug("Decrypting Web link %d, %s" % (i + 1, link)) +            decrypted_link = self.decrypt(link) +            if decrypted_link: +                package_links.append(decrypted_link) + +        return package_links + + +    def decryptLink(self, link): +        try: +            url = link.replace("link-", "frame-") +            link = self.load(url, just_header=True)['location'] +            return link +        except Exception, detail: +            self.logDebug("Error decrypting link %s, %s" % (link, detail)) + + +    def _getCipherParams(self): +        pattern = r'<input.*?name="%s".*?value="(.*?)"' + +        # Get jk +        jk_re = pattern % NCryptIn.JK_KEY +        vjk = re.findall(jk_re, self.html) + +        # Get crypted +        crypted_re = pattern % NCryptIn.CRYPTED_KEY +        vcrypted = re.findall(crypted_re, self.html) + +        # Log and return +        self.logDebug("Detected %d crypted blocks" % len(vcrypted)) +        return vcrypted, vjk + + +    def _getLinks(self, crypted, jk): +        # Get key +        jreturn = self.js.eval("%s f()" % jk) +        self.logDebug("JsEngine returns value [%s]" % jreturn) +        key = binascii.unhexlify(jreturn) + +        # Decode crypted +        crypted = base64.standard_b64decode(crypted) + +        # Decrypt +        Key = key +        IV = key +        obj = AES.new(Key, AES.MODE_CBC, IV) +        text = obj.decrypt(crypted) + +        # Extract links +        text = text.replace("\x00", "").replace("\r", "") +        links = text.split("\n") +        links = filter(lambda x: x != "", links) + +        # Log and return +        self.logDebug("Block has %d links" % len(links)) +        return links diff --git a/pyload/plugin/crypter/NetfolderIn.py b/pyload/plugin/crypter/NetfolderIn.py new file mode 100644 index 000000000..279c99d94 --- /dev/null +++ b/pyload/plugin/crypter/NetfolderIn.py @@ -0,0 +1,70 @@ +# -*- coding: utf-8 -*- + +import re + +from pyload.plugin.internal.SimpleCrypter import SimpleCrypter + + +class NetfolderIn(SimpleCrypter): +    __name    = "NetfolderIn" +    __type    = "crypter" +    __version = "0.72" + +    __pattern = r'http://(?:www\.)?netfolder\.in/((?P<id1>\w+)/\w+|folder\.php\?folder_id=(?P<id2>\w+))' +    __config  = [("use_subfolder", "bool", "Save package to subfolder", True), +                   ("subfolder_per_package", "bool", "Create a subfolder for each package", True)] + +    __description = """NetFolder.in decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("RaNaN", "RaNaN@pyload.org"), +                       ("fragonib", "fragonib[AT]yahoo[DOT]es")] + + +    NAME_PATTERN = r'<div class="Text">Inhalt des Ordners <span.*>(?P<N>.+)</span></div>' + + +    def prepare(self): +        super(NetfolderIn, self).prepare() + +        # Check for password protection +        if self.isPasswordProtected(): +            self.html = self.submitPassword() +            if not self.html: +                self.fail(_("Incorrect password, please set right password on Add package form and retry")) + + +    def isPasswordProtected(self): +        if '<input type="password" name="password"' in self.html: +            self.logDebug("Links are password protected") +            return True +        return False + + +    def submitPassword(self): +        # Gather data +        try: +            m = re.match(self.__pattern, self.pyfile.url) +            id = max(m.group('id1'), m.group('id2')) +        except AttributeError: +            self.logDebug("Unable to get package id from url [%s]" % self.pyfile.url) +            return +        url = "http://netfolder.in/folder.php?folder_id=" + id +        password = self.getPassword() + +        # Submit package password +        post = {'password': password, 'save': 'Absenden'} +        self.logDebug("Submitting password [%s] for protected links with id [%s]" % (password, id)) +        html = self.load(url, {}, post) + +        # Check for invalid password +        if '<div class="InPage_Error">' in html: +            self.logDebug("Incorrect password, please set right password on Edit package form and retry") +            return None + +        return html + + +    def getLinks(self): +        links = re.search(r'name="list" value="(.*?)"', self.html).group(1).split(",") +        self.logDebug("Package has %d links" % len(links)) +        return links diff --git a/pyload/plugin/crypter/NosvideoCom.py b/pyload/plugin/crypter/NosvideoCom.py new file mode 100644 index 000000000..a9f29cf74 --- /dev/null +++ b/pyload/plugin/crypter/NosvideoCom.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- + +from pyload.plugin.internal.SimpleCrypter import SimpleCrypter + + +class NosvideoCom(SimpleCrypter): +    __name    = "NosvideoCom" +    __type    = "crypter" +    __version = "0.03" + +    __pattern = r'http://(?:www\.)?nosvideo\.com/\?v=\w+' +    __config  = [("use_subfolder", "bool", "Save package to subfolder", True), +                   ("subfolder_per_package", "bool", "Create a subfolder for each package", True)] + +    __description = """Nosvideo.com decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("igel", "igelkun@myopera.com")] + + +    LINK_PATTERN = r'href="(http://(?:w{3}\.)?nosupload\.com/\?d=\w+)"' +    NAME_PATTERN = r'<[tT]itle>Watch (?P<N>.+?)<' diff --git a/pyload/plugin/crypter/OneKhDe.py b/pyload/plugin/crypter/OneKhDe.py new file mode 100644 index 000000000..c3e5a6a3b --- /dev/null +++ b/pyload/plugin/crypter/OneKhDe.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- + +import re + +from pyload.utils import html_unescape +from pyload.plugin.Crypter import Crypter + + +class OneKhDe(Crypter): +    __name    = "OneKhDe" +    __type    = "crypter" +    __version = "0.10" + +    __pattern = r'http://(?:www\.)?1kh\.de/f/' +    __config  = [("use_subfolder", "bool", "Save package to subfolder", True), +                   ("subfolder_per_package", "bool", "Create a subfolder for each package", True)] + +    __description = """1kh.de decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("spoob", "spoob@pyload.org")] + + +    def __init__(self, parent): +        Crypter.__init__(self, parent) +        self.parent = parent + + +    def file_exists(self): +        """ returns True or False +        """ +        return True + + +    def proceed(self, url, location): +        url = self.parent.url +        self.html = self.load(url) +        link_ids = re.findall(r"<a id=\"DownloadLink_(\d*)\" href=\"http://1kh.de/", self.html) +        for id in link_ids: +            new_link = html_unescape(re.search("width=\"100%\" src=\"(.*)\"></iframe>", self.load("http://1kh.de/l/" + id)).group(1)) +            self.urls.append(new_link) diff --git a/pyload/plugin/crypter/OronCom.py b/pyload/plugin/crypter/OronCom.py new file mode 100644 index 000000000..24c941f19 --- /dev/null +++ b/pyload/plugin/crypter/OronCom.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- + +from pyload.plugin.internal.DeadCrypter import DeadCrypter, create_getInfo + + +class OronCom(DeadCrypter): +    __name    = "OronCom" +    __type    = "crypter" +    __version = "0.11" + +    __pattern = r'http://(?:www\.)?oron\.com/folder/\w+' +    __config  = [] + +    __description = """Oron.com folder decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("DHMH", "webmaster@pcProfil.de")] + + +getInfo = create_getInfo(OronCom) diff --git a/pyload/plugin/crypter/PastebinCom.py b/pyload/plugin/crypter/PastebinCom.py new file mode 100644 index 000000000..95c925733 --- /dev/null +++ b/pyload/plugin/crypter/PastebinCom.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- + +from pyload.plugin.internal.SimpleCrypter import SimpleCrypter + + +class PastebinCom(SimpleCrypter): +    __name    = "PastebinCom" +    __type    = "crypter" +    __version = "0.03" + +    __pattern = r'http://(?:www\.)?pastebin\.com/\w+' +    __config  = [("use_subfolder", "bool", "Save package to subfolder", True), +                   ("subfolder_per_package", "bool", "Create a subfolder for each package", True)] + +    __description = """Pastebin.com decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("stickell", "l.stickell@yahoo.it")] + + +    LINK_PATTERN = r'<div class="de\d+">(https?://[^ <]+)(?:[^<]*)</div>' +    NAME_PATTERN = r'<div class="paste_box_line1" title="(?P<N>[^"]+)">' diff --git a/pyload/plugin/crypter/QuickshareCz.py b/pyload/plugin/crypter/QuickshareCz.py new file mode 100644 index 000000000..5bb68c960 --- /dev/null +++ b/pyload/plugin/crypter/QuickshareCz.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- + +import re +from pyload.plugin.Crypter import Crypter + + +class QuickshareCz(Crypter): +    __name    = "QuickshareCz" +    __type    = "crypter" +    __version = "0.10" + +    __pattern = r'http://(?:www\.)?quickshare\.cz/slozka-\d+.*' +    __config  = [("use_subfolder", "bool", "Save package to subfolder", True), +                   ("subfolder_per_package", "bool", "Create a subfolder for each package", True)] + +    __description = """Quickshare.cz folder decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("zoidberg", "zoidberg@mujmail.cz")] + + +    FOLDER_PATTERN = r'<textarea[^>]*>(.*?)</textarea>' +    LINK_PATTERN = r'(http://www\.quickshare\.cz/\S+)' + + +    def decrypt(self, pyfile): +        html = self.load(pyfile.url) + +        m = re.search(self.FOLDER_PATTERN, html, re.S) +        if m is None: +            self.error(_("FOLDER_PATTERN not found")) +        self.urls.extend(re.findall(self.LINK_PATTERN, m.group(1))) diff --git a/pyload/plugin/crypter/RSLayerCom.py b/pyload/plugin/crypter/RSLayerCom.py new file mode 100644 index 000000000..934b3cac8 --- /dev/null +++ b/pyload/plugin/crypter/RSLayerCom.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- + +from pyload.plugin.internal.DeadCrypter import DeadCrypter, create_getInfo + + +class RSLayerCom(DeadCrypter): +    __name    = "RSLayerCom" +    __type    = "crypter" +    __version = "0.21" + +    __pattern = r'http://(?:www\.)?rs-layer\.com/directory-' +    __config  = [] + +    __description = """RS-Layer.com decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("hzpz", "")] + + +getInfo = create_getInfo(RSLayerCom) diff --git a/pyload/plugin/crypter/RapidfileshareNet.py b/pyload/plugin/crypter/RapidfileshareNet.py new file mode 100644 index 000000000..7003f017e --- /dev/null +++ b/pyload/plugin/crypter/RapidfileshareNet.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- + +from pyload.plugin.internal.XFSCrypter import XFSCrypter + + +class RapidfileshareNet(XFSCrypter): +    __name    = "RapidfileshareNet" +    __type    = "crypter" +    __version = "0.03" + +    __pattern = r'http://(?:www\.)?rapidfileshare\.net/users/\w+/\d+/\w+' +    __config  = [("use_subfolder", "bool", "Save package to subfolder", True), +                   ("subfolder_per_package", "bool", "Create a subfolder for each package", True)] + +    __description = """Rapidfileshare.net folder decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("guidobelix", "guidobelix@hotmail.it")] + + +    HOSTER_DOMAIN = "rapidfileshare.net" diff --git a/pyload/plugin/crypter/RelinkUs.py b/pyload/plugin/crypter/RelinkUs.py new file mode 100644 index 000000000..1773f6a22 --- /dev/null +++ b/pyload/plugin/crypter/RelinkUs.py @@ -0,0 +1,293 @@ +# -*- coding: utf-8 -*- + +from __future__ import with_statement + +import base64 +import binascii +import re +import os + +from Crypto.Cipher import AES +from pyload.plugin.Crypter import Crypter + + +class RelinkUs(Crypter): +    __name    = "RelinkUs" +    __type    = "crypter" +    __version = "3.11" + +    __pattern = r'http://(?:www\.)?relink\.us/(f/|((view|go)\.php\?id=))(?P<id>.+)' +    __config  = [("use_subfolder", "bool", "Save package to subfolder", True), +                   ("subfolder_per_package", "bool", "Create a subfolder for each package", True)] + +    __description = """Relink.us decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("fragonib", "fragonib[AT]yahoo[DOT]es"), +                       ("AndroKev", "neureither.kevin@gmail.com")] + + +    PREFERRED_LINK_SOURCES = ["cnl2", "dlc", "web"] + +    OFFLINE_TOKEN = r'<title>Tattooside' + +    PASSWORD_TOKEN = r'container_password.php' +    PASSWORD_ERROR_ROKEN = r'You have entered an incorrect password' +    PASSWORD_SUBMIT_URL = r'http://www.relink.us/container_password.php' + +    CAPTCHA_TOKEN = r'container_captcha.php' +    CAPTCHA_ERROR_ROKEN = r'You have solved the captcha wrong' +    CAPTCHA_IMG_URL = r'http://www.relink.us/core/captcha/circlecaptcha.php' +    CAPTCHA_SUBMIT_URL = r'http://www.relink.us/container_captcha.php' + +    FILE_TITLE_REGEX = r'<th>Title</th><td>(.*)</td></tr>' +    FILE_NOTITLE = r'No title' + +    CNL2_FORM_REGEX = r'<form id="cnl_form-(.*?)</form>' +    CNL2_FORMINPUT_REGEX = r'<input.*?name="%s".*?value="(.*?)"' +    CNL2_JK_KEY = "jk" +    CNL2_CRYPTED_KEY = "crypted" + +    DLC_LINK_REGEX = r'<a href=".*?" class="dlc_button" target="_blank">' +    DLC_DOWNLOAD_URL = r'http://www.relink.us/download.php' + +    WEB_FORWARD_REGEX = r'getFile\(\'(?P<link>.+)\'\)' +    WEB_FORWARD_URL = r'http://www.relink.us/frame.php' +    WEB_LINK_REGEX = r'<iframe name="Container" height="100%" frameborder="no" width="100%" src="(?P<link>.+)"></iframe>' + + +    def setup(self): +        self.fileid = None +        self.package = None +        self.password = None +        self.captcha = False + + +    def decrypt(self, pyfile): +        # Init +        self.initPackage(pyfile) + +        # Request package +        self.requestPackage() + +        # Check for online +        if not self.isOnline(): +            self.offline() + +        # Check for protection +        if self.isPasswordProtected(): +            self.unlockPasswordProtection() +            self.handleErrors() + +        if self.isCaptchaProtected(): +            self.captcha = True +            self.unlockCaptchaProtection() +            self.handleErrors() + +        # Get package name and folder +        (package_name, folder_name) = self.getPackageInfo() + +        # Extract package links +        package_links = [] +        for sources in self.PREFERRED_LINK_SOURCES: +            package_links.extend(self.handleLinkSource(sources)) +            if package_links:  # use only first source which provides links +                break +        package_links = set(package_links) + +        # Pack +        if package_links: +            self.packages = [(package_name, package_links, folder_name)] + + +    def initPackage(self, pyfile): +        self.fileid = re.match(self.__pattern, pyfile.url).group('id') +        self.package = pyfile.package() +        self.password = self.getPassword() + + +    def requestPackage(self): +        self.html = self.load(self.pyfile.url, decode=True) + + +    def isOnline(self): +        if self.OFFLINE_TOKEN in self.html: +            self.logDebug("File not found") +            return False +        return True + + +    def isPasswordProtected(self): +        if self.PASSWORD_TOKEN in self.html: +            self.logDebug("Links are password protected") +            return True + + +    def isCaptchaProtected(self): +        if self.CAPTCHA_TOKEN in self.html: +            self.logDebug("Links are captcha protected") +            return True +        return False + + +    def unlockPasswordProtection(self): +        self.logDebug("Submitting password [%s] for protected links" % self.password) +        passwd_url = self.PASSWORD_SUBMIT_URL + "?id=%s" % self.fileid +        passwd_data = {'id': self.fileid, 'password': self.password, 'pw': 'submit'} +        self.html = self.load(passwd_url, post=passwd_data, decode=True) + + +    def unlockCaptchaProtection(self): +        self.logDebug("Request user positional captcha resolving") +        captcha_img_url = self.CAPTCHA_IMG_URL + "?id=%s" % self.fileid +        coords = self.decryptCaptcha(captcha_img_url, forceUser=True, imgtype="png", result_type='positional') +        self.logDebug("Captcha resolved, coords [%s]" % str(coords)) +        captcha_post_url = self.CAPTCHA_SUBMIT_URL + "?id=%s" % self.fileid +        captcha_post_data = {'button.x': coords[0], 'button.y': coords[1], 'captcha': 'submit'} +        self.html = self.load(captcha_post_url, post=captcha_post_data, decode=True) + + +    def getPackageInfo(self): +        name = folder = None + +        # Try to get info from web +        m = re.search(self.FILE_TITLE_REGEX, self.html) +        if m is not None: +            title = m.group(1).strip() +            if not self.FILE_NOTITLE in title: +                name = folder = title +                self.logDebug("Found name [%s] and folder [%s] in package info" % (name, folder)) + +        # Fallback to defaults +        if not name or not folder: +            name = self.package.name +            folder = self.package.folder +            self.logDebug("Package info not found, defaulting to pyfile name [%s] and folder [%s]" % (name, folder)) + +        # Return package info +        return name, folder + + +    def handleErrors(self): +        if self.PASSWORD_ERROR_ROKEN in self.html: +            msg = "Incorrect password, please set right password on 'Edit package' form and retry" +            self.logDebug(msg) +            self.fail(_(msg)) + +        if self.captcha: +            if self.CAPTCHA_ERROR_ROKEN in self.html: +                self.invalidCaptcha() +                self.retry() +            else: +                self.correctCaptcha() + + +    def handleLinkSource(self, source): +        if source == 'cnl2': +            return self.handleCNL2Links() +        elif source == 'dlc': +            return self.handleDLCLinks() +        elif source == 'web': +            return self.handleWEBLinks() +        else: +            self.error('Unknown source type "%s" (this is probably a bug)' % source) + + +    def handleCNL2Links(self): +        self.logDebug("Search for CNL2 links") +        package_links = [] +        m = re.search(self.CNL2_FORM_REGEX, self.html, re.S) +        if m is not None: +            cnl2_form = m.group(1) +            try: +                (vcrypted, vjk) = self._getCipherParams(cnl2_form) +                for (crypted, jk) in zip(vcrypted, vjk): +                    package_links.extend(self._getLinks(crypted, jk)) +            except Exception: +                self.logDebug("Unable to decrypt CNL2 links") +        return package_links + + +    def handleDLCLinks(self): +        self.logDebug("Search for DLC links") +        package_links = [] +        m = re.search(self.DLC_LINK_REGEX, self.html) +        if m is not None: +            container_url = self.DLC_DOWNLOAD_URL + "?id=%s&dlc=1" % self.fileid +            self.logDebug("Downloading DLC container link [%s]" % container_url) +            try: +                dlc = self.load(container_url) +                dlc_filename = self.fileid + ".dlc" +                dlc_filepath = os.path.join(self.config['general']['download_folder'], dlc_filename) +                with open(dlc_filepath, "wb") as f: +                    f.write(dlc) +                package_links.append(dlc_filepath) +            except Exception: +                self.fail("Unable to download DLC container") +        return package_links + + +    def handleWEBLinks(self): +        self.logDebug("Search for WEB links") + +        package_links = [] +        params        = re.findall(self.WEB_FORWARD_REGEX, self.html) + +        self.logDebug("Decrypting %d Web links" % len(params)) + +        for index, param in enumerate(params): +            try: +                url = self.WEB_FORWARD_URL + "?%s" % param + +                self.logDebug("Decrypting Web link %d, %s" % (index + 1, url)) + +                res  = self.load(url, decode=True) +                link = re.search(self.WEB_LINK_REGEX, res).group('link') + +                package_links.append(link) + +            except Exception, detail: +                self.logDebug("Error decrypting Web link %s, %s" % (index, detail)) + +            self.setWait(4) +            self.wait() + +        return package_links + + +    def _getCipherParams(self, cnl2_form): +        # Get jk +        jk_re = self.CNL2_FORMINPUT_REGEX % self.CNL2_JK_KEY +        vjk = re.findall(jk_re, cnl2_form, re.I) + +        # Get crypted +        crypted_re = self.CNL2_FORMINPUT_REGEX % RelinkUs.CNL2_CRYPTED_KEY +        vcrypted = re.findall(crypted_re, cnl2_form, re.I) + +        # Log and return +        self.logDebug("Detected %d crypted blocks" % len(vcrypted)) +        return vcrypted, vjk + + +    def _getLinks(self, crypted, jk): +        # Get key +        jreturn = self.js.eval("%s f()" % jk) +        self.logDebug("JsEngine returns value [%s]" % jreturn) +        key = binascii.unhexlify(jreturn) + +        # Decode crypted +        crypted = base64.standard_b64decode(crypted) + +        # Decrypt +        Key = key +        IV = key +        obj = AES.new(Key, AES.MODE_CBC, IV) +        text = obj.decrypt(crypted) + +        # Extract links +        text = text.replace("\x00", "").replace("\r", "") +        links = text.split("\n") +        links = filter(lambda x: x != "", links) + +        # Log and return +        self.logDebug("Package has %d links" % len(links)) +        return links diff --git a/pyload/plugin/crypter/SafelinkingNet.py b/pyload/plugin/crypter/SafelinkingNet.py new file mode 100644 index 000000000..1b5eeeb63 --- /dev/null +++ b/pyload/plugin/crypter/SafelinkingNet.py @@ -0,0 +1,79 @@ +# -*- coding: utf-8 -*- + +import re + +from BeautifulSoup import BeautifulSoup + +from pyload.utils import json_loads +from pyload.plugin.Crypter import Crypter +from pyload.plugin.internal.captcha import SolveMedia + + +class SafelinkingNet(Crypter): +    __name    = "SafelinkingNet" +    __type    = "crypter" +    __version = "0.11" + +    __pattern = r'https?://(?:www\.)?safelinking\.net/([pd])/\w+' +    __config  = [("use_subfolder", "bool", "Save package to subfolder", True), +                   ("subfolder_per_package", "bool", "Create a subfolder for each package", True)] + +    __description = """Safelinking.net decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("quareevo", "quareevo@arcor.de")] + + +    SOLVEMEDIA_PATTERN = "solvemediaApiKey = '([\w.-]+)';" + + +    def decrypt(self, pyfile): +        url = pyfile.url + +        if re.match(self.__pattern, url).group(1) == "d": + +            header = self.load(url, just_header=True) +            if 'location' in header: +                self.urls = [header['location']] +            else: +                self.error(_("Couldn't find forwarded Link")) + +        else: +            postData = {"post-protect": "1"} + +            if "link-password" in self.html: +                postData['link-password'] = self.getPassword() + +            if "altcaptcha" in self.html: +                for _i in xrange(5): +                    m = re.search(self.SOLVEMEDIA_PATTERN, self.html) +                    if m: +                        captchaKey = m.group(1) +                        captcha = SolveMedia(self) +                        captchaProvider = "Solvemedia" +                    else: +                        self.fail(_("Error parsing captcha")) + +                    challenge, response = captcha.challenge(captchaKey) +                    postData['adcopy_challenge'] = challenge +                    postData['adcopy_response']  = response + +                    self.html = self.load(url, post=postData) +                    if "The password you entered was incorrect" in self.html: +                        self.fail(_("Incorrect Password")) +                    if not "The CAPTCHA code you entered was wrong" in self.html: +                        break + +            pyfile.package().password = "" +            soup = BeautifulSoup(self.html) +            scripts = soup.findAll("script") +            for s in scripts: +                if "d_links" in s.text: +                    break +            m = re.search('d_links":(\[.*?\])', s.text) +            if m: +                linkDict = json_loads(m.group(1)) +                for link in linkDict: +                    if not "http://" in link['full']: +                        self.urls.append("https://safelinking.net/d/" + link['full']) +                    else: +                        self.urls.append(link['full']) diff --git a/pyload/plugin/crypter/SecuredIn.py b/pyload/plugin/crypter/SecuredIn.py new file mode 100644 index 000000000..a5e12a352 --- /dev/null +++ b/pyload/plugin/crypter/SecuredIn.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- + +from pyload.plugin.internal.DeadCrypter import DeadCrypter, create_getInfo + + +class SecuredIn(DeadCrypter): +    __name    = "SecuredIn" +    __type    = "crypter" +    __version = "0.21" + +    __pattern = r'http://(?:www\.)?secured\.in/download-[\d]+-\w{8}\.html' +    __config  = [] + +    __description = """Secured.in decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("mkaay", "mkaay@mkaay.de")] + + +getInfo = create_getInfo(SecuredIn) diff --git a/pyload/plugin/crypter/SexuriaCom.py b/pyload/plugin/crypter/SexuriaCom.py new file mode 100644 index 000000000..08f289541 --- /dev/null +++ b/pyload/plugin/crypter/SexuriaCom.py @@ -0,0 +1,94 @@ +# -*- coding: utf-8 -*- + +import re + +from pyload.plugin.Crypter import Crypter + + +class SexuriaCom(Crypter): +    __name    = "SexuriaCom" +    __type    = "crypter" +    __version = "0.01" + +    __pattern = r'http://(?:www\.)?sexuria\.com/(v1/)?(Pornos_Kostenlos_.+?_(\d+)\.html|dl_links_\d+_\d+\.html|id=\d+\&part=\d+\&link=\d+)' +    __config  = [("use_subfolder", "bool", "Save package to subfolder", True), +                   ("subfolder_per_package", "bool", "Create a subfolder for each package", True)] + +    __description = """Sexuria.com decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("NETHead", "NETHead.AT.gmx.DOT.net")] + + +    PATTERN_SUPPORTED_MAIN     = re.compile(r'http://(www\.)?sexuria\.com/(v1/)?Pornos_Kostenlos_.+?_(\d+)\.html', flags=re.I) +    PATTERN_SUPPORTED_CRYPT    = re.compile(r'http://(www\.)?sexuria\.com/(v1/)?dl_links_\d+_(?P<ID>\d+)\.html', flags=re.I) +    PATTERN_SUPPORTED_REDIRECT = re.compile(r'http://(www\.)?sexuria\.com/out\.php\?id=(?P<ID>\d+)\&part=\d+\&link=\d+', flags=re.I) +    PATTERN_TITLE              = re.compile(r'<title> - (?P<TITLE>.*) Sexuria - Kostenlose Pornos - Rapidshare XXX Porn</title>', flags=re.I) +    PATTERN_PASSWORD           = re.compile(r'<strong>Passwort: </strong></div></td>.*?bgcolor="#EFEFEF">(?P<PWD>.*?)</td>', flags=re.I | re.S) +    PATTERN_DL_LINK_PAGE       = re.compile(r'"(dl_links_\d+_\d+\.html)"', flags=re.I) +    PATTERN_REDIRECT_LINKS     = re.compile(r'value="(http://sexuria\.com/out\.php\?id=\d+\&part=\d+\&link=\d+)" readonly', flags=re.I) + + +    def decrypt(self, pyfile): +        # Init +        self.pyfile = pyfile +        self.package = pyfile.package() + +        # Get package links +        package_name, self.links, folder_name, package_pwd = self.decryptLinks(self.pyfile.url) +        self.packages = [(package_name, self.links, folder_name)] + + +    def decryptLinks(self, url): +        linklist = [] +        name = self.package.name +        folder = self.package.folder +        password = None + +        if re.match(self.PATTERN_SUPPORTED_MAIN, url): +            # Processing main page +            html = self.load(url) +            links = re.findall(self.PATTERN_DL_LINK_PAGE, html) +            for link in links: +                linklist.append("http://sexuria.com/v1/" + link) + +        elif re.match(self.PATTERN_SUPPORTED_REDIRECT, url): +            # Processing direct redirect link (out.php), redirecting to main page +            id = re.search(self.PATTERN_SUPPORTED_REDIRECT, url).group('ID') +            if id: +                linklist.append("http://sexuria.com/v1/Pornos_Kostenlos_liebe_%s.html" % id) + +        elif re.match(self.PATTERN_SUPPORTED_CRYPT, url): +            # Extract info from main file +            id = re.search(self.PATTERN_SUPPORTED_CRYPT, url).group('ID') +            html = self.load("http://sexuria.com/v1/Pornos_Kostenlos_info_%s.html" % id, decode=True) + +            title = re.search(self.PATTERN_TITLE, html).group('TITLE').strip() +            if title: +                name = folder = title +                self.logDebug("Package info found, name [%s] and folder [%s]" % (name, folder)) + +            pwd = re.search(self.PATTERN_PASSWORD, html).group('PWD') +            if pwd: +                password = pwd.strip() +                self.logDebug("Password info [%s] found" % password) + +            # Process link (dl_link) +            html = self.load(url) +            links = re.findall(self.PATTERN_REDIRECT_LINKS, html) +            if len(links) == 0: +                self.LogError("Broken for link %s" % link) +            else: +                for link in links: +                    link = link.replace("http://sexuria.com/", "http://www.sexuria.com/") +                    finallink = self.load(link, just_header=True)['location'] +                    if not finallink or "sexuria.com/" in finallink: +                        self.LogError("Broken for link %s" % link) +                    else: +                        linklist.append(finallink) + +        # Debug log +        self.logDebug("%d supported links" % len(linklist)) +        for i, link in enumerate(linklist): +            self.logDebug("Supported link %d, %s" % (i + 1, link)) + +        return name, linklist, folder, password diff --git a/pyload/plugin/crypter/ShareLinksBiz.py b/pyload/plugin/crypter/ShareLinksBiz.py new file mode 100644 index 000000000..b3f8f8b75 --- /dev/null +++ b/pyload/plugin/crypter/ShareLinksBiz.py @@ -0,0 +1,286 @@ +# -*- coding: utf-8 -*- + +import base64 +import binascii +import re + +from Crypto.Cipher import AES +from pyload.plugin.Crypter import Crypter + + +class ShareLinksBiz(Crypter): +    __name    = "ShareLinksBiz" +    __type    = "crypter" +    __version = "1.14" + +    __pattern = r'http://(?:www\.)?(share-links|s2l)\.biz/(?P<ID>_?\w+)' +    __config  = [("use_subfolder", "bool", "Save package to subfolder", True), +                   ("subfolder_per_package", "bool", "Create a subfolder for each package", True)] + +    __description = """Share-Links.biz decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("fragonib", "fragonib[AT]yahoo[DOT]es")] + + +    def setup(self): +        self.baseUrl = None +        self.fileId = None +        self.package = None +        self.captcha = False + + +    def decrypt(self, pyfile): +        # Init +        self.initFile(pyfile) + +        # Request package +        url = self.baseUrl + '/' + self.fileId +        self.html = self.load(url, decode=True) + +        # Unblock server (load all images) +        self.unblockServer() + +        # Check for protection +        if self.isPasswordProtected(): +            self.unlockPasswordProtection() +            self.handleErrors() + +        if self.isCaptchaProtected(): +            self.captcha = True +            self.unlockCaptchaProtection() +            self.handleErrors() + +        # Extract package links +        package_links = [] +        package_links.extend(self.handleWebLinks()) +        package_links.extend(self.handleContainers()) +        package_links.extend(self.handleCNL2()) +        package_links = set(package_links) + +        # Get package info +        package_name, package_folder = self.getPackageInfo() + +        # Pack +        self.packages = [(package_name, package_links, package_folder)] + + +    def initFile(self, pyfile): +        url = pyfile.url +        if 's2l.biz' in url: +            url = self.load(url, just_header=True)['location'] +        self.baseUrl = "http://www.%s.biz" % re.match(self.__pattern, url).group(1) +        self.fileId = re.match(self.__pattern, url).group('ID') +        self.package = pyfile.package() + + +    def isOnline(self): +        if "No usable content was found" in self.html: +            self.logDebug("File not found") +            return False +        return True + + +    def isPasswordProtected(self): +        if re.search(r'''<form.*?id="passwordForm".*?>''', self.html): +            self.logDebug("Links are protected") +            return True +        return False + + +    def isCaptchaProtected(self): +        if '<map id="captchamap"' in self.html: +            self.logDebug("Links are captcha protected") +            return True +        return False + + +    def unblockServer(self): +        imgs = re.findall(r"(/template/images/.*?\.gif)", self.html) +        for img in imgs: +            self.load(self.baseUrl + img) + + +    def unlockPasswordProtection(self): +        password = self.getPassword() +        self.logDebug("Submitting password [%s] for protected links" % password) +        post = {"password": password, 'login': 'Submit form'} +        url = self.baseUrl + '/' + self.fileId +        self.html = self.load(url, post=post, decode=True) + + +    def unlockCaptchaProtection(self): +        # Get captcha map +        captchaMap = self._getCaptchaMap() +        self.logDebug("Captcha map with [%d] positions" % len(captchaMap.keys())) + +        # Request user for captcha coords +        m = re.search(r'<img src="/captcha.gif\?d=(.*?)&PHPSESSID=(.*?)&legend=1"', self.html) +        captchaUrl = self.baseUrl + '/captcha.gif?d=%s&PHPSESSID=%s' % (m.group(1), m.group(2)) +        self.logDebug("Waiting user for correct position") +        coords = self.decryptCaptcha(captchaUrl, forceUser=True, imgtype="gif", result_type='positional') +        self.logDebug("Captcha resolved, coords [%s]" % str(coords)) + +        # Resolve captcha +        href = self._resolveCoords(coords, captchaMap) +        if href is None: +            self.invalidCaptcha() +            self.retry(wait_time=5) +        url = self.baseUrl + href +        self.html = self.load(url, decode=True) + + +    def _getCaptchaMap(self): +        mapp = {} +        for m in re.finditer(r'<area shape="rect" coords="(.*?)" href="(.*?)"', self.html): +            rect = eval('(' + m.group(1) + ')') +            href = m.group(2) +            mapp[rect] = href +        return mapp + + +    def _resolveCoords(self, coords, captchaMap): +        x, y = coords +        for rect, href in captchaMap.iteritems(): +            x1, y1, x2, y2 = rect +            if (x >= x1 and x <= x2) and (y >= y1 and y <= y2): +                return href + + +    def handleErrors(self): +        if "The inserted password was wrong" in self.html: +            self.logDebug("Incorrect password, please set right password on 'Edit package' form and retry") +            self.fail(_("Incorrect password, please set right password on 'Edit package' form and retry")) + +        if self.captcha: +            if "Your choice was wrong" in self.html: +                self.invalidCaptcha() +                self.retry(wait_time=5) +            else: +                self.correctCaptcha() + + +    def getPackageInfo(self): +        name = folder = None + +        # Extract from web package header +        title_re = r'<h2><img.*?/>(.*)</h2>' +        m = re.search(title_re, self.html, re.S) +        if m is not None: +            title = m.group(1).strip() +            if 'unnamed' not in title: +                name = folder = title +                self.logDebug("Found name [%s] and folder [%s] in package info" % (name, folder)) + +        # Fallback to defaults +        if not name or not folder: +            name = self.package.name +            folder = self.package.folder +            self.logDebug("Package info not found, defaulting to pyfile name [%s] and folder [%s]" % (name, folder)) + +        # Return package info +        return name, folder + + +    def handleWebLinks(self): +        package_links = [] +        self.logDebug("Handling Web links") + +        #@TODO: Gather paginated web links +        pattern = r'javascript:_get\(\'(.*?)\', \d+, \'\'\)' +        ids = re.findall(pattern, self.html) +        self.logDebug("Decrypting %d Web links" % len(ids)) +        for i, ID in enumerate(ids): +            try: +                self.logDebug("Decrypting Web link %d, [%s]" % (i + 1, ID)) + +                dwLink = self.baseUrl + "/get/lnk/" + ID +                res = self.load(dwLink) + +                code = re.search(r'frm/(\d+)', res).group(1) +                fwLink = self.baseUrl + "/get/frm/" + code +                res = self.load(fwLink) + +                jscode = re.search(r'<script language="javascript">\s*eval\((.*)\)\s*</script>', res, re.S).group(1) +                jscode = self.js.eval("f = %s" % jscode) +                jslauncher = "window=''; parent={frames:{Main:{location:{href:''}}},location:''}; %s; parent.frames.Main.location.href" + +                dlLink = self.js.eval(jslauncher % jscode) + +                self.logDebug("JsEngine returns value [%s] for redirection link" % dlLink) + +                package_links.append(dlLink) +            except Exception, detail: +                self.logDebug("Error decrypting Web link [%s], %s" % (ID, detail)) +        return package_links + + +    def handleContainers(self): +        package_links = [] +        self.logDebug("Handling Container links") + +        pattern = r'javascript:_get\(\'(.*?)\', 0, \'(rsdf|ccf|dlc)\'\)' +        containersLinks = re.findall(pattern, self.html) +        self.logDebug("Decrypting %d Container links" % len(containersLinks)) +        for containerLink in containersLinks: +            link = "%s/get/%s/%s" % (self.baseUrl, containerLink[1], containerLink[0]) +            package_links.append(link) +        return package_links + + +    def handleCNL2(self): +        package_links = [] +        self.logDebug("Handling CNL2 links") + +        if '/lib/cnl2/ClicknLoad.swf' in self.html: +            try: +                (crypted, jk) = self._getCipherParams() +                package_links.extend(self._getLinks(crypted, jk)) +            except Exception: +                self.fail(_("Unable to decrypt CNL2 links")) +        return package_links + + +    def _getCipherParams(self): +        # Request CNL2 +        code   = re.search(r'ClicknLoad.swf\?code=(.*?)"', self.html).group(1) +        url    = "%s/get/cnl2/%s" % (self.baseUrl, code) +        res    = self.load(url) +        params = res.split(";;") + +        # Get jk +        strlist = list(base64.standard_b64decode(params[1])) +        strlist.reverse() +        jk = ''.join(strlist) + +        # Get crypted +        strlist = list(base64.standard_b64decode(params[2])) +        strlist.reverse() +        crypted = ''.join(strlist) + +        # Log and return +        return crypted, jk + + +    def _getLinks(self, crypted, jk): +        # Get key +        jreturn = self.js.eval("%s f()" % jk) +        self.logDebug("JsEngine returns value [%s]" % jreturn) +        key = binascii.unhexlify(jreturn) + +        # Decode crypted +        crypted = base64.standard_b64decode(crypted) + +        # Decrypt +        Key = key +        IV = key +        obj = AES.new(Key, AES.MODE_CBC, IV) +        text = obj.decrypt(crypted) + +        # Extract links +        text = text.replace("\x00", "").replace("\r", "") +        links = text.split("\n") +        links = filter(lambda x: x != "", links) + +        # Log and return +        self.logDebug("Block has %d links" % len(links)) +        return links diff --git a/pyload/plugin/crypter/SharingmatrixCom.py b/pyload/plugin/crypter/SharingmatrixCom.py new file mode 100644 index 000000000..53f1afa32 --- /dev/null +++ b/pyload/plugin/crypter/SharingmatrixCom.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- + +from pyload.plugin.internal.DeadCrypter import DeadCrypter, create_getInfo + + +class SharingmatrixCom(DeadCrypter): +    __name    = "SharingmatrixCom" +    __type    = "crypter" +    __version = "0.01" + +    __pattern = r'http://(?:www\.)?sharingmatrix\.com/folder/\w+' + +    __description = """Sharingmatrix.com folder decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("zoidberg", "zoidberg@mujmail.cz")] + + +getInfo = create_getInfo(SharingmatrixCom) diff --git a/pyload/plugin/crypter/SpeedLoadOrg.py b/pyload/plugin/crypter/SpeedLoadOrg.py new file mode 100644 index 000000000..e40d321be --- /dev/null +++ b/pyload/plugin/crypter/SpeedLoadOrg.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- + +from pyload.plugin.internal.DeadCrypter import DeadCrypter, create_getInfo + + +class SpeedLoadOrg(DeadCrypter): +    __name    = "SpeedLoadOrg" +    __type    = "crypter" +    __version = "0.30" + +    __pattern = r'http://(?:www\.)?speedload\.org/(\d+~f$|folder/\d+/)' +    __config  = [] + +    __description = """Speedload decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("stickell", "l.stickell@yahoo.it")] + + +getInfo = create_getInfo(SpeedLoadOrg) diff --git a/pyload/plugin/crypter/StealthTo.py b/pyload/plugin/crypter/StealthTo.py new file mode 100644 index 000000000..0d05c3c64 --- /dev/null +++ b/pyload/plugin/crypter/StealthTo.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- + +from pyload.plugin.internal.DeadCrypter import DeadCrypter, create_getInfo + + +class StealthTo(DeadCrypter): +    __name    = "StealthTo" +    __type    = "crypter" +    __version = "0.20" + +    __pattern = r'http://(?:www\.)?stealth\.to/folder/.+' +    __config  = [] + +    __description = """Stealth.to decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("spoob", "spoob@pyload.org")] + + +getInfo = create_getInfo(StealthTo) diff --git a/pyload/plugin/crypter/TnyCz.py b/pyload/plugin/crypter/TnyCz.py new file mode 100644 index 000000000..19427b845 --- /dev/null +++ b/pyload/plugin/crypter/TnyCz.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- + +from pyload.plugin.internal.SimpleCrypter import SimpleCrypter + +import re + + +class TnyCz(SimpleCrypter): +    __name    = "TnyCz" +    __type    = "crypter" +    __version = "0.03" + +    __pattern = r'http://(?:www\.)?tny\.cz/\w+' +    __config  = [("use_subfolder", "bool", "Save package to subfolder", True), +                   ("subfolder_per_package", "bool", "Create a subfolder for each package", True)] + +    __description = """Tny.cz decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("Walter Purcaro", "vuolter@gmail.com")] + + +    NAME_PATTERN = r'<title>(?P<N>.+) - .+</title>' + + +    def getLinks(self): +        m = re.search(r'<a id=\'save_paste\' href="(.+save\.php\?hash=.+)">', self.html) +        return re.findall(".+", self.load(m.group(1), decode=True)) if m else None diff --git a/pyload/plugin/crypter/TrailerzoneInfo.py b/pyload/plugin/crypter/TrailerzoneInfo.py new file mode 100644 index 000000000..106524f1c --- /dev/null +++ b/pyload/plugin/crypter/TrailerzoneInfo.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- + +from pyload.plugin.internal.DeadCrypter import DeadCrypter, create_getInfo + + +class TrailerzoneInfo(DeadCrypter): +    __name    = "TrailerzoneInfo" +    __type    = "crypter" +    __version = "0.03" + +    __pattern = r'http://(?:www\.)?trailerzone\.info/.*?' +    __config  = [] + +    __description = """TrailerZone.info decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("godofdream", "soilfiction@gmail.com")] + + +getInfo = create_getInfo(TrailerzoneInfo) diff --git a/pyload/plugin/crypter/TurbobitNet.py b/pyload/plugin/crypter/TurbobitNet.py new file mode 100644 index 000000000..0ea49c694 --- /dev/null +++ b/pyload/plugin/crypter/TurbobitNet.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- + +import re + +from pyload.plugin.internal.SimpleCrypter import SimpleCrypter +from pyload.utils import json_loads + + +class TurbobitNet(SimpleCrypter): +    __name    = "TurbobitNet" +    __type    = "crypter" +    __version = "0.05" + +    __pattern = r'http://(?:www\.)?turbobit\.net/download/folder/(?P<ID>\w+)' +    __config  = [("use_subfolder", "bool", "Save package to subfolder", True), +                   ("subfolder_per_package", "bool", "Create a subfolder for each package", True)] + +    __description = """Turbobit.net folder decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("stickell", "l.stickell@yahoo.it"), +                       ("Walter Purcaro", "vuolter@gmail.com")] + + +    NAME_PATTERN = r'src=\'/js/lib/grid/icon/folder.png\'> <span>(?P<N>.+?)</span>' + + +    def _getLinks(self, id, page=1): +        gridFile = self.load("http://turbobit.net/downloadfolder/gridFile", +                             get={"rootId": id, "rows": 200, "page": page}, decode=True) +        grid = json_loads(gridFile) + +        if grid['rows']: +            for i in grid['rows']: +                yield i['id'] +            for id in self._getLinks(id, page + 1): +                yield id +        else: +            return + + +    def getLinks(self): +        id = re.match(self.__pattern, self.pyfile.url).group("ID") +        fixurl = lambda id: "http://turbobit.net/%s.html" % id +        return map(fixurl, self._getLinks(id)) diff --git a/pyload/plugin/crypter/TusfilesNet.py b/pyload/plugin/crypter/TusfilesNet.py new file mode 100644 index 000000000..55b9c5deb --- /dev/null +++ b/pyload/plugin/crypter/TusfilesNet.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- + +import math +import re +from urlparse import urljoin + +from pyload.plugin.internal.XFSCrypter import XFSCrypter + + +class TusfilesNet(XFSCrypter): +    __name    = "TusfilesNet" +    __type    = "crypter" +    __version = "0.07" + +    __pattern = r'https?://(?:www\.)?tusfiles\.net/go/(?P<ID>\w+)' +    __config  = [("use_subfolder", "bool", "Save package to subfolder", True), +                   ("subfolder_per_package", "bool", "Create a subfolder for each package", True)] + +    __description = """Tusfiles.net folder decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("Walter Purcaro", "vuolter@gmail.com"), +                       ("stickell", "l.stickell@yahoo.it")] + + +    HOSTER_DOMAIN = "tusfiles.net" + +    PAGES_PATTERN = r'>\((\d+) \w+\)<' + +    URL_REPLACEMENTS = [(__pattern + ".*", r'https://www.tusfiles.net/go/\g<ID>/')] + + +    def loadPage(self, page_n): +        return self.load(urljoin(self.pyfile.url, str(page_n)), decode=True) + + +    def handleMultiPages(self): +        pages = re.search(self.PAGES_PATTERN, self.html) +        if pages: +            pages = int(math.ceil(int(pages.group('pages')) / 25.0)) +        else: +            return + +        for p in xrange(2, pages + 1): +            self.html = self.loadPage(p) +            self.links += self.getLinks() diff --git a/pyload/plugin/crypter/UlozTo.py b/pyload/plugin/crypter/UlozTo.py new file mode 100644 index 000000000..d886c9d08 --- /dev/null +++ b/pyload/plugin/crypter/UlozTo.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- + +import re +from pyload.plugin.Crypter import Crypter + + +class UlozTo(Crypter): +    __name    = "UlozTo" +    __type    = "crypter" +    __version = "0.20" + +    __pattern = r'http://(?:www\.)?(uloz\.to|ulozto\.(cz|sk|net)|bagruj\.cz|zachowajto\.pl)/(m|soubory)/.*' +    __config  = [("use_subfolder", "bool", "Save package to subfolder", True), +                   ("subfolder_per_package", "bool", "Create a subfolder for each package", True)] + +    __description = """Uloz.to folder decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("zoidberg", "zoidberg@mujmail.cz")] + + +    FOLDER_PATTERN = r'<ul class="profile_files">(.*?)</ul>' +    LINK_PATTERN = r'<br /><a href="/([^"]+)">[^<]+</a>' +    NEXT_PAGE_PATTERN = r'<a class="next " href="/([^"]+)"> </a>' + + +    def decrypt(self, pyfile): +        html = self.load(pyfile.url) + +        new_links = [] +        for i in xrange(1, 100): +            self.logInfo(_("Fetching links from page %i") % i) +            m = re.search(self.FOLDER_PATTERN, html, re.S) +            if m is None: +                self.error(_("FOLDER_PATTERN not found")) + +            new_links.extend(re.findall(self.LINK_PATTERN, m.group(1))) +            m = re.search(self.NEXT_PAGE_PATTERN, html) +            if m: +                html = self.load("http://ulozto.net/" + m.group(1)) +            else: +                break +        else: +            self.logInfo(_("Limit of 99 pages reached, aborting")) + +        if new_links: +            self.urls = [map(lambda s: "http://ulozto.net/%s" % s, new_links)] diff --git a/pyload/plugin/crypter/UploadableCh.py b/pyload/plugin/crypter/UploadableCh.py new file mode 100644 index 000000000..bf6bd09eb --- /dev/null +++ b/pyload/plugin/crypter/UploadableCh.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- + +from pyload.plugin.internal.SimpleCrypter import SimpleCrypter + + +class UploadableCh(SimpleCrypter): +    __name    = "UploadableCh" +    __type    = "crypter" +    __version = "0.03" + +    __pattern = r'http://(?:www\.)?uploadable\.ch/list/\w+' +    __config  = [("use_subfolder", "bool", "Save package to subfolder", True), +                   ("subfolder_per_package", "bool", "Create a subfolder for each package", True)] + +    __description = """Uploadable.ch folder decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("guidobelix", "guidobelix@hotmail.it"), +                       ("Walter Purcaro", "vuolter@gmail.com")] + + +    LINK_PATTERN = r'"(.+?)" class="icon_zipfile">' +    NAME_PATTERN = r'<div class="folder"><span> </span>(?P<N>.+?)</div>' +    OFFLINE_PATTERN = r'We are sorry... The URL you entered cannot be found on the server.' +    TEMP_OFFLINE_PATTERN = r'<div class="icon_err">' diff --git a/pyload/plugin/crypter/UploadedTo.py b/pyload/plugin/crypter/UploadedTo.py new file mode 100644 index 000000000..fbae7e7d6 --- /dev/null +++ b/pyload/plugin/crypter/UploadedTo.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- + +import re + +from urlparse import urljoin + +from pyload.plugin.internal.SimpleCrypter import SimpleCrypter + + +class UploadedTo(SimpleCrypter): +    __name    = "UploadedTo" +    __type    = "crypter" +    __version = "0.42" + +    __pattern = r'http://(?:www\.)?(uploaded|ul)\.(to|net)/(f|folder|list)/(?P<id>\w+)' +    __config  = [("use_subfolder", "bool", "Save package to subfolder", True), +                   ("subfolder_per_package", "bool", "Create a subfolder for each package", True)] + +    __description = """UploadedTo decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("stickell", "l.stickell@yahoo.it")] + + +    PLAIN_PATTERN = r'<small class="date"><a href="(?P<plain>[\w/]+)" onclick=' +    NAME_PATTERN = r'<title>(?P<N>.+?)<' + + +    def getLinks(self): +        m = re.search(self.PLAIN_PATTERN, self.html) +        if m is None: +            self.error(_("PLAIN_PATTERN not found")) + +        plain_link = urljoin("http://uploaded.net/", m.group('plain')) +        return self.load(plain_link).split('\n')[:-1] diff --git a/pyload/plugin/crypter/WiiReloadedOrg.py b/pyload/plugin/crypter/WiiReloadedOrg.py new file mode 100644 index 000000000..66ef764e4 --- /dev/null +++ b/pyload/plugin/crypter/WiiReloadedOrg.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- + +from pyload.plugin.internal.DeadCrypter import DeadCrypter, create_getInfo + + +class WiiReloadedOrg(DeadCrypter): +    __name    = "WiiReloadedOrg" +    __type    = "crypter" +    __version = "0.11" + +    __pattern = r'http://(?:www\.)?wii-reloaded\.org/protect/get\.php\?i=.+' +    __config  = [] + +    __description = """Wii-Reloaded.org decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("hzpz", "")] + + +getInfo = create_getInfo(WiiReloadedOrg) diff --git a/pyload/plugin/crypter/WuploadCom.py b/pyload/plugin/crypter/WuploadCom.py new file mode 100644 index 000000000..ad1a789a0 --- /dev/null +++ b/pyload/plugin/crypter/WuploadCom.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- + +from pyload.plugin.internal.DeadCrypter import DeadCrypter, create_getInfo + + +class WuploadCom(DeadCrypter): +    __name    = "WuploadCom" +    __type    = "crypter" +    __version = "0.01" + +    __pattern = r'http://(?:www\.)?wupload\.com/folder/\w+' + +    __description = """Wupload.com folder decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("zoidberg", "zoidberg@mujmail.cz")] + + +getInfo = create_getInfo(WuploadCom) diff --git a/pyload/plugin/crypter/XFileSharingPro.py b/pyload/plugin/crypter/XFileSharingPro.py new file mode 100644 index 000000000..eedf7ab26 --- /dev/null +++ b/pyload/plugin/crypter/XFileSharingPro.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- + +import re + +from pyload.plugin.internal.XFSCrypter import XFSCrypter + + +class XFileSharingPro(XFSCrypter): +    __name    = "XFileSharingPro" +    __type    = "crypter" +    __version = "0.03" + +    __pattern = r'^unmatchable$' +    __config  = [("use_subfolder", "bool", "Save package to subfolder", True), +                   ("subfolder_per_package", "bool", "Create a subfolder for each package", True)] + +    __description = """XFileSharingPro dummy folder decrypter plugin for hook""" +    __license     = "GPLv3" +    __authors     = [("Walter Purcaro", "vuolter@gmail.com")] + + +    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.crypterPlugins[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) diff --git a/pyload/plugin/crypter/XupPl.py b/pyload/plugin/crypter/XupPl.py new file mode 100644 index 000000000..233d96534 --- /dev/null +++ b/pyload/plugin/crypter/XupPl.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- + +from pyload.plugin.Crypter import Crypter + + +class XupPl(Crypter): +    __name    = "XupPl" +    __type    = "crypter" +    __version = "0.10" + +    __pattern = r'https?://(?:[^/]*\.)?xup\.pl/.*' +    __config  = [("use_subfolder", "bool", "Save package to subfolder", True), +                   ("subfolder_per_package", "bool", "Create a subfolder for each package", True)] + +    __description = """Xup.pl decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("z00nx", "z00nx0@gmail.com")] + + +    def decrypt(self, pyfile): +        header = self.load(pyfile.url, just_header=True) +        if 'location' in header: +            self.urls = [header['location']] +        else: +            self.fail(_("Unable to find link")) diff --git a/pyload/plugin/crypter/YoutubeBatch.py b/pyload/plugin/crypter/YoutubeBatch.py new file mode 100644 index 000000000..8f23b0149 --- /dev/null +++ b/pyload/plugin/crypter/YoutubeBatch.py @@ -0,0 +1,148 @@ +# -*- coding: utf-8 -*- + +import re + +from urlparse import urljoin + +from pyload.utils import json_loads +from pyload.plugin.Crypter import Crypter +from pyload.utils import safe_join + + +class YoutubeBatch(Crypter): +    __name    = "YoutubeBatch" +    __type    = "crypter" +    __version = "1.01" + +    __pattern = r'https?://(?:www\.|m\.)?youtube\.com/(?P<TYPE>user|playlist|view_play_list)(/|.*?[?&](?:list|p)=)(?P<ID>[\w-]+)' +    __config = [("use_subfolder", "bool", "Save package to subfolder", True), +                ("subfolder_per_package", "bool", "Create a subfolder for each package", True), +                ("likes", "bool", "Grab user (channel) liked videos", False), +                ("favorites", "bool", "Grab user (channel) favorite videos", False), +                ("uploads", "bool", "Grab channel unplaylisted videos", True)] + +    __description = """Youtube.com channel & playlist decrypter plugin""" +    __license     = "GPLv3" +    __authors     = [("Walter Purcaro", "vuolter@gmail.com")] + + +    API_KEY = "AIzaSyCKnWLNlkX-L4oD1aEzqqhRw1zczeD6_k0" + + +    def api_response(self, ref, req): +        req.update({"key": self.API_KEY}) +        url = urljoin("https://www.googleapis.com/youtube/v3/", ref) +        page = self.load(url, get=req) +        return json_loads(page) + + +    def getChannel(self, user): +        channels = self.api_response("channels", {"part": "id,snippet,contentDetails", "forUsername": user, "maxResults": "50"}) +        if channels['items']: +            channel = channels['items'][0] +            return {"id": channel['id'], +                    "title": channel['snippet']['title'], +                    "relatedPlaylists": channel['contentDetails']['relatedPlaylists'], +                    "user": user}  # One lone channel for user? + + +    def getPlaylist(self, p_id): +        playlists = self.api_response("playlists", {"part": "snippet", "id": p_id}) +        if playlists['items']: +            playlist = playlists['items'][0] +            return {"id": p_id, +                    "title": playlist['snippet']['title'], +                    "channelId": playlist['snippet']['channelId'], +                    "channelTitle": playlist['snippet']['channelTitle']} + + +    def _getPlaylists(self, id, token=None): +        req = {"part": "id", "maxResults": "50", "channelId": id} +        if token: +            req.update({"pageToken": token}) + +        playlists = self.api_response("playlists", req) + +        for playlist in playlists['items']: +            yield playlist['id'] + +        if "nextPageToken" in playlists: +            for item in self._getPlaylists(id, playlists['nextPageToken']): +                yield item + + +    def getPlaylists(self, ch_id): +        return map(self.getPlaylist, self._getPlaylists(ch_id)) + + +    def _getVideosId(self, id, token=None): +        req = {"part": "contentDetails", "maxResults": "50", "playlistId": id} +        if token: +            req.update({"pageToken": token}) + +        playlist = self.api_response("playlistItems", req) + +        for item in playlist['items']: +            yield item['contentDetails']['videoId'] + +        if "nextPageToken" in playlist: +            for item in self._getVideosId(id, playlist['nextPageToken']): +                yield item + + +    def getVideosId(self, p_id): +        return list(self._getVideosId(p_id)) + + +    def decrypt(self, pyfile): +        m = re.match(self.__pattern, pyfile.url) +        m_id = m.group("ID") +        m_type = m.group("TYPE") + +        if m_type == "user": +            self.logDebug("Url recognized as Channel") +            user = m_id +            channel = self.getChannel(user) + +            if channel: +                playlists = self.getPlaylists(channel['id']) +                self.logDebug("%s playlist\s found on channel \"%s\"" % (len(playlists), channel['title'])) + +                relatedplaylist = {p_name: self.getPlaylist(p_id) for p_name, p_id in channel['relatedPlaylists'].iteritems()} +                self.logDebug("Channel's related playlists found = %s" % relatedplaylist.keys()) + +                relatedplaylist['uploads']['title'] = "Unplaylisted videos" +                relatedplaylist['uploads']['checkDups'] = True  #: checkDups flag + +                for p_name, p_data in relatedplaylist.iteritems(): +                    if self.getConfig(p_name): +                        p_data['title'] += " of " + user +                        playlists.append(p_data) +            else: +                playlists = [] +        else: +            self.logDebug("Url recognized as Playlist") +            playlists = [self.getPlaylist(m_id)] + +        if not playlists: +            self.fail(_("No playlist available")) + +        addedvideos = [] +        urlize = lambda x: "https://www.youtube.com/watch?v=" + x +        for p in playlists: +            p_name = p['title'] +            p_videos = self.getVideosId(p['id']) +            p_folder = safe_join(self.config['general']['download_folder'], p['channelTitle'], p_name) +            self.logDebug("%s video\s found on playlist \"%s\"" % (len(p_videos), p_name)) + +            if not p_videos: +                continue +            elif "checkDups" in p: +                p_urls = [urlize(v_id) for v_id in p_videos if v_id not in addedvideos] +                self.logDebug("%s video\s available on playlist \"%s\" after duplicates cleanup" % (len(p_urls), p_name)) +            else: +                p_urls = map(urlize, p_videos) + +            self.packages.append((p_name, p_urls, p_folder))  #: folder is NOT recognized by pyload 0.4.9! + +            addedvideos.extend(p_videos) diff --git a/pyload/plugin/crypter/__init__.py b/pyload/plugin/crypter/__init__.py new file mode 100644 index 000000000..40a96afc6 --- /dev/null +++ b/pyload/plugin/crypter/__init__.py @@ -0,0 +1 @@ +# -*- coding: utf-8 -*-  | 
