exif_datify 0.2.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rspec +2 -0
- data/.travis.yml +9 -0
- data/README.md +2 -0
- data/Rakefile +4 -0
- data/exe/datify +22 -2
- data/exif_datify.gemspec +2 -1
- data/lib/exif_datify/version.rb +1 -1
- data/lib/exif_datify.rb +76 -4
- data/test_data/picJan15.png +0 -0
- data/test_data/picNov14.png +0 -0
- metadata +23 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1baeb60c1646391ea957a9aff2855dc313527592
|
4
|
+
data.tar.gz: d25ca1f3e98dfdc20073b1d9efb5ce4f6bd24a9a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ce49620dce50308bd452f7c4fc167289caf6342099fc4cebc4966187683d37336f75625177e0d3265a068e807ac2caeeac1602fbef26ae52fb2e062ebf663b07
|
7
|
+
data.tar.gz: 28ee0c87e4228f59c7259461512e281f12d0e32980ee04fe0cbfaa946cc3ff48d1e58982ec08a3ab93451ce6e21c524743a6011d7fa5765963a79fcdbf28596e
|
data/.rspec
ADDED
data/.travis.yml
ADDED
data/README.md
CHANGED
data/Rakefile
CHANGED
data/exe/datify
CHANGED
@@ -10,11 +10,27 @@ extensions = nil
|
|
10
10
|
opt_parser = OptionParser.new do |opts|
|
11
11
|
opts.banner = "Usage: datify [options] path"
|
12
12
|
|
13
|
+
opts.on('-r', '--rename', "Sets the operation to renaming (default)") do
|
14
|
+
date_extractor.rename!
|
15
|
+
end
|
16
|
+
|
17
|
+
opts.on('-m', '--move DESTINATION_FOLDER', "Sets the operation to move") do |destination|
|
18
|
+
date_extractor.move!(destination)
|
19
|
+
end
|
20
|
+
|
21
|
+
opts.on('-c', '--copy DESTINATION_FOLDER', "Sets the operation to copy") do |destination|
|
22
|
+
date_extractor.copy!(destination)
|
23
|
+
end
|
24
|
+
|
25
|
+
opts.on('-s', '--subdirectories', "For move and copy, create new directories in destination for each year and month") do
|
26
|
+
date_extractor.month_subdirectories!
|
27
|
+
end
|
28
|
+
|
13
29
|
opts.on("-e", "--ext jpg,mov,png", Array, "File extensions to process.", "All by defaults.") do |list|
|
14
30
|
extensions = list.map { |e| ".#{e.downcase}" }
|
15
31
|
end
|
16
32
|
|
17
|
-
opts.on("-t", "--tags x,y,z", Array, "EXIF tags to use. Ordered by priority.", "Default is #{date_extractor.tags.join(',')}") do |list|
|
33
|
+
opts.on("-t", "--tags x,y,z", Array, "EXIF tags to use. Ordered by priority.", "Default is #{date_extractor.tags.join(', ')}") do |list|
|
18
34
|
date_extractor.tags = list
|
19
35
|
end
|
20
36
|
|
@@ -26,6 +42,10 @@ opt_parser = OptionParser.new do |opts|
|
|
26
42
|
date_extractor.quiet!
|
27
43
|
end
|
28
44
|
|
45
|
+
opts.on("-v", "--verbose", "Verbose logging") do |q|
|
46
|
+
date_extractor.logger.level = Logger::DEBUG
|
47
|
+
end
|
48
|
+
|
29
49
|
opts.on("-h", "--help", "Prints this help") do
|
30
50
|
puts opts
|
31
51
|
exit
|
@@ -40,7 +60,7 @@ if File.directory?(ARGV[0])
|
|
40
60
|
next if FileTest.directory?(entry)
|
41
61
|
next unless extensions.nil? or extensions.include?(File.extname(entry).downcase)
|
42
62
|
begin
|
43
|
-
date_extractor.
|
63
|
+
date_extractor.process(entry)
|
44
64
|
rescue StandardError => e
|
45
65
|
puts "Error: #{e}"
|
46
66
|
end
|
data/exif_datify.gemspec
CHANGED
@@ -19,6 +19,7 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
20
|
spec.require_paths = ["lib"]
|
21
21
|
|
22
|
-
spec.add_development_dependency "bundler", "~> 1.
|
22
|
+
spec.add_development_dependency "bundler", "~> 1.13"
|
23
23
|
spec.add_development_dependency "rake", "~> 10.0"
|
24
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
24
25
|
end
|
data/lib/exif_datify/version.rb
CHANGED
data/lib/exif_datify.rb
CHANGED
@@ -1,25 +1,52 @@
|
|
1
1
|
require "exif_datify/version"
|
2
2
|
require 'date'
|
3
3
|
require 'json'
|
4
|
+
require 'logger'
|
5
|
+
require 'fileutils'
|
4
6
|
|
5
7
|
module ExifDatify
|
6
8
|
class DateExtractor
|
7
|
-
attr_reader :counters
|
9
|
+
attr_reader :operation, :counters, :logger
|
8
10
|
attr_accessor :datetime_format, :tags
|
9
11
|
DATETIME_REGEX = /^\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2}/
|
10
12
|
|
11
13
|
def initialize
|
14
|
+
@logger = Logger.new(STDOUT)
|
15
|
+
@logger.level = Logger::WARN
|
12
16
|
@tags = ['DateTimeOriginal', 'MediaCreateDate']
|
13
17
|
@datetime_format = "%Y-%m-%d_%H-%M-%S_"
|
14
18
|
@quiet = false
|
15
19
|
@counters = Hash.new(0)
|
20
|
+
rename!
|
21
|
+
@month_subdirectories = false
|
16
22
|
end
|
17
23
|
|
18
24
|
def quiet!
|
19
25
|
@quiet = true
|
20
26
|
end
|
21
27
|
|
28
|
+
def month_subdirectories!
|
29
|
+
@month_subdirectories = true
|
30
|
+
end
|
31
|
+
|
32
|
+
def rename!
|
33
|
+
@operation = :rename
|
34
|
+
end
|
35
|
+
|
36
|
+
def move!(destination)
|
37
|
+
raise "#{destination} does not exist" unless FileTest.directory?(destination)
|
38
|
+
@operation = :move
|
39
|
+
@destination = destination
|
40
|
+
end
|
41
|
+
|
42
|
+
def copy!(destination)
|
43
|
+
raise "#{destination} does not exist" unless FileTest.directory?(destination)
|
44
|
+
@operation = :copy
|
45
|
+
@destination = destination
|
46
|
+
end
|
47
|
+
|
22
48
|
def extract_datetime(file_path)
|
49
|
+
@logger.debug "Extracting datetime from #{file_path}"
|
23
50
|
meta = exiftool(file_path)
|
24
51
|
@tags.each do |tag|
|
25
52
|
return DateTime.parse(meta[tag]) if meta[tag]
|
@@ -27,15 +54,60 @@ module ExifDatify
|
|
27
54
|
nil
|
28
55
|
end
|
29
56
|
|
30
|
-
def
|
57
|
+
def process(file_path)
|
31
58
|
@counters[:total] += 1
|
32
|
-
|
33
|
-
|
59
|
+
datetime = extract_datetime(file_path)
|
60
|
+
if datetime.nil?
|
61
|
+
puts "Could not extract date from #{current_name}" unless @quiet
|
62
|
+
else
|
63
|
+
operate(file_path, datetime)
|
34
64
|
end
|
35
65
|
end
|
36
66
|
|
37
67
|
private
|
38
68
|
|
69
|
+
def destination(file_path, datetime)
|
70
|
+
return File.dirname(file_path) if operation == :rename
|
71
|
+
return @destination unless @month_subdirectories
|
72
|
+
File.join(@destination, datetime.strftime('%Y'), datetime.strftime('%m'))
|
73
|
+
end
|
74
|
+
|
75
|
+
def operate(file_path, datetime)
|
76
|
+
@logger.debug "Processing #{file_path} with #{datetime}"
|
77
|
+
current_name = File.basename(file_path)
|
78
|
+
prefix = datetime.strftime(@datetime_format)
|
79
|
+
|
80
|
+
# No prefix if the basename has a good format already.
|
81
|
+
prefix = '' if current_name.start_with?(prefix) or current_name =~ DATETIME_REGEX
|
82
|
+
|
83
|
+
prefixed_name = File.join(destination(file_path, datetime), prefix + current_name)
|
84
|
+
unless File.expand_path(file_path) == File.expand_path(prefixed_name)
|
85
|
+
if File.exist?(prefixed_name)
|
86
|
+
raise "Cannot #{operation} #{current_name}, #{prefixed_name} already exists."
|
87
|
+
else
|
88
|
+
@logger.debug "Destination: #{prefixed_name}"
|
89
|
+
perform_operation(file_path, prefixed_name)
|
90
|
+
puts "Performed #{operation} on #{current_name} to #{prefixed_name}." unless @quiet
|
91
|
+
@counters[:renamed] += 1
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def perform_operation(file_path, destination)
|
97
|
+
case operation
|
98
|
+
when :rename
|
99
|
+
File.rename(file_path, destination)
|
100
|
+
when :move
|
101
|
+
FileUtils.mkdir_p File.dirname(destination)
|
102
|
+
FileUtils.mv(file_path, destination)
|
103
|
+
when :copy
|
104
|
+
FileUtils.mkdir_p File.dirname(destination)
|
105
|
+
FileUtils.cp(file_path, destination)
|
106
|
+
else
|
107
|
+
raise "Unknown operation #{operation}"
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
39
111
|
def prepend_date(file_path)
|
40
112
|
datetime = extract_datetime(file_path)
|
41
113
|
current_name = File.basename(file_path)
|
Binary file
|
Binary file
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: exif_datify
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Harold Waterkeyn
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-09-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '1.
|
19
|
+
version: '1.13'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '1.
|
26
|
+
version: '1.13'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.0'
|
41
55
|
description: Name files based on exif information
|
42
56
|
email:
|
43
57
|
- hwaterke@users.noreply.github.com
|
@@ -47,6 +61,8 @@ extensions: []
|
|
47
61
|
extra_rdoc_files: []
|
48
62
|
files:
|
49
63
|
- ".gitignore"
|
64
|
+
- ".rspec"
|
65
|
+
- ".travis.yml"
|
50
66
|
- Gemfile
|
51
67
|
- LICENSE
|
52
68
|
- README.md
|
@@ -57,6 +73,8 @@ files:
|
|
57
73
|
- exif_datify.gemspec
|
58
74
|
- lib/exif_datify.rb
|
59
75
|
- lib/exif_datify/version.rb
|
76
|
+
- test_data/picJan15.png
|
77
|
+
- test_data/picNov14.png
|
60
78
|
homepage: https://github.com/hwaterke/exif_datify
|
61
79
|
licenses:
|
62
80
|
- MIT
|
@@ -77,7 +95,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
77
95
|
version: '0'
|
78
96
|
requirements: []
|
79
97
|
rubyforge_project:
|
80
|
-
rubygems_version: 2.5.
|
98
|
+
rubygems_version: 2.5.2
|
81
99
|
signing_key:
|
82
100
|
specification_version: 4
|
83
101
|
summary: Prepend files with date and time from exif information
|