def test_config_manager(mock_os_makedirs):
    config = ConfigManager(conf_dir="directory")
    # check if new directory was created
    assert mock_os_makedirs.called_with("directory")

    # check parsing of key elements:
    assert config.quality == "1080, 720"
    assert config.dir == "directory"
    assert config.file == "conf.ini"
    assert config.download_dir == "~/videos"
    assert dict(config.subscriptions) == {}

    # test writing abilities
    config.add_entry("test", "0")
    assert dict(config.subscriptions) == {"test": "0"}
Пример #2
0
def subscribe_to(show, episode):
    """
    subscribe to a show at and set progress to specified episodes
    :param show: the search term for the name of the show, it can be an approximation
    :param episode: the initial episode to set the show. defaults to 0 (as if no episodes were watched).
    :return: returns a tuple - first element indicates the success status, the second one is the exact name of the show.
    """
    config = ConfigManager()
    title = Parser().get_episodes(show)[0]["title"]

    if title.lower() in config.conf["subscriptions"]:
        return False, title

    config.conf["subscriptions"][title.lower()] = episode
    with open(os.path.join(config.dir, config.file), "w") as f:
        config.conf.write(f)

    return True, title
Пример #3
0
            # don't forget to uncomment!
            print("Download Completed !")
            Video = GetVideoDirAndConvert(showName, str(episode))
            SaveToDatabase(seriesID, showName, episode, cursor, Video,
                           Database)


while True:

    Database = mysql.connector.connect(host="127.0.0.1",
                                       user="******",
                                       passwd="python",
                                       database="streaming")

    p = Parser()
    config = ConfigManager()
    cursor = Database.cursor()
    cursor.execute("Select * FROM DownloadList")
    results = cursor.fetchall()

    for result in results:
        print(result[1])
        Id = (result[1], )
        sql = "Select * FROM series WHERE id = '%s'"
        cursor.execute(sql, Id)
        Series = cursor.fetchone()
        DownloadShow(Series[0], Series[1], cursor, Database)

        if Series[4] == "Finished Airing":
            sql = "DELETE FROM DownloadList WHERE SeriesID ='%s'"
            cursor.execute(sql, Id)
