def test_directory__episode(): episode_path = Path("/some/episode/path").absolute() target = Target( Path(), Settings(media=MediaType.EPISODE, episode_directory=episode_path), ) assert target.directory == episode_path
def __init__(self, file_path: Union[str, Path], settings: Settings): self._settings = settings self._has_moved: False self._has_renamed: False self.source = Path(file_path).resolve() self.metadata = parse_metadata(file_path=file_path, media_hint=settings.media) self.provider_type = settings.api_for(self.metadata.media) self._override_metadata_ids(settings) self._register_provider()
def run(load_configuration=True, load_arguments=True): """The main program loop.""" # setup arguments and load runtime configuration try: settings = Settings( load_configuration=load_configuration, load_arguments=load_arguments ) except MnamerException as e: tty.msg(str(e), MessageType.ERROR) raise SystemExit(1) targets = Target.populate_paths(settings) tty.configure(settings) # handle directives and configuration if settings.version: tty.msg(f"mnamer version {VERSION}") raise SystemExit(0) if settings.config_dump: print(settings.as_json) raise SystemExit(0) tty.msg("Starting mnamer", MessageType.HEADING) if settings.no_cache: clear_cache() tty.msg("cache cleared", MessageType.ALERT) if settings.test: tty.msg("testing mode", MessageType.ALERT) if settings.configuration_path: tty.msg( f"loaded config from '{settings.configuration_path}'", MessageType.ALERT, ) # print configuration details tty.msg("\nsystem", debug=True) tty.msg(SYSTEM, debug=True) tty.msg("\nsettings", debug=True) tty.msg(settings.as_dict, debug=True) tty.msg("\ntargets", debug=True) tty.msg(targets or [None], debug=True) # exit early if no media files are found total_count = len(targets) if total_count == 0: tty.msg("", debug=True) tty.msg("no media files found", MessageType.ALERT) raise SystemExit(0) # main program loop success_count = 0 for target in targets: # announce file media_label = target.metadata.media.value.title() filename_label = target.source.name filesize_label = get_filesize(target.source) tty.msg( f'\nProcessing {media_label} "{filename_label}" ({filesize_label})', MessageType.HEADING, ) tty.msg(target.source, debug=True) # list details tty.msg( f"using {target.provider_type.value}", MessageType.ALERT, debug=True ) tty.msg("\nsearch parameters", debug=True) tty.msg(target.metadata.as_dict, debug=True) tty.msg("", debug=True) # find match for target matches = [] try: matches = target.query() except MnamerNotFoundException: tty.msg("no matches found", MessageType.ALERT) except MnamerNetworkException: tty.msg("network error", MessageType.ALERT) if not matches and settings.no_guess: tty.msg("skipping (--no-guess)", MessageType.ALERT) continue try: if settings.batch: match = matches[0] if matches else target.metadata elif not matches: match = tty.confirm_guess(target.metadata) else: tty.msg("results") match = tty.prompt(matches) except MnamerSkipException: tty.msg("skipping (user request)", MessageType.ALERT) continue except MnamerAbortException: tty.msg("aborting (user request)", MessageType.ERROR) break target.metadata.update(match) # sanity check move if target.destination == target.source: tty.msg( f"skipping (source and destination paths are the same)", MessageType.ALERT, ) continue if settings.no_overwrite and target.destination.exists(): tty.msg( f"skipping (--no-overwrite)", MessageType.ALERT, ) continue tty.msg( f"moving to {target.destination.absolute()}", MessageType.SUCCESS, ) # rename and move file if settings.test: success_count += 1 continue try: target.relocate() except MnamerException: tty.msg("FAILED!", MessageType.ERROR) else: tty.msg("OK!", MessageType.SUCCESS) success_count += 1 # report results if success_count == 0: message_type = MessageType.ERROR elif success_count == total_count: message_type = MessageType.SUCCESS else: message_type = MessageType.ALERT tty.msg( f"\n{success_count} out of {total_count} files processed successfully", message_type, )
def test_version(flag: str, e2e_run: Callable): result = e2e_run(flag) assert result.code == 0 assert result.out == f"mnamer version {VERSION}" @patch("mnamer.__main__.clear_cache") def test_directives__cache_clear(mock_clear_cache: MagicMock, e2e_run: Callable): result = e2e_run("--no_cache") assert result.code == 0 assert "cache cleared" in result.out mock_clear_cache.assert_called_once() @pytest.mark.parametrize("key", Settings._serializable_fields()) @patch("mnamer.utils.crawl_out") def test_directives__config_dump(mock_crawl_out: MagicMock, key: str, e2e_run: Callable): mock_crawl_out.return_value = None result = e2e_run("--config_dump") assert result.code == 0 if key.startswith("api_key"): return json_out = json.loads(result.out) value = DEFAULT_SETTINGS[key] expected = getattr(value, "value", value) actual = json_out[key] assert actual == expected
def test_directory__movie(): movie_path = Path("/some/movie/path").absolute() target = Target( Path(), Settings(media=MediaType.MOVIE, movie_directory=movie_path)) assert target.directory == movie_path
def test_media__override(media: MediaType): target = Target(Path(), Settings(media=media)) assert target.media is media
def test_media__episode(): target = Target(Path("ninja turtles s01e01.mkv"), Settings()) assert target.media is MediaType.EPISODE
def test_media__movie(): target = Target(Path("ninja turtles (1990).mkv"), Settings()) assert target.media is MediaType.MOVIE