示例#1
0
    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))
示例#2
0
    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))
示例#3
0
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)]
示例#4
0
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)]
示例#5
0
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)]
示例#6
0
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)]
示例#7
0
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)]
示例#8
0
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)]
示例#9
0
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)]
示例#10
0
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)]
示例#11
0
    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))
示例#12
0
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)]
示例#13
0
    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)
示例#14
0
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)]
示例#15
0
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)]
示例#16
0
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