Пример #1
0
def dl(ctx, anime_url, episode_range, url, player, skip_download, quality,
       force_download, log_level, download_dir):
    """ Download the anime using the url or search for it.
    """

    util.setup_logger(log_level)
    util.print_info(__version__)

    cls = get_anime_class(anime_url)

    if not cls:
        anime_url = util.search_and_get_url(anime_url)
        cls = get_anime_class(anime_url)

    try:
        anime = cls(anime_url, quality=quality)
    except NotFoundError as e:
        echo(e.args[0])
        return
    if episode_range is None:
        episode_range = '1:' + str(len(anime) + 1)

    logging.info('Found anime: {}'.format(anime.title))

    anime = util.split_anime(anime, episode_range)
    util.process_anime(anime,
                       player=player,
                       force_download=force_download,
                       download_dir=download_dir,
                       url=url,
                       skip_download=skip_download)
Пример #2
0
def dl(ctx, anime_url, episode_range, url, player, skip_download, quality,
       force_download, log_level, download_dir, file_format, provider,
       external_downloader):
    """ Download the anime using the url or search for it.
    """

    util.setup_logger(log_level)
    util.print_info(__version__)

    cls = get_anime_class(anime_url)

    if not cls:
        anime_url = util.search(anime_url, provider)
        cls = get_anime_class(anime_url)

    try:
        anime = cls(anime_url, quality=quality)
    except Exception as e:
        echo(click.style(str(e), fg='red'))
        return

    # TODO: Refractor this somewhere else. (util?)
    if episode_range is None:
        episode_range = '1:'
    if episode_range.endswith(':'):
        episode_range += str(len(anime) + 1)
    if episode_range.startswith(':'):
        episode_range = '1' + episode_range

    logging.info('Found anime: {}'.format(anime.title))

    anime = util.split_anime(anime, episode_range)

    if url or player:
        skip_download = True

    if download_dir and not skip_download:
        logging.info('Downloading to {}'.format(os.path.abspath(download_dir)))

    for episode in anime:
        if url:
            util.print_episodeurl(episode)

        if player:
            util.play_episode(episode, player=player)

        if not skip_download:
            if external_downloader:
                logging.info('Downloading episode {} of {}'.format(
                    episode.ep_no, anime.title))
                util.external_download(external_downloader,
                                       episode,
                                       file_format,
                                       path=download_dir)
                continue

            episode.download(force=force_download,
                             path=download_dir,
                             format=file_format)
            print()
Пример #3
0
    def _get_anime_info_class(self, url):
        cls = get_anime_class(url)
        if not cls:
            logger.warn(
                f"The url: {url} is no longer supported. The provider needs to be set manually upon selection."
            )
            """
            Provides some level of backcompatability when watch lists have providers that have been removed. They are then warned via logger that they will 
            have to change providers using the set function when an anime is selected in the list. 
            """
            url = ALL_ANIME_SITES[0][1]
            cls = get_anime_class(url)

        # TODO: Maybe this is better off as a mixin
        class AnimeInfo(cls, sitename=cls.sitename):
            def __init__(self, *args, **kwargs):
                self.episodes_done = kwargs.pop('episodes_done', 0)
                self._timestamp = kwargs.pop('timestamp', 0)
                # Initial values needed for MAL which can't be got yet from just a simple addition to the watch list.
                self.score = 0
                self.watch_status = 'watching'
                self.colours = 'blue'
                self.mal_ID = 0
                super(cls, self).__init__(*args, **kwargs)

            def progress(self):
                return (self.episodes_done, len(self))

        return AnimeInfo
Пример #4
0
def command(ctx, anime_url, episode_range, url, player, skip_download, quality,
            force_download, download_dir, file_format, provider,
            external_downloader, chunk_size, disable_ssl, fallback_qualities,
            choice):
    """ Download the anime using the url or search for it.
    """
    util.print_info(__version__)
    # TODO: Replace by factory
    cls = get_anime_class(anime_url)

    disable_ssl = cls and cls.__name__ == 'Masterani' or disable_ssl
    session.get_session().verify = not disable_ssl

    if not cls:
        anime_url = util.search(anime_url, provider, choice)
        cls = get_anime_class(anime_url)

    anime = cls(anime_url,
                quality=quality,
                fallback_qualities=fallback_qualities)
    logger.info('Found anime: {}'.format(anime.title))

    animes = util.parse_ep_str(anime, episode_range)

    # TODO:
    # Two types of plugins:
    #   - Aime plugin: Pass the whole anime
    #   - Ep plugin: Pass each episode
    if url or player:
        skip_download = True

    if download_dir and not skip_download:
        logger.info('Downloading to {}'.format(os.path.abspath(download_dir)))

    for episode in animes:
        if url:
            util.print_episodeurl(episode)

        if player:
            util.play_episode(episode, player=player)

        if not skip_download:
            if external_downloader:
                logging.info('Downloading episode {} of {}'.format(
                    episode.ep_no, anime.title))
                util.external_download(external_downloader,
                                       episode,
                                       file_format,
                                       path=download_dir)
                continue
            if chunk_size is not None:
                chunk_size *= 1e6
                chunk_size = int(chunk_size)
            with requests_cache.disabled():
                episode.download(force=force_download,
                                 path=download_dir,
                                 format=file_format,
                                 range_size=chunk_size)
            print()
