def update_file_fields(self): '''Method to apply the new filename and path to the video''' try: os.renames(self.current_path, self.set_path) self.current_path = self.set_path self.current_filename = self.set_filename except OSError: error("Failed to rename the file", "matroska") error(self.current_path, "matroska") return 1 return 0
def run(): '''Method that manages the script lifecycle and activities''' # Accept a path if not entered via the command line wd = args.path or input("Enter the directory path to the file(s): ") wd = os.path.expanduser(wd) if os.path.isdir(wd) or os.path.isdir(os.getcwd() + wd): os.chdir(wd) else: error("Directory not found.", "run") return 1 # Recursively search the current working directory and subdirectories # for files ending with a .mkv extension video_list = [] mkv_list = glob('**/*.mkv', recursive=True) # mp4_list = glob('**/*.mp4', recursive=True) # avi_list = glob('**/*.mp4', recursive=True) video_list.extend(mkv_list) # video_list.extend(mp4_list) # video_list.extend(avi_list) video_list.sort() if not args.mode: print(''' Run the script in one of two currently supported modes.\n 1 - Single mode. This mode looks for all video files in a given\n directory and gives the user the option to edit them one by one.\n 2 - Batch mode. This mode lets the user specify a pattern or rule\n which will be used to edit the video files in the given directory. ''') process = args.mode or input("Single mode or batch mode? (s/b) ") if process.lower() in ["single", "s"]: clrscr() status_code = process_individual(video_list) elif process.lower() in ["batch", "b"]: clrscr() status_code = process_batch_metadata(video_list) else: error("Invalid processing option.", "run") return 1 if status_code == 1: return 1 return 0
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
def update_metadata_fields(self): '''Method to apply the new metadata values to the video''' # Build the string to call mkvpropedit and set the metadata correctly shell_command = ''.join([ "mkvpropedit \"", self.current_path, "\" --edit info --set \"title=", self.set_metadata_title, "\"" ]) result = subprocess.run([shell_command], universal_newlines=True, shell=True, stdout=subprocess.PIPE) if result.returncode == 0: self.current_metadata_title = self.set_metadata_title return 0 if result.returncode == 1: warning("mkvpropedit: " + result.stdout, "matroska") warning(self.current_path, "matroska") self.current_metadata_title = self.set_metadata_title return 1 error("mkvpropedit:" + result.stdout, "matroska") error(self.current_path, "matroska") return 2
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