Пример #1
0
def watch(anime_name, new, update_all, _list, quality, log_level, remove,
          download_dir, provider):
    """
    With watch you can keep track of any anime you watch.

    Available Commands after selection of an anime:\n
    set        : set episodes_done, provider and title.
                 Ex: set episodes_done=3\n
    remove     : remove selected anime from watch list\n
    update     : Update the episodes of the currrent anime\n
    watch      : Watch selected anime\n
    download   : Download episodes of selected anime
    """
    util.setup_logger(log_level)
    util.print_info(__version__)

    watcher = _watch.Watcher()

    if new:
        if anime_name:
            query = anime_name
        else:
            query = click.prompt('Enter a anime name or url', type=str)

        url = util.search(query, provider)

        watcher.new(url)
        sys.exit(0)

    if remove:
        anime = watcher.get(anime_name)
        if anime and click.confirm("Remove '{}'".format(anime.title),
                                   abort=True):
            watcher.remove(anime)
        else:
            logging.error("Couldn't find '{}'. "
                          "Use a better search term.".format(anime_name))
            sys.exit(1)
        sys.exit(0)

    if update_all:
        animes = watcher.anime_list()
        for anime in animes:
            watcher.update_anime(anime)

    if _list:
        list_animes(watcher, quality, download_dir)
        sys.exit(0)

    if anime_name:
        anime = watcher.get(anime_name)
        if not anime:
            logging.error("Couldn't find '{}'."
                          "Use a better search term.".format(anime_name))
            sys.exit(1)

        anime.quality = quality

        logging.info('Found {}'.format(anime.title))
        watch_anime(watcher, anime)
Пример #2
0
def command(test_query):
    """Test all sites to see which ones are working and which ones aren't. Test naruto as a default."""
    util.print_info(__version__)
    logger = logging.getLogger("anime_downloader")
    logger.setLevel(logging.ERROR)

    threads = []

    for site in sitenames:
        t = SiteThread(site, daemon=True)
        t.start()
        threads.append(t)

    for thread in threads:
        if os.name == 'nt':
            p, f = 'Works: ', "Doesn't work: "  # Emojis doesn't work in cmd
        else:
            p, f = '✅ ', '❌ '
        thread.join(timeout=10)
        if not thread.is_alive():
            if not thread.exception:
                # echo(click.style('Works ', fg='green') + site)
                echo(click.style(p, fg='green') + thread.site)
            else:
                logging.debug('Error occurred during testing')
                logging.debug(thread.exception)
                echo(click.style(f, fg='red') + thread.site)
        else:
            logging.debug('timeout during testing')
            echo(click.style(f, fg='red') + thread.site)
Пример #3
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)
Пример #4
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()
Пример #5
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()
Пример #6
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()
Пример #7
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()
Пример #8
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
Пример #9
0
def command(anime_name, new, update_all, _list, quality, remove, download_dir,
            mal_import, provider):
    """
    With watch you can keep track of any anime you watch.
    Available Commands after selection of an anime:\n
    set        : set episodes_done, provider and title.
                 Ex: set episodes_done=3\n
    remove     : remove selected anime from watch list\n
    update     : Update the episodes of the currrent anime\n
    watch      : Watch selected anime\n
    download   : Download episodes of selected anime
    back       : Returns back to the list
    """
    util.print_info(__version__)
    watcher = _watch.Watcher()

    if not os.path.exists(watcher.WATCH_FILE):
        with open(watcher.WATCH_FILE, "w") as f:
            f.write("[]")

    if new:
        if anime_name:
            query = anime_name
        else:
            query = click.prompt('Enter a anime name or url', type=str)

        url, _ = util.search(query, provider)

        watcher.new(url)
        sys.exit(0)

    with open(watcher.WATCH_FILE, "r") as f:
        contents = f.read()
        # print(contents)
        if "[]" in contents:
            logger.error(
                "Add something to the watch list using `anime watch --new`")
            sys.exit(1)

    if remove:
        anime = watcher.get(anime_name)
        if anime and click.confirm("Remove '{}'".format(anime.title),
                                   abort=True):
            watcher.remove(anime)
        else:
            logging.error("Couldn't find '{}'. "
                          "Use a better search term.".format(anime_name))
            sys.exit(1)
        sys.exit(0)

    if update_all:
        animes = watcher.anime_list()
        for anime in animes:
            watcher.update_anime(anime)

    if mal_import:
        # Hack, but needed to prompt the user. Uses the anime name as
        # parameter.
        PATH = anime_name
        if PATH:
            query = PATH
        else:
            query = click.prompt('Enter the file path for the MAL .xml file',
                                 type=str)

        if query.endswith('.xml'):
            watcher._import_from_MAL(query)
            sys.exit(0)
        else:
            logging.error(
                "Either the file selected was not an .xml or no file was selected."
            )
            sys.exit(1)

    # Defaults the command to anime watch -l all.
    # It's a bit of a hack to use sys.argv, but doesn't break
    # if new commands are added (provided you used a bunch of and statements)
    _list = 'all' if sys.argv[-1] == 'watch' else _list
    if _list:
        filt = _list
        list_animes(watcher, quality, download_dir, None, _filter=filt)
        sys.exit(0)

    if anime_name:
        anime = watcher.get(anime_name)
        if not anime:
            logger.error("Couldn't find '{}'."
                         "Use a better search term.".format(anime_name))
            sys.exit(1)

        anime.quality = quality

        logger.info('Found {}'.format(anime.title))
        watch_anime(watcher, anime, quality, download_dir)
