-
Notifications
You must be signed in to change notification settings - Fork 2
/
sw-consolidate
executable file
·133 lines (110 loc) · 5.22 KB
/
sw-consolidate
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
#!/usr/bin/env python3
import argparse, os, os.path, sqlite3, time, datetime, re
parser = argparse.ArgumentParser()
parser.add_argument("-d", "--datadir", metavar="DIRECTORY", help="path to Shotwell's private data", default=os.path.join(os.getenv("XDG_DATA_HOME",default=os.path.join(os.getenv("HOME", default="~"),".local","share")),"shotwell"))
parser.add_argument("-f","--flag",action="store_true",help="flag anomalies (unflag everything else)")
parser.add_argument("LIBDIR", help="directory to move photos to")
args = parser.parse_args()
librarypath=args.LIBDIR
if not os.path.isdir(librarypath):
print("Not a directory: " + librarypath)
exit(1)
dbpath = os.path.join(args.datadir,"data","photo.db")
def dateTimestamp(year,month,day):
return int(time.mktime(datetime.datetime(year,month,day, 0,0,0, 0).timetuple()))
goodTimestamp = dateTimestamp(1980,1,1)
def str2(n):
if n < 10:
return "0"+str(n)
else:
return str(n)
def checkversion(path,conn):
(version,) = conn.execute("SELECT schema_version FROM versiontable").fetchone()
if not version in [20,24]:
raise Exception (path + ": wrong schema " + str(version) + " (should be 20 or 24)")
with sqlite3.connect(dbpath) as conn:
checkversion(dbpath,conn)
libpathre = re.compile(os.path.join("^"+librarypath,"(\d\d\d\d)","(\d\d)","(\d\d)","(.*)$"))
for tablename in ["phototable","videotable"]:
if args.flag:
conn.execute("UPDATE "+tablename+" SET flags=flags&~16")
def flagitem(path):
if args.flag:
conn.execute("UPDATE "+tablename+" SET flags=flags|16 WHERE filename=?",[path])
def move(oldpath,newpath):
def movefile():
os.makedirs(os.path.dirname(newpath),exist_ok=True)
os.rename(oldpath,newpath)
def moveentry():
(count,) = conn.execute("SELECT COUNT(*) FROM "+tablename+" WHERE filename=?",[newpath]).fetchone()
if count > 0:
conn.execute("DELETE FROM "+tablename+" WHERE filename=?",[oldpath])
else:
conn.execute("UPDATE "+tablename+" SET filename=? WHERE filename=?",[newpath,oldpath])
oldexists = os.path.isfile(oldpath)
newexists = os.path.isfile(newpath)
if oldexists:
if newexists:
if os.path.samefile(oldpath,newpath):
print ("Renaming: "+oldpath+" to "+newpath)
moveentry()
else:
# both exist
print("Collision: " + oldpath + " & " + newpath)
flagitem(oldpath)
flagitem(newpath)
else:
# can move old to new
print ("Moving: "+oldpath+" to "+newpath)
movefile()
moveentry()
else:
if newexists:
# already moved, so just update database
print ("Updating: "+oldpath+" to "+newpath)
moveentry()
else:
# missing
print("Missing: " + oldpath)
flagitem(oldpath)
# fix timestamp
updates = dict()
for (filepath,timestamp) in conn.execute("SELECT filename,exposure_time FROM "+tablename):
if timestamp is None or timestamp < goodTimestamp:
print("Bad time: " + filepath + ": " + str(timestamp))
flagitem(filepath)
fname = os.path.basename(filepath)
m = re.match("^(\d\d\d\d\d\d\d\d\d\d\d\d\d)\.jpg$",fname)
if m:
ft = int(int(m.group(1))/1000)
if ft >= goodTimestamp:
updates[filepath]=ft
continue
m = libpathre.match(filepath)
if m:
ft = dateTimestamp(int(m.group(1)),int(m.group(2)),int(m.group(3)))
if ft >= goodTimestamp:
updates[filepath]=ft
continue
for filepath in updates.keys():
print ("Updating: "+filepath)
conn.execute("UPDATE "+tablename+" SET exposure_time=? WHERE filename=?",(updates[filepath],filepath))
# fix wrong place
moves = dict()
for (filepath,timestamp) in conn.execute("SELECT filename,exposure_time FROM "+tablename):
if timestamp is None:
timestamp = goodTimestamp
if os.path.isfile(filepath) and os.path.getsize(filepath) == 0:
print("Empty: " + filepath)
m = libpathre.match(filepath)
dt = datetime.datetime.fromtimestamp(timestamp)
newpath=os.path.join(librarypath,str(dt.year),str2(dt.month),str2(dt.day),os.path.basename(filepath))
if m:
ft = dateTimestamp(int(m.group(1)),int(m.group(2)),int(m.group(3)))
if abs(ft - timestamp) > 86400:
moves[filepath] = newpath
else:
moves[filepath] = newpath
for oldpath in moves.keys():
newpath = moves[oldpath]
move(oldpath,newpath)