Пример #5
0
async def episode(ctx, number):
    async with ctx.typing():
        str_id = str(ctx.author.id)
        f = Load(anime_config)
        if Int(number):
            if str_id in f:
                user = f[str_id]
                user["episode"] = int(number) - 1
                Write(f, anime_config)
                Provider = get_anime_class(f[str_id].get(
                    "provider", default_provider))
                print(user["select"]["url"])
                await ctx.send(f'Selected episode {number}')
                try:
                    print(user["select"]["url"])
                    anime = Provider(user["select"]["url"])
                    embed = discord.Embed(
                        title=user["select"]["title"] +
                        f' - Episode {user["episode"]+1}/{len(anime)}',
                        url=anime[user["episode"]].source().stream_url)
                except:
                    await ctx.send('Error selecting episode')
                try:
                    await ctx.send(embed=embed)
                except:
                    await ctx.send(anime[user["episode"]].source().stream_url)
        else:
            await ctx.send(f'Invalid number: "{number}"')
Пример #6
0
async def _select(message, str_id, number):
    f = Load(anime_config)
    if str_id in f and Int(number):
        Provider = get_anime_class(f[str_id].get("provider", default_provider))
        user = f[str_id]
        number = int(number) - 1  #Starts from 1
        await message.channel.send('Selected: ' +
                                   user["data"][number]["title"] +
                                   f' - **Episode: {user["episode"]+1}**')
        user["select"]["url"], user["select"]["title"] = user["data"][number][
            "url"], user["data"][number]["title"]
        Write(f, anime_config)
        try:
            anime = Provider(user["data"][number]["url"])
            embed = discord.Embed(
                title=user["data"][number]["title"] +
                f' - Episode {user["episode"]+1}/{len(anime)}',
                url=anime[user["episode"]].source().stream_url)
        except:
            await message.channel.send('Error selecting episode')

        try:  #Fix embed here
            await message.channel.send(embed=embed)
        except:
            await message.channel.send(
                anime[user["episode"]].source().stream_url)
Пример #7
0
def getDownloadFromUrl(url):
    print("Getting video meta-data for the url: {}".format(url))
    kissAnimeInterface = get_anime_class('kissanime')
    currentAnime = kissAnimeInterface(url, quality="480p")
    currentAnimeName = currentAnime.title

    episodes = len(currentAnime)
    files = checkForAnimeYamlFile(os.getcwd())

    if currentAnimeName.replace(" ", "-") + ".yaml" in files:
        episodeNum = getCurrentEpisodeFromYaml(files, currentAnimeName)
    else:
        episodeNum = -1

    print("Found {} videos in this series to download. \n".format(episodes))
    print("Downloading {} episdoes. This may take some time!".format(episodes))

    if episodeNum == -1 or episodeNum == 0:
        print("Starting a new download session for `{}`".format(
            currentAnimeName))
        normalDownload(episodes, currentAnime, currentAnimeName)
    # do a normal download as there is not a cache file here
    else:
        print("Resuming download session for `{}` at episode: {}".format(
            currentAnimeName, episodeNum))
        downloadFromPos(episodes, currentAnime, currentAnimeName, episodeNum)
        # download from the current episode, rewriting the latest one just incase it is corrupt.

    # once the files have been downloaded move them to the correct directory
    moveVideosToSelectedDir(currentAnimeName,
                            currentAnimeName.replace(" ", "-") + ".yaml")
Пример #8
0
    def get_animes(self):
        # if nothing is selected it returns -1
        # this makes the choice the first one if nothing is selected from search.
        if self.searchOutput.currentRow() != -1:
            choice = self.searchOutput.currentRow() + 1
        else:
            choice = 1

        start = self.animeEpisodeStart.text(
        ) if self.animeEpisodeStart.text().isnumeric() else 1
        end = int(self.animeEpisodeEnd.text()) + \
            1 if self.animeEpisodeEnd.text().isnumeric() else ''
        episode_range = f'{start}:{end}'

        anime = self.animeName.text()
        provider = self.providers.currentText()
        print(anime, provider, choice)
        anime_url, _ = util.search(anime, provider, choice)

        cls = get_anime_class(anime_url)
        anime = cls(anime_url)
        ep_range = util.parse_episode_range(len(anime), episode_range)
        animes = util.split_anime(anime, ep_range)
        # animes = util.parse_ep_str(anime, episode_range)
        anime_title = anime.title
        # maybe make animes/anime_title self.animes?
        return animes, anime_title
Пример #9
0
    def run(self):
        try:
            ani = get_anime_class(self.provider)
            self.search_result = ani.search(self.anime)
            if self.search_result:
                if self.verify:
                    ratios = [[
                        fuzz.token_set_ratio(self.anime.lower(),
                                             sr.title.lower()), sr
                    ] for sr in self.search_result]
                    ratios = sorted(ratios, key=lambda x: x[0], reverse=True)

                    end = len(ratios)
                    for r in range(self.v_tries):
                        if r == end: break
                        try:
                            anime_choice = ratios[r][1]
                            anime_url = ani(anime_choice.url)
                            stream_url = anime_url[0].source().stream_url
                            self.exception = None
                            break
                        except Exception as e:
                            self.exception = e

                self.search_result = util.format_search_results(
                    self.search_result)

        except Exception as e:
            self.exception = e
Пример #10
0
async def _(event):
    if event.fwd_from:
        return
    input_str = event.pattern_match.group(1)
    lmao = input_str.split(":", 1)
    site = lmao[0]
    lol = lmao[1]
    why = site.lower()

    Twist = get_anime_class(why)
    search = Twist.search(lol)

    title1 = search[0].title
    url1 = search[0].url
    title2 = search[1].title
    url2 = search[1].url
    title3 = search[2].title
    url3 = search[2].url
    title4 = search[3].title
    url4 = search[3].url
    title5 = search[4].title
    url5 = search[4].url

    await event.edit(
        f"<b><u>Anime Search Complete</b></u> \n\n\n<b>Title</b>:-  <code>{title1}</code> \n<b>URL Link</b>:- <code>{url1}</code>\n\n<b>Title</b>:-  <code>{title2}</code> \n<b>URL Link</b>:- <code>{url2}</code>\n\n<b>Title</b>:-  <code>{title3}</code> \n<b>URL Link</b>:- <code>{url3}</code>\n\n<b>Title</b>:-  <code>{title4}</code> \n<b>URL Link</b>:- <code>{url4}</code>\n\n<b>Title</b>:-  <code>{title5}</code> \n<b>URL Link</b>:- <code>{url5}</code>",
        parse_mode="HTML",
    )
