-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdateDirs.py
More file actions
172 lines (142 loc) · 5 KB
/
dateDirs.py
File metadata and controls
172 lines (142 loc) · 5 KB
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
#!/usr/bin/env python3
# @file: dateDirs.py
# @auth: Sprax Lines
# @date: 2016-06-02 17:36:26 Thu 02 Jun
# Sprax Lines 2016.07.12 Updated for Python 3.5
'''
Group photos and videos by date and move them to folders named
for the dates found. Moves .jpg and .mov files by default, but
the file extensions can be specified.
Usage: python <thisScript> [inputDir [filePatterns [outSuffix]]]
'''
# Sprax Lines 2012 ?
# import modules
from collections import defaultdict
import glob
import os
import re
# from stat import S_ISREG, S_ISDIR, ST_MTIME, ST_MODE
from stat import ST_MTIME
import shutil
import sys
import time
def dateDirs(dirpath, dirSuffix, patterns, verbose):
""" Make dictionary mapping file modification dates to file names """
# get all entries in the directory w/ stats
print()
print("DirPath: ", dirpath)
print("Patterns: ", patterns)
print("Directories: ")
try:
in_dirs = filter(os.path.isdir, os.listdir(dirpath))
except FileNotFoundError:
print("Input directory (", dirpath, ") not found; quitting.\n")
exit(1)
if verbose > 2:
for dn in in_dirs:
print("\t", dn)
out_dirs = []
for dp in sorted(in_dirs):
dn = os.path.basename(dp)
try:
ts = time.strptime(dn, "%b %d, %Y")
# print("time.ts: ", ts)
dates = time.strftime("%Y.%m.%d_%a", ts)
print("dirName ==> dated :: %s ==> %s" % (dn, dates))
canonDateDirName = getUniqueDirName(in_dirs, dates)
if verbose > 1:
print("unique cannonical dir name: ", canonDateDirName)
print("Moving ", dn, " to ", canonDateDirName)
shutil.move(dn, canonDateDirName)
out_dirs.append(canonDateDirName)
except:
if verbose > 0:
print("dirName (%s) did not parse as a date" % dn)
print("Files: ")
files = []
for pattern in patterns:
files.extend(filter(os.path.isfile, glob.glob(dirpath + "/" + pattern)))
pairs = ((os.stat(fn), fn) for fn in files)
if verbose > 1:
print(files)
print()
print("Dictionary: ")
date2files = make_date_to_files_dic(pairs, dirSuffix)
for key in sorted(date2files.keys()):
print(key)
dfiles = sorted(date2files[key])
for fn in dfiles:
print("\t\t" + fn)
return out_dirs, date2files
def make_date_to_files_dic(pairs, dirSuffix):
'''maps each found date to a list of files'''
date2files = defaultdict(list)
# On Windows `ST_CTIME` is a creation date,
# but on Unix it could be something else.
# Use `ST_MTIME` to sort by a modification date
for fstat, path in sorted(pairs):
modtime = fstat[ST_MTIME]
tstruct = time.localtime(modtime)
datestr = time.strftime("%Y.%m.%d_%a", tstruct)
if len(dirSuffix) > 0:
datestr = datestr + "_" + dirSuffix
print(modtime, datestr, os.path.basename(path))
print(time.ctime(modtime), os.path.basename(path))
date2files[datestr].append(path)
return date2files
def getUniqueDirName(dirs, baseName):
'''
if there is already a directory with this name (baseName), make a new name
'''
suffix = 0
uniqDirName = baseName
while uniqDirName in dirs:
suffix += 1
uniqDirName = baseName + "_" + str(suffix)
return uniqDirName
def moveFilesToDateDirs(dirs, date2files):
'''Actually move the files into the date-named directories'''
print("moveFilesToDateDirs")
for dirName in sorted(date2files.keys()):
# Get unique directory name -- this is redundant (TODO)
uniqDirName = getUniqueDirName(dirs, dirName)
if not os.path.exists(uniqDirName):
print("Making directory: ", uniqDirName)
os.makedirs(uniqDirName)
dfiles = date2files[dirName]
for fn in dfiles:
print("Moving ", fn, " to ", uniqDirName)
shutil.move(fn, uniqDirName)
def main():
""" Print out dictionary of modfication dates and files in a directory."""
verbose = 3
# simple, inflexible arg parsing:
numArgs = len(sys.argv)
if numArgs > 44:
print(sys.argv[0])
print(dateDirs.__doc__)
# path to the directory (relative or absolute)
# dirpath = sys.argv[1] if len(sys.argv) == 2 else r'.'
if numArgs > 1:
dirpath = sys.argv[1]
else:
dirpath = "."
begPatArgs = 2
if numArgs > 3 and re.match("--s", sys.argv[2]):
dirSuffix = sys.argv[3]
if verbose > 0:
print("Suffix: ", dirSuffix)
begPatArgs = 4
else:
dirSuffix = ''
if numArgs > begPatArgs:
patterns = sys.argv[begPatArgs:]
else:
patterns = ['*.jpeg', '*.jpg', '*.mov', '*.mp4', '*.png']
out_dirs, date2files = dateDirs(dirpath, dirSuffix, patterns, verbose)
if len(date2files.keys()) > 0:
moveFilesToDateDirs(out_dirs, date2files)
else:
print("The date2files dict is empty.")
if __name__ == '__main__':
main()