Example #1
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
Example #2
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()
Example #3
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()