Пример #4
0
def main():
    argparser = argparse.ArgumentParser(description="horrible script for downloading anime")
    argparser.add_argument("-d", "--download", help="download a specific anime", type=str)
    argparser.add_argument("-o", "--output", help="directory to which it will download the files", type=str)
    argparser.add_argument("-e", "--episodes", help="specify specific episodes to download", type=str)
    argparser.add_argument("-l", "--list", help="display list of available episodes", action="store_true")
    argparser.add_argument("-r", "--resolution", help="specify resolution quality", type=str)
    argparser.add_argument("--subscribe", help="add a show to the config file", type=str)
    argparser.add_argument("--batch", help="search for batches as well as regular files", action="store_true")
    argparser.add_argument("-q", "--quiet", help="set quiet mode on", action="store_true")
    argparser.add_argument("-lc", "--list-current", help="list all currently airing shows", action="store_true")
    argparser.add_argument("-c", "--config", help="config file location", type=str)
    argparser.add_argument("--noconfirm", help="Bypass any and all “Are you sure?” messages.", action="store_true")
    args = argparser.parse_args()

    logger = logging.getLogger("info")

    if not args.config:
        config = ConfigManager()
    else:
        path, file = os.path.split(args.config)
        if file:
            config = ConfigManager(conf_dir=path, file=file)
        elif path:
            config = ConfigManager(conf_dir=path)
        else:
            config = ConfigManager()
    parser = Parser()

    if args.subscribe:
        episode_number = args.episodes if args.episodes else "0"
        title = parser.get_proper_title(args.subscribe)
        success, show = config.add_entry(title, episode_number)
        if success:
            print(f"Successfully subscribed to: \"{show.lower()}\"")
            print(f"Latest watched episode is - {episode_number}")
        else:
            print(f"You're already subscribed to \"{show}\", omitting changes...")
        exit(0)

    if args.list:
        print("\n".join(parser.shows.keys()))
        exit(0)

    if args.list_current:
        print("\n".join(parser.current_shows.keys()))
        exit(0)

    clear()

    if args.output:
        config.download_dir = args.output

    if args.resolution:
        config.quality = args.resolution

    qualities = config.quality.split(",")
    if not valid_qualities(qualities):
        print("Bad resolution specified, aborting...")
        exit(1)

    if args.download:
        title = parser.get_proper_title(args.download)
        if not args.quiet:
            print(f"{fg(3)}FETCHING:{fg.rs} {title}")
        episodes = parser.get_episodes(args.download, batches=args.batch)
        def should_download(episode):
            if not args.episodes:
                return True
            return episode_filter(float(episode["episode"]), args.episodes)

        filtered_episodes = list(filter(should_download, episodes))
        if not args.quiet:
            clear()
            dots = "." * (50 - len(title))
            found_str = f"FOUND ({len(filtered_episodes)})"
            print(f"{fg(3)}FETCHING: {fg.rs}{title}{dots}{fg(10)}{found_str}{fg.rs}")

            episodes_len = len(filtered_episodes) * len(qualities)
            print(f'{fg(2)}\nFound {episodes_len} file{"s" if episodes_len > 1 else ""} to download:\n{fg.rs}')
            for episode in filtered_episodes:
                for quality in qualities:
                    print(f'{title} - {episode["episode"]} [{quality}p].mkv')

            if not args.noconfirm and not args.quiet:
                inp = input(f'{fg(3)}\nwould you like to proceed? [Y/n] {fg.rs}')
                if inp not in ('', 'Y', 'y', 'yes', 'Yes'):
                    print(fg(1) + 'aborting download\n' + fg.rs)
                    exit(1)

        for episode in filtered_episodes:
            download(episode, qualities, config.download_dir)
            config.update_entry(title, episode["episode"])
        exit(0)


    manager = Manager()
    initial_downloads_dict = {parser.get_proper_title(title): None for title in config.subscriptions.keys()}
    downloads = manager.dict(initial_downloads_dict)
    printing_lock = Lock()
    procs = []
    method = "batches" if args.batch else "show"

    if not args.quiet:
        clear()
        for title in initial_downloads_dict.keys():
            print(f"{fg(3)}FETCHING:{fg.rs} {title}")

    for entry in config.subscriptions.items():
        proc = Process(
            target=fetch_episodes,
            args=(entry, downloads, printing_lock, parser, args.batch, args.quiet)
        )
        proc.start()
        procs.append(proc)

    for proc in procs:
        proc.join()

    downloads_list = []
    for episodes in downloads.values():
        for episode in episodes:
            downloads_list.append(episode)

    if downloads_list == []:
        if not args.quiet:
            print(fg(1) + 'No new episodes were found. Exiting ' + fg.rs)
        logger.info("No new episodes were found. Exiting ")
        exit(0)

    logger.info("found the following files:")
    if not args.quiet:
        episodes_len = len(downloads_list) * len(qualities)
        print(f'{fg(2)}\nFound {episodes_len} file{"s" if episodes_len > 1 else ""} to download:\n{fg.rs}')
    for episode in downloads_list:
        for quality in qualities:
            if not args.quiet:
                print(f'{episode["title"]} - {episode["episode"]} [{quality}p].mkv')
            logger.info(f'{episode["title"]} - {episode["episode"]} [{quality}p].mkv')

    if not args.noconfirm and not args.quiet:
        inp = input(f'{fg(3)}\nwould you like to proceed? [Y/n] {fg.rs}')
        if inp not in ('', 'Y', 'y', 'yes', 'Yes'):
            print(fg(1) + 'aborting download\n' + fg.rs)
            logger.info("user has aboorted the download")
            exit(1)


    for episode in downloads_list:
        download(episode, qualities, config.download_dir)
        config.update_entry(episode["title"], episode["episode"])
        logger.info(f'updated entry: {episode["title"]} - {episode["episode"]}')
    exit(0)
