#!/usr/bin/env python # -*- coding: utf-8 -*- # Test links (random.bin): # http://www29.zippyshare.com/v/55578602/file.html import re import subprocess import tempfile import os from module.plugins.internal.SimpleHoster import SimpleHoster, create_getInfo, timestamp from module.plugins.internal.CaptchaService import ReCaptcha from module.common.json_layer import json_loads class ZippyshareCom(SimpleHoster): __name__ = "ZippyshareCom" __type__ = "hoster" __pattern__ = r"(?P<HOST>http://www\d{0,2}\.zippyshare.com)/v(?:/|iew.jsp.*key=)(?P<KEY>\d+)" __version__ = "0.42" __description__ = """Zippyshare.com Download Hoster""" __author_name__ = ("spoob", "zoidberg", "stickell") __author_mail__ = ("spoob@pyload.org", "zoidberg@mujmail.cz", "l.stickell@yahoo.it") __config__ = [("swfdump_path", "string", "Path to swfdump", "")] FILE_NAME_PATTERN = r'>Name:</font>\s*<font [^>]*>(?P<N>[^<]+)</font><br />' FILE_SIZE_PATTERN = r'>Size:</font>\s*<font [^>]*>(?P<S>[0-9.,]+) (?P<U>[kKMG]+)i?B</font><br />' FILE_INFO_PATTERN = r'document\.getElementById\(\'dlbutton\'\)\.href = "[^;]*/(?P<N>[^"]+)";' FILE_OFFLINE_PATTERN = r'>File does not exist on this server</div>' SH_COOKIES = [('zippyshare.com', 'ziplocale', 'en')] DOWNLOAD_URL_PATTERN = r"<script type=\"text/javascript\">([^<]*?)(document\.getElementById\('dlbutton'\).href = [^;]+;)" SEED_PATTERN = r'swfobject.embedSWF\("([^"]+)".*?seed: (\d+)' CAPTCHA_KEY_PATTERN = r'Recaptcha.create\("([^"]+)"' CAPTCHA_SHORTENCODE_PATTERN = r"shortencode: '([^']+)'" CAPTCHA_DOWNLOAD_PATTERN = r"document.location = '([^']+)'" LAST_KNOWN_VALUES = (9, 2374755) # time = (seed * multiply) % modulo def setup(self): self.multiDL = True def handleFree(self): url = self.get_file_url() if not url: self.fail("Download URL not found.") self.logDebug("Download URL: %s" % url) self.download(url) check = self.checkDownload({ "swf_values": re.compile(self.SEED_PATTERN) }) if check == "swf_values": swf_sts = self.getStorage("swf_sts") if not swf_sts: self.setStorage("swf_sts", 2) self.setStorage("swf_stamp", 0) elif swf_sts == '1': self.setStorage("swf_sts", 2) self.retry(max_tries=1) def get_file_url(self): """ returns the absolute downloadable filepath """ url = None found = re.search(self.DOWNLOAD_URL_PATTERN, self.html, re.S) #Method #1: JS eval if found and re.search(r'span id="omg" class="(\d*)"', self.html): js = "\n".join(found.groups()) d = re.search(r'span id="omg" class="(\d*)"', self.html).group(1) regex = r"document.getElementById\('omg'\).getAttribute\('class'\)" js = re.sub(regex, d, js) regex = r"document.getElementById\(\\*'dlbutton\\*'\).href = " js = re.sub(regex, '', js) url = self.js.eval(js) elif found and re.search(r"document.getElementById\(\\*'dlbutton\\*'\).omg", self.html): js = "\n".join(found.groups()) regex = r"document.getElementById\(\\*'dlbutton\\*'\).omg" omg = re.search(regex + r" = ([^;]+);", js).group(1) js = re.sub(regex + r" = ([^;]+);", '', js) js = re.sub(regex, omg, js) js = re.sub(r"document.getElementById\(\\*'dlbutton\\*'\).href = ", '', js) url = self.js.eval(js) elif found and re.search(r"document.getElementById\(\\*'dlbutton\\*'\).href = \"", self.html): js = "\n".join(found.groups()) js = re.sub(r"document.getElementById\(\\*'dlbutton\\*'\).href = ", '', js) url = self.js.eval(js) else: #Method #2: SWF eval url = self.swf_eval() if not url: #Method #3: Captcha url = self.do_recaptcha() return self.file_info['HOST'] + url def swf_eval(self): multiply = modulo = None seed_search = re.search(self.SEED_PATTERN, self.html) if seed_search: swf_url, file_seed = seed_search.groups() swf_sts = self.getStorage("swf_sts") swf_stamp = int(self.getStorage("swf_stamp") or 0) swf_version = self.getStorage("version") self.logDebug("SWF", swf_sts, swf_stamp, swf_version) if not swf_sts: self.logDebug('Using default values') multiply, modulo = self.LAST_KNOWN_VALUES elif swf_sts == "1": self.logDebug('Using stored values') multiply = self.getStorage("multiply") modulo = self.getStorage("modulo") elif swf_sts == "2": if swf_version < self.__version__: self.logDebug('Reverting to default values') self.setStorage("swf_sts", "") self.setStorage("version", self.__version__) multiply, modulo = self.LAST_KNOWN_VALUES elif (swf_stamp + 3600000) < timestamp(): swfdump = self.get_swfdump_path() if swfdump: multiply, modulo = self.get_swf_values(self.file_info['HOST'] + swf_url, swfdump) else: self.logWarning("Swfdump not found. Install swftools to bypass captcha.") if multiply and modulo: self.logDebug("TIME = (%s * %s) %s" % (file_seed, multiply, modulo)) url = "/download?key=%s&time=%d" % (self.file_info['KEY'], (int(file_seed) * int(multiply)) % int(modulo)) return url return None def get_swf_values(self, swf_url, swfdump): self.logDebug('Parsing values from %s' % swf_url) multiply = modulo = None fd, fpath = tempfile.mkstemp() try: swf_data = self.load(swf_url) os.write(fd, swf_data) p = subprocess.Popen([swfdump, '-a', fpath], stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, err = p.communicate() if err: self.logError(err) else: m_str = re.search(r'::break.*?{(.*?)}', out, re.S).group(1) multiply = re.search(r'pushbyte (\d+)', m_str).group(1) modulo = re.search(r'pushint (\d+)', m_str).group(1) finally: os.close(fd) os.remove(fpath) if multiply and modulo: self.setStorage("multiply", multiply) self.setStorage("modulo", modulo) self.setStorage("swf_sts", 1) self.setStorage("version", self.__version__) else: self.logError("Parsing SWF failed: swfdump not installed or plugin out of date") self.setStorage("swf_sts", 2) self.setStorage("swf_stamp", timestamp()) return multiply, modulo def get_swfdump_path(self): # used for detecting if swfdump is installed def is_exe(ppath): return os.path.isfile(ppath) and os.access(ppath, os.X_OK) program = self.getConfig("swfdump_path") or "swfdump" swfdump = None ppath, pname = os.path.split(program) if ppath: if is_exe(program): swfdump = program else: for ppath in os.environ["PATH"].split(os.pathsep): exe_file = os.path.join(ppath, program) if is_exe(exe_file): swfdump = exe_file # return path to the executable or None if not found return swfdump def do_recaptcha(self): self.logDebug('Trying to solve captcha') captcha_key = re.search(self.CAPTCHA_KEY_PATTERN, self.html).group(1) shortencode = re.search(self.CAPTCHA_SHORTENCODE_PATTERN, self.html).group(1) url = re.search(self.CAPTCHA_DOWNLOAD_PATTERN, self.html).group(1) recaptcha = ReCaptcha(self) for i in range(5): challenge, code = recaptcha.challenge(captcha_key) response = json_loads(self.load(self.file_info['HOST'] + '/rest/captcha/test', post={'challenge': challenge, 'response': code, 'shortencode': shortencode})) self.logDebug("reCaptcha response : %s" % response) if response == True: self.correctCaptcha() break else: self.invalidCaptcha() else: self.fail("Invalid captcha") return url getInfo = create_getInfo(ZippyshareCom)