organize-media.py (2681B)
1 #!/usr/bin/python3 2 3 # Script that finds all media files in a source directory and moves them to a target 4 # directory on the format <target>/<year>/<month>/ based on the media file date. 5 6 from exif import Image 7 from datetime import datetime as dt 8 import os 9 import sys 10 import re 11 12 DEBUG=False 13 14 15 if len(sys.argv) >= 3: 16 NEW_MEDIA_DIR=sys.argv[1] 17 SORTED_MEDIA_DIR=sys.argv[2] 18 else: 19 NEW_MEDIA_DIR=os.environ['NEW_MEDIA_DIR'] 20 SORTED_MEDIA_DIR=os.environ['SORTED_MEDIA_DIR'] 21 22 ts_fmt_exif = '%Y:%m:%d %H:%M:%S' 23 ts_fmts_filename = [ 24 re.compile('.+_(?P<year>\d{4})(?P<month>\d\d)(?P<day>\d\d)_(?P<hour>\d\d)(?P<min>\d\d)(?P<sec>\d\d).+') 25 ] 26 27 # Tries to get the date of a media file, first by reading EXIF data, 28 # then by parsing the filename if unsuccessful. 29 # Returns date as a touple: (year, month, day). 30 def extract_img_date(filename): 31 if '.mp4' not in filename: 32 try: 33 img = Image(open(filename, 'rb')) 34 ts = dt.strptime(img.datetime, ts_fmt_exif) 35 if DEBUG: 36 print('Found date in exif data') 37 return (str(ts.year), str(ts.month).rjust(2, '0'), str(ts.day).rjust(2, '0')) 38 except Exception as e: 39 pass 40 # Then try different filename formats 41 for fmt in ts_fmts_filename: 42 match = fmt.match(filename) 43 if match: 44 if DEBUG: 45 print('Found date in filename') 46 return (match.group('year'), match.group('month'), match.group('day')) 47 return None 48 49 # Takes a date touple (year, month, day) and creates <SORTED_MEDIA_DIR>/<year>/<month> 50 # if it doesn't exist already 51 def create_and_get_month_dir(date): 52 month_dir=os.path.join(SORTED_MEDIA_DIR, date[0], date[1]) 53 if os.path.exists(month_dir): 54 if DEBUG: 55 print(f'Directory "{month_dir}" exists') 56 return month_dir 57 if DEBUG: 58 print(f'SIMULATED: Directory "{month_dir}" created') 59 else: 60 os.makedirs(month_dir) 61 return month_dir 62 63 if not os.path.exists(NEW_MEDIA_DIR): 64 print(f'{NEW_MEDIA_DIR} does not exist') 65 exit(1) 66 67 # Do the organization 68 for [root, dirs, files] in os.walk(NEW_MEDIA_DIR): 69 for filename in files: 70 if not filename: 71 continue 72 old_path = os.path.join(root, filename) 73 date = extract_img_date(old_path) 74 if not date: 75 if DEBUG: 76 print('No date found for ' + filename) 77 continue 78 month_dir = create_and_get_month_dir(date) 79 new_path = os.path.join(month_dir, filename) 80 if DEBUG: 81 print(f'SIMULATED: Moved {old_path} to {new_path}') 82 else: 83 os.rename(old_path, new_path)