forked from ChrisMagnuson/sort-PhotorecRecoveredFiles
-
Notifications
You must be signed in to change notification settings - Fork 29
/
Copy pathjpgSorter.py
128 lines (105 loc) · 4.78 KB
/
jpgSorter.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import os.path
import ntpath
from time import localtime, strftime, strptime, mktime
import shutil
import exifread
unknownDateFolderName = "date-unknown"
def getMinimumCreationTime(exif_data):
creationTime = None
dateTime = exif_data.get('DateTime')
if (dateTime is None):
dateTime = exif_data.get('Image DateTime')
dateTimeOriginal = exif_data.get('EXIF DateTimeOriginal')
dateTimeDigitized = exif_data.get('EXIF DateTimeDigitized')
# 3 differnt time fields that can be set independently result in 9 if-cases
if (dateTime is None):
if (dateTimeOriginal is None):
# case 1/9: dateTime, dateTimeOriginal, and dateTimeDigitized = None
# case 2/9: dateTime and dateTimeOriginal = None, then use dateTimeDigitized
creationTime = dateTimeDigitized
else:
# case 3/9: dateTime and dateTimeDigitized = None, then use dateTimeOriginal
# case 4/9: dateTime = None, prefere dateTimeOriginal over dateTimeDigitized
creationTime = dateTimeOriginal
else:
# case 5-9: when creationTime is set, prefere it over the others
creationTime = dateTime
return creationTime
def postprocessImage(images, imageDirectory, fileName):
imagePath = os.path.join(imageDirectory, fileName)
image = open(imagePath, 'rb')
creationTime = None
try:
exifTags = exifread.process_file(image, details=False)
creationTime = getMinimumCreationTime(exifTags)
except:
print("invalid exif tags for " + fileName)
# distinct different time types
if creationTime is None:
creationTime = localtime(os.path.getctime(imagePath))
else:
try:
creationTime = strptime(str(creationTime), "%Y:%m:%d %H:%M:%S")
except:
creationTime = localtime(os.path.getctime(imagePath))
images.append((mktime(creationTime), imagePath))
image.close()
# Creates the requested path recursively.
def createPath(newPath):
if not os.path.exists(newPath):
os.makedirs(newPath)
# Pass None for month to create 'year/eventNumber' directories instead of 'year/month/eventNumber'.
def createNewFolder(destinationRoot, year, month, eventNumber):
if month is not None:
newPath = os.path.join(destinationRoot, year, month, str(eventNumber))
else:
newPath = os.path.join(destinationRoot, year, str(eventNumber))
createPath(newPath)
def createUnknownDateFolder(destinationRoot):
path = os.path.join(destinationRoot, unknownDateFolderName)
createPath(path)
def writeImages(images, destinationRoot, minEventDeltaDays, splitByMonth=False):
minEventDelta = minEventDeltaDays * 60 * 60 * 24 # convert in seconds
sortedImages = sorted(images)
previousTime = None
eventNumber = 0
previousDestination = None
today = strftime("%d/%m/%Y")
for imageTuple in sortedImages:
destination = ""
destinationFilePath = ""
t = localtime(imageTuple[0])
year = strftime("%Y", t)
month = splitByMonth and strftime("%m", t) or None
creationDate = strftime("%d/%m/%Y", t)
fileName = ntpath.basename(imageTuple[1])
if(creationDate == today):
createUnknownDateFolder(destinationRoot)
destination = os.path.join(destinationRoot, unknownDateFolderName)
destinationFilePath = os.path.join(destination, fileName)
else:
if (previousTime == None) or ((previousTime + minEventDelta) < imageTuple[0]):
eventNumber = eventNumber + 1
createNewFolder(destinationRoot, year, month, eventNumber)
previousTime = imageTuple[0]
destComponents = [destinationRoot, year, month, str(eventNumber)]
destComponents = [v for v in destComponents if v is not None]
destination = os.path.join(*destComponents)
# it may be possible that an event covers 2 years.
# in such a case put all the images to the event in the old year
if not (os.path.exists(destination)):
destination = previousDestination
# destination = os.path.join(destinationRoot, str(int(year) - 1), str(eventNumber))
previousDestination = destination
destinationFilePath = os.path.join(destination, fileName)
if not (os.path.exists(destinationFilePath)):
shutil.move(imageTuple[1], destination)
else:
if (os.path.exists(imageTuple[1])):
os.remove(imageTuple[1])
def postprocessImages(imageDirectory, minEventDeltaDays, splitByMonth):
images = []
for root, dirs, files in os.walk(imageDirectory):
for file in files:
postprocessImage(images, imageDirectory, file)
writeImages(images, imageDirectory, minEventDeltaDays, splitByMonth)