Пример #5
0
def main(args):
    clear()
    CONFIG = ConfigManager()
    PARSER = Parser()
    # change to custom download dir if user has specified
    if args.output:
        CONFIG.download_dir = args.output

    QUALITIES = (CONFIG.quality
                 if not args.resolution else args.resolution).split(",")
    # validating qualities object to fit format:
    if not verify_quality(QUALITIES):
        print("Bad resolution specified, aborting...")
        exit(1)

    downloads = []
    if args.download:  # we want to set the correct title
        title = Parser().get_episodes(args.download)[0]["title"]

    downloads = multiprocessing.Manager().dict()
    procs = []
    l = multiprocessing.Lock()

    # all the variables set, lets start with the iterations:
    for show, last_watched in [(title,
                                0)] if args.download else CONFIG.subscriptions:
        proc = multiprocessing.Process(target=fetch_episodes,
                                       args=(PARSER, show, last_watched,
                                             downloads, args, l))

        proc.start()
        procs.append(proc)

    for proc in procs:
        proc.join()

    downloads_flat = flatten_dict(downloads)

    # after we iterated on all of the shows we have a list of stuff to download.
    # but first we must check the list if it contains data:
    if not downloads_flat:
        if args.download:  # we want to display a different message in each case.
            print(fg(1) + "Couldn't find specified anime. Exiting" + fg.rs)
        else:
            print(fg(1) + 'No new episodes were found. Exiting ' + fg.rs)
        exit(1)  # arguably should be exit code 0

    # summerizing info about the download
    reprint_results(downloads, QUALITIES)
    inp = input(
        f'{fg(3)}\nwould you like to re-arrange the downloads? (Return for default) {fg.rs}'
    )
    if inp is "":  # continue as usually.
        pass

    elif inp in ("Y", "y", "yes", "Yes"):  # do the re-arrangment
        print(
            "press SPACE to toggle select a show, use UP/DOWN to arrange, when done - press RETURN"
        )

        # set some helpful variables
        shows_download_keys = downloads.keys()
        current_index = 0
        selected = False

        while True:
            # printing all of the info from before, to reset the new data
            reprint_results(downloads, QUALITIES)
            print(
                f'{fg(3)}\nwould you like to re-arrange the downloads? (Return for default) {fg.rs}',
                inp)
            print(
                "press SPACE to toggle select a show, use UP/DOWN to arrange, when done - press RETURN"
            )
            for i, show in enumerate(
                    shows_download_keys
            ):  # here we set the colors of the new data
                if i == current_index:
                    if selected:
                        print(f"{fg(12)}{i+1}. {show}{fg.rs}")
                    else:
                        print(f"{fg(3)}{i+1}. {fg.rs}{show}")
                else:
                    print(f"{i+1}. {show}")

            keypress = getKey()
            if keypress == " ":  # SPACE
                selected = not selected

            elif keypress in ("up", "down"):  # ARROWS (ANY)
                # this has to be done no matter which arrow key is pressed:
                if selected:
                    removed = shows_download_keys.pop(current_index)

                # this is how it works to detect the individual arrows.
                # https://www.daniweb.com/posts/jump/1087957
                if keypress == "up":  # UP
                    if current_index > 0:
                        current_index -= 1

                elif keypress == "down":  # DOWN
                    if current_index < len(shows_download_keys) - (
                            0 if selected else 1):
                        current_index += 1

                # once we know what key was pressed, we need to return the value we removed
                if selected:
                    shows_download_keys.insert(current_index, removed)

            elif keypress == "\r":  # RETURN
                for show in shows_download_keys:
                    downloads[show] = downloads.pop(show)

                downloads_flat = flatten_dict(downloads)
                print(
                    f"{fg(3)}The download order will be as follows:{fg.rs}\n")
                for episode in downloads_flat:
                    for quality in QUALITIES:
                        print(
                            f'{episode["title"]} - {episode["episode"]} [{quality}p].mkv'
                        )
                break

    else:
        print(fg(1) + 'aborting download\n' + fg.rs)
        exit(1)

    #l et the downloads begin!
    abs_path = os.path.expanduser(CONFIG.download_dir)
    for episode_obj in downloads_flat:
        download(episode_obj, QUALITIES, abs_path)

        if not args.download:
            CONFIG.conf["subscriptions"][episode_obj["title"].lower(
            )] = episode_obj["episode"].lstrip("0")
            with open(os.path.join(CONFIG.dir, CONFIG.file), "w") as f:
                CONFIG.conf.write(f)