Пример #11
0
def search(query, provider):
    # Since this function outputs to stdout this should ideally be in
    # cli. But it is used in watch too. :(
    cls = get_anime_class(provider)
    try:
        search_results = cls.search(query)
    except Exception as e:
        logging.error(click.style(str(e), fg='red'))
        sys.exit(1)
    click.echo(format_search_results(search_results))

    if not search_results:
        logging.error('No such Anime found. Please ensure correct spelling.')
        sys.exit(1)

    val = click.prompt('Enter the anime no: ', type=int, default=1)

    try:
        url = search_results[val - 1].url
        title = search_results[val - 1].title
    except IndexError:
        logging.error('Only maximum of {} search results are allowed.'
                      ' Please input a number less than {}'.format(
                          len(search_results),
                          len(search_results) + 1))
        sys.exit(1)

    logging.info('Selected {}'.format(title))

    return url
Пример #12
0
def fuzzy_match_metadata(seasons_info, search_results):
    # Gets the SearchResult object with the most similarity title-wise to the first MAL/Anilist result
    results = []
    for i in seasons_info:
        for j in search_results:
            # Allows for returning of cleaned title by the provider using 'title_cleaned' in meta_info.
            # To make fuzzy matching better.
            title_provider = j.title.strip() if not j.meta_info.get('title_cleaned') else j.meta_info.get('title_cleaned').strip()
            # On some titles this will be None
            # causing errors below
            title_info = i.title

            # Essentially adds the chosen key to the query if the version is in use
            # Dirty solution, but should work pretty well

            config = Config['siteconfig'].get(get_anime_class(j.url).sitename, {})
            version = config.get('version')
            version_use = version == 'dubbed'
            # Adds something like (Sub) or (Dub) to the title
            key_used = j.meta_info.get('version_key_dubbed', '') if version_use else j.meta_info.get('version_key_subbed', '')
            title_info += ' ' + key_used
            title_info = title_info.strip()

            # TODO add synonyms
            # 0 if there's no japanese name
            jap_ratio = fuzz.ratio(i.jp_title, j.meta_info['jp_title']) if j.meta_info.get('jp_title') else 0
            # Outputs the max ratio for japanese or english name (0-100)
            ratio = max(fuzz.ratio(title_info, title_provider), jap_ratio)
            logger.debug('Ratio: {}, Info title: {}, Provider Title: {}, Key used: {}'.format(ratio, title_info, title_provider, key_used))
            results.append(MatchObject(i, j, ratio))

    # Returns the result with highest ratio
    return max(results, key=lambda item: item.ratio)
Пример #13
0
async def anime(client, message):
    pablo = await edit_or_reply(message, "`Searching For Anime.....`")
    anime = get_text(message)
    if not anime:
        await pablo.edit("`Please Give Me A Valid Input. You Can Check Help Menu To Know More!`")
        return
    lmao = anime.split(":", 1)
    try:
        site = lmao[1]
    except BaseException:
        site = "animeonline360"
        await pablo.edit(
            "Please Provide Site Name From Next Time. Now Continuing With Default Site."
        )

    lol = lmao[0]
    why = site.lower()
    Twist = get_anime_class(why)
    try:
        search = Twist.search(lol)
    except BaseException:
        await ommhg.edit("Please Try Different Site. Given Site Is Down.")

    title1 = search[0].title
    url1 = search[0].url
    title2 = search[1].title
    url2 = search[1].url
    title3 = search[2].title
    url3 = search[2].url
    title4 = search[3].title
    url4 = search[3].url
    title5 = search[4].title
    url5 = search[4].url
    NopZ = f"<b><u>Anime Search Complete</b></u> \n\n\n<b>Title</b>:-  <code>{title1}</code> \n<b>URL Link</b>:- {url1}\n\n<b>Title</b>:-  <code>{title2}</code> \n<b>URL Link</b>:- {url2}\n\n<b>Title</b>:-  <code>{title3}</code>\n<b>URL Link</b>:- {url3}\n\n<b>Title</b>:-  <code>{title4}</code> \n<b>URL Link</b>:- {url4}\n\n<b>Title</b>:-  <code>{title5}</code> \n<b>URL Link</b>:- {url5}\n\n<b>Links Gathered By Friday\nGet Your Own Friday From @FRIDAYCHAT</b>"
    await pablo.edit(NopZ, parse_mode="html")
Пример #14
0
def dl(ctx, anime_url, episode_range, url, player, skip_download, quality,
       force_download, log_level, download_dir, file_format, provider):
    """ Download the anime using the url or search for it.
    """

    util.setup_logger(log_level)
    util.print_info(__version__)

    cls = get_anime_class(anime_url)

    if not cls:
        anime_url = util.search(anime_url, provider)
        cls = get_anime_class(anime_url)

    try:
        anime = cls(anime_url, quality=quality)
    except Exception as e:
        echo(click.style(str(e), fg='red'))
        return
    if episode_range is None:
        episode_range = '1:' + str(len(anime) + 1)

    logging.info('Found anime: {}'.format(anime.title))

    anime = util.split_anime(anime, episode_range)

    if url or player:
        skip_download = True

    if download_dir and not skip_download:
        logging.info('Downloading to {}'.format(os.path.abspath(download_dir)))

    for episode in anime:
        if url:
            util.print_episodeurl(episode)

        if player:
            util.play_episode(episode, player=player)

        if not skip_download:
            episode.download(force=force_download,
                             path=download_dir,
                             format=file_format)
            print()
