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
|
#!/usr/bin/env ruby
require 'date'
$possible_devices = { "SIGMA DP2 Merrill" => "dp2m", "FP2" => "fp2", "Canon EOS 1000D" => "1000d", "iPad Air" => "ipadair", "iPhone 5s" => "iphone5s", "iPhone SE" => "iphonese", "IQ180" => "iq180", "iPhone XR" => "iphonexr", "NIKON D70" => "d70" }
$possible_devices.default = "unknown-device"
file_ext = ARGV[0]
if !file_ext
file_ext = "jpg"
end
if ARGV[1]
$possible_devices.default = ARGV[1]
end
ids = []
while line = STDIN.gets # list of files
a = line.split('.')
a.pop
ids << a.join('.')
end
used_prefixes = {} # prefix -> 0..N
def parse_timestamp s
d = s.split(':', 2)[1]
d.strip!
d.gsub!(/^(\d\d\d\d):(\d\d):(\d\d)/, "\\1-\\2-\\3")
return DateTime.parse d
end
def determine_datetime dts, subsec=nil
dt = dts.min # get the actual original date
if subsec != nil and subsec.to_i > 0 # add sub-seconds if available
if dt.strftime("%L") == "000"
s = format_datetime(dt)+".#{subsec}"
dt = DateTime.parse s
end
end
return dt
end
def format_datetime dt
if dt.strftime("%L") == "000"
return dt.strftime("%Y-%m-%dT%H:%M:%S")
else
return dt.strftime("%Y-%m-%dT%H:%M:%S.%L")
end
end
def get_possible_device s
s.strip!
s.downcase!
$possible_devices.each { |k,v|
if s.downcase.start_with? k.downcase
return v
end
}
return $possible_devices.default
end
def parse_device s
d = s.split(':', 2)[1]
return get_possible_device d
end
def determine_device a
a.each { |s|
if s != $possible_devices.default
return s
end
}
return $possible_devices.default
end
ids.each do |i|
exif = `exiftool "#{i}.#{file_ext}" 2>/dev/null`
a = exif.split "\n"
timestamps = []
subsec_time = nil
devices = []
a.each { |j|
if j.start_with? "Camera Model Name" \
or j.start_with? "Model" \
or j.start_with? "Lens Model"
devices << parse_device(j)
elsif j.start_with? "Date/Time Original" \
or j.start_with? "Creation Date" \
or j.start_with? "Create Date" \
or j.start_with? "Media Create Date" \
or j.start_with? "Track Create Date" \
or j.start_with? "File Modification Date/Time"
begin
timestamps << parse_timestamp(j)
rescue
end
elsif j.start_with? "Sub Sec Time Original"
subsec_time = j.split(':', 2)[1].strip
end
}
if timestamps.size == 0
puts "No timestamp found"
exit
end
skip = false
new_prefix = ""
add = 0
begin
t = format_datetime(determine_datetime(timestamps, subsec_time))
d = determine_device devices
new_prefix = "#{t}-#{d}"
add = 1
rescue
puts "Cannot determine metadata for #{i}, skipping!"
skip = true
end
next if skip
while used_prefixes.has_key? new_prefix
new_prefix = "#{t}-#{add}-#{d}"
add += 1
end
used_prefixes[new_prefix] = true
Dir.glob("#{i}*").each { |f|
ext = f.sub("#{i}","")
if File.exists? "#{new_prefix}#{ext}"
puts "File exists: #{new_prefix}#{ext} (#{i})!"
exit
else
`mv \"#{i}#{ext}\" #{new_prefix}#{ext}`
end
}
end
|