Пример #10
0
def command(anime_name, new, update_all, _list, quality, remove, download_dir,
            provider):
    """
    With watch you can keep track of any anime you watch.

    Available Commands after selection of an anime:\n
    set        : set episodes_done, provider and title.
                 Ex: set episodes_done=3\n
    remove     : remove selected anime from watch list\n
    update     : Update the episodes of the currrent anime\n
    watch      : Watch selected anime\n
    download   : Download episodes of selected anime
    """
    util.print_info(__version__)
    echo(
        'Watch is deprecated in favour of adl: https://github.com/RaitaroH/adl .'
    )
    echo(
        'You can use dl command to stream anime if you do not want anime tracking.'
    )
    echo('watch command may come back in the future.')

    watcher = _watch.Watcher()

    if new:
        if anime_name:
            query = anime_name
        else:
            query = click.prompt('Enter a anime name or url', type=str)

        url = util.search(query, provider)

        watcher.new(url)
        sys.exit(0)

    if remove:
        anime = watcher.get(anime_name)
        if anime and click.confirm("Remove '{}'".format(anime.title),
                                   abort=True):
            watcher.remove(anime)
        else:
            logging.error("Couldn't find '{}'. "
                          "Use a better search term.".format(anime_name))
            sys.exit(1)
        sys.exit(0)

    if update_all:
        animes = watcher.anime_list()
        for anime in animes:
            watcher.update_anime(anime)

    if _list:
        list_animes(watcher, quality, download_dir)
        sys.exit(0)

    if anime_name:
        anime = watcher.get(anime_name)
        if not anime:
            logger.error("Couldn't find '{}'."
                         "Use a better search term.".format(anime_name))
            sys.exit(1)

        anime.quality = quality

        logger.info('Found {}'.format(anime.title))
        watch_anime(watcher, anime)