Пример #15
0
def hello(name, ep, provider, autoplay):
    Anime = get_anime_class(provider)
    player = 'mpv'
    searchResults = Anime.search(name)
    # click.echo(searchResults)
    anime = Anime(searchResults[0].url)
    print(anime)

    episode = anime[ep - 1]
    episode2 = anime[ep]
    click.echo(episode.source().stream_url)
    #click.echo(episode2.source().stream_url)
    click.echo(episode.source().referer)
    # util.play_episode(episode, player=player, title=f'{anime.title} - Episode {episode.ep_no}')
    # title=f'{anime.title} - Episode {episode.ep_no}'
    # title2=f'{anime.title} - Episode {episode2.ep_no}'
    # p = subprocess.Popen([
    # player,
    # '--title={}'.format(title),
    # '--referrer="{}"'.format(episode.source().referer),
    # episode.source().stream_url,
    # '--title={}'.format(title2),
    # '--referrer="{}"'.format(episode2.source().referer),
    # episode2.source().stream_url
    # ])
    tfile = tempfile.NamedTemporaryFile(mode='a+', suffix='.m3u8')
    mpvArgs = [
        player, '--referrer={}'.format('https://twist.moe/'), '--playlist'
    ]
    if player == 'mpv':
        util.makePlaylist(anime[0:1], tfile)
        # for epi in anime:
        # title = f'{anime.title} - Episode {epi.ep_no}'
        # mpvArgs += ['--title={}'.format(title),
        # 'ffmpeg://{}'.format(epi.source().stream_url)]
        # click.echo("uai")
        print(tfile.name)
        mpvArgs.append(tfile.name)
        print(mpvArgs)
        tfile.seek(0)
        print(tfile.read())
        #mpvArgs.append('{0} >/dev/null 2>&1 &')
        #subprocess.Popen("nohup usr/local/bin/otherscript.pl {0} >/dev/null 2>&1 &", shell=True)
        print(''.join(mpvArgs))
        p = subprocess.Popen(mpvArgs)
        p.wait()
        util.addAnimesToPlaylist(anime[1:], tfile)
        print("humm")
        print(anime[0:1])
        print(anime[1:])
        print("uaaaaaaaaaaaaaaaaaaaaaaaa")
    else:
        p = subprocess.Popen([player, episode.source().stream_url])
        p.wait()
Пример #16
0
    def PrintResults(self):
        '''
        This function will return the search outputs for the user to select what anime they want.
        '''
        self.searchOutput.clear()
        cls = get_anime_class(self.providers.currentText())
        searchResults = cls.search(self.animeName.text())
        searchResults = [v.title for v in searchResults]

        self.searchOutput.addItems(searchResults)
        self.searchOutput.repaint()
Пример #17
0
async def provider(ctx, provider):
    async with ctx.typing():
        f = Load(anime_config)
        str_id = str(ctx.author.id)
        if get_anime_class(provider):
            f[str_id]['provider'] = provider
            Write(f, anime_config)
            await ctx.send(f'Selected provider "{provider}"')
        else:
            await ctx.send(
                f'Invalid provider, choose from: {[a[0] for a in ALL_ANIME_SITES]}'
            )
Пример #18
0
    def run(self):
        try:
            ani = get_anime_class(self.site)

            # this should be more dynamic
            sr = ani.search('naruto')[0]

            anime = ani(sr.url)

            stream_url = anime[0].source().stream_url
        except Exception as e:
            self.exception = e
Пример #19
0
def Search(query, Provider):
    Provider = get_anime_class(Provider)
    results = ''
    #results = '```'
    print(f'Query: {query}')
    search = Provider.search(query)
    for a in range(len(search)):
        """discord limit of 2000 chars, should ideally split the messages"""
        if len(f'{results}\n{str(search[a])}') + 3 < 1999:
            results = f'{results}\n{a+1}: {str(search[a])}'
    #results += '```'
    return (results, search)
Пример #20
0
    def _get_anime_info_class(self, url):
        cls = get_anime_class(url)

        # TODO: Maybe this is better off as a mixin
        class AnimeInfo(cls):
            def __init__(self, *args, **kwargs):
                self.episodes_done = kwargs.pop('episodes_done', 0)
                self._timestamp = kwargs.pop('timestamp', 0)

                super(cls, self).__init__(*args, **kwargs)

            def progress(self):
                return (self.episodes_done, len(self))

        return AnimeInfo
Пример #21
0
def search(query, provider, val=None, season_info=None, ratio=50):
    # Will use animeinfo sync if season_info is provided

    # Since this function outputs to stdout this should ideally be in
    # cli. But it is used in watch too. :(
    cls = get_anime_class(provider)
    search_results = cls.search(query)

    if not search_results:
        logger.error('No such Anime found. Please ensure correct spelling.')
        return None, None

    if season_info:
        from anime_downloader import animeinfo
        match = animeinfo.fuzzy_match_metadata([season_info], search_results)
        logger.debug('Match ratio: {}'.format(match.ratio))
        # ratios are a range between 0-100 where 100 means 100% match.
        if match.ratio >= ratio and not val:
            logger.debug('Selected {}'.format(match.SearchResult.title))
            return match.SearchResult.url, None

    click.echo(format_search_results(search_results), err=True)
    # Loop to allow re-propmt if the user chooses incorrectly
    # Makes it harder to unintentionally exit the anime command if it's automated
    while True:
        if val == None:
            val = click.prompt('Enter the anime no{}:'.format(
                ' (0 to switch provider)' * (season_info != None)),
                               type=int,
                               default=1,
                               err=True)
        try:
            url = search_results[val - 1].url
            title = search_results[val - 1].title
        except IndexError:
            logger.error('Only maximum of {} search results are allowed.'
                         ' Please input a number less than {}'.format(
                             len(search_results),
                             len(search_results) + 1))
            val = False
            continue
        break

    # Doesn't print if skipped.
    if season_info is None or val != 0:
        logger.info('Selected {}'.format(title))

    return url, val
