def _episode_worker(self, link): episode_number = int(re.search( r'/Anime/.+?/Episode-(\d{3,})\?id=\d+$', link ).group(1)) if not self._should_process(episode_number): return self.logger.info('Processing episode {}'.format(episode_number)) response, soup = self._get( self._get_url() + link, return_response=True ) quality_select = soup.find('select', {'id': 'selectQuality'}) if quality_select is None: self.logger.warning('Could not extract sources, captcha required') return for option in quality_select: quality = int(''.join([x for x in option.text if x.isdigit()])) src = base64.b64decode(option.get('value')).decode('utf-8') self._add_source(episode_number, Source(src, quality)) self.logger.info('Done processing episode {}'.format(episode_number))
def _episode_worker(self, link): # First extract the anime and episodes ids results = re.search(r'/watch/([0-9]+)/.+?/([0-9]+)', link) id = results.group(1) episode_number = int(results.group(2)) if not self._should_process(episode_number): return self.logger.info('Processing episode {}'.format(episode_number)) # Then get the downlaod link src = self.session.post('http://moetube.net/rui.php', data={ 'id': id, 'ep': episode_number, 'chk': 1 }).text try: quality = get_quality(src) except: return self._add_source(episode_number, Source(src, quality)) self.logger.info('Done processing episode {}'.format(episode_number))
def unshorten(url, quality=None): '''Inspired from https://github.com/Zanzibar82/plugin.video.streamondemand/ blob/bf655c445e77be57ef4ece84f11b5899a41e0939/servers/openload.py.''' import js2py html = requests.get(url).text # Extract the obfuscated code from which we can deduce the url matches = re.findall(r'(゚ω゚ノ= /`m´)ノ ~┻━┻.+?)</script>', html) matches = [AADecoder(m).decode() for m in matches] logger.debug(matches) # Search the index (the page have two urls, we need to select the correct # one). js = re.search(r'window.+[\n\s]?.+= (.+?);', matches[0]).group(1) index = js2py.eval_js(js) logger.debug(index) # Now we get the valid url section = matches[index] function = re.search(r'window.+\[\d\]=(\(.+\));window', section).group(1) url = conv(function) logger.debug(matches) if quality is None: quality = get_quality(url) return [Source(url, quality)]
def unshorten(url, quality=None): html = requests.get(url).text src = re.search(r'downloadlink: "(.+?)",', html).group(1) if quality is None: logger.warning('[videonest] quality was not passed') quality = get_quality(src) return [Source(src, quality)]
def unshorten(url, quality=None): soup = BeautifulSoup(requests.get(url).text, 'html.parser') src = '' if quality is None: logger.warning('[{{name}}] quality was not passed') quality = get_quality(src) return [Source(src, quality)]
def unshorten(url, quality=None): soup = BeautifulSoup(requests.get(url).text, 'html.parser') link = soup.find('a', {'id': 'download-btn'}).get('href') logger.debug('[solidfiles] Found {}'.format(link)) if quality is None: quality = get_quality(link) return [Source(link, quality)]
def unshorten(url, quality=None): html = requests.get(url).text if 'File was deleted' in html: logger.warning('[mp4upload] File at {} was deleted'.format(url)) return [] src = re.search(r'"file": "(.+)"', html).group(1) if quality is None: logger.warning('[mp4upload] quality was not passed') quality = get_quality(src) return [Source(src, quality)]
def unshorten(url, quality=None): html = requests.get(url).text logger.debug(html) frame_html = str(base64.b64decode( re.search(r'atob\(\'(.+)\'\)', html).group(1) )) src = re.search(r'<source src="(.+?)" type="', frame_html).group(1) logger.debug('[stream.moe] found source {}'.format(src)) if quality is None: logger.warning('[stream.moe] quality was not passed') quality = get_quality(src) return [Source(src, quality)]
def unshorten(url, quality=None): source = requests.get(url).text # Quoted url to a page that redirects to the source quoted_url = re.search(r'_url = "(.+?)";', source).group(1) query_string = urllib.parse.urlparse( urllib.parse.unquote(quoted_url)).query # The script just redirect by decoding the passed base64 url encoded_url = urllib.parse.parse_qs(query_string)['url'][0] src = base64.b64decode(encoded_url).decode('utf-8') if quality is None: logger.warning('[playbb] quality was not passed') quality = get_quality(src) return [Source(src, quality)]
def unshorten(url, quality=None): import js2py html = requests.get(url).text javascript = '{}.split(\'|\')[1]'.format( re.search(r'\["fmt_stream_map"\,(".+?")\]', html).group(1)) logger.debug('Executing: {}'.format(javascript)) src = js2py.eval_js(javascript) logger.debug('[google drive] found source {}'.format(src)) if quality is None: logger.warning('[google drive] quality was not passed') quality = get_quality(src) return [Source(src, quality)]
def _episode_worker(self, url): results = re.search(r'/Watch/(\d+)/(.+)/episode-(\d{1,3})/', url) episode_number = int(results.group(3)) if not self._should_process(episode_number): return self.logger.info('Processing episode {}'.format(episode_number)) soup = self._post('http://chiaanime.co/lib/picasa.php', data={ 'id': results.group(1), 'anime': results.group(2), 'episode': episode_number, 'player': 'html5' }) for link in soup.select('#divDownload a'): quality = int(re.search(r'(\d+)p', link.text).group(1)) self._add_source(episode_number, Source(link.get('href'), quality)) self.logger.info('Done processing episode {}'.format(episode_number))
def unshorten(url, quality=None): soup = BeautifulSoup(requests.get(url).text, 'html.parser') form = soup.find('form', {'name': 'F1'}) payload = {} fields = ['op', 'id', 'rand', 'referer', 'method_free', 'method_premium'] for input in form.select('input'): if input.get('name') not in fields: continue payload[input.get('name')] = input.get('value') logger.debug('[tufiles] {}'.format(payload)) src = requests.post(url, data=payload, stream=True).url if quality is None: logger.warning('[tusfiles] quality was not passed') quality = get_quality(src) return [Source(src, quality)]
def map_sources(self, episode): if not self._should_process(episode['episode_number']): return retries = 0 success = False episode_response = None while retries < 10 and not success: url = ('http://api.htvanime.com/api/v1/anime_episode_videos/?' 'anime_episode_slug={}').format(episode['slug']) try: # We have a lot of 500 errors there.. episode_response = requests.get(url, timeout=3).json() if episode_response is not None: break else: self.logger.warning('Retrying, {} left'.format(retries)) retries += 1 except (json.decoder.JSONDecodeError, requests.exceptions.ReadTimeout): retries += 1 self.logger.warning('Retrying, {} left'.format(retries)) # TODO: special episodes if not episode['episode_number']: return None episode_number = int(episode['episode_number']) self.logger.info('Processing episode {}'.format(episode_number)) for source in episode_response: quality = int(''.join(x for x in source['quality'] if x.isdigit())) source = Source(source['url'], quality) self._add_source(episode_number, source)
def unshorten(url, quality=None): if not url.startswith('https'): url = 'https' + url[4:] def get_payload(source, selector, fields): soup = BeautifulSoup(source, 'html.parser') form = soup.select(selector) payload = {} for input in soup.find_all('input'): if input.get('name') not in fields: continue payload[input.get('name')] = input.get('value') return payload download_1_payload = get_payload( requests.get(url).text, 'form', ['op', 'usr_login', 'id', 'fname', 'referer', 'method_free']) download_2_payload = get_payload( requests.post(url, data=download_1_payload).text, 'form[name="F1"]', ['op', 'usr_login', 'id', 'fname', 'referer', 'method_free']) soup = BeautifulSoup( requests.post(url, data=download_2_payload).text, 'html.parser') src = soup.select('.text-center a')[0].get('href') if quality is None: logger.warning('[upload.af] quality was not passed') quality = get_quality(src) return [Source(src, quality)]
def unshorten(url, quality=None): id = re.search(r'https?://bakavideo.tv/embed/(.+)', url).group(1) data = requests.get( 'https://bakavideo.tv/get/files.embed?f={}'.format(id)).json() html = base64.b64decode(data['content']).decode('utf-8').replace( '\n', '').replace('\t', '') soup = BeautifulSoup(html, 'html.parser') source_div = src = soup.find('source') if not source_div: return None src = source_div.get('src') logger.debug('[bakavideo] found source {}'.format(src)) if quality is None: logger.warning('[bakavideo] quality was not passed') quality = get_quality(src) return [Source(src, quality)]
def unshorten(url, quality=None): # Some of the videos are available on the first page. If this regex is # successfull, then the video is directly available. # On the download page, the download link does not use href, but calls some # javascript. After a short inspection of the code, I determined we only # need to extract the parameter of the called method to be able to generate # the link ourselves. soup = BeautifulSoup(requests.get(url).text, 'html.parser') # Lists all the download links download_table = soup.find('table', {'class': 'tbl1'}) if not download_table: logger.warning('[tiwi.kiwi] could not locate download table') return None sources = [] for tr in download_table.find_all('tr'): # We filter out the first row (header) like that, since there are no # thead or tbody. if len(tr.find_all('a')) <= 0: continue # First get the quality quality_regex_results = re.search(r'[0-9]+x([0-9]+), .+ [a-zA-Z]+', tr.find_all('td')[1].text) if not quality_regex_results: continue quality = int(quality_regex_results.group(1)) logger.debug('[tiwi.kiwi] found link with quality {}'.format(quality)) # Then extract the download url onclick_regex_result = re.search( r"download_video\('(.+)','(.+)','(.+)'\)", tr.find('a').get('onclick')) if not onclick_regex_result: continue code = onclick_regex_result.group(1) mode = onclick_regex_result.group(2) hash = onclick_regex_result.group(3) logger.debug('[tiwi.kiwi] {}'.format({ 'code': code, 'mode': mode, 'hash': hash })) url = ('http://tiwi.kiwi/dl?op=download_orig&id={}&' 'mode={}&hash={}'.format(code, mode, hash)) # The website often returns an unauthorized error, that we can bypass # by sending more requests. Usually, only one or two requests are # needed. retries = 10 retry = 0 while retry < retries: download_soup = BeautifulSoup( requests.get(url).text, 'html.parser') # The container is always present. However, the span isn't when a # security error occur. span = download_soup.find('div', {'id': 'container'}).find('span') if not span: logger.warning('[tiwi.kiwi] Retrying, {} left'.format(retry)) retry += 1 continue link = span.find('a').get('href') logger.debug('[tiwi.kiwi] Found link: {}'.format(link)) sources.append(Source(link, quality)) break return sources