phtools 0.10.0 → 0.11.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +43 -0
- data/.rubocop_todo.yml +373 -0
- data/Guardfile +6 -3
- data/History.md +4 -0
- data/TODO.md +2 -0
- data/exe/phbackup +2 -1
- data/exe/phfixdto +2 -1
- data/exe/phfixfmd +2 -1
- data/exe/phgettags +2 -1
- data/exe/phls +2 -1
- data/exe/phmove +6 -3
- data/exe/phrename +2 -1
- data/exe/phtools +3 -1
- data/lib/phbackup.rb +2 -2
- data/lib/phevent.rb +2 -1
- data/lib/phfixdto.rb +4 -3
- data/lib/phfixfmd.rb +2 -2
- data/lib/phgettags.rb +7 -7
- data/lib/phls.rb +5 -6
- data/lib/phmove.rb +12 -21
- data/lib/phrename.rb +7 -6
- data/lib/phtagset.rb +2 -1
- data/lib/phtools/error.rb +2 -1
- data/lib/phtools/exif_tagger/error.rb +1 -0
- data/lib/phtools/exif_tagger/tag_collection.rb +17 -14
- data/lib/phtools/exif_tagger/tag_writer.rb +8 -7
- data/lib/phtools/exif_tagger/tags/_tag.rb +92 -37
- data/lib/phtools/exif_tagger/tags/_tag_array_of_strings.rb +35 -0
- data/lib/phtools/exif_tagger/tags/_tag_date.rb +25 -27
- data/lib/phtools/exif_tagger/tags/_tag_hash_of_strings.rb +39 -0
- data/lib/phtools/exif_tagger/tags/_tag_string.rb +32 -0
- data/lib/phtools/exif_tagger/tags/city.rb +7 -21
- data/lib/phtools/exif_tagger/tags/coded_character_set.rb +6 -21
- data/lib/phtools/exif_tagger/tags/collections.rb +20 -26
- data/lib/phtools/exif_tagger/tags/copyright.rb +6 -22
- data/lib/phtools/exif_tagger/tags/country.rb +6 -23
- data/lib/phtools/exif_tagger/tags/country_code.rb +5 -21
- data/lib/phtools/exif_tagger/tags/create_date.rb +17 -13
- data/lib/phtools/exif_tagger/tags/creator.rb +14 -25
- data/lib/phtools/exif_tagger/tags/date_time_original.rb +18 -13
- data/lib/phtools/exif_tagger/tags/gps_created.rb +21 -44
- data/lib/phtools/exif_tagger/tags/image_unique_id.rb +12 -27
- data/lib/phtools/exif_tagger/tags/keywords.rb +15 -27
- data/lib/phtools/exif_tagger/tags/location.rb +6 -23
- data/lib/phtools/exif_tagger/tags/modify_date.rb +8 -8
- data/lib/phtools/exif_tagger/tags/state.rb +6 -23
- data/lib/phtools/exif_tagger/tags/world_region.rb +6 -22
- data/lib/phtools/exif_tagger/tags.rb +2 -1
- data/lib/phtools/exif_tagger.rb +1 -0
- data/lib/phtools/ph_file.rb +35 -14
- data/lib/phtools/runner.rb +4 -4
- data/lib/phtools/utils.rb +1 -0
- data/lib/phtools/version.rb +2 -1
- data/lib/phtools.rb +11 -9
- metadata +7 -2
@@ -0,0 +1,39 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
# encoding: UTF-8
|
4
|
+
# (c) ANB Andrew Bizyaev
|
5
|
+
|
6
|
+
require_relative '_tag'
|
7
|
+
|
8
|
+
module ExifTagger
|
9
|
+
module Tag
|
10
|
+
class TagHashOfStrings < Tag
|
11
|
+
private
|
12
|
+
|
13
|
+
def validate_hash_items
|
14
|
+
end
|
15
|
+
|
16
|
+
def validate_type
|
17
|
+
if @value.is_a?(Hash)
|
18
|
+
@value.each_value do |val|
|
19
|
+
validate_string_size(val)
|
20
|
+
end
|
21
|
+
unknown_keys = @value.keys - self.class::VALID_KEYS
|
22
|
+
unknown_keys.each do |k|
|
23
|
+
@errors << %(#{tag_name}: KEY '#{k}' is unknown)
|
24
|
+
end
|
25
|
+
missed_keys = self.class::VALID_KEYS - @value.keys
|
26
|
+
missed_keys.each do |k|
|
27
|
+
@errors << %(#{tag_name}: KEY '#{k}' is missed)
|
28
|
+
end
|
29
|
+
validate_hash_items if @errors.empty?
|
30
|
+
else
|
31
|
+
@errors << %(#{tag_name}: '#{@value}' is a wrong type \(#{@value.class}\))
|
32
|
+
end
|
33
|
+
return if @errors.empty?
|
34
|
+
@value_invalid << @value
|
35
|
+
@value = EMPTY
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
# encoding: UTF-8
|
4
|
+
# (c) ANB Andrew Bizyaev
|
5
|
+
|
6
|
+
require_relative '_tag'
|
7
|
+
|
8
|
+
module ExifTagger
|
9
|
+
module Tag
|
10
|
+
class TagString < Tag
|
11
|
+
private
|
12
|
+
|
13
|
+
def get_from_raw
|
14
|
+
@raw_values.each_value do |value|
|
15
|
+
return value unless Tag.empty?(value)
|
16
|
+
end
|
17
|
+
EMPTY
|
18
|
+
end
|
19
|
+
|
20
|
+
def validate_type
|
21
|
+
if @value.is_a?(String)
|
22
|
+
validate_string_size(@value)
|
23
|
+
else
|
24
|
+
@errors << %(#{tag_name}: '#{@value}' is a wrong type \(#{@value.class}\))
|
25
|
+
end
|
26
|
+
return if @errors.empty?
|
27
|
+
@value_invalid << @value
|
28
|
+
@value = EMPTY
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -1,38 +1,24 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
2
3
|
# encoding: UTF-8
|
3
4
|
# (c) ANB Andrew Bizyaev
|
4
5
|
|
5
|
-
require_relative '
|
6
|
+
require_relative '_tag_string'
|
6
7
|
|
7
8
|
module ExifTagger
|
8
9
|
module Tag
|
9
10
|
# MWG:City, String[0,32]
|
10
11
|
# = IPTC:City XMP-photoshop:City XMP-iptcExt:LocationShownCity
|
11
|
-
|
12
|
-
MAX_BYTESIZE = 32
|
13
|
-
EXIFTOOL_TAGS = %w(City LocationShownCity)
|
12
|
+
# Read sequence from mini_exiftool hash: City, LocationShownCity
|
14
13
|
|
15
|
-
|
16
|
-
|
17
|
-
|
14
|
+
class City < TagString
|
15
|
+
MAX_BYTESIZE = 32
|
16
|
+
EXIFTOOL_TAGS = %w(City LocationShownCity).freeze
|
18
17
|
|
19
18
|
private
|
20
19
|
|
21
|
-
def validate
|
22
|
-
bsize = @value.bytesize
|
23
|
-
if bsize > MAX_BYTESIZE
|
24
|
-
@errors << %(#{tag_name}: '#{@value}' ) +
|
25
|
-
%(is #{bsize - MAX_BYTESIZE} bytes longer than allowed #{MAX_BYTESIZE})
|
26
|
-
@value_invalid << @value
|
27
|
-
@value = ''
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
20
|
def generate_write_script_lines
|
32
|
-
@write_script_lines
|
33
|
-
unless @value.empty?
|
34
|
-
@write_script_lines << %Q(-MWG:City=#{@value})
|
35
|
-
end
|
21
|
+
@write_script_lines << %(-MWG:City=#{@value})
|
36
22
|
end
|
37
23
|
end
|
38
24
|
end
|
@@ -1,37 +1,22 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
2
3
|
# encoding: UTF-8
|
3
4
|
# (c) ANB Andrew Bizyaev
|
4
5
|
|
5
|
-
require_relative '
|
6
|
+
require_relative '_tag_string'
|
6
7
|
|
7
8
|
module ExifTagger
|
8
9
|
module Tag
|
9
10
|
# -IPTC:CodedCharacterSet, string[0,32]!
|
10
|
-
class CodedCharacterSet < Tag
|
11
|
-
MAX_BYTESIZE = 32
|
12
|
-
EXIFTOOL_TAGS = %w(CodedCharacterSet)
|
13
11
|
|
14
|
-
|
15
|
-
|
16
|
-
|
12
|
+
class CodedCharacterSet < TagString
|
13
|
+
MAX_BYTESIZE = 32
|
14
|
+
EXIFTOOL_TAGS = %w(CodedCharacterSet).freeze
|
17
15
|
|
18
16
|
private
|
19
17
|
|
20
|
-
def validate
|
21
|
-
bsize = @value.bytesize
|
22
|
-
if bsize > MAX_BYTESIZE
|
23
|
-
@errors << %{#{tag_name}: '#{@value}' } +
|
24
|
-
%{is #{bsize - MAX_BYTESIZE} bytes longer than allowed #{MAX_BYTESIZE}}
|
25
|
-
@value_invalid << @value
|
26
|
-
@value = ''
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
18
|
def generate_write_script_lines
|
31
|
-
@write_script_lines
|
32
|
-
unless @value.empty?
|
33
|
-
@write_script_lines << %Q(-IPTC:CodedCharacterSet=#{@value})
|
34
|
-
end
|
19
|
+
@write_script_lines << %(-IPTC:CodedCharacterSet=#{@value})
|
35
20
|
end
|
36
21
|
end
|
37
22
|
end
|
@@ -1,44 +1,38 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
2
3
|
# encoding: UTF-8
|
3
4
|
# (c) ANB Andrew Bizyaev
|
4
5
|
|
5
|
-
require_relative '
|
6
|
+
require_relative '_tag_hash_of_strings'
|
6
7
|
|
7
8
|
module ExifTagger
|
8
9
|
module Tag
|
9
|
-
# Collections (struct+)
|
10
|
+
# XMP-mwg-coll:Collections (struct+)
|
10
11
|
# CollectionName
|
11
12
|
# CollectionURI
|
12
|
-
class Collections <
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
super
|
17
|
-
end
|
13
|
+
class Collections < TagHashOfStrings
|
14
|
+
MAX_BYTESIZE = 64
|
15
|
+
VALID_KEYS = [:collection_name, :collection_uri].freeze
|
16
|
+
EXIFTOOL_TAGS = %w(CollectionName CollectionURI).freeze
|
18
17
|
|
19
18
|
private
|
20
19
|
|
21
|
-
def
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
@value = {}
|
33
|
-
end
|
20
|
+
def get_from_raw
|
21
|
+
result = {}
|
22
|
+
v = @raw_values['CollectionName']
|
23
|
+
v = v.split('; ') if v.is_a?(String)
|
24
|
+
result[:collection_name] = v[0]
|
25
|
+
|
26
|
+
v = @raw_values['CollectionURI']
|
27
|
+
v = v.split('; ') if v.is_a?(String)
|
28
|
+
result[:collection_uri] = v[0]
|
29
|
+
|
30
|
+
result
|
34
31
|
end
|
35
32
|
|
36
33
|
def generate_write_script_lines
|
37
|
-
@write_script_lines
|
38
|
-
|
39
|
-
@write_script_lines << %Q(-XMP-mwg-coll:Collections-={CollectionName=#{@value[:collection_name]}, CollectionURI=#{@value[:collection_uri]}})
|
40
|
-
@write_script_lines << %Q(-XMP-mwg-coll:Collections+={CollectionName=#{@value[:collection_name]}, CollectionURI=#{@value[:collection_uri]}})
|
41
|
-
end
|
34
|
+
@write_script_lines << %(-XMP-mwg-coll:Collections-={CollectionName=#{@value[:collection_name]}, CollectionURI=#{@value[:collection_uri]}})
|
35
|
+
@write_script_lines << %(-XMP-mwg-coll:Collections+={CollectionName=#{@value[:collection_name]}, CollectionURI=#{@value[:collection_uri]}})
|
42
36
|
end
|
43
37
|
end
|
44
38
|
end
|
@@ -1,38 +1,22 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
2
3
|
# encoding: UTF-8
|
3
4
|
# (c) ANB Andrew Bizyaev
|
4
5
|
|
5
|
-
require_relative '
|
6
|
+
require_relative '_tag_string'
|
6
7
|
|
7
8
|
module ExifTagger
|
8
9
|
module Tag
|
9
10
|
# NMG:Copyright, string[0,128]
|
10
|
-
#
|
11
|
-
class Copyright <
|
11
|
+
# EXIF:Copyright, IPTC:CopyrightNotice, XMP-dc:Rights
|
12
|
+
class Copyright < TagString
|
12
13
|
MAX_BYTESIZE = 128
|
13
|
-
EXIFTOOL_TAGS = %w(Copyright CopyrightNotice Rights)
|
14
|
-
|
15
|
-
def initialize(value_raw = '')
|
16
|
-
super(value_raw.to_s)
|
17
|
-
end
|
14
|
+
EXIFTOOL_TAGS = %w(Copyright CopyrightNotice Rights).freeze
|
18
15
|
|
19
16
|
private
|
20
17
|
|
21
|
-
def validate
|
22
|
-
bsize = @value.bytesize
|
23
|
-
if bsize > MAX_BYTESIZE
|
24
|
-
@errors << %{#{tag_name}: '#{@value}' } +
|
25
|
-
%{is #{bsize - MAX_BYTESIZE} bytes longer than allowed #{MAX_BYTESIZE}}
|
26
|
-
@value_invalid << @value
|
27
|
-
@value = ''
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
18
|
def generate_write_script_lines
|
32
|
-
@write_script_lines
|
33
|
-
unless @value.empty?
|
34
|
-
@write_script_lines << %Q(-MWG:Copyright=#{@value})
|
35
|
-
end
|
19
|
+
@write_script_lines << %(-MWG:Copyright=#{@value})
|
36
20
|
end
|
37
21
|
end
|
38
22
|
end
|
@@ -1,39 +1,22 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
2
3
|
# encoding: UTF-8
|
3
4
|
# (c) ANB Andrew Bizyaev
|
4
5
|
|
5
|
-
require_relative '
|
6
|
+
require_relative '_tag_string'
|
6
7
|
|
7
8
|
module ExifTagger
|
8
9
|
module Tag
|
9
10
|
# MWG:Country, String[0,64]
|
10
|
-
#
|
11
|
-
|
12
|
-
class Country < Tag
|
11
|
+
# IPTC:Country-PrimaryLocationName, XMP-photoshop:Country, XMP-iptcExt:LocationShownCountryName
|
12
|
+
class Country < TagString
|
13
13
|
MAX_BYTESIZE = 64
|
14
|
-
EXIFTOOL_TAGS = %w(Country-PrimaryLocationName Country LocationShownCountryName)
|
15
|
-
|
16
|
-
def initialize(value_raw = '')
|
17
|
-
super(value_raw.to_s)
|
18
|
-
end
|
14
|
+
EXIFTOOL_TAGS = %w(Country-PrimaryLocationName Country LocationShownCountryName).freeze
|
19
15
|
|
20
16
|
private
|
21
17
|
|
22
|
-
def validate
|
23
|
-
bsize = @value.bytesize
|
24
|
-
if bsize > MAX_BYTESIZE
|
25
|
-
@errors << %(#{tag_name}: '#{@value}' ) +
|
26
|
-
%(is #{bsize - MAX_BYTESIZE} bytes longer than allowed #{MAX_BYTESIZE})
|
27
|
-
@value_invalid << @value
|
28
|
-
@value = ''
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
18
|
def generate_write_script_lines
|
33
|
-
@write_script_lines
|
34
|
-
unless @value.empty?
|
35
|
-
@write_script_lines << %Q(-MWG:Country=#{@value})
|
36
|
-
end
|
19
|
+
@write_script_lines << %(-MWG:Country=#{@value})
|
37
20
|
end
|
38
21
|
end
|
39
22
|
end
|
@@ -1,37 +1,21 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
2
3
|
# encoding: UTF-8
|
3
4
|
# (c) ANB Andrew Bizyaev
|
4
5
|
|
5
|
-
require_relative '
|
6
|
+
require_relative '_tag_string'
|
6
7
|
|
7
8
|
module ExifTagger
|
8
9
|
module Tag
|
9
10
|
# XMP-iptcExt:LocationShownCountryCode, String
|
10
|
-
class CountryCode <
|
11
|
+
class CountryCode < TagString
|
11
12
|
MAX_BYTESIZE = 32
|
12
|
-
EXIFTOOL_TAGS = %w(LocationShownCountryCode)
|
13
|
-
|
14
|
-
def initialize(value_raw = '')
|
15
|
-
super(value_raw.to_s)
|
16
|
-
end
|
13
|
+
EXIFTOOL_TAGS = %w(LocationShownCountryCode).freeze
|
17
14
|
|
18
15
|
private
|
19
16
|
|
20
|
-
def validate
|
21
|
-
bsize = @value.bytesize
|
22
|
-
if bsize > MAX_BYTESIZE
|
23
|
-
@errors << %(#{tag_name}: '#{@value}' ) +
|
24
|
-
%(is #{bsize - MAX_BYTESIZE} bytes longer than allowed #{MAX_BYTESIZE})
|
25
|
-
@value_invalid << @value
|
26
|
-
@value = ''
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
17
|
def generate_write_script_lines
|
31
|
-
@write_script_lines
|
32
|
-
unless @value.empty?
|
33
|
-
@write_script_lines << %Q(-XMP-iptcExt:LocationShownCountryCode=#{@value})
|
34
|
-
end
|
18
|
+
@write_script_lines << %(-XMP:LocationShownCountryCode=#{@value})
|
35
19
|
end
|
36
20
|
end
|
37
21
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
2
3
|
# encoding: UTF-8
|
3
4
|
# (c) ANB Andrew Bizyaev
|
4
5
|
|
@@ -7,25 +8,28 @@ require_relative '_tag_date'
|
|
7
8
|
module ExifTagger
|
8
9
|
module Tag
|
9
10
|
# -MWG:CreateDate:
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
# IPTC:DigitalCreationTime
|
14
|
-
# XMP-xmp:CreateDate
|
11
|
+
# EXIF:CreateDate (EXIF:SubSecTimeDigitized),
|
12
|
+
# IPTC:DigitalCreationDate+IPTC:DigitalCreationTime,
|
13
|
+
# XMP-xmp:CreateDate
|
15
14
|
# creation date of the digital representation
|
16
15
|
class CreateDate < TagDate
|
17
|
-
|
16
|
+
MAX_BYTESIZE = 32
|
17
|
+
EXIFTOOL_TAGS = %w(CreateDate SubSecTimeDigitized DigitalCreationDate DigitalCreationTime).freeze
|
18
18
|
|
19
19
|
private
|
20
20
|
|
21
|
+
def get_from_raw
|
22
|
+
return @raw_values['CreateDate'] unless Tag.empty?(@raw_values['CreateDate'])
|
23
|
+
return make_date_from(@raw_values['DigitalCreationDate'], @raw_values['DigitalCreationTime']) unless Tag.empty?(@raw_values['DigitalCreationDate'])
|
24
|
+
EMPTY
|
25
|
+
end
|
26
|
+
|
21
27
|
def generate_write_script_lines
|
22
|
-
@write_script_lines
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
@write_script_lines << %Q(-MWG:CreateDate=#{@value.strftime('%F %T')})
|
28
|
-
end
|
28
|
+
@write_script_lines << if @value.is_a?(DateTime)
|
29
|
+
%(-MWG:CreateDate=#{@value.strftime('%F %T')})
|
30
|
+
else
|
31
|
+
%(-MWG:CreateDate=#{@value})
|
32
|
+
end
|
29
33
|
end
|
30
34
|
end
|
31
35
|
end
|
@@ -1,41 +1,30 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
2
3
|
# encoding: UTF-8
|
3
4
|
# (c) ANB Andrew Bizyaev
|
4
5
|
|
5
|
-
require_relative '
|
6
|
+
require_relative '_tag_array_of_strings'
|
6
7
|
|
7
8
|
module ExifTagger
|
8
9
|
module Tag
|
9
10
|
# MWG:Creator, string[0,32]+, List of strings
|
10
|
-
#
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
# EXIF:Artist, IPTC:By-line, XMP-dc:Creator
|
12
|
+
# exiftool types:
|
13
|
+
# Artist = String "aaa; bbb"
|
14
|
+
# By-line = Array ["aaa", "bbb"] OR String "aaa"
|
15
|
+
# Creator = Array ["aaa", "bbb"] OR String "aaa"
|
14
16
|
|
15
|
-
|
16
|
-
|
17
|
-
|
17
|
+
class Creator < TagArrayOfStrings
|
18
|
+
MAX_BYTESIZE = 32
|
19
|
+
EXIFTOOL_TAGS = %w(Artist By-line Creator).freeze
|
18
20
|
|
19
21
|
private
|
20
22
|
|
21
|
-
def validate
|
22
|
-
@value.each do |v|
|
23
|
-
bsize = v.bytesize
|
24
|
-
if bsize > MAX_BYTESIZE
|
25
|
-
@errors << %(#{tag_name}: '#{v}' ) +
|
26
|
-
%(is #{bsize - MAX_BYTESIZE} bytes longer than allowed #{MAX_BYTESIZE})
|
27
|
-
@value_invalid << v
|
28
|
-
end
|
29
|
-
end
|
30
|
-
@value = @value - @value_invalid
|
31
|
-
end
|
32
|
-
|
33
23
|
def generate_write_script_lines
|
34
|
-
@
|
35
|
-
|
36
|
-
|
37
|
-
@write_script_lines << %
|
38
|
-
@write_script_lines << %Q(-MWG:Creator+=#{o})
|
24
|
+
@value.each do |o|
|
25
|
+
unless Tag.empty?(o)
|
26
|
+
@write_script_lines << %(-MWG:Creator-=#{o})
|
27
|
+
@write_script_lines << %(-MWG:Creator+=#{o})
|
39
28
|
end
|
40
29
|
end
|
41
30
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
2
3
|
# encoding: UTF-8
|
3
4
|
# (c) ANB Andrew Bizyaev
|
4
5
|
|
@@ -7,25 +8,29 @@ require_relative '_tag_date'
|
|
7
8
|
module ExifTagger
|
8
9
|
module Tag
|
9
10
|
# -MWG:DateTimeOriginal:
|
10
|
-
# EXIF:DateTimeOriginal
|
11
|
-
# EXIF:SubSecTimeOriginal
|
12
|
-
# IPTC:DateCreated
|
13
|
-
# IPTC:TimeCreated
|
14
|
-
# XMP-photoshop:DateCreated
|
11
|
+
# EXIF:DateTimeOriginal, (EXIF:SubSecTimeOriginal), IPTC:DateCreated + IPTC:TimeCreated, XMP-photoshop:DateCreated
|
15
12
|
# creation date of the intellectual content being shown
|
16
13
|
class DateTimeOriginal < TagDate
|
17
|
-
|
14
|
+
MAX_BYTESIZE = 32
|
15
|
+
EXIFTOOL_TAGS = %w(DateTimeOriginal SubSecTimeOriginal DateCreated TimeCreated).freeze
|
18
16
|
|
19
17
|
private
|
20
18
|
|
21
|
-
def
|
22
|
-
@
|
23
|
-
|
24
|
-
|
25
|
-
@
|
26
|
-
when @value.kind_of?(DateTime) || @value.kind_of?(Time)
|
27
|
-
@write_script_lines << %Q(-MWG:DateTimeOriginal=#{@value.strftime('%F %T')})
|
19
|
+
def get_from_raw
|
20
|
+
return @raw_values['DateTimeOriginal'] unless Tag.empty?(@raw_values['DateTimeOriginal'])
|
21
|
+
unless Tag.empty?(@raw_values['DateCreated'])
|
22
|
+
return @raw_values['DateCreated'] if @raw_values['DateCreated'].is_a?(DateTime)
|
23
|
+
return make_date_from(@raw_values['DateCreated'], @raw_values['TimeCreated']) if @raw_values['DateCreated'].is_a?(String)
|
28
24
|
end
|
25
|
+
EMPTY
|
26
|
+
end
|
27
|
+
|
28
|
+
def generate_write_script_lines
|
29
|
+
@write_script_lines << if @value.is_a?(DateTime)
|
30
|
+
%(-MWG:DateTimeOriginal=#{@value.strftime('%F %T')})
|
31
|
+
else
|
32
|
+
%(-MWG:DateTimeOriginal=#{@value})
|
33
|
+
end
|
29
34
|
end
|
30
35
|
end
|
31
36
|
end
|
@@ -1,8 +1,9 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
2
3
|
# encoding: UTF-8
|
3
4
|
# (c) ANB Andrew Bizyaev
|
4
5
|
|
5
|
-
require_relative '
|
6
|
+
require_relative '_tag_hash_of_strings'
|
6
7
|
|
7
8
|
module ExifTagger
|
8
9
|
module Tag
|
@@ -13,9 +14,10 @@ module ExifTagger
|
|
13
14
|
# GPSLongitudeRef (string[2] 'E' = East, 'W' = West)
|
14
15
|
# GPSAltitude (rational64u)
|
15
16
|
# GPSAltitudeRef (int8u 0 = Above Sea Level, 1 = Below Sea Level)
|
16
|
-
class GpsCreated <
|
17
|
-
|
18
|
-
|
17
|
+
class GpsCreated < TagHashOfStrings
|
18
|
+
MAX_BYTESIZE = 64
|
19
|
+
VALID_KEYS = [:gps_latitude, :gps_latitude_ref, :gps_longitude, :gps_longitude_ref, :gps_altitude, :gps_altitude_ref].freeze
|
20
|
+
VALID_VALUES = { gps_latitude_ref: %w(N S North South), gps_longitude_ref: %w(E W East West), gps_altitude_ref: ['Above Sea Level', 'Below Sea Level', '0', '1'] }.freeze
|
19
21
|
EXIFTOOL_TAGS = %w(
|
20
22
|
GPSPosition
|
21
23
|
GPSLatitude
|
@@ -24,54 +26,29 @@ module ExifTagger
|
|
24
26
|
GPSLongitudeRef
|
25
27
|
GPSAltitude
|
26
28
|
GPSAltitudeRef
|
27
|
-
)
|
28
|
-
|
29
|
-
def initialize(value_raw = {})
|
30
|
-
# TODO: value = value_raw.each { |k, v| value_raw[k] = v.to_s }
|
31
|
-
super
|
32
|
-
end
|
29
|
+
).freeze
|
33
30
|
|
34
31
|
private
|
35
32
|
|
36
|
-
def
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
end
|
45
|
-
if @errors.empty?
|
46
|
-
valid_values = ['N', 'S']
|
47
|
-
unless valid_values.include? @value[:gps_latitude_ref]
|
48
|
-
@errors << %(#{tag_name}: value of 'gps_latitude_ref' should be one of #{valid_values})
|
49
|
-
end
|
50
|
-
valid_values = ['E', 'W']
|
51
|
-
unless valid_values.include? @value[:gps_longitude_ref]
|
52
|
-
@errors << %(#{tag_name}: value of 'gps_longitude_ref' should be one of #{valid_values})
|
53
|
-
end
|
54
|
-
valid_values = ['Above Sea Level', 'Below Sea Level']
|
55
|
-
unless valid_values.include? @value[:gps_altitude_ref]
|
56
|
-
@errors << %(#{tag_name}: value of 'gps_altitude_ref' should be one of #{valid_values})
|
33
|
+
def get_from_raw
|
34
|
+
{ gps_latitude: @raw_values['GPSLatitude'], gps_latitude_ref: @raw_values['GPSLatitudeRef'], gps_longitude: @raw_values['GPSLongitude'], gps_longitude_ref: @raw_values['GPSLongitudeRef'], gps_altitude: @raw_values['GPSAltitude'], gps_altitude_ref: @raw_values['GPSAltitudeRef'] }
|
35
|
+
end
|
36
|
+
|
37
|
+
def validate_hash_items
|
38
|
+
VALID_VALUES.each do |vv_key, vv_val|
|
39
|
+
unless vv_val.include?(@value[vv_key])
|
40
|
+
@errors << %(#{tag_name}: value of '#{vv_key}' should be one of #{vv_val})
|
57
41
|
end
|
58
42
|
end
|
59
|
-
unless @errors.empty?
|
60
|
-
@value_invalid << @value
|
61
|
-
@value = {}
|
62
|
-
end
|
63
43
|
end
|
64
44
|
|
65
45
|
def generate_write_script_lines
|
66
|
-
@write_script_lines =
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
@write_script_lines << %Q(-GPSAltitude=#{@value[:gps_altitude]})
|
73
|
-
@write_script_lines << %Q(-GPSAltitudeRef=#{@value[:gps_altitude_ref]})
|
74
|
-
end
|
46
|
+
@write_script_lines << %(-GPSLatitude="#{@value[:gps_latitude]}")
|
47
|
+
@write_script_lines << %(-GPSLatitudeRef=#{@value[:gps_latitude_ref]})
|
48
|
+
@write_script_lines << %(-GPSLongitude="#{@value[:gps_longitude]}")
|
49
|
+
@write_script_lines << %(-GPSLongitudeRef=#{@value[:gps_longitude_ref]})
|
50
|
+
@write_script_lines << %(-GPSAltitude=#{@value[:gps_altitude]})
|
51
|
+
@write_script_lines << %(-GPSAltitudeRef=#{@value[:gps_altitude_ref]})
|
75
52
|
end
|
76
53
|
end
|
77
54
|
end
|
@@ -1,46 +1,31 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
2
3
|
# encoding: UTF-8
|
3
4
|
# (c) ANB Andrew Bizyaev
|
4
5
|
|
5
|
-
require_relative '
|
6
|
+
require_relative '_tag_string'
|
6
7
|
|
7
8
|
module ExifTagger
|
8
9
|
module Tag
|
9
10
|
# ImageUniqueID, String
|
10
|
-
class ImageUniqueId <
|
11
|
-
MAX_BYTESIZE = 32
|
12
|
-
EXIFTOOL_TAGS = %w(ImageUniqueID)
|
11
|
+
class ImageUniqueId < TagString
|
12
|
+
MAX_BYTESIZE = 32
|
13
|
+
EXIFTOOL_TAGS = %w(ImageUniqueID).freeze
|
13
14
|
|
14
|
-
|
15
|
-
super(value_raw.to_s)
|
16
|
-
end
|
15
|
+
private
|
17
16
|
|
18
|
-
def
|
17
|
+
def validate_vs_previous
|
19
18
|
@warnings = []
|
20
|
-
|
21
|
-
|
22
|
-
|
19
|
+
return if @previous.nil?
|
20
|
+
val = @previous.raw_values[EXIFTOOL_TAGS[0]]
|
21
|
+
if val =~ /(\d{8}-\S+)/
|
22
|
+
@warnings << "#{tag_name} has original value: '#{val}'"
|
23
23
|
end
|
24
24
|
@warnings.freeze
|
25
25
|
end
|
26
26
|
|
27
|
-
private
|
28
|
-
|
29
|
-
def validate
|
30
|
-
bsize = @value.bytesize
|
31
|
-
if bsize > MAX_BYTESIZE
|
32
|
-
@errors << %(#{tag_name}: '#{@value}' ) +
|
33
|
-
%(is #{bsize - MAX_BYTESIZE} bytes longer than allowed #{MAX_BYTESIZE})
|
34
|
-
@value_invalid << @value
|
35
|
-
@value = ''
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
27
|
def generate_write_script_lines
|
40
|
-
@write_script_lines
|
41
|
-
unless @value.empty?
|
42
|
-
@write_script_lines << %Q(-ImageUniqueID=#{@value})
|
43
|
-
end
|
28
|
+
@write_script_lines << %(-ImageUniqueID=#{@value})
|
44
29
|
end
|
45
30
|
end
|
46
31
|
end
|