Пример #22
0
    def _get_anime_info_class(self, url):
        cls = get_anime_class(url)

        # TODO: Maybe this is better off as a mixin
        class AnimeInfo(cls, sitename=cls.sitename):
            def __init__(self, *args, **kwargs):
                self.episodes_done = kwargs.pop('episodes_done', 0)
                self._timestamp = kwargs.pop('timestamp', 0)
                self.score = 0
                self.watch_status = 'watching'
                self.colours = 'blue'
                super(cls, self).__init__(*args, **kwargs)

            def progress(self):
                return (self.episodes_done, len(self))

        return AnimeInfo
Пример #23
0
async def _(event):
    if event.fwd_from:
        return
    input_str = event.pattern_match.group(1)
    ommhg = await edit_or_reply(event, "Searching For Anime.....")
    lmao = input_str.split(":", 1)
    try:
        site = lmao[1]
    except:
        site = "animeonline360"
        await edit_or_reply(
            event,
            "Please Provide Site Name From Next Time. Now Continuing With Default Site."
        )

    lol = lmao[0]
    why = site.lower()

    Twist = get_anime_class(why)
    try:
        search = Twist.search(lol)
    except:
        await ommhg.edit("Please Try Different Site. Given Site Is Down.")

    title1 = search[0].title
    url1 = search[0].url
    title2 = search[1].title
    url2 = search[1].url
    title3 = search[2].title
    url3 = search[2].url
    title4 = search[3].title
    url4 = search[3].url
    title5 = search[4].title
    url5 = search[4].url
    NopZ = f"<b><u>Anime Search Complete</b></u> \n\n\n<b>Title</b>:-  <code>{title1}</code> \n<b>URL Link</b>:- {url1}\n\n<b>Title</b>:-  <code>{title2}</code> \n<b>URL Link</b>:- {url2}\n\n<b>Title</b>:-  <code>{title3}</code>\n<b>URL Link</b>:- {url3}\n\n<b>Title</b>:-  <code>{title4}</code> \n<b>URL Link</b>:- {url4}\n\n<b>Title</b>:-  <code>{title5}</code> \n<b>URL Link</b>:- {url5}\n\n<b>Links Gathered By Friday\nGet Your Own Friday From @FRIDAYCHAT</b>"
    await borg.send_message(
        event.chat_id,
        NopZ,
        parse_mode="HTML",
    )
    await ommhg.delete()
Пример #24
0
async def _(event):
    if event.fwd_from:
        return
    input_str = event.pattern_match.group(1)
    searchthund = await event.reply("Searching Your Anime")
    inptstr = input_str.split(":", 1)
    try:
        site = inptstr[1]
    except:
        site = "Twist.moe"
        await event.reply("Searching from default website.")

    strzerooo = inptstr[0]
    chichidoyouloveme = site.lower()

    Twist = get_anime_class(chichidoyouloveme)
    try:
        search = Twist.search(strzerooo)
    except:
        await searchthund.edit("Error 404 Site is down.")

    title1 = search[0].title
    url1 = search[0].url
    title2 = search[1].title
    url2 = search[1].url
    title3 = search[2].title
    url3 = search[2].url
    title4 = search[3].title
    url4 = search[3].url
    title5 = search[4].title
    url5 = search[4].url

    await event.edit(
        f"<b><u>Anime Search Complete Say Thanks To ThunderUserbot</b></u> \n\n\n<b>Title</b>:-  <code>{title1}</code> \n<b>URL Link</b>:- {url1}\n\n<b>Title</b>:-  <code>{title2}</code> \n<b>URL Link</b>:- {url2}\n\n<b>Title</b>:-  <code>{title3}</code>\n<b>URL Link</b>:- {url3}\n\n<b>Title</b>:-  <code>{title4}</code> \n<b>URL Link</b>:- {url4}\n\n<b>Title</b>:-  <code>{title5}</code> \n<b>URL Link</b>:- {url5}\n\n<b>Enjoy</b>",
        parse_mode="HTML",
    )
    await searchthund.delete()
Пример #25
0
def get_episode(link, provider, parent):
    try:
        episode_class = AnimeEpisode.subclasses[provider]
        episode = episode_class(link, parent=DummyParent())
        source = episode.source()
        return {
            "link": source.stream_url,
            "headers": {
                "referer": source.referer
            }
        }
    except KeyError:
        provider_ = get_anime_class(provider)
        search = provider_(parent)
        print(search)
        episode_class = AnimeEpisode.subclasses[provider]
        episode = episode_class(link, parent=DummyParent())
        source = episode.source()
        return {
            "link": source.stream_url,
            "headers": {
                "referer": source.referer
            }
        }