Пример #11
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()
Пример #12
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()
Пример #13
0
def command(anime, prompt_found, providers, exclude, verify, v_tries, no_fuzzy,
            print_results, timeout):
    """Test all sites to see which ones are working and which ones aren't. Test naruto as a default. Return results for each provider."""

    util.print_info(__version__)
    logger = logging.getLogger("anime_downloader")
    logger.setLevel(logging.ERROR)

    if providers:
        providers = [p.strip() for p in providers.split(",")]
        for p in providers:
            if not p in sitenames:
                raise click.BadParameter(
                    f"{p}. Choose from {', '.join(sitenames)}")
    else:
        providers = sitenames

    if exclude:
        exclude = [e.strip() for e in exclude.split(",")]
        for e in exclude:
            if not e in sitenames:
                raise click.BadParameter(
                    f"{e}. Choose from {', '.join(sitenames)}")
            else:
                if e in providers:
                    providers.remove(e)

    if os.name == 'nt':
        p, f = '', ''  # Emojis don't work in cmd
    else:
        p, f = '✅ ', '❌ '

    if verify:
        timeout = timeout + (3 * (v_tries - 1))

    threads = []
    matches = []

    for provider in providers:
        t = SiteThread(provider, anime, verify, v_tries, daemon=True)
        t.start()
        threads.append(t)

    for i, thread in enumerate(threads):
        try:
            click.echo(f"[{i+1} of {len(threads)}] Searching ", nl=False)
            click.secho(f"{thread.provider}", nl=False, fg="cyan")
            click.echo(f"... (CTRL-C to stop) : ", nl=False)
            thread.join(timeout=timeout)
            if not thread.is_alive():
                if not thread.exception:
                    if thread.search_result:
                        if not no_fuzzy:
                            ratio = fuzz.token_set_ratio(
                                anime.lower(), thread.search_result.lower())
                        else:
                            ratio = 100
                        if ratio > 50:
                            matches.append(
                                [thread.provider, thread.search_result, ratio])
                            click.secho(p + "Works, anime found.", fg="green")
                            if prompt_found:
                                if print_results:
                                    click.echo(
                                        f"\n- - -{thread.provider}- - -\n\n{thread.search_result}"
                                    )
                                confirm = click.confirm(
                                    f"Found anime in {thread.provider}. Keep seaching?",
                                    default=True)
                                if not confirm:
                                    break
                        else:
                            click.secho(p + "Works, anime not found.",
                                        fg="yellow")
                    else:
                        click.secho(p + "Works, anime not found.", fg="yellow")
                else:
                    logging.debug('Error occurred during testing.')
                    logging.debug(thread.exception)
                    if thread.search_result:
                        click.secho(
                            f + "Not working: anime found, extraction failed.",
                            fg="red")
                    else:
                        click.secho(f + "Not working.", fg="red")
            else:
                logging.debug('Timeout during testing.')
                click.secho(
                    f +
                    "Not working: Timeout. Use -t to specify longer waiting period.",
                    fg="red")

        except KeyboardInterrupt:
            skip = click.confirm(
                f"\nSkip {thread.provider} and continue searching? (Press enter for Yes)",
                default=True)
            if not skip:
                break

    if print_results:
        click.echo("\n" + util.format_matches(matches))
    else:
        click.echo("\n" + "Test finished.")
Пример #14
0
def command(anime_name, new, update_all, _list, quality, remove, download_dir,
            provider):
    """
    With watch you can keep track of any anime you watch.
    Available Commands after selection of an anime:\n
    set        : set episodes_done, provider and title.
                 Ex: set episodes_done=3\n
    remove     : remove selected anime from watch list\n
    update     : Update the episodes of the currrent anime\n
    watch      : Watch selected anime\n
    download   : Download episodes of selected anime
    back       : Returns back to the list
    """
    util.print_info(__version__)
    watcher = _watch.Watcher()

    if new:
        if anime_name:
            query = anime_name
        else:
            query = click.prompt('Enter a anime name or url', type=str)

        url = util.search(query, provider)

        watcher.new(url)
        sys.exit(0)

    if remove:
        anime = watcher.get(anime_name)
        if anime and click.confirm("Remove '{}'".format(anime.title),
                                   abort=True):
            watcher.remove(anime)
        else:
            logging.error("Couldn't find '{}'. "
                          "Use a better search term.".format(anime_name))
            sys.exit(1)
        sys.exit(0)

    if update_all:
        animes = watcher.anime_list()
        for anime in animes:
            watcher.update_anime(anime)

    # Defaults the command to anime watch -l all.
    # It's a bit of a hack to use sys.argv, but doesn't break
    # if new commands are added (provided you used a bunch of and statements)
    _list = 'all' if sys.argv[-1] == 'watch' else _list
    if _list:
        filt = _list
        list_animes(watcher, quality, download_dir, None, _filter=filt)
        sys.exit(0)

    if anime_name:
        anime = watcher.get(anime_name)
        if not anime:
            logger.error("Couldn't find '{}'."
                         "Use a better search term.".format(anime_name))
            sys.exit(1)

        anime.quality = quality

        logger.info('Found {}'.format(anime.title))
        watch_anime(watcher, anime, quality, download_dir)