diff options
Diffstat (limited to 'module/plugins')
30 files changed, 416 insertions, 198 deletions
diff --git a/module/plugins/accounts/LinestorageCom.py b/module/plugins/accounts/LinestorageCom.py deleted file mode 100644 index 87dd2a1d3..000000000 --- a/module/plugins/accounts/LinestorageCom.py +++ /dev/null @@ -1,18 +0,0 @@ -# -*- coding: utf-8 -*- - -from module.plugins.internal.XFSAccount import XFSAccount - - -class LinestorageCom(XFSAccount): - __name__ = "LinestorageCom" - __type__ = "account" - __version__ = "0.04" - __status__ = "testing" - - __description__ = """Linestorage.com account plugin""" - __license__ = "GPLv3" - __authors__ = [("Walter Purcaro", "vuolter@gmail.com")] - - - HOSTER_DOMAIN = "linestorage.com" - HOSTER_URL = "http://linestorage.com/" diff --git a/module/plugins/accounts/OboomCom.py b/module/plugins/accounts/OboomCom.py index 380368b70..a792848ea 100644 --- a/module/plugins/accounts/OboomCom.py +++ b/module/plugins/accounts/OboomCom.py @@ -40,7 +40,7 @@ class OboomCom(Account): get={'auth': user, 'pass': pbkdf2})) - if not result[0] == 200: + if result[0] != 200: self.log_warning(_("Failed to log in: %s") % result[1]) self.login_fail() @@ -52,10 +52,7 @@ class OboomCom(Account): userData = account_data['user'] - if userData['premium'] == "null": - premium = False - else: - premium = True + premium = userData['premium'] != "null" if userData['premium_unix'] == "null": validUntil = -1 @@ -65,7 +62,7 @@ class OboomCom(Account): traffic = userData['traffic'] trafficLeft = traffic['current'] / 1024 #@TODO: Remove `/ 1024` in 0.4.10 - maxTraffic = traffic['max'] / 1024 #@TODO: Remove `/ 1024` in 0.4.10 + maxTraffic = traffic['max'] / 1024 #@TODO: Remove `/ 1024` in 0.4.10 session = account_data['session'] diff --git a/module/plugins/accounts/RapiduNet.py b/module/plugins/accounts/RapiduNet.py index 1ec29bd77..2033d377f 100644 --- a/module/plugins/accounts/RapiduNet.py +++ b/module/plugins/accounts/RapiduNet.py @@ -62,5 +62,5 @@ class RapiduNet(Account): self.log_debug(json) - if not json['message'] == "success": + if json['message'] != "success": self.login_fail() diff --git a/module/plugins/accounts/UptoboxCom.py b/module/plugins/accounts/UptoboxCom.py index 68aaecc47..7cc217823 100644 --- a/module/plugins/accounts/UptoboxCom.py +++ b/module/plugins/accounts/UptoboxCom.py @@ -4,16 +4,16 @@ from module.plugins.internal.XFSAccount import XFSAccount class UptoboxCom(XFSAccount): - __name__ = "UptoboxCom" - __type__ = "account" - __version__ = "0.09" - __status__ = "testing" + __name__ = "UptoboxCom" + __type__ = "account" + __version__ = "0.12" + __status__ = "testing" - __description__ = """DDLStorage.com account plugin""" - __license__ = "GPLv3" - __authors__ = [("zoidberg", "zoidberg@mujmail.cz")] + __description__ = """Uptobox.com account plugin""" + __license__ = "GPLv3" + __authors__ = [("benbox69", "dev@tollet.me")] - HOSTER_DOMAIN = "uptobox.com" - HOSTER_URL = "https://uptobox.com/" - LOGIN_URL = "https://login.uptobox.com/" + HOSTER_DOMAIN = "uptobox.com" + HOSTER_URL = "https://uptobox.com/" + LOGIN_URL = "https://login.uptobox.com/logarithme/" diff --git a/module/plugins/crypter/Go4UpCom.py b/module/plugins/crypter/Go4UpCom.py index 026982014..2d423a1a9 100644..100755 --- a/module/plugins/crypter/Go4UpCom.py +++ b/module/plugins/crypter/Go4UpCom.py @@ -4,18 +4,20 @@ import re import urlparse from module.plugins.internal.SimpleCrypter import SimpleCrypter, create_getInfo +import json class Go4UpCom(SimpleCrypter): __name__ = "Go4UpCom" __type__ = "crypter" - __version__ = "0.13" + __version__ = "0.14" __status__ = "testing" __pattern__ = r'http://go4up\.com/(dl/\w{12}|rd/\w{12}/\d+)' __config__ = [("use_premium" , "bool", "Use premium account if available" , True), ("use_subfolder" , "bool", "Save package to subfolder" , True), - ("subfolder_per_pack", "bool", "Create a subfolder for each package", True)] + ("subfolder_per_pack", "bool", "Create a subfolder for each package", True), + ("preferred_hoster" , "int" , "Id of preferred hoster or 0 for all", 0)] __description__ = """Go4Up.com decrypter plugin""" __license__ = "GPLv3" @@ -32,19 +34,20 @@ class Go4UpCom(SimpleCrypter): def get_links(self): links = [] - - m = re.search(r'(/download/gethosts/.+?)"', self.html) - if m: - self.html = self.load(urlparse.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 + preference = self.get_config("preferred_hoster") + + hosterslink_re = re.search(r'(/download/gethosts/.+?)"', self.html) + if hosterslink_re: + hosters = self.load(urlparse.urljoin("http://go4up.com/", hosterslink_re.group(1))) + for hoster in json.loads(hosters): + if preference != 0 and preference != int(hoster["hostId"]): + continue + pagelink_re = re.search(self.LINK_PATTERN, hoster["link"]) + if pagelink_re: + page = self.load(pagelink_re.group(1)) + link_re = re.search(r'<b><a href="(.+?)"', page) + if link_re: + links.append(link_re.group(1)) return links diff --git a/module/plugins/crypter/GoogledriveComFolder.py b/module/plugins/crypter/GoogledriveComFolder.py index 88c7ebab2..e7a5bae2c 100644 --- a/module/plugins/crypter/GoogledriveComFolder.py +++ b/module/plugins/crypter/GoogledriveComFolder.py @@ -6,11 +6,11 @@ from module.plugins.internal.SimpleCrypter import SimpleCrypter, create_getInfo class GoogledriveComFolder(SimpleCrypter): __name__ = "GoogledriveCom" __type__ = "crypter" - __version__ = "0.02" + __version__ = "0.03" __status__ = "testing" __pattern__ = r'https?://(?:www\.)?drive\.google\.com/folderview\?.*id=\w+' - __config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True), #: Overrides pyload.config['general']['folder_per_package'] + __config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True), ("subfolder_per_pack", "bool", "Create a subfolder for each package", True)] __description__ = """Drive.google.com folder decrypter plugin""" diff --git a/module/plugins/crypter/LinkCryptWs.py b/module/plugins/crypter/LinkCryptWs.py index af13f55f6..16ee1d4f1 100644 --- a/module/plugins/crypter/LinkCryptWs.py +++ b/module/plugins/crypter/LinkCryptWs.py @@ -14,7 +14,7 @@ from module.utils import html_unescape class LinkCryptWs(Crypter): __name__ = "LinkCryptWs" __type__ = "crypter" - __version__ = "0.10" + __version__ = "0.12" __status__ = "testing" __pattern__ = r'http://(?:www\.)?linkcrypt\.ws/(dir|container)/(?P<ID>\w+)' @@ -31,7 +31,6 @@ class LinkCryptWs(Crypter): def setup(self): - self.captcha = False self.links = [] self.sources = ['cnl', 'web', 'dlc', 'rsdf', 'ccf'] @@ -60,7 +59,6 @@ class LinkCryptWs(Crypter): self.retry(8, 15, _("Can't handle Key-Captcha")) if self.is_captcha_protected(): - self.captcha = True self.unlock_captcha_protection() self.handle_captcha_errors() @@ -154,7 +152,7 @@ class LinkCryptWs(Crypter): unrarpw = sitein[indexi:indexe] - if not (unrarpw == "Password" or "Dateipasswort") : + if unrarpw not in ("Password", "Dateipasswort"): self.log_debug("File password set to: [%s]"% unrarpw) self.pyfile.package().password = unrarpw @@ -165,12 +163,11 @@ class LinkCryptWs(Crypter): def handle_captcha_errors(self): - if self.captcha: - if "Your choice was wrong!" in self.html: - self.captcha.invalid() - self.retry() - else: - self.captcha.correct() + if "Your choice was wrong!" in self.html: + self.captcha.invalid() + self.retry() + else: + self.captcha.correct() def handle_link_source(self, type): diff --git a/module/plugins/crypter/MultiUpOrg.py b/module/plugins/crypter/MultiUpOrg.py index 23e6dfa4a..fb228c3cd 100644 --- a/module/plugins/crypter/MultiUpOrg.py +++ b/module/plugins/crypter/MultiUpOrg.py @@ -9,10 +9,10 @@ from module.plugins.internal.SimpleCrypter import SimpleCrypter, create_getInfo class MultiUpOrg(SimpleCrypter): __name__ = "MultiUpOrg" __type__ = "crypter" - __version__ = "0.04" + __version__ = "0.05" __status__ = "testing" - __pattern__ = r'http://(?:www\.)?multiup\.org/(en|fr)/(?P<TYPE>project|download|miror)/\w+(/\w+)?' + __pattern__ = r'http://(?:www\.)?multiup\.org/(en|fr)/(?P<TYPE>project|download|mirror)/\w+(/\w+)?' __config__ = [("use_premium" , "bool", "Use premium account if available" , True), ("use_subfolder" , "bool", "Save package to subfolder" , True), ("subfolder_per_pack", "bool", "Create a subfolder for each package", True)] @@ -34,8 +34,8 @@ class MultiUpOrg(SimpleCrypter): pattern = r'style="width:97%;text-align:left".*\n.*href="(.*)"' if m_type == "download": dl_pattern = r'href="(.*)">.*\n.*<h5>DOWNLOAD</h5>' - miror_page = urlparse.urljoin("http://www.multiup.org/", re.search(dl_pattern, self.html).group(1)) - self.html = self.load(miror_page) + mirror_page = urlparse.urljoin("http://www.multiup.org/", re.search(dl_pattern, self.html).group(1)) + self.html = self.load(mirror_page) return re.findall(pattern, self.html) diff --git a/module/plugins/crypter/SexuriaCom.py b/module/plugins/crypter/SexuriaCom.py index 7942d5e42..24a5060b9 100644 --- a/module/plugins/crypter/SexuriaCom.py +++ b/module/plugins/crypter/SexuriaCom.py @@ -1,25 +1,23 @@ # -*- coding: utf-8 -*- import re - from module.plugins.internal.Crypter import Crypter - class SexuriaCom(Crypter): __name__ = "SexuriaCom" __type__ = "crypter" - __version__ = "0.04" + __version__ = "0.10" __status__ = "testing" __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_pack", "bool", "Create a subfolder for each package", True)] + __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")] - + #: Constants PATTERN_SUPPORTED_MAIN = r'http://(www\.)?sexuria\.com/(v1/)?Pornos_Kostenlos_.+?_(\d+)\.html' PATTERN_SUPPORTED_CRYPT = r'http://(www\.)?sexuria\.com/(v1/)?dl_links_\d+_(?P<ID>\d+)\.html' PATTERN_SUPPORTED_REDIRECT = r'http://(www\.)?sexuria\.com/out\.php\?id=(?P<ID>\d+)\&part=\d+\&link=\d+' @@ -27,15 +25,17 @@ class SexuriaCom(Crypter): PATTERN_PASSWORD = r'<strong>Passwort: </strong></div></td>.*?bgcolor="#EFEFEF">(?P<PWD>.*?)</td>' PATTERN_DL_LINK_PAGE = r'"(dl_links_\d+_\d+\.html)"' PATTERN_REDIRECT_LINKS = r'value="(http://sexuria\.com/out\.php\?id=\d+\&part=\d+\&link=\d+)" readonly' - + LIST_PWDIGNORE = ["Kein Passwort", "-"] def decrypt(self, pyfile): #: Init self.pyfile = pyfile self.package = pyfile.package() - #: Get package links + #: Decrypt and add links package_name, self.links, folder_name, package_pwd = self.decrypt_links(self.pyfile.url) + if package_pwd: + self.pyfile.package().password = package_pwd self.packages = [(package_name, self.links, folder_name)] @@ -62,34 +62,45 @@ class SexuriaCom(Crypter): #: Extract info from main file id = re.search(self.PATTERN_SUPPORTED_CRYPT, url, re.I).group('ID') html = self.load("http://sexuria.com/v1/Pornos_Kostenlos_info_%s.html" % id) + #: Webpage title / Package name + titledata = re.search(self.PATTERN_TITLE, html, re.I) + if not titledata: + self.log_warning("No title data found, has site changed?") + else: + title = titledata.group('TITLE').strip() + if title: + name = folder = title + self.log_debug("Package info found, name [%s] and folder [%s]" % (name, folder)) + #: Password + pwddata = re.search(self.PATTERN_PASSWORD, html, re.I | re.S) + if not pwddata: + self.log_warning("No password data found, has site changed?") + else: + pwd = pwddata.group('PWD').strip() + if pwd and not (pwd in self.LIST_PWDIGNORE): + password = pwd + self.log_debug("Package info found, password [%s]" % password) - title = re.search(self.PATTERN_TITLE, html, re.I).group('TITLE').strip() - if title: - name = folder = title - self.log_debug("Package info found, name [%s] and folder [%s]" % (name, folder)) - - pwd = re.search(self.PATTERN_PASSWORD, html, re.I | re.S).group('PWD') - if pwd and pwd not in ("Kein Passwort", "-"): - password = pwd.strip() - self.log_debug("Password info [%s] found" % password) - - #: Process link (dl_link) + #: Process links (dl_link) html = self.load(url) links = re.findall(self.PATTERN_REDIRECT_LINKS, html, re.I) - if len(links) == 0: + if not links: self.log_error(_("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: + if not finallink or ("sexuria.com/" in finallink): self.log_error(_("Broken for link: %s") % link) else: linklist.append(finallink) - #: Debug log - self.log_debug("%d supported links" % len(linklist)) - for i, link in enumerate(linklist): - self.log_debug("Supported link %d, %s" % (i + 1, link)) + #: Log result + if not linklist: + self.fail(_("Unable to extract links (maybe plugin out of date?)")) + else: + for i, link in enumerate(linklist): + self.log_debug("Supported link %d/%d: %s" % (i+1, len(linklist), link)) + #: All done, return to caller return name, linklist, folder, password diff --git a/module/plugins/crypter/TNTVillageScambioeticoOrg.py b/module/plugins/crypter/TNTVillageScambioeticoOrg.py index 6ba1ee19b..e85a8fbb7 100644 --- a/module/plugins/crypter/TNTVillageScambioeticoOrg.py +++ b/module/plugins/crypter/TNTVillageScambioeticoOrg.py @@ -6,11 +6,11 @@ from module.plugins.internal.SimpleCrypter import SimpleCrypter, create_getInfo class TNTVillageScambioeticoOrg(SimpleCrypter): __name__ = "TNTVillageScambioeticoOrg" __type__ = "crypter" - __version__ = "0.02" + __version__ = "0.03" __status__ = "testing" __pattern__ = r'http://(?:www\.)?forum\.tntvillage\.scambioetico\.org/index\.php\?.*showtopic=\d+' - __config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True), #: Overrides pyload.config['general']['folder_per_package'] + __config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True), ("subfolder_per_pack", "bool", "Create a subfolder for each package", True)] __description__ = """TNTVillage.scambioetico.org decrypter plugin""" diff --git a/module/plugins/hooks/Checksum.py b/module/plugins/hooks/Checksum.py index da4d35df1..64c5fa3ff 100644 --- a/module/plugins/hooks/Checksum.py +++ b/module/plugins/hooks/Checksum.py @@ -38,7 +38,7 @@ def compute_checksum(local_file, algorithm): class Checksum(Addon): __name__ = "Checksum" __type__ = "hook" - __version__ = "0.20" + __version__ = "0.21" __status__ = "testing" __config__ = [("check_checksum", "bool" , "Check checksum? (If False only size will be verified)", True ), @@ -114,7 +114,7 @@ class Checksum(Addon): api_size = int(data['size']) file_size = os.path.getsize(local_file) - if api_size is not file_size: + if api_size != file_size: self.log_warning(_("File %s has incorrect size: %d B (%d expected)") % (pyfile.name, file_size, api_size)) self.check_failed(pyfile, local_file, "Incorrect file size") diff --git a/module/plugins/hooks/ExtractArchive.py b/module/plugins/hooks/ExtractArchive.py index eab196160..87cd38ade 100644 --- a/module/plugins/hooks/ExtractArchive.py +++ b/module/plugins/hooks/ExtractArchive.py @@ -51,7 +51,7 @@ except ImportError: pass from module.plugins.internal.Addon import Addon, Expose, threaded -from module.plugins.internal.Plugin import replace_patterns +from module.plugins.internal.Plugin import exists, replace_patterns from module.plugins.internal.Extractor import ArchiveError, CRCError, PasswordError from module.utils import fs_encode, save_join as fs_join, uniqify @@ -107,7 +107,7 @@ class ArchiveQueue(object): class ExtractArchive(Addon): __name__ = "ExtractArchive" __type__ = "hook" - __version__ = "1.49" + __version__ = "1.50" __status__ = "testing" __config__ = [("activated" , "bool" , "Activated" , True ), @@ -288,7 +288,7 @@ class ExtractArchive(Addon): if subfolder: out = fs_join(out, pypack.folder) - if not os.path.exists(out): + if not exists(out): os.makedirs(out) matched = False @@ -313,7 +313,7 @@ class ExtractArchive(Addon): for fname, fid, fout in targets: name = os.path.basename(fname) - if not os.path.exists(fname): + if not exists(fname): self.log_debug(name, "File not found") continue @@ -356,7 +356,7 @@ class ExtractArchive(Addon): for filename in new_files: file = fs_encode(fs_join(os.path.dirname(archive.filename), filename)) - if not os.path.exists(file): + if not exists(file): self.log_debug("New file %s does not exists" % filename) continue @@ -476,7 +476,7 @@ class ExtractArchive(Addon): deltotrash = self.get_config('deltotrash') for f in delfiles: file = fs_encode(f) - if not os.path.exists(file): + if not exists(file): continue if not deltotrash: diff --git a/module/plugins/hooks/IRCInterface.py b/module/plugins/hooks/IRCInterface.py index 08b1bad0c..5d8928a57 100644 --- a/module/plugins/hooks/IRCInterface.py +++ b/module/plugins/hooks/IRCInterface.py @@ -18,7 +18,7 @@ from module.utils import formatSize class IRCInterface(Thread, Addon): __name__ = "IRCInterface" __type__ = "hook" - __version__ = "0.15" + __version__ = "0.16" __status__ = "testing" __config__ = [("host" , "str" , "IRC-Server Address" , "Enter your server here!"), @@ -40,7 +40,7 @@ class IRCInterface(Thread, Addon): def __init__(self, core, manager): Thread.__init__(self) Addon.__init__(self, core, manager) - self.set_daemon(True) + self.setDaemon(True) def activate(self): diff --git a/module/plugins/hooks/TransmissionRPC.py b/module/plugins/hooks/TransmissionRPC.py new file mode 100644 index 000000000..2ca06a9ad --- /dev/null +++ b/module/plugins/hooks/TransmissionRPC.py @@ -0,0 +1,84 @@ +# -*- coding: utf-8 -*- + +import random +import re + +import pycurl + +from module.common.json_layer import json_loads, json_dumps +from module.network.HTTPRequest import BadHeader +from module.network.RequestFactory import getRequest as get_request +from module.plugins.internal.Addon import Addon + + +class TransmissionRPC(Addon): + __name__ = "TransmissionRPC" + __type__ = "hook" + __version__ = "0.12" + __status__ = "testing" + + __pattern__ = r"https?://.+\.torrent|magnet:\?.+" + __config__ = [("rpc_url", "str", "Transmission RPC URL", "http://127.0.0.1:9091/transmission/rpc")] + + __description__ = """Send torrent and magnet URLs to Transmission Bittorent daemon via RPC""" + __license__ = "GPLv3" + __authors__ = [("GammaC0de", None)] + + + def init(self): + self.event_map = {'linksAdded': "links_added"} + + + def links_added(self, links, pid): + pattern = re.compile(self.__pattern__) + urls = [link for link in links if pattern.match(link)] + + for url in urls: + self.log_debug("Sending link: %s" % url) + self.send_to_transmission(url) + links.remove(url) + + + def send_to_transmission(self, url): + transmission_rpc_url = self.get_config('rpc_url') + client_request_id = self.__name__ + "".join(random.choice('0123456789ABCDEF') for _i in xrange(4)) + req = get_request() + + try: + response = self.load(transmission_rpc_url, + post=json_dumps({'arguments': {'filename': url}, + 'method' : 'torrent-add', + 'tag' : client_request_id}), + req=req) + + except BadHeader, e: + if e.code == 409: + headers = dict(re.findall(r"(?P<name>.+?): (?P<value>.+?)\r?\n", req.header)) + session_id = headers['X-Transmission-Session-Id'] + req.c.setopt(pycurl.HTTPHEADER, ["X-Transmission-Session-Id: %s" % session_id]) + try: + response = self.load(transmission_rpc_url, + post=json_dumps({'arguments': {'filename': url}, + 'method' : 'torrent-add', + 'tag' : client_request_id}), + req=req) + + except Exception, e: + self.log_error(e) + return + + else: + self.log_error(e) + return + + except Exception, e: + self.log_error(e) + return + + try: + res = json_loads(response) + if "result" in res: + self.log_debug("Result: %s" % res['result']) + + except Exception, e: + self.log_error(e) diff --git a/module/plugins/hooks/XFileSharingPro.py b/module/plugins/hooks/XFileSharingPro.py index 7567a31a3..9b9c7f0ad 100644 --- a/module/plugins/hooks/XFileSharingPro.py +++ b/module/plugins/hooks/XFileSharingPro.py @@ -29,18 +29,20 @@ class XFileSharingPro(Hook): r'https?://(?:[^/]+\.)?(?P<DOMAIN>%s)/(?:user|folder)s?/\w+')} HOSTER_BUILTIN = [#WORKING HOSTERS: - "ani-stream.com", "backin.net", "cloudsix.me", "eyesfile.ca", "file4safe.com", - "fileband.com", "filedwon.com", "fileparadox.in", "filevice.com", - "hostingbulk.com", "junkyvideo.com", "linestorage.com", "ravishare.com", + "ani-stream.com", "backin.net", "cloudsix.me", "eyesfile.ca", + "file4safe.com", "fileband.com", "filedwon.com", "fileparadox.in", + "filevice.com", "hostingbulk.com", "junkyvideo.com", "ravishare.com", "ryushare.com", "salefiles.com", "sendmyway.com", "sharebeast.com", - "sharesix.com", "thefile.me", "verzend.be", "worldbytez.com", "xvidstage.com", + "sharesix.com", "thefile.me", "verzend.be", "worldbytez.com", + "xvidstage.com", #: NOT TESTED: "101shared.com", "4upfiles.com", "filemaze.ws", "filenuke.com", "linkzhost.com", "mightyupload.com", "rockdizfile.com", "sharerepo.com", "shareswift.com", "uploadbaz.com", "uploadc.com", "vidbull.com", "zalaa.com", "zomgupload.com", #: NOT WORKING: - "amonshare.com", "banicrazy.info", "boosterking.com", "host4desi.com", "laoupload.com", "rd-fs.com"] + "amonshare.com", "banicrazy.info", "boosterking.com", "host4desi.com", + "laoupload.com", "rd-fs.com"] CRYPTER_BUILTIN = ["junocloud.me", "rapidfileshare.net"] diff --git a/module/plugins/hoster/OneFichierCom.py b/module/plugins/hoster/OneFichierCom.py index cba67b26c..70229a6ef 100644 --- a/module/plugins/hoster/OneFichierCom.py +++ b/module/plugins/hoster/OneFichierCom.py @@ -2,13 +2,14 @@ import re +from module.network.RequestFactory import getURL as get_url from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo class OneFichierCom(SimpleHoster): __name__ = "OneFichierCom" __type__ = "hoster" - __version__ = "0.88" + __version__ = "0.90" __status__ = "testing" __pattern__ = r'https?://(?:www\.)?(?:(?P<ID1>\w+)\.)?(?P<HOST>1fichier\.com|alterupload\.com|cjoint\.net|d(es)?fichiers\.com|dl4free\.com|megadl\.fr|mesfichiers\.org|piecejointe\.net|pjointe\.com|tenvoi\.com)(?:/\?(?P<ID2>\w+))?' @@ -28,6 +29,8 @@ class OneFichierCom(SimpleHoster): COOKIES = [("1fichier.com", "LG", "en")] + DIRECT_LINK = True + NAME_PATTERN = r'>File\s*Name :</td>\s*<td.*>(?P<N>.+?)<' SIZE_PATTERN = r'>Size :</td>\s*<td.*>(?P<S>[\d.,]+) (?P<U>[\w^_]+)' OFFLINE_PATTERN = r'File not found !\s*<' @@ -40,7 +43,61 @@ class OneFichierCom(SimpleHoster): self.resume_download = True + @classmethod + def get_info(cls, url="", html=""): + redirect = url + for i in xrange(10): + try: + headers = dict(re.findall(r"(?P<name>.+?): (?P<value>.+?)\r?\n", get_url(redirect, just_header=True).lower())) + if 'location' in headers and headers['location']: + redirect = headers['location'] + else: + if 'content-type' in headers and headers['content-type'] == "application/octet-stream": + if "filename=" in headers.get('content-disposition'): + name = dict(_i.split("=") for _i in map(str.strip, headers['content-disposition'].split(";"))[1:])['filename'].strip("\"'") + else: + name = url + + info = {'name' : name, + 'size' : long(headers.get('content-length')), + 'status': 3, + 'url' : url} + + else: + info = super(OneFichierCom, cls).get_info(url, html) + + break + + except Exception, e: + info = {'status' : 8, + 'error' : e.message} + + else: + info = {'status' : 8, + 'error' : _("Too many redirects")} + + return info + + + def handle_direct(self, pyfile): + redirect = pyfile.url + for i in xrange(self.get_config("maxredirs", plugin="UserAgentSwitcher")): + + headers = self.load(redirect, just_header=True) + if 'location' in headers and headers['location']: + self.log_debug("Redirect #%d to: %s" % (i, redirect)) + redirect = headers['location'] + else: + if 'content-type' in headers and headers['content-type'] == "application/octet-stream": + self.link = pyfile.url + break + else: + self.fail(_("Too many redirects")) + + def handle_free(self, pyfile): + self.check_errors() + id = self.info['pattern']['ID1'] or self.info['pattern']['ID2'] url, inputs = self.parse_html_form('action="https://1fichier.com/\?%s' % id) diff --git a/module/plugins/hoster/OpenloadIo.py b/module/plugins/hoster/OpenloadIo.py index c46462344..372ce28f9 100644 --- a/module/plugins/hoster/OpenloadIo.py +++ b/module/plugins/hoster/OpenloadIo.py @@ -6,25 +6,25 @@ from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo class OpenloadIo(SimpleHoster): __name__ = "OpenloadIo" __type__ = "hoster" - __version__ = "0.04" + __version__ = "0.05" __status__ = "testing" - __pattern__ = r'https?://(?:www\.)?openload\.io/f/[\w_-]{11}' + __pattern__ = r'https?://(?:www\.)?openload\.(co|io)/f/[\w-]+' - __description__ = """Openload.io hoster plugin""" + __description__ = """Openload.co hoster plugin""" __license__ = "GPLv3" __authors__ = [(None, None)] NAME_PATTERN = r'<span id="filename">(?P<N>.+?)</' - SIZE_PATTERN = r'<span class="count">(?P<S>[\d.,]+) (?P<U>[\w^_]+)<' + SIZE_PATTERN = r'<span class="count">(?P<S>[\d.,]+) (?P<U>[\w^_]+)' OFFLINE_PATTERN = r">(We can't find the file you are looking for)" - LINK_FREE_PATTERN = r'id="real\w*download"><a href="(https?://[\w\.]+\.openload\.io/dl/.*?)"' + LINK_FREE_PATTERN = r'id="real\w*download"><a href="(https?://[\w\.]+\.openload\.co/dl/.*?)"' def setup(self): - self.multiDL = True + self.multiDL = True self.chunk_limit = 1 diff --git a/module/plugins/hoster/PremiumizeMe.py b/module/plugins/hoster/PremiumizeMe.py index d968eccec..e682a5a4c 100644 --- a/module/plugins/hoster/PremiumizeMe.py +++ b/module/plugins/hoster/PremiumizeMe.py @@ -7,7 +7,7 @@ from module.plugins.internal.MultiHoster import MultiHoster, create_getInfo class PremiumizeMe(MultiHoster): __name__ = "PremiumizeMe" __type__ = "hoster" - __version__ = "0.20" + __version__ = "0.21" __status__ = "testing" __pattern__ = r'^unmatchable$' #: Since we want to allow the user to specify the list of hoster to use we let MultiHoster.activate @@ -44,6 +44,12 @@ class PremiumizeMe(MultiHoster): status = data['status'] if status == 200: + if 'filename' in data['result']: + self.pyfile.name = data['result']['filename'] + + if 'filesize' in data['result']: + self.pyfile.size = data['result']['filesize'] + self.link = data['result']['location'] return diff --git a/module/plugins/hoster/ShareonlineBiz.py b/module/plugins/hoster/ShareonlineBiz.py index b5af3ea35..dbe7fe401 100644 --- a/module/plugins/hoster/ShareonlineBiz.py +++ b/module/plugins/hoster/ShareonlineBiz.py @@ -79,7 +79,7 @@ class ShareonlineBiz(SimpleHoster): post={'dl_free' : "1", 'recaptcha_challenge_field': challenge, 'recaptcha_response_field' : response}) - if not res == "0": + if res != "0": self.captcha.correct() return res else: @@ -136,7 +136,7 @@ class ShareonlineBiz(SimpleHoster): self.log_debug(dlinfo) - if not dlinfo['status'] == "online": + if dlinfo['status'] != "online": self.offline() else: pyfile.name = dlinfo['name'] diff --git a/module/plugins/hoster/UlozTo.py b/module/plugins/hoster/UlozTo.py index b402433a4..066d1daf0 100644 --- a/module/plugins/hoster/UlozTo.py +++ b/module/plugins/hoster/UlozTo.py @@ -15,7 +15,7 @@ def convert_decimal_prefix(m): class UlozTo(SimpleHoster): __name__ = "UlozTo" __type__ = "hoster" - __version__ = "1.13" + __version__ = "1.14" __status__ = "testing" __pattern__ = r'http://(?:www\.)?(uloz\.to|ulozto\.(cz|sk|net)|bagruj\.cz|zachowajto\.pl)/(?:live/)?(?P<ID>\w+/[^/?]*)' @@ -27,7 +27,7 @@ class UlozTo(SimpleHoster): INFO_PATTERN = r'<p>File <strong>(?P<N>[^<]+)</strong> is password protected</p>' - NAME_PATTERN = r'<title>(?P<N>[^<]+) \| Uloz\.to</title>' + NAME_PATTERN = r'<title>(?P<N>.+?) \|' SIZE_PATTERN = r'<span id="fileSize">.*?(?P<S>[\d.,]+\s[kMG]?B)</span>' OFFLINE_PATTERN = r'<title>404 - Page not found</title>|<h1 class="h1">File (has been deleted|was banned)</h1>' @@ -68,7 +68,9 @@ class UlozTo(SimpleHoster): #: New version - better to get new parameters (like captcha reload) because of image url - since 6.12.2013 self.log_debug('Using "new" version') - xapca = self.load("http://www.ulozto.net/reloadXapca.php", get={'rnd': str(int(time.time()))}) + xapca = self.load("http://www.ulozto.net/reloadXapca.php", + get={'rnd': str(int(time.time()))}) + xapca = xapca.replace('sound":"', 'sound":"http:').replace('image":"', 'image":"http:') self.log_debug("xapca = " + str(xapca)) data = json_loads(xapca) @@ -121,7 +123,7 @@ class UlozTo(SimpleHoster): def check_file(self): check = self.check_download({ - 'wrong_captcha': re.compile(r'<ul class="error">\s*<li>Error rewriting the text.</li>'), + 'wrong_captcha': ">An error ocurred while verifying the user", 'offline' : re.compile(self.OFFLINE_PATTERN), 'passwd' : self.PASSWD_PATTERN, 'server_error' : 'src="http://img.ulozto.cz/error403/vykricnik.jpg"', #: Paralell dl, server overload etc. diff --git a/module/plugins/hoster/UserscloudCom.py b/module/plugins/hoster/UserscloudCom.py new file mode 100644 index 000000000..ebaed4859 --- /dev/null +++ b/module/plugins/hoster/UserscloudCom.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- + +import re + +from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo + + +class UserscloudCom(SimpleHoster): + __name__ = "UserscloudCom" + __type__ = "hoster" + __version__ = "0.01" + __status__ = "testing" + + __pattern__ = r'https?://(?:www\.)?userscloud\.com/\w{12}' + + __description__ = """Userscloud.com hoster plugin""" + __license__ = "GPLv3" + __authors__ = [("GammaC0de", None)] + + + NAME_PATTERN = r'<h2 class="strong margin-none">(?P<N>.+?)<' + SIZE_PATTERN = r'<div class="ribbon">(?P<S>[\d.,]+) (?P<U>[\w^_]+)<' + OFFLINE_PATTERN = r'The file you are trying to download is no longer available' + + + def setup(self): + self.multiDL = True + self.resume_download = False + self.chunk_limit = 1 + + + def handle_free(self, pyfile): + self.download(pyfile.url, + post=dict(re.findall(r'<input type="hidden" name="(.+?)" value="(.*?)">', self.html))) + + +getInfo = create_getInfo(UserscloudCom) diff --git a/module/plugins/hoster/YoutubeCom.py b/module/plugins/hoster/YoutubeCom.py index 86cca7cf1..5c7c13962 100644 --- a/module/plugins/hoster/YoutubeCom.py +++ b/module/plugins/hoster/YoutubeCom.py @@ -6,37 +6,17 @@ import subprocess import urllib from module.plugins.internal.Hoster import Hoster -from module.plugins.internal.Plugin import replace_patterns +from module.plugins.internal.Plugin import replace_patterns, which from module.utils import html_unescape -def which(program): - """ - Works exactly like the unix command which - Courtesy of http://stackoverflow.com/a/377028/675646 - """ - isExe = lambda x: os.path.isfile(x) and os.access(x, os.X_OK) - - fpath, fname = os.path.split(program) - - if fpath: - if isExe(program): - return program - else: - for path in os.environ['PATH'].split(os.pathsep): - path = path.strip('"') - exe_file = os.path.join(path, program) - if isExe(exe_file): - return exe_file - - class YoutubeCom(Hoster): __name__ = "YoutubeCom" __type__ = "hoster" - __version__ = "0.45" + __version__ = "0.46" __status__ = "testing" - __pattern__ = r'https?://(?:[^/]*\.)?(youtube\.com|youtu\.be)/watch\?(?:.*&)?v=.+' + __pattern__ = r'https?://(?:[^/]*\.)?(youtu\.be/|youtube\.com/watch\?(?:.*&)?v=)\w+' __config__ = [("quality", "sd;hd;fullhd;240p;360p;480p;720p;1080p;3072p", "Quality Setting" , "hd" ), ("fmt" , "int" , "FMT/ITAG Number (0 for auto)", 0 ), (".mp4" , "bool" , "Allow .mp4" , True ), @@ -51,7 +31,7 @@ class YoutubeCom(Hoster): ("zoidberg", "zoidberg@mujmail.cz")] - URL_REPLACEMENTS = [(r'youtu\.be/', 'youtube.com/')] + URL_REPLACEMENTS = [(r'youtu\.be/', 'youtube.com/watch?v=')] #: Invalid characters that must be removed from the file name invalid_chars = u'\u2605:?><"|\\' diff --git a/module/plugins/internal/Addon.py b/module/plugins/internal/Addon.py index 45ca98eac..4ccaaba8b 100644 --- a/module/plugins/internal/Addon.py +++ b/module/plugins/internal/Addon.py @@ -25,7 +25,7 @@ def threaded(fn): class Addon(Plugin): __name__ = "Addon" __type__ = "hook" #@TODO: Change to `addon` in 0.4.10 - __version__ = "0.04" + __version__ = "0.05" __status__ = "testing" __config__ = [] #: [("name", "type", "desc", "default")] @@ -57,6 +57,12 @@ class Addon(Plugin): self.init_events() + #@TODO: Remove in 0.4.10 + def _log(self, level, plugintype, pluginname, messages): + plugintype = "addon" if plugintype is "hook" else plugintype + return super(Addon, self)._log(level, plugintype, pluginname, messages) + + def init_events(self): if self.event_map: for event, funcs in self.event_map.items(): diff --git a/module/plugins/internal/Captcha.py b/module/plugins/internal/Captcha.py index c08050ee8..b864fd2d8 100644 --- a/module/plugins/internal/Captcha.py +++ b/module/plugins/internal/Captcha.py @@ -12,7 +12,7 @@ from module.plugins.internal.Plugin import Plugin class Captcha(Plugin): __name__ = "Captcha" __type__ = "captcha" - __version__ = "0.42" + __version__ = "0.43" __status__ = "testing" __description__ = """Base anti-captcha plugin""" @@ -50,18 +50,18 @@ class Captcha(Plugin): pass - def decrypt(self, url, get={}, post={}, ref=False, cookies=False, decode=False, + def decrypt(self, url, get={}, post={}, ref=False, cookies=True, decode=False, input_type='jpg', output_type='textual', ocr=True, timeout=120): img = self.load(url, get=get, post=post, ref=ref, cookies=cookies, decode=decode) return self._decrypt(img, input_type, output_type, ocr, timeout) #@TODO: Definitely choose a better name for this method! - def _decrypt(self, raw, input_type='jpg', output_type='textual', ocr=False, timeout=120): + def _decrypt(self, data, input_type='jpg', output_type='textual', ocr=False, timeout=120): """ Loads a captcha and decrypts it with ocr, plugin, user input - :param raw: image raw data + :param data: image raw data :param get: get part for request :param post: post part for request :param cookies: True if cookies should be enabled @@ -77,7 +77,7 @@ class Captcha(Plugin): time_ref = ("%.2f" % time.time())[-6:].replace(".", "") with open(os.path.join("tmp", "captcha_image_%s_%s.%s" % (self.plugin.__name__, time_ref, input_type)), "wb") as tmp_img: - tmp_img.write(raw) + tmp_img.write(data) if ocr: if isinstance(ocr, basestring): @@ -90,7 +90,7 @@ class Captcha(Plugin): captchaManager = self.pyload.captchaManager try: - self.task = captchaManager.newTask(raw, input_type, tmp_img.name, output_type) + self.task = captchaManager.newTask(data, input_type, tmp_img.name, output_type) captchaManager.handleCaptcha(self.task) @@ -120,7 +120,7 @@ class Captcha(Plugin): self.log_warning(_("Error removing: %s") % tmp_img.name, e) traceback.print_exc() - self.log_info(_("Captcha result: ") + result) #@TODO: Remove from here? + #self.log_info(_("Captcha result: ") + result) #@TODO: Remove from here? return result diff --git a/module/plugins/internal/Container.py b/module/plugins/internal/Container.py index 729592a0d..66e1ad904 100644 --- a/module/plugins/internal/Container.py +++ b/module/plugins/internal/Container.py @@ -63,7 +63,7 @@ class Container(Crypter): f.write(content) except IOError, e: - self.fail(str(e)) #@TODO: Remove `str` in 0.4.10 + self.fail(e) else: self.pyfile.name = os.path.basename(self.pyfile.url) diff --git a/module/plugins/internal/Hoster.py b/module/plugins/internal/Hoster.py index b397a92a6..ac42182c4 100644 --- a/module/plugins/internal/Hoster.py +++ b/module/plugins/internal/Hoster.py @@ -44,7 +44,7 @@ def create_getInfo(klass): class Hoster(Plugin): __name__ = "Hoster" __type__ = "hoster" - __version__ = "0.20" + __version__ = "0.22" __status__ = "testing" __pattern__ = r'^unmatchable$' @@ -368,7 +368,7 @@ class Hoster(Plugin): url = self.fixurl(url) if not url or not isinstance(url, basestring): - self.fail(_("No url given")) + self.fail(_("No given url")) if self.pyload.debug: self.log_debug("DOWNLOAD URL " + url, @@ -412,7 +412,7 @@ class Hoster(Plugin): if disposition and newname: finalname = urlparse.urlparse(newname).path.split('/')[-1].split(' filename*=')[0] - if finalname != newname != self.pyfile.name: + if finalname != newname: try: os.rename(fs_join(location, newname), fs_join(location, finalname)) @@ -421,8 +421,9 @@ class Hoster(Plugin): finalname = newname self.log_info(_("`%s` saved as `%s`") % (self.pyfile.name, finalname)) - self.pyfile.name = finalname - filename = os.path.join(location, finalname) + + self.pyfile.name = finalname + filename = os.path.join(location, finalname) self.set_permissions(fs_encode(filename)) @@ -431,9 +432,35 @@ class Hoster(Plugin): return self.last_download - def check_download(self, rules, delete=False, file_size=0, size_tolerance=1024, read_size=1048576): + def check_filesize(self, file_size, size_tolerance=1024): + """ + Checks the file size of the last downloaded file + + :param file_size: expected file size + :param size_tolerance: size check tolerance """ - Checks the content of the last downloaded file, re match is saved to `lastCheck` + if not self.last_download: + return + + download_size = os.stat(fs_encode(self.last_download)).st_size + + if download_size < 1: + self.fail(_("Empty file")) + + elif file_size > 0: + diff = abs(file_size - download_size) + + if diff > size_tolerance: + self.fail(_("File size mismatch | Expected file size: %s | Downloaded file size: %s") + % (file_size, download_size)) + + elif diff != 0: + self.log_warning(_("File size is not equal to expected size")) + + + def check_download(self, rules, delete=False, read_size=1048576, file_size=0, size_tolerance=1024): + """ + Checks the content of the last downloaded file, re match is saved to `last_check` :param rules: dict with names and rules to match (compiled regexp or strings) :param delete: delete if matched @@ -446,26 +473,11 @@ class Hoster(Plugin): last_download = fs_encode(self.last_download) if not self.last_download or not exists(last_download): - self.last_download = "" + self.last_download = "" #@NOTE: Bad place... self.fail(self.pyfile.error or _("No file downloaded")) try: - download_size = os.stat(last_download).st_size - - if download_size < 1: - do_delete = True - self.fail(_("Empty file")) - - elif file_size > 0: - diff = abs(file_size - download_size) - - if diff > size_tolerance: - do_delete = True - self.fail(_("File size mismatch | Expected file size: %s | Downloaded file size: %s") - % (file_size, download_size)) - - elif diff != 0: - self.log_warning(_("File size is not equal to expected size")) + self.check_filesize(file_size, size_tolerance) with open(last_download, "rb") as f: content = f.read(read_size) @@ -495,8 +507,8 @@ class Hoster(Plugin): traceback.print_exc() else: + self.log_info(_("File deleted: ") + self.last_download) self.last_download = "" - self.log_info(_("File deleted")) def direct_link(self, url, follow_location=None): diff --git a/module/plugins/internal/Plugin.py b/module/plugins/internal/Plugin.py index 8bc5d4a65..feabe9f1d 100644 --- a/module/plugins/internal/Plugin.py +++ b/module/plugins/internal/Plugin.py @@ -52,11 +52,40 @@ def fixurl(url): return html_unescape(urllib.unquote(url.decode('unicode-escape'))).strip().rstrip('/') +def fixname(m): + m = unicodedata.normalize('NFKD', m) + output = '' + for c in m: + if not unicodedata.combining(c): + output += c + return output + + #@TODO: Move to utils in 0.4.10 def timestamp(): return int(time.time() * 1000) +#@TODO: Move to utils in 0.4.10 +def which(program): + """ + Works exactly like the unix command which + Courtesy of http://stackoverflow.com/a/377028/675646 + """ + isExe = lambda x: os.path.isfile(x) and os.access(x, os.X_OK) + + fpath, fname = os.path.split(program) + + if fpath: + if isExe(program): + return program + else: + for path in os.environ['PATH'].split(os.pathsep): + exe_file = os.path.join(path.strip('"'), program) + if isExe(exe_file): + return exe_file + + def seconds_to_midnight(gmt=0): now = datetime.datetime.utcnow() + datetime.timedelta(hours=gmt) @@ -325,7 +354,7 @@ class Plugin(object): url = fixurl(url) if not url or not isinstance(url, basestring): - self.fail(_("No url given")) + self.fail(_("No given url")) if self.pyload.debug: self.log_debug("LOAD URL " + url, diff --git a/module/plugins/internal/SimpleCrypter.py b/module/plugins/internal/SimpleCrypter.py index 6a3f91a5b..d348f92e2 100644 --- a/module/plugins/internal/SimpleCrypter.py +++ b/module/plugins/internal/SimpleCrypter.py @@ -10,11 +10,11 @@ from module.utils import fixup, html_unescape class SimpleCrypter(Crypter, SimpleHoster): __name__ = "SimpleCrypter" __type__ = "crypter" - __version__ = "0.60" + __version__ = "0.61" __status__ = "testing" __pattern__ = r'^unmatchable$' - __config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True), #: Overrides pyload.config['general']['folder_per_package'] + __config__ = [("use_subfolder" , "bool", "Save package to subfolder" , True), ("subfolder_per_pack", "bool", "Create a subfolder for each package", True)] __description__ = """Simple decrypter plugin""" @@ -91,6 +91,7 @@ class SimpleCrypter(Crypter, SimpleHoster): def decrypt(self, pyfile): + self.links = [] #@TODO: Recheck in 0.4.10 self.prepare() self.check_info() #@TODO: Remove in 0.4.10 diff --git a/module/plugins/internal/SimpleHoster.py b/module/plugins/internal/SimpleHoster.py index 69f88081a..89af22c87 100644 --- a/module/plugins/internal/SimpleHoster.py +++ b/module/plugins/internal/SimpleHoster.py @@ -11,7 +11,7 @@ from module.PyFile import statusMap as _statusMap from module.network.HTTPRequest import BadHeader from module.network.RequestFactory import getURL as get_url from module.plugins.internal.Hoster import Hoster, create_getInfo, parse_fileInfo -from module.plugins.internal.Plugin import Fail, encode, fixurl, replace_patterns, seconds_to_midnight, set_cookie, set_cookies +from module.plugins.internal.Plugin import Fail, encode, fixurl, fixname, replace_patterns, seconds_to_midnight, set_cookie, set_cookies from module.utils import fixup, fs_encode, parseFileSize as parse_size @@ -22,12 +22,13 @@ statusMap = dict((v, k) for k, v in _statusMap.items()) class SimpleHoster(Hoster): __name__ = "SimpleHoster" __type__ = "hoster" - __version__ = "1.81" + __version__ = "1.82" __status__ = "testing" __pattern__ = r'^unmatchable$' - __config__ = [("use_premium", "bool", "Use premium account if available" , True), - ("fallback" , "bool", "Fallback to free download if premium fails", True)] + __config__ = [("use_premium" , "bool", "Use premium account if available" , True), + ("premium_fallback", "bool", "Fallback to free download if premium fails", True), + ("chk_filesize" , "bool", "Check file size" , True)] __description__ = """Simple hoster plugin""" __license__ = "GPLv3" @@ -174,7 +175,8 @@ class SimpleHoster(Hoster): info['status'] = 2 if 'N' in info['pattern']: - info['name'] = replace_patterns(fixurl(info['pattern']['N']), + name = fixname(info['pattern']['N']) + info['name'] = replace_patterns(fixurl(name), cls.NAME_REPLACEMENTS) if 'S' in info['pattern']: @@ -294,7 +296,7 @@ class SimpleHoster(Hoster): self.check_file() except Fail, e: #@TODO: Move to PluginThread in 0.4.10 - if self.get_config('fallback', True) and self.premium: + if self.get_config('premium_fallback', True) and self.premium: self.log_warning(_("Premium download failed"), e) self.restart(nopremium=True) @@ -309,15 +311,16 @@ class SimpleHoster(Hoster): self.captcha.invalid() self.retry(10, reason=_("Wrong captcha")) - # 10485760 is 10MB, tolerance is used when comparing displayed size on the hoster website to real size - # For example displayed size can be 1.46GB for example, but real size can be 1.4649853GB elif self.check_download({'Empty file': re.compile(r'\A((.|)(\2|\s)*)\Z')}, - file_size=self.info['size'] if 'size' in self.info else 0, - size_tolerance=10485760, - delete=False): #@TODO: Make `delete` settable in 0.4.10 + delete=True): self.error(_("Empty file")) else: + if self.get_config('chk_filesize', False) and 'size' in self.info: + # 10485760 is 10MB, tolerance is used when comparing displayed size on the hoster website to real size + # For example displayed size can be 1.46GB for example, but real size can be 1.4649853GB + self.check_filesize(self.info['size'], size_tolerance=10485760) + self.log_debug("Using default check rules...") for r, p in self.FILE_ERRORS: errmsg = self.check_download({r: re.compile(p)}) @@ -340,7 +343,7 @@ class SimpleHoster(Hoster): self.check_errors() self.log_info(_("No errors found")) - self.pyfile.error = "" + self.pyfile.error = "" #@TODO: Recheck in 0.4.10 def check_errors(self): diff --git a/module/plugins/internal/XFSAccount.py b/module/plugins/internal/XFSAccount.py index 5a4cc35fb..3f2158a0b 100644 --- a/module/plugins/internal/XFSAccount.py +++ b/module/plugins/internal/XFSAccount.py @@ -4,6 +4,7 @@ import re import time import urlparse +from module.common.json_layer import json_loads from module.plugins.internal.Account import Account from module.plugins.internal.Plugin import parse_html_form, set_cookie @@ -11,7 +12,7 @@ from module.plugins.internal.Plugin import parse_html_form, set_cookie class XFSAccount(Account): __name__ = "XFSAccount" __type__ = "account" - __version__ = "0.43" + __version__ = "0.44" __status__ = "testing" __description__ = """XFileSharing account plugin""" @@ -174,5 +175,13 @@ class XFSAccount(Account): html = self.load(url, post=inputs, cookies=self.COOKIES) - if re.search(self.LOGIN_FAIL_PATTERN, html): - self.login_fail() + try: + json = json_loads(html) + + except ValueError: + if re.search(self.LOGIN_FAIL_PATTERN, html): + self.login_fail() + + else: + if not 'success' in json or not json['success']: + self.login_fail() |