Пример #26
0
def command(ctx, anime_url, episode_range, url, player, skip_download, quality,
            force_download, download_dir, file_format, provider,
            external_downloader, chunk_size, disable_ssl, fallback_qualities,
            choice, skip_fillers, speed_limit, sub, dub):
    """ Download the anime using the url or search for it.
    """
    """if episode_range:
        regexed_range = re.compile("^:?(\d+)?:?(\d+)?$").search(episode_range)
        # Prevent such cases as: :5: and :1:1
        if not regexed_range or (len(regexed_range.groups()) >= episode_range.count(":") and episode_range.count(":") != 1):
            raise click.UsageError(
                "Invalid value for '--episode' / '-e': {} is not a valid range".format(episode_range))
"""
    if sub and dub:
        raise click.UsageError(
            "--dub/-d and --sub/-s flags cannot be used together")

    query = anime_url[:]

    util.print_info(__version__)
    # TODO: Replace by factory
    cls = get_anime_class(anime_url)

    disable_ssl = cls and cls.__name__ == 'Masterani' or disable_ssl
    session.get_session().verify = not disable_ssl

    if not cls:
        anime_url, _ = util.search(anime_url, provider, choice)
        cls = get_anime_class(anime_url)

    subbed = None

    if sub or dub:
        subbed = subbed is not None

    anime = cls(anime_url,
                quality=quality,
                fallback_qualities=fallback_qualities,
                subbed=subbed)
    logger.info('Found anime: {}'.format(anime.title))

    animes = util.parse_ep_str(anime, episode_range)
    if not animes:
        # Issue #508.
        raise exceptions.NotFoundError('No episodes found within index.')

    # TODO:
    # Two types of plugins:
    #   - Aime plugin: Pass the whole anime
    #   - Ep plugin: Pass each episode
    if url or player:
        skip_download = True

    if download_dir and not skip_download:
        logger.info('Downloading to {}'.format(os.path.abspath(download_dir)))
    if skip_fillers:
        fillers = util.get_filler_episodes(query)
    if speed_limit:
        logger.info("Speed is being limited to {}".format(speed_limit))
    for episode in animes:
        if skip_fillers and fillers:
            if episode.ep_no in fillers:
                logger.info(
                    "Skipping episode {} because it is a filler.".format(
                        episode.ep_no))
                continue

        if url:
            util.print_episodeurl(episode)

        if player:
            util.play_episode(episode,
                              player=player,
                              title=f'{anime.title} - Episode {episode.ep_no}')

        if not skip_download:
            if external_downloader:
                logging.info('Downloading episode {} of {}'.format(
                    episode.ep_no, anime.title))
                util.external_download(external_downloader,
                                       episode,
                                       file_format,
                                       speed_limit,
                                       path=download_dir)
                continue
            if chunk_size is not None:
                chunk_size *= 1e6
                chunk_size = int(chunk_size)
            with requests_cache.disabled():
                episode.download(force=force_download,
                                 path=download_dir,
                                 format=file_format,
                                 range_size=chunk_size)
            print()
Пример #27
0
def dl(ctx, anime_url, episode_range, url, player, skip_download, quality,
       force_download, log_level, download_dir, file_format, provider,
       external_downloader, chunk_size, disable_ssl, fallback_qualities):
    """ Download the anime using the url or search for it.
    """

    util.setup_logger(log_level)
    util.print_info(__version__)

    cls = get_anime_class(anime_url)

    disable_ssl = cls and cls.__name__ == 'Masterani' or disable_ssl
    session.get_session().verify = not disable_ssl

    if not cls:
        anime_url = util.search(anime_url, provider)
        cls = get_anime_class(anime_url)

    try:
        anime = cls(anime_url,
                    quality=quality,
                    fallback_qualities=fallback_qualities)
    except Exception as e:
        if log_level != 'DEBUG':
            echo(click.style(str(e), fg='red'))
        else:
            raise
        return

    logging.info('Found anime: {}'.format(anime.title))

    anime = util.parse_ep_str(anime, episode_range)

    if url or player:
        skip_download = True

    if download_dir and not skip_download:
        logging.info('Downloading to {}'.format(os.path.abspath(download_dir)))

    for episode in anime:
        if url:
            util.print_episodeurl(episode)

        if player:
            util.play_episode(episode, player=player)

        if not skip_download:
            if external_downloader:
                logging.info('Downloading episode {} of {}'.format(
                    episode.ep_no, anime.title))
                util.external_download(external_downloader,
                                       episode,
                                       file_format,
                                       path=download_dir)
                continue
            if chunk_size is not None:
                chunk_size *= 1e6
                chunk_size = int(chunk_size)
            episode.download(force=force_download,
                             path=download_dir,
                             format=file_format,
                             range_size=chunk_size)
            print()
