mauvehed's dotfiles for personal and work environments
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)