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"}
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
# 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)
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)
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)