Пример #28
0
def list_animes(watcher, quality, download_dir, imp=None, _filter=None):

    click.echo('Available Commands: swap, new')
    watcher.list(filt=_filter)
    inp = click.prompt('Select an anime', default="1") if not imp else imp
    provider = Config['watch']['provider']
    # Not a number as input and command
    if not str(inp).isnumeric():
        if ' ' in str(inp).strip():
            args = command_parser(str(inp))
            key = args[0].lower()
            vals = args[1:]
            if key == 'new':
                query = vals[0]
                if '--provider' in vals:
                    if vals.index('--provider') + 1 < len(vals):
                        provider = vals[vals.index('--provider') + 1]
                url, _ = util.search(query, provider)
                watcher.new(url)

            if key == 'swap':
                if vals[0] in [
                        'all', 'watching', 'completed', 'planned', 'dropped',
                        'hold'
                ]:
                    return list_animes(watcher,
                                       quality,
                                       download_dir,
                                       imp=imp,
                                       _filter=vals[0])

            return list_animes(watcher, quality, download_dir, imp=imp)
        else:
            # Exits if neither int or actual command
            sys.exit(0)

    try:
        anime = watcher.get(int(inp) - 1)
    except IndexError:
        sys.exit(0)

    # Make the selected anime first result
    watcher.update(anime)
    while True:
        click.clear()
        click.secho('Title: ' +
                    click.style(anime.title, fg='green', bold=True))
        click.echo('episodes_done: {}'.format(
            click.style(str(anime.episodes_done), bold=True, fg='yellow')))
        click.echo('Length: {}'.format(len(anime)))
        click.echo('Provider: {}'.format(anime.sitename))
        click.echo('Score: {}'.format(anime.score))
        click.echo('Watch Status: {}'.format(anime.watch_status))
        meta = ''
        for k, v in anime.meta.items():
            meta += '{}: {}\n'.format(k, click.style(str(v), bold=True))
        click.echo(meta)

        click.echo('Available Commands: set, remove, update, watch, back,'
                   ' download.\n')

        inp = click.prompt('Press q to exit', default='q').strip()

        # TODO: A better way to handle commands. Use regex. Refractor to class?
        # Decorator?
        if inp == 'q':
            sys.exit(0)
        elif inp == 'back':
            list_animes(watcher, quality, download_dir, imp=imp)
        elif inp == 'remove':
            watcher.remove(anime)
            list_animes(watcher, quality, download_dir, imp=imp)
        elif inp == 'update':
            watcher.update_anime(anime)
        elif inp == 'watch':
            anime.quality = quality
            watch_anime(watcher, anime, quality, download_dir)
        elif inp.startswith('watch '):
            anime.quality = quality
            watch_anime(watcher,
                        anime,
                        quality,
                        download_dir,
                        player_class=inp.split('watch ')[-1])

        elif inp.startswith('download'):
            # You can use download 3:10 for selected episodes
            try:
                inp = inp.split('download ')[1]
            except IndexError:
                inp = ':'
            animes = util.parse_ep_str(anime, inp)

            # Using the config from dl.
            if not download_dir:
                download_dir = Config['dl']['download_dir']
            # These things could be flags.
            external_downloader = Config['dl']['external_downloader']
            file_format = Config['dl']['file_format']
            speed_limit = Config['dl']['speed_limit']

            for episode in animes:
                util.external_download(external_downloader,
                                       episode,
                                       file_format,
                                       speed_limit,
                                       path=download_dir)

        elif inp.startswith('set '):
            inp = inp.split('set ')[-1]
            key, val = [v.strip() for v in inp.split('=')]
            key = key.lower()

            if key == 'title':
                watcher.remove(anime)
                setattr(anime, key, val)
                watcher.add(anime)

            elif key == 'episodes_done':
                # Retries if invalid input.
                if not val.isnumeric():
                    # Uncomment this if you want to let the user know.
                    #logger.error("Invalid integer")
                    # input()
                    continue
                # Prevents setting length above max amount of episodes.
                val = val if int(val) <= len(anime) else len(anime)
                setattr(anime, key, int(val))
                watcher.update(anime)

            elif key == 'provider':
                # Checks if it's an invalid provider preventing errors.
                if not get_anime_class(val):
                    # Probably good to list providers here before looping.
                    continue
                # Watch can quit if no anime is found, not ideal.
                url, _ = util.search(anime.title, val)
                watcher.remove(anime)
                newanime = watcher.new(url)
                newanime.episodes_done = anime.episodes_done
                newanime.score = anime.score
                newanime.watch_status = anime.watch_status
                newanime._timestamp = anime._timestamp
                watcher.update(newanime)
                anime = newanime

            elif key == 'score':
                anime.score = val
                watcher.update(anime)

            elif key == 'watch_status':
                if val in [
                        'watching', 'completed', 'dropped', 'planned', 'all'
                ]:
                    colours = {
                        'watching': 'cyan',
                        'completed': 'green',
                        'dropped': 'red',
                        'planned': 'yellow',
                        'hold': 'white'
                    }
                    anime.watch_status = val
                    anime.colours = colours.get(anime.watch_status, 'yellow')
                    watcher.update(anime)
Пример #29
0
def command(ctx, anime_url, episode_range, url, player, skip_download, quality,
            force_download, download_dir, file_format, provider,
            external_downloader, chunk_size, disable_ssl, fallback_qualities, choice, skip_fillers, speed_limit):
    """ Download the anime using the url or search for it.
    """
    query = anime_url[:]

    util.print_info(__version__)
    # TODO: Replace by factory
    cls = get_anime_class(anime_url)

    disable_ssl = cls and cls.__name__ == 'Masterani' or disable_ssl
    session.get_session().verify = not disable_ssl

    if not cls:
        anime_url, _ = util.search(anime_url, provider, choice)
        cls = get_anime_class(anime_url)

    anime = cls(anime_url, quality=quality,
                fallback_qualities=fallback_qualities)
    logger.info('Found anime: {}'.format(anime.title))

    animes = util.parse_ep_str(anime, episode_range)
    if not animes:
        # Issue #508.
        raise exceptions.NotFoundError('No episodes found within index.')

    # TODO:
    # Two types of plugins:
    #   - Aime plugin: Pass the whole anime
    #   - Ep plugin: Pass each episode
    if url or player:
        skip_download = True

    if download_dir and not skip_download:
        logger.info('Downloading to {}'.format(os.path.abspath(download_dir)))
    if skip_fillers:
        fillers = util.get_filler_episodes(query)
    if speed_limit:
        logger.info("Speed is being limited to {}".format(speed_limit))
    for episode in animes:
        if skip_fillers and fillers:
            if episode.ep_no in fillers:
                logger.info("Skipping episode {} because it is a filler.".format(episode.ep_no))
                continue

        if url:
            util.print_episodeurl(episode)

        if player:
            util.play_episode(episode, player=player, title=f'{anime.title} - Episode {episode.ep_no}')

        if not skip_download:
            if external_downloader:
                logging.info('Downloading episode {} of {}'.format(
                    episode.ep_no, anime.title)
                )
                util.external_download(external_downloader, episode,
                                       file_format, speed_limit, path=download_dir)
                continue
            if chunk_size is not None:
                chunk_size *= 1e6
                chunk_size = int(chunk_size)
            with requests_cache.disabled():
                episode.download(force=force_download,
                                 path=download_dir,
                                 format=file_format,
                                 range_size=chunk_size)
            print()
