Reputation: 329
I'm trying to automate organizing my photography folder of over 3000 photos.
I'd like to get the date the file was created, create a new folder of that date formatted as DD-MM-YYYY
and move the file from its current folder into the new folder.
I was able to retrieve the created date of one of the files using the below code
print("created: %s" % time.ctime(os.path.getctime(file)))
Which returns created: Fri Mar 22 17:49:36 2019
.
Below is a sample of the folder. In this case, the created date is the same as the modified date but this is not always the case!
How can I achieve this?
Upvotes: 3
Views: 3797
Reputation: 523
You can use mtime
instead of ctime
but as it looks from your screenshot and as far as I know, there is no way to get the 'time created' time on windows. ctime
stands for change time and is more subject to changes than mtime
. (Detailed explaination here)
What you can do in order to get to your goal, is read out the EXIF-data from your images. They should hold the date and time when your images were taken. If you are unsure, if your images hold EXIF-data, you can use the following script to fall back to mtime
, if no exif-data is found:
import exifread
import shutil
import os
import sys
import datetime
ALLOWED_EXTENSIONS = set(['png', 'jpg', 'jpeg', 'cr2'])
def allowed_file(filename):
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
if len(sys.argv) < 1:
print('Please provide directory as argument!')
directory = sys.argv[1] # get the directory where we are looking for images
img_files = os.listdir(directory) # get the files of the directory
for img in img_files:
date = None
if allowed_file(img): # check if the file is an image file
full_path = os.path.join(directory, img)
with open(full_path, 'rb') as image_file:
tags = exifread.process_file(image_file, stop_tag='EXIF DateTimeOriginal')
date_taken = str(tags.get('EXIF DateTimeOriginal'))
try:
date_time_obj = datetime.datetime.strptime(date_taken, '%Y:%m:%d %H:%M:%S')
date = date_time_obj.date() # getting the date in YYYY-MM-DD format
except ValueError:
print('Cannot find EXIF')
if not date:
print('Using mtime')
mtime = os.path.getmtime(full_path)
date_time_obj = datetime.datetime.fromtimestamp(mtime)
date = date_time_obj.date()
print('Image: {} - Date: {}'.format(img, date))
new_directory = 'Sorted/{}'.format(date)
os.makedirs(new_directory, exist_ok=True) # make the new directory
shutil.copyfile(full_path, os.path.join(new_directory, img)) # copy file into the new directory - it will have the format YYYY-MM-DD
This script will read out EXIF data from your images, if there is none, it falls back to mtime
, creates folders and copies the images into the folders.
Please note that in this script I formatted the date to YYYY-MM-DD. You can change it of course easily. It's just, that the directories in the Sorted
-folder than are displayed in ascending order, which is convinient. But of course not mandatory.
If you safe the script as sort.py
you can start it with python sort.py <directory-to-sort>
. (exifread
and shutil
must be installed via pip install
before that)
Upvotes: 2
Reputation: 56885
You can use os.listdir
to get a list of files in a directory, then filter them by os.path.isfile
and/or f.endswith
to only accept image files. You pretty much have the timestamp code (you can use strftime
to format it), so it's a matter of making any necessary directories with os.makedirs
and copying the files with os.replace
.
All relevant methods can be found in the documentation for the os
and datetime
modules.
import os
from datetime import datetime
path = "."
ext = "CR2"
for f in os.listdir(path):
fpath = os.path.join(path, f)
if os.path.isfile(fpath) and fpath.endswith(ext):
time = datetime.fromtimestamp(os.path.getctime(fpath)).strftime("%d-%m-%Y")
os.makedirs(os.path.join(path, time), exist_ok=True)
os.replace(fpath, os.path.join(path, time, f))
If you want to accept multiple extensions and organize them into subfolders by extension, you can use:
import os
from datetime import datetime
path = "foo"
exts = set(["cr2", "jpg"])
for f in os.listdir(path):
fpath = os.path.join(path, f)
ext = f.split(".")[-1].lower()
if os.path.isfile(fpath) and ext in exts:
time = datetime.fromtimestamp(os.path.getctime(fpath)).strftime("%d-%m-%Y")
os.makedirs(os.path.join(path, time, ext), exist_ok=True)
os.replace(fpath, os.path.join(path, time, ext, f))
Upvotes: 3