mauvehed's dotfiles for personal and work environments
at main 109 lines 4.7 kB view raw
1import os 2import subprocess 3import argparse 4import logging 5 6# Function to get the duration of a video file using ffprobe 7def get_video_duration(video_path): 8 try: 9 result = subprocess.run( 10 [ 11 'ffprobe', '-v', 'error', '-select_streams', 'v:0', 12 '-show_entries', 'format=duration', '-of', 'csv=p=0', video_path 13 ], 14 stdout=subprocess.PIPE, 15 stderr=subprocess.PIPE 16 ) 17 # Convert duration from seconds to a float 18 return float(result.stdout.strip()) 19 except Exception as e: 20 logging.error(f"Error getting duration for {video_path}: {e}") 21 return None 22 23# Function to delete files using sudo 24def delete_file_with_sudo(file): 25 try: 26 subprocess.run(['sudo', 'rm', file], check=True) 27 print(f"Deleted {file}.") 28 logging.info(f"Successfully deleted: {file}") 29 except subprocess.CalledProcessError as e: 30 print(f"Failed to delete {file}: {e}") 31 logging.error(f"Failed to delete {file}: {e}") 32 33# Function to prompt user for bulk deletion and log the action 34def prompt_for_bulk_deletion(files_to_delete, test_mode): 35 if not files_to_delete: 36 print("No files marked for deletion.") 37 logging.info("No files were marked for deletion.") 38 return 39 40 print("The following files are marked for deletion:") 41 for file, duration in files_to_delete: 42 hours = int(duration // 3600) 43 minutes = int((duration % 3600) // 60) 44 seconds = int(duration % 60) 45 print(f" - {file} (Duration: {hours:02}:{minutes:02}:{seconds:02})") 46 logging.info(f"File marked for deletion: {file} (Duration: {hours:02}:{minutes:02}:{seconds:02})") 47 48 while True: 49 user_input = input("Do you want to delete all these files? (y/n): ").strip().lower() 50 if user_input in ['y', 'n']: 51 if user_input == 'y': 52 logging.info("User chose to delete the marked files.") 53 if test_mode: 54 print("Test mode: The files listed above would have been deleted.") 55 logging.info("Test mode: No files were deleted.") 56 else: 57 for file, _ in files_to_delete: 58 delete_file_with_sudo(file) # Use sudo for deletion 59 else: 60 print("No files were deleted.") 61 logging.info("User chose not to delete the marked files.") 62 break 63 64# Main script logic 65def main(folder_path, max_length, test_mode, debug_mode, log_file): 66 # Set up logging 67 logging.basicConfig(filename=log_file, level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') 68 logging.info("Script started.") 69 70 files_to_delete = [] # List to keep track of files marked for deletion 71 72 # Iterate over all files in the specified folder 73 for root, dirs, files in os.walk(folder_path): 74 for file in files: 75 # Process video files with supported extensions 76 if file.lower().endswith(('.mp4', '.mkv', '.avi', '.mov', '.flv', '.m4v')): 77 video_path = os.path.join(root, file) 78 duration = get_video_duration(video_path) 79 80 if duration is None: 81 logging.warning(f"Skipping {file} due to error retrieving duration.") 82 continue 83 84 # Debug print to show file processing and duration 85 if debug_mode: 86 print(f"Processing file: {file}, Duration: {duration} seconds") 87 88 # If video is shorter than the maximum length, mark for deletion 89 if duration < max_length: 90 files_to_delete.append((video_path, duration)) 91 92 # Prompt for bulk deletion 93 prompt_for_bulk_deletion(files_to_delete, test_mode) 94 95 logging.info("Script finished.") 96 97if __name__ == "__main__": 98 # Set up argument parser 99 parser = argparse.ArgumentParser(description="Delete videos shorter than a specified length.") 100 parser.add_argument("folder", help="The folder containing video files to scan.") 101 parser.add_argument("max_length", type=int, help="The maximum video length in seconds. Videos shorter than this will be candidates for deletion.") 102 parser.add_argument("log_file", help="The path to the log file.") 103 parser.add_argument("--test", action="store_true", help="Simulate the execution without actually deleting any files.") 104 parser.add_argument("--debug", action="store_true", help="Enable debug mode to print processing information.") 105 106 args = parser.parse_args() 107 108 # Run the main function 109 main(args.folder, args.max_length, args.test, args.debug, args.log_file)