Пример #30
0
def command(ctx, anime_url, episode_range, player, force_download, provider,
            skip_fillers, ratio, url, choice, download_metadata):
    """
    dl with fallback providers\n
    Will use another provider even if the chosen one fails.\n
    """

    # Borrows some config from the original dl command.
    # This can all be flags, but ezdl is made to be easy.
    fallback_qualities = Config['dl']['fallback_qualities']
    download_dir = Config['dl']['download_dir']
    quality = Config['dl']['quality']
    url = Config['dl']['url'] if not url else url
    skip_download = Config['dl']['skip_download']
    chunk_size = Config['dl']['chunk_size']
    speed_limit = Config['dl']['speed_limit']

    external_downloader = Config['dl']['external_downloader']
    file_format = Config['ezdl']['file_format']
    fallback_providers = Config['ezdl']['fallback_providers']

    query = anime_url[:]
    util.print_info(__version__)

    fallback_providers.insert(0, provider)
    # Eliminates duplicates while keeping order
    providers = sorted(set(fallback_providers), key=fallback_providers.index)

    info = animeinfo.search_anilist(query, choice)

    logger.info('Selected "{}" '.format(info.title))
    episode_count = info.episodes - 1
    # Interprets the episode range for use in a for loop.
    # 1:3 -> for _episode in range(1, 4):
    episode_range = util.parse_episode_range(episode_count, episode_range)
    episode_range_split = episode_range.split(':')
    # Issue #508.
    if episode_range_split[0] > episode_range_split[-1]:
        raise exceptions.NotFoundError('No episodes found within index.')

    # Stores the choices for each provider, to prevent re-prompting search.
    # As the current setup runs episode wise without this a 12 episode series would give 12+ prompts.
    choice_dict = {}

    # Doesn't work on nyaa since it only returns one episode.
    for episode_range in range(int(episode_range_split[0]),
                               int(episode_range_split[-1]) + 1):
        # Exits if all providers are skipped.
        if [choice_dict[i] for i in choice_dict] == [0] * len(providers):
            logger.info('All providers skipped, exiting')
            exit()

        for provider in providers:
            if not get_anime_class(provider):
                logger.info('"{}" is an invalid provider'.format(provider))
                continue

            logger.debug('Current provider: {}'.format(provider))
            # TODO: Replace by factory
            cls = get_anime_class(anime_url)

            # To make the downloads use the correct name if URL:s are used.
            real_provider = cls.sitename if cls else provider
            # This will allow for animeinfo metadata in filename and one filename for multiple providers.
            rep_dict = {
                'animeinfo_anime_title': util.slugify(info.title),
                'provider': util.slugify(real_provider),
                'anime_title': '{anime_title}',
                'ep_no': '{ep_no}'
            }
            fixed_file_format = file_format.format(**rep_dict)
            # Keeping this as I don't know the impact of removing it.
            # It's False by default in normal dl.
            disable_ssl = False
            session.get_session().verify = not disable_ssl

            # This is just to make choices in providers presistent between searches.
            choice_provider = choice_dict.get(provider)

            if not cls:
                _anime_url, choice_provider = util.search(anime_url,
                                                          provider,
                                                          val=choice_provider,
                                                          season_info=info,
                                                          ratio=ratio)
                choice_dict[provider] = choice_provider
                if choice_provider == 0 or not _anime_url:
                    logger.info('Skipped')
                    continue

                cls = get_anime_class(_anime_url)

            try:
                anime = cls(_anime_url,
                            quality=quality,
                            fallback_qualities=fallback_qualities)
            # I have yet to investigate all errors this can output
            # No sources found gives error which exits the script
            except:
                continue

            logger.debug('Found anime: {}'.format(anime.title))

            try:
                animes = util.parse_ep_str(anime, str(episode_range))
            except RuntimeError:
                logger.error(
                    'No episode found with index {}'.format(episode_range))
                continue
            except:
                logger.error('Unknown provider error')
                continue

            # TODO:
            # Two types of plugins:
            #   - Aime plugin: Pass the whole anime
            #   - Ep plugin: Pass each episode
            if url or player:
                skip_download = True

            if download_dir and not skip_download:
                logger.info('Downloading to {}'.format(
                    os.path.abspath(download_dir)))
            if skip_fillers:
                fillers = util.get_filler_episodes(query)
            for episode in animes:
                if skip_fillers and fillers:
                    if episode.ep_no in fillers:
                        logger.info(
                            "Skipping episode {} because it is a filler.".
                            format(episode.ep_no))
                        continue

                if download_metadata:
                    util.download_metadata(fixed_file_format, info.metadata,
                                           episode)

                if url:
                    util.print_episodeurl(episode)

                if player:
                    util.play_episode(
                        episode,
                        player=player,
                        title=f'{anime.title} - Episode {episode.ep_no}')

                if not skip_download:
                    if external_downloader:
                        logging.info('Downloading episode {} of {}'.format(
                            episode.ep_no, anime.title))
                        util.external_download(external_downloader,
                                               episode,
                                               fixed_file_format,
                                               path=download_dir,
                                               speed_limit=speed_limit)
                        continue
                    if chunk_size is not None:
                        chunk_size = int(chunk_size)
                        chunk_size *= 1e6
                    with requests_cache.disabled():
                        episode.download(force=force_download,
                                         path=download_dir,
                                         format=fixed_file_format,
                                         range_size=chunk_size)
                    print()

            # If it's all successfull proceeds to next ep instead of looping.
            break