Exemple #1
0
    def __init__(self, filepath):

        # Store the current filename
        self.current_filename = os.path.basename(filepath)
        # Store the filename set by the user
        self.set_filename = os.path.basename(filepath)
        # Store the current path
        self.current_path = filepath
        # Store the path entered by the user
        self.set_path = filepath

        # Fetch the current title from the file metadata using mediainfo
        file_metadata = subprocess.run(
            ["mediainfo --Inform=\"General;%Title%\" \"" + filepath + "\""],
            universal_newlines=True,
            shell=True,
            stdout=subprocess.PIPE)
        debug(str(file_metadata), "matroska")

        # Check if the mediainfo command ran successfully
        # by looking at the return code
        if file_metadata.returncode:
            warning("Mediainfo failed to run correctly.", "matroska")

        # Store the current title
        if file_metadata.returncode or file_metadata.stdout == '\n':
            self.current_metadata_title = "N/A"
        else:
            self.current_metadata_title = file_metadata.stdout.splitlines()[0]
        # Store the title entered by the user
        self.set_metadata_title = self.current_metadata_title
def normalize_path(pathname):
    '''Takes a path and tries to guess its absolute path'''

    # Expand ~ or %HOME% if present in the path
    pathname = os.path.expanduser(pathname)

    # Check if resulting path is an absolute or relative path
    # and convert if necessary
    if not os.path.isabs(pathname):
        pathname = os.path.abspath(pathname)

    # Check if path already exists and raise a warning if it does
    if os.path.exists(pathname):
        warning("Path already exists and will be overwritten.", "path")

    # Check if the path is valid
    debug(pathname, "path")
    if is_pathname_valid(pathname):
        return pathname
    error("Illegal path encountered.", "path")
    return 1
Exemple #3
0
def apply_changes(videos):
    '''Method to apply changes to queued edits'''

    # Store the total number of edited videos
    total_updated = len(videos)
    # Display the queued videos to be modified
    print("About to apply changes to {0} videos.".format(total_updated))
    for video in videos:
        print(video.current_filename + ":")
        if video.current_path != video.set_path:
            print("New path: " + video.set_path)
        if video.current_metadata_title != video.set_metadata_title:
            print("New title: " + video.set_metadata_title)
    process = input("Continue? (y/n) ")
    clrscr()

    if process.lower() in ["yes", "y"]:
        for video in videos:
            status_code = video.update_metadata_fields()
            # Raise an error and stop further processing on error
            if status_code == 2:
                return 1
            debug("Applied change for video - " + str(video.current_path),
                  "run")

        for video in videos:
            status_code = video.update_file_fields()
            # Raise an error and stop further processing on error
            if status_code == 1:
                return 1
            debug("Renamed video - " + str(video.current_path), "run")

        print("Applied changes to {0} videos.".format(total_updated))
    else:
        debug("Changes discarded.", "run")
        print("Changes discarded.")

    if not args.no_restart:
        input("Press ENTER to continue")
    return 0
Exemple #4
0
def process_individual(video_list):
    '''Method to process all the video files in a given directory
    and give the user the option to edit them one by one
    '''

    # List to store all the video file objects
    videos = []

    # Instantiate objects to store the video data
    for file in video_list:
        videos.append(Matroska(os.getcwd() + "/" + file))

    process_count = 1
    update_count = 0
    # Store whether user wants to continue processing or not
    stop_flag = False
    # Store the total videos to process
    total = len(videos)
    # List to store all the modified videos
    updated_videos = []

    # Accept user inputs for the files
    for video in videos:
        while True:
            debug("Processing file no. " + str(process_count), "run")

            print("File {0} of {1}".format(process_count, total))
            print("Path: ", video.current_path)
            print("Filename: ", video.current_filename)
            print("Video title: ", video.current_metadata_title)

            temp = input("Enter the new video path " "(Press ENTER to skip) ")
            if temp:
                path = normalize_path(temp)
                if path == 1:
                    return 1
                video.set_path = temp
                video.set_filename = os.path.basename(video.set_path)

            temp = input("Enter the new video title "
                         "(Press ENTER to skip, \\ to copy filename) ")
            if temp == '\\':
                video.set_metadata_title = os.path.splitext(
                    video.set_filename)[0]
            elif temp:
                video.set_metadata_title = temp

            # Add only those videos that have been updated
            if (video.current_filename != video.set_filename) or (
                    video.current_metadata_title != video.set_metadata_title):
                updated_videos.append(video)
                update_count += 1

            process = input(
                "Press r to redo, s to stop processing, e to exit, "
                "ENTER to continue ")
            if process.lower() == 'r':
                update_count -= 1
                continue
            elif process.lower() == 's':
                stop_flag = True
            elif process.lower() == 'e':
                debug("Forced exit by user.", "run")
                return 0

            process_count += 1
            clrscr()
            break

        # Stop the loop to proceed to applying the changes
        if stop_flag:
            break
        stop_flag = False

    # Call the function to apply the edits that have been made if any
    if len(updated_videos) > 0:
        status_code = apply_changes(updated_videos)
    else:
        status_code = 0
    return status_code
Exemple #5
0
def process_batch_metadata(video_list):
    '''Method to process all the video files in a directory and
    give the user the option to edit them in a batch
    '''

    # Store the list of videos in the current directory
    videos = []
    for file in video_list:
        videos.append(Matroska(os.getcwd() + "/" + file))

    while True:
        # Accept pattern to edit metadata
        if not args.m_pattern:
            print(COLOR["CYAN"] + "METADATA PATTERN" + COLOR["END"] + "\n"
                  "{dir:d} - directory based numbering, {file:d} "
                  "file based numbering" + "\n"
                  "Example - Person of Interest S{dir:02d}E{file:02d} -> "
                  "Person of Interest S01E01")
        m_pattern = args.m_pattern or input(
            "Enter the metadata pattern (\\ to skip) ")
        debug(m_pattern, "run")

        # Accept metadata to edit filenames
        if not args.f_pattern:
            print(COLOR["CYAN"] + "FILE PATTERN" + COLOR["END"] + "\n"
                  "{dir:d} - directory based numbering, {file:d} "
                  "file based numbering" + "\n"
                  "Example - Person of Interest S{dir:02d}E{file:02d}.mkv -> "
                  "Person of Interest S01E01.mkv\n"
                  "Pattern must translate to a valid path")
        f_pattern = args.f_pattern or input(
            "Enter the file pattern (\\ to skip) ")
        debug(f_pattern, "run")

        # Accept custom offsets for filenames and metadata
        # TODO: Add support for per directory file offsets
        if args.offset == "True":
            directory_offset = input("Enter directory offset (optional) ") or 1
            file_offset = input("Enter file offset (optional) ") or 1
        elif args.offset == "False":
            directory_offset = 1
            file_offset = 1
        else:
            try:
                # Try literal evaluation of the argument and store in tuple
                tup = literal_eval(args.offset)
            except:
                error("Invalid offsets passed.", "run")
                return 1
            directory_offset = tup[0]
            file_offset = tup[1]

        # Store current video's current path
        current_path = os.path.dirname(videos[0].current_path)
        for video in videos:
            # Increment directory offset and reset file offset when
            # the directory of the previous video doesn't match the current
            if os.path.dirname(video.current_path) != current_path:
                current_path = os.path.dirname(video.current_path)
                directory_offset += 1
                file_offset = 1
                debug(current_path, "run")
            if m_pattern != "\\":
                video.set_metadata_title = m_pattern.format(
                    dir=directory_offset, file=file_offset)
            if f_pattern != "\\":
                path = normalize_path(
                    f_pattern.format(dir=directory_offset, file=file_offset))
                # Return if the path is invalid
                if path == 1:
                    return 1
                video.set_path = path
                video.set_filename = os.path.basename(video.set_path)
            file_offset += 1

        process = input("Press r to redo, e to exit, ENTER to continue ")
        if process.lower() == 'r':
            continue
        elif process.lower() == 'e':
            debug("Forced exit by user.", "run")
            return 0

        clrscr()
        break

    # Call function to apply the changes
    status_code = apply_changes(videos)

    return status_code
Exemple #6
0
        help='specify true (default), false, or specific offset in '
        '\"(dir, file)\" format')
    # Add argument to terminate the script after 1 run
    parser.add_argument(
        '-n',
        '--no_restart',
        action='store_true',
        help='don\'t restart the script after a batch job is complete.')
    # Add argument to specify which mode to run the script in
    parser.add_argument(
        '-m',
        '--mode',
        default=None,
        help='specify the mode to run the script in - single or batch.')
    args = parser.parse_args()
    debug(str(args), "run")

    while True:
        status_code = run()
        if status_code == 1:
            print("The script encountered an error.")

        # Reset the value for the next iteration so that the path
        # can be accepted via user input
        args.path = None

        if args.no_restart:
            break
        process = input("Restart? (y/n) ")
        if process.lower() in ['yes', 'y']:
            debug("Restarting...", "run")