forked from ChrisMagnuson/sort-PhotorecRecoveredFiles
-
Notifications
You must be signed in to change notification settings - Fork 29
/
recovery.py
executable file
·159 lines (124 loc) · 6.05 KB
/
recovery.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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#!/usr/bin/env python
import os
import os.path
from time import localtime, strftime
import shutil
import jpgSorter
import numberOfFilesPerFolderLimiter
import exifread
from time import localtime, strftime, strptime, mktime
def getNumberOfFilesInFolderRecursively(start_path = '.'):
numberOfFiles = 0
for dirpath, dirnames, filenames in os.walk(start_path):
for f in filenames:
fp = os.path.join(dirpath, f)
if(os.path.isfile(fp)):
numberOfFiles += 1
return numberOfFiles
def getNumberOfFilesInFolder(path):
return len(os.listdir(path))
def log(logString):
print(strftime("%H:%M:%S", localtime()) + ": " + logString)
def moveFile(file, destination):
extension = os.path.splitext(file)[1][1:].upper()
sourcePath = os.path.join(root, file)
destinationDirectory = os.path.join(destination, extension)
if not os.path.exists(destinationDirectory):
os.mkdir(destinationDirectory)
fileName = str(fileCounter) + "." + extension.lower()
destinationFile = os.path.join(destinationDirectory, fileName)
if not os.path.exists(destinationFile):
shutil.copy(sourcePath, destinationFile)
def get_args():
import argparse
description = (
"Sort files recoverd by Photorec.\n"
"The input files are first copied to the destination, sorted by file type.\n"
"Then JPG files are sorted based on creation year (and optionally month).\n"
"Finally any directories containing more than a maximum number of files are accordingly split into separate directories."
)
parser = argparse.ArgumentParser(description=description, formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('source', metavar='src', type=str, help='source directory with files recovered by Photorec')
parser.add_argument('destination', metavar='dest', type=str, help='destination directory to write sorted files to')
parser.add_argument('-n', '--max-per-dir', type=int, default=500, required=False, help='maximum number of files per directory')
parser.add_argument('-m', '--split-months', action='store_true', required=False, help='split JPEG files not only by year but by month as well')
parser.add_argument('-k', '--keep_filename', action='store_true', required=False, help='keeps the original filenames when copying')
parser.add_argument('-d', '--min-event-delta', type=int, default=4, required=False, help='minimum delta in days between two days')
parser.add_argument('-j', '--date_time_filename', action='store_true', required=False, help='sets the filename to the exif date and time if possible - otherwise keep the original filename')
return parser.parse_args()
maxNumberOfFilesPerFolder = 500
splitMonths = False
source = None
destination = None
keepFilename = False
date_time_filename = False
args = get_args()
source = args.source
destination = args.destination
maxNumberOfFilesPerFolder = args.max_per_dir
splitMonths = args.split_months
keepFilename = args.keep_filename
date_time_filename = args.date_time_filename
minEventDeltaDays = args.min_event_delta
print("Reading from source '%s', writing to destination '%s' (max %i files per directory, splitting by year %s)." %
(source, destination, maxNumberOfFilesPerFolder, splitMonths and "and month" or "only"))
if keepFilename:
print("I will keep you filenames as they are")
elif date_time_filename:
print("If possible I will rename your files like <Date>_<Time>.jpg - otherwise keep the filenames as they are")
else:
print("I will rename your files like '1.jpg'")
while ((source is None) or (not os.path.exists(source))):
source = input('Enter a valid source directory\n')
while ((destination is None) or (not os.path.exists(destination))):
destination = input('Enter a valid destination directory\n')
fileNumber = getNumberOfFilesInFolderRecursively(source)
if fileNumber > 100:
onePercentFiles = int(fileNumber/100)
else:
onePercentFiles = fileNumber
totalAmountToCopy = str(fileNumber)
print("Files to copy: " + totalAmountToCopy)
fileCounter = 0
for root, dirs, files in os.walk(source, topdown=False):
for file in files:
extension = os.path.splitext(file)[1][1:].upper()
sourcePath = os.path.join(root, file)
if extension:
destinationDirectory = os.path.join(destination, extension)
else:
destinationDirectory = os.path.join(destination, "_NO_EXTENSION")
if not os.path.exists(destinationDirectory):
os.mkdir(destinationDirectory)
if keepFilename:
fileName = file
elif date_time_filename:
index = 0
image = open(sourcePath, 'rb')
exifTags = exifread.process_file(image, details=False)
image.close()
creationTime = jpgSorter.getMinimumCreationTime(exifTags)
try:
creationTime = strptime(str(creationTime), "%Y:%m:%d %H:%M:%S")
creationTime = strftime("%Y%m%d_%H%M%S", creationTime)
fileName = str(creationTime) + "." + extension.lower()
while os.path.exists(os.path.join(destinationDirectory, fileName)):
index += 1
fileName = str(creationTime) + "(" + str(index) + ")" + "." + extension.lower()
except:
fileName = file
else:
if extension:
fileName = str(fileCounter) + "." + extension.lower()
else:
fileName = str(fileCounter)
destinationFile = os.path.join(destinationDirectory, fileName)
if not os.path.exists(destinationFile):
shutil.copy2(sourcePath, destinationFile)
fileCounter += 1
if((fileCounter % onePercentFiles) == 0):
log(str(fileCounter) + " / " + totalAmountToCopy + " processed.")
log("start special file treatment")
jpgSorter.postprocessImages(os.path.join(destination, "JPG"), minEventDeltaDays, splitMonths)
log("assure max file per folder number")
numberOfFilesPerFolderLimiter.limitFilesPerFolder(destination, maxNumberOfFilesPerFolder)