Beispiel #1
0
 def destination(self) -> Path:
     """
     The destination Path for the target based on its metadata and user
     preferences.
     """
     if self.directory:
         dir_head = format(self.metadata, str(self.directory))
         dir_head = filename_sanitize(dir_head)
         dir_head = Path(dir_head)
     else:
         dir_head = self.source.parent
     if self._formatting:
         file_path = format(self.metadata, self._formatting)
         if self._settings.replacements:
             file_path = filename_replace(file_path,
                                          self._settings.replacements)
         file_path = filename_sanitize(file_path)
         file_path = Path(file_path)
     else:
         file_path = self.source.name
     dir_tail, filename = path.split(file_path)
     directory = Path(dir_head, dir_tail)
     if self._settings.scene:
         filename = filename_scenify(filename)
     if self._settings.lower:
         filename = filename.lower()
     return Path(directory, filename).resolve()
Beispiel #2
0
 def test_dir_concat(self):
     filename = "somedir%s%ssomefile" % (sep, sep)
     expected = "somedir%ssomefile" % sep
     actual = filename_sanitize(filename)
     self.assertEqual(expected, actual)
Beispiel #3
0
 def test_remove_illegal_chars(self):
     filename = "<:*sup*:>"
     expected = "sup"
     actual = filename_sanitize(filename)
     self.assertEqual(expected, actual)
Beispiel #4
0
 def test_condense_whitespace(self):
     filename = "fix  these    spaces\tplease "
     expected = "fix these spaces please"
     actual = filename_sanitize(filename)
     self.assertEqual(expected, actual)
Beispiel #5
0
 def test_dir_concat(self):
     filename = "somedir%s%ssomefile" % (sep, sep)
     expected = "somedir%ssomefile" % sep
     actual = filename_sanitize(filename)
     self.assertEqual(expected, actual)
Beispiel #6
0
 def test_remove_illegal_chars(self):
     filename = "<:*sup*:>"
     expected = "sup"
     actual = filename_sanitize(filename)
     self.assertEqual(expected, actual)
Beispiel #7
0
 def test_condense_whitespace(self):
     filename = "fix  these    spaces\tplease "
     expected = "fix these spaces please"
     actual = filename_sanitize(filename)
     self.assertEqual(expected, actual)
Beispiel #8
0
def process_files(
    targets, user_media=None, test_run=False, id_key=None, **config
):
    """ Processes targets, relocating them as needed
    """
    notify = Notify()

    # Begin processing files
    detection_count = 0
    success_count = 0
    for file_path in dir_crawl(
        targets, config.get("recurse", False), config.get("extension_mask")
    ):
        notify.heading("Detected File")

        blacklist = config.get("blacklist", ())
        if any(match(b, file_stem(file_path)) for b in blacklist):
            notify.info("%s (blacklisted)" % file_path)
            continue
        else:
            print(file_stem(file_path))

        # Print metadata fields
        meta = meta_parse(file_path, user_media)
        if config["verbose"] is True:
            for field, value in meta.items():
                notify.verbose("%s: %s" % (field, value), True)

        # Print search results
        detection_count += 1
        notify.heading("Query Results")
        results = provider_search(meta, id_key, **config)
        i = 1
        hits = []
        while i < int(config.get("max_hits", 15)):
            try:
                hit = next(results)
                print("  [%s] %s" % (i, hit))
                hits.append(hit)
                i += 1
            except (StopIteration, MapiNotFoundException):
                break

        # Skip hit if no hits
        if not hits:
            notify.info("None found! Skipping.", True)
            continue

        # Select first if batch
        if config.get("batch") is True:
            meta.update(hits[0])

        # Prompt user for input
        else:
            print("  [RETURN] for default, [s]kip, [q]uit")
            abort = skip = None
            while True:
                selection = notify.prompt("Your Choice")

                # Catch default selection
                if not selection:
                    meta.update(hits[0])
                    break

                # Catch skip hit (just break w/o changes)
                elif selection in ["s", "S", "skip", "SKIP"]:
                    skip = True
                    break

                # Quit (abort and exit)
                elif selection in ["q", "Q", "quit", "QUIT"]:
                    abort = True
                    break

                # Catch result choice within presented range
                elif selection.isdigit() and 0 < int(selection) < len(hits) + 1:
                    meta.update(hits[int(selection) - 1])
                    break

                # Re-prompt if user input is invalid wrt to presented options
                else:
                    print("\nInvalid selection, please try again.")

            # User requested to skip file...
            if skip is True:
                notify.info("Skipping rename, as per user request.", True)
                continue

            # User requested to exit...
            elif abort is True:
                notify.info("\nAborting, as per user request.")
                return

        # Create file path
        notify.heading("Processing File")
        media = meta["media"]
        template = config.get("%s_template" % media)
        dest_path = meta.format(template)
        if config.get("%s_destination" % media):
            dest_dir = meta.format(config.get("%s_destination" % media, ""))
            dest_path = "%s/%s" % (dest_dir, dest_path)
        dest_path = filename_sanitize(dest_path)
        dest_path = filename_replace(dest_path, config.get("replacements"))
        if config.get("scene") is True:
            dest_path = filename_scenify(dest_path)
        dest_path = realpath(dest_path)

        # Attempt to process file
        try:
            if not test_run:
                # TODO: create parent paths
                shutil_move(str(file_path), str(dest_path))
            notify.info("Relocating file to '%s'" % dest_path, True)
        except IOError as e:
            notify.error(" Failed!", True)
            if config.get("verbose") is True:
                notify.verbose(e)
        else:
            notify.success("Success!", True)
            success_count += 1

    # Summarize session outcome
    if not detection_count:
        print("")
        notify.alert('No media files found. "mnamer --help" for usage.')
        return

    if success_count == 0:
        outcome_colour = "red"
    elif success_count < detection_count:
        outcome_colour = "yellow"
    else:
        outcome_colour = "green"
    cprint(
        "\nSuccessfully processed %s out of %s files"
        % (success_count, detection_count),
        outcome_colour,
    )