Files
Media_Scripts/ReviewTranscode.py

111 lines
3.5 KiB
Python

import os
import csv
import shutil
import argparse
from tqdm import tqdm
import ctypes
def is_windows():
return os.name == 'nt'
def hide_windows_console():
if is_windows():
try:
ctypes.windll.user32.ShowWindow(
ctypes.windll.kernel32.GetConsoleWindow(), 0)
except Exception:
pass
def process_files(csv_path, dry_run=False):
# Constants
MAX_DISPLAY_LEN = 90
RED = "\033[91m"
RESET = "\033[0m"
# Read all rows
with open(csv_path, newline='', encoding='utf-8') as f:
reader = csv.DictReader(f)
rows = list(reader)
fieldnames = reader.fieldnames
# Compute max length for padding (after truncation if needed)
def safe_name(name):
return name if len(name) <= MAX_DISPLAY_LEN else name[:MAX_DISPLAY_LEN - 3] + "..."
all_filenames = [safe_name(os.path.basename(row['original_file'])) for row in rows if 'original_file' in row]
max_filename_len = max(len(name) for name in all_filenames)
updated = False
for row in (pbar := tqdm(rows, desc="Processing files", unit="file")):
status = row.get('accepted', '').strip()
orig = row['original_file']
trans = row['transcoded_file']
orig_dir = os.path.dirname(orig)
base, _ = os.path.splitext(os.path.basename(orig))
target = os.path.join(orig_dir, base + '.mkv')
# Format filename for display
filename = os.path.basename(orig)
if len(filename) > MAX_DISPLAY_LEN:
display_name = filename[:MAX_DISPLAY_LEN - 3] + "..."
display_name_colored = f"{RED}{display_name}{RESET}"
else:
display_name = filename
display_name_colored = display_name
padded_name = display_name_colored.ljust(max_filename_len + len(RED) + len(RESET)) # pad including ANSI
# Update progress bar
pbar.set_description(f"Processing: {padded_name}")
if status == 'o':
if not os.path.exists(trans):
continue
if not dry_run:
try:
if os.path.exists(orig):
os.remove(orig)
shutil.move(trans, target)
row['accepted'] = 'D'
updated = True
except Exception:
pass
elif status == 'x':
if os.path.exists(trans):
if not dry_run:
try:
os.remove(trans)
updated = True
except Exception:
pass
if updated and not dry_run:
backup = csv_path + '.bak'
shutil.copy(csv_path, backup)
with open(csv_path, 'w', newline='', encoding='utf-8') as f:
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
writer.writerows(rows)
if __name__ == '__main__':
parser = argparse.ArgumentParser(
description='Replace original videos with AV1 transcodes based on CSV accepted column'
)
parser.add_argument('csvfile', help='Path to the CSV result file')
parser.add_argument('--dry-run', action='store_true',
help='Show actions without making changes')
parser.add_argument('--hide-console', action='store_true',
help='Hide Windows console window (GUI mode)')
args = parser.parse_args()
if args.hide_console:
hide_windows_console()
process_files(args.csvfile, dry_run=args.dry_run)