-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcore.py
181 lines (164 loc) · 7.53 KB
/
core.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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
# coding=utf-8
import os
import time
import re
import shutil
import datetime
import exifread
import sys
from wx import CallAfter
__author__ = 'vid'
class Core(object):
def __init__(self, source_dirs=None, output_dir=None, formats_filter=None, mode='move', remove_duplicates=True,
img_name='{old}', folder_name='{old}', remove_date_from_old_dir_name=False, use_date_from_name=False, date_from_name='', reference=None,
go_back=False):
self.date_from_name = date_from_name
self.use_date_from_name = use_date_from_name
self.date_from_name_len = len(time.strftime(self.date_from_name))
self.go_back = go_back
self.reference = reference
self.duplicate_names = [''] + [' (' + str(i) + ')' for i in range(1000)]
self.mode = mode
self.filter = [i for i in formats_filter if len(i) > 0]
self.recursive = True # TODO
self.remove_duplicate_images = remove_duplicates
# dir naming
self.folder_name = folder_name # %Y-ear %m-onth %d-day %H-hour %M-minute %S-second {old} - old name
self.remove_date_from_dir_name = remove_date_from_old_dir_name # remove everything from beginning to first alphabet character
# image naming
self.img_name = img_name # %Y-ear %m-onth %d-day %H-hour %M-minute %S-second {old} - old name | %H;%M ({old})
if source_dirs and output_dir:
self.rename_and_sort(source_dirs, output_dir)
def update_gui(self, back=False, close=False):
if close:
self.reference.dialog.Close()
if back:
self.reference.dialog.browser.GoBack()
return
self.reference.dialog.browser.RunScript('''
$('#progressbar>div').width('{percent}%');
'''.replace('{percent}', self.percentage))
def rename_and_sort(self, source_dirs, destination):
not_coppied = 0
if self.remove_duplicate_images:
files_list = self.no_duplicates(source_dirs)
else:
files_list = self.allow_duplicates(source_dirs)
for img in files_list:
self.percentage = str(float(files_list.index(img)) / len(files_list) * 100.)
if self.reference:
from wx.richtext import wx
wx.CallAfter(self.update_gui)
root, filename, extension = img
if destination not in root:
date_taken = self.get_date_created(os.path.join(root, filename))
# folder naming
new_dir_name = date_taken.strftime(self.folder_name)
old_dir_name = os.path.basename(root)
if self.remove_date_from_dir_name:
old_dir_name = re.split('^[0-9-_.\s]+', old_dir_name, 1)[-1]
try:
new_dir_name = new_dir_name.replace('{old}', old_dir_name).strip()
except:
pass
# img naming
new_img_name = date_taken.strftime(self.img_name)
try:
new_img_name = new_img_name.replace('{old}', filename.split('.')[0])
except:
pass
new_img_name += '.' + extension
# copy / move, mkdirs
dest_path = os.path.join(destination, new_dir_name)
if not os.path.isdir(dest_path):
try:
os.makedirs(dest_path)
except Exception, e:
print e
for i in self.duplicate_names:
try:
print filename + ' --> ' + dest_path, new_img_name + i
if self.mode == 'copy':
shutil.copy(os.path.join(root, filename), os.path.join(dest_path, new_img_name + i))
elif self.mode == 'move':
shutil.move(os.path.join(root, filename), os.path.join(dest_path, new_img_name + i))
break
except Exception, e:
print e
else:
not_coppied += 1
print not_coppied, 'images not copied'
self.percentage = '100'
if self.reference:
CallAfter(self.update_gui)
time.sleep(.2)
if self.go_back and self.reference:
CallAfter(lambda: self.update_gui(back=True))
elif self.reference:
self.reference.dialog.Close()
def get_date_created(self, path):
print path
if self.use_date_from_name:
print 'ok'
try:
file_name = os.path.basename(path)
except:
file_name = ''
print file_name
for i in range(self.date_from_name_len, len(file_name)):
try:
date_taken = datetime.datetime.fromtimestamp(time.mktime(
time.strptime(file_name[i-self.date_from_name_len:i], self.date_from_name)
))
return date_taken
except:
pass
print 'cannot retreive date from', file_name
with open(path, 'rb') as f:
try:
date_taken = datetime.datetime.fromtimestamp(time.mktime(
time.strptime(str(exifread.process_file(f)['EXIF DateTimeOriginal']), '%Y:%m:%d %H:%M:%S'))
)
except:
date_taken = datetime.datetime.fromtimestamp(os.path.getmtime(path))
return date_taken
def no_duplicates(self, source_dirs):
result = {}
counter = 0
for source_dir in source_dirs:
for root, dirnames, filenames in os.walk(unicode(source_dir)):
for filename in filenames:
counter += 1
path = os.path.join(root, filename)
if os.path.isfile(path):
if len(filename.split('.')) > 1:
result[filename + str(os.path.getsize(path))] = [root, filename,
filename.split('.')[-1].lower()]
else:
result[filename + str(os.path.getsize(path))] = [root, filename, '']
print 'removed ' + str(counter - len(result)) + ' duplicates'
if self.filter:
result = [result[i] for i in result if result[i][2] in self.filter]
else:
result = [result[i] for i in result]
return result
def allow_duplicates(self, source_dirs):
result = []
for source_dir in source_dirs:
for root, dirnames, filenames in os.walk(unicode(source_dir)):
for filename in filenames:
if len(filename.split('.')) > 1:
result.append([root, filename, filename.split('.')[-1].lower()])
else:
result.append([root, filename, ''])
if self.filter:
result = [i for i in result if i[2] in self.filter]
return result
if __name__ == '__main__':
t = Core(mode='move',
formats_filter=['jpg', 'mov', 'mp4', 'png', 'wmv', 'avi', 'tif', 'mts', 'jpeg'],
remove_duplicates=True,
img_name='%H;%M ({old})',
folder_name='%Y_%m_%d')
t.rename_and_sort([r'source_dir'],
r'destination_dir')