예제 #1
0
class MockTest(unittest.TestCase):
    def setUp(self):
        self.parser = Parser()

    def test_current_season(self):
        with HTTMock(current_season_mock):
            current = self.parser.current_shows
            self.assertEqual(list(current),
                             ["Test 1", "Test 2", "Test 3", "Test 4"])

    def test_shows_list(self):
        with HTTMock(shows_mock):
            shows = self.parser.shows
            self.assertEqual(
                shows, {
                    'Test 1': 'test-1',
                    'Test 2': 'test-2',
                    'Test 3': 'test-3',
                    'Test 4': 'test-4'
                })

    def test_get_episodes(self):
        with HTTMock(api_mock):
            episodes = self.parser.get_episodes("test", limit=4)
            self.assertEqual(len(episodes), 4)
            batch = self.parser.get_batches("test")
            self.assertEqual(batch[0]["title"].lower(), "one-punch man")

    def test_show_id(self):
        with HTTMock(showid_mock):
            showid = self.parser._get_show_id("doesn't matter")
            self.assertTrue(showid, 123456789)
예제 #2
0
def test_get_batches():
    parser = Parser()
    title = "Kateikyoushi Hitman Reborn!"
    batches = parser.get_batches(title)
    assert len(batches) == 2

    for batch in batches:
        assert batch["title"] == title
        has_magnet = []
        for resolution in "480", "720", "1080":
            assert resolution in batch
            has_magnet.append("Magnet" in batch[resolution])

        assert has_magnet == sorted(has_magnet, reverse=True)
        assert has_magnet[0]
예제 #3
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
예제 #4
0
def test_get_proper_title():
    with HTTMock(shows_mock):
        parser = Parser()
        reasonable_titles = [
            "Test 1",  # exact match
            "test 1",  # almost same
            "tast 1",  # typo
        ]
        for title in reasonable_titles:
            proper_title = parser.get_proper_title(title)
            assert proper_title == "Test 1"
        incorrect_titles = [
            "",  # blank
            "random",  # non-matching text
            "123"
        ]
        for title in incorrect_titles:
            assert parser.get_proper_title(title, min_threshold=70) == ""

        assert parser.get_proper_title("Hello $amp; World") == "Hello & World"
예제 #5
0
def test_get_shows():
    with HTTMock(shows_mock):
        parser = Parser()
        assert parser.shows == parser.current_shows
        assert parser.shows == {
            'Test 1': 'test-1',
            'Test 2': 'test-2',
            'Test 3': 'test-3',
            'Test 4': 'test-4',
            "Hello & World": "hello&world"
        }
def test_get_episodes():
    # without mocking, we'll do live testing on the website.
    parser = Parser()
    for limit in 0, 3, 12, 24, 28:
        title = parser.get_proper_title("one piece")
        showid = parser._get_show_id(title)
        shows_html = parser._get_html(showid, limit, "show")
        episodes = list(parser._parse_html(shows_html))
        assert len(episodes) == 12 * round(limit / 12)

        proper_get_episodes = parser.get_episodes("one piece", limit=limit)
        for index, episode in enumerate(proper_get_episodes):
            episode.pop("title")
            proper = episode.keys()
            non_proper = episodes[index].keys()
            error_msg = f"proper: {proper} \nnon proper: {non_proper}"
            assert episode == episodes[index], error_msg
예제 #7
0
def test_show_id():
    parser = Parser()
    assert parser._get_show_id("no way this will ever be an anime") == -1
예제 #8
0
            subprocess.check_call(passValues)
            # 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'"
예제 #9
0
 def setUp(self):
     self.parser = Parser()
예제 #10
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)
예제 #11
0
#!/usr/bin/env python3
from HorribleDownloader import Parser, ConfigManager
import json

print ("Hello World")
p = Parser()
config = ConfigManager()
episodes = p.get_episodes("Hibike! Euphonium")


print(episodes[0]['1080']['Magnet']);

#print(episodes[0]);
#s = episodes[0].replace("'", '"')
#y = json.loads[s];
#print(y["episode"]);

#for x in episodes:
#    s = "["+str(x)+"]";
#    s = str.replace("'", '"')
#    y = json.loads(s);
#    print(y["episde"]);
#    print("\n");
예제 #12
0
def cli():
    try:
        parser = argparse.ArgumentParser(
            description='horrible script for downloading anime')
        parser.add_argument('-d',
                            '--download',
                            help="download a specific anime",
                            type=str)
        parser.add_argument(
            '-o',
            '--output',
            help="directory to which it will download the files",
            type=str)
        parser.add_argument('-e',
                            '--episodes',
                            help="specify specific episodes to download",
                            type=str)
        parser.add_argument('-l',
                            '--list',
                            help="display list of available episodes",
                            action="store_true")
        parser.add_argument('-r',
                            '--resolution',
                            help="specify resolution quality",
                            type=str)
        parser.add_argument('--subscribe',
                            help="add a show to the config file",
                            type=str)
        parser.add_argument('--batch',
                            help="search for batches as well as regular files",
                            action="store_true")
        parser.add_argument('-q',
                            '--quiet',
                            help="set quiet mode on",
                            action="store_true")
        parser.add_argument('-lc',
                            '--list-current',
                            help="list all currently airing shows",
                            action="store_true")
        args = parser.parse_args()

        if args.subscribe:
            episode_number = args.episodes if args.episodes else "0"
            status, show = subscribe_to(args.subscribe, episode_number)

            if status:
                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:
            shows = list(Parser().shows.keys())
            print("\n".join(shows))
            exit(0)

        if args.list_current:
            shows = list(Parser().current_shows)
            print("\n".join(shows))
            exit(0)

        main(args)

    except KeyboardInterrupt:
        print(f"{fg(1)}\nAborting download...{fg.rs}")
예제 #13
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)