snippets

More or less useful code snippets
Log | Files | Refs

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)