phtools 0.10.0 → 0.11.1

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.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +43 -0
  3. data/.rubocop_todo.yml +373 -0
  4. data/Guardfile +6 -3
  5. data/History.md +4 -0
  6. data/TODO.md +2 -0
  7. data/exe/phbackup +2 -1
  8. data/exe/phfixdto +2 -1
  9. data/exe/phfixfmd +2 -1
  10. data/exe/phgettags +2 -1
  11. data/exe/phls +2 -1
  12. data/exe/phmove +6 -3
  13. data/exe/phrename +2 -1
  14. data/exe/phtools +3 -1
  15. data/lib/phbackup.rb +2 -2
  16. data/lib/phevent.rb +2 -1
  17. data/lib/phfixdto.rb +4 -3
  18. data/lib/phfixfmd.rb +2 -2
  19. data/lib/phgettags.rb +7 -7
  20. data/lib/phls.rb +5 -6
  21. data/lib/phmove.rb +12 -21
  22. data/lib/phrename.rb +7 -6
  23. data/lib/phtagset.rb +2 -1
  24. data/lib/phtools/error.rb +2 -1
  25. data/lib/phtools/exif_tagger/error.rb +1 -0
  26. data/lib/phtools/exif_tagger/tag_collection.rb +17 -14
  27. data/lib/phtools/exif_tagger/tag_writer.rb +8 -7
  28. data/lib/phtools/exif_tagger/tags/_tag.rb +92 -37
  29. data/lib/phtools/exif_tagger/tags/_tag_array_of_strings.rb +35 -0
  30. data/lib/phtools/exif_tagger/tags/_tag_date.rb +25 -27
  31. data/lib/phtools/exif_tagger/tags/_tag_hash_of_strings.rb +39 -0
  32. data/lib/phtools/exif_tagger/tags/_tag_string.rb +32 -0
  33. data/lib/phtools/exif_tagger/tags/city.rb +7 -21
  34. data/lib/phtools/exif_tagger/tags/coded_character_set.rb +6 -21
  35. data/lib/phtools/exif_tagger/tags/collections.rb +20 -26
  36. data/lib/phtools/exif_tagger/tags/copyright.rb +6 -22
  37. data/lib/phtools/exif_tagger/tags/country.rb +6 -23
  38. data/lib/phtools/exif_tagger/tags/country_code.rb +5 -21
  39. data/lib/phtools/exif_tagger/tags/create_date.rb +17 -13
  40. data/lib/phtools/exif_tagger/tags/creator.rb +14 -25
  41. data/lib/phtools/exif_tagger/tags/date_time_original.rb +18 -13
  42. data/lib/phtools/exif_tagger/tags/gps_created.rb +21 -44
  43. data/lib/phtools/exif_tagger/tags/image_unique_id.rb +12 -27
  44. data/lib/phtools/exif_tagger/tags/keywords.rb +15 -27
  45. data/lib/phtools/exif_tagger/tags/location.rb +6 -23
  46. data/lib/phtools/exif_tagger/tags/modify_date.rb +8 -8
  47. data/lib/phtools/exif_tagger/tags/state.rb +6 -23
  48. data/lib/phtools/exif_tagger/tags/world_region.rb +6 -22
  49. data/lib/phtools/exif_tagger/tags.rb +2 -1
  50. data/lib/phtools/exif_tagger.rb +1 -0
  51. data/lib/phtools/ph_file.rb +35 -14
  52. data/lib/phtools/runner.rb +4 -4
  53. data/lib/phtools/utils.rb +1 -0
  54. data/lib/phtools/version.rb +2 -1
  55. data/lib/phtools.rb +11 -9
  56. 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 '_tag'
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
- class City < Tag
12
- MAX_BYTESIZE = 32
13
- EXIFTOOL_TAGS = %w(City LocationShownCity)
12
+ # Read sequence from mini_exiftool hash: City, LocationShownCity
14
13
 
15
- def initialize(value_raw = '')
16
- super(value_raw.to_s)
17
- end
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 '_tag'
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
- def initialize(value_raw = '')
15
- super(value_raw.to_s)
16
- end
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 '_tag'
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 < Tag
13
- VALID_KEYS = [:collection_name, :collection_uri]
14
- EXIFTOOL_TAGS = %w(CollectionName CollectionURI)
15
- def initialize(value_raw = {})
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 validate
22
- unknown_keys = @value.keys - VALID_KEYS
23
- unknown_keys.each do |k|
24
- @errors << %{#{tag_name}: KEY '#{k}' is unknown}
25
- end
26
- missed_keys = VALID_KEYS - @value.keys
27
- missed_keys.each do |k|
28
- @errors << %{#{tag_name}: KEY '#{k}' is missed}
29
- end
30
- unless @errors.empty?
31
- @value_invalid << @value
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
- unless @value.empty?
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 '_tag'
6
+ require_relative '_tag_string'
6
7
 
7
8
  module ExifTagger
8
9
  module Tag
9
10
  # NMG:Copyright, string[0,128]
10
- # = EXIF:Copyright IPTC:CopyrightNotice XMP-dc:Rights
11
- class Copyright < Tag
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 '_tag'
6
+ require_relative '_tag_string'
6
7
 
7
8
  module ExifTagger
8
9
  module Tag
9
10
  # MWG:Country, String[0,64]
10
- # = IPTC:Country-PrimaryLocationName XMP-photoshop:Country
11
- # XMP-iptcExt:LocationShownCountryName
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 '_tag'
6
+ require_relative '_tag_string'
6
7
 
7
8
  module ExifTagger
8
9
  module Tag
9
10
  # XMP-iptcExt:LocationShownCountryCode, String
10
- class CountryCode < Tag
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
- # EXIF:CreateDate
11
- # EXIF:SubSecTimeDigitized
12
- # IPTC:DigitalCreationDate
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
- EXIFTOOL_TAGS = %w(CreateDate SubSecTimeDigitized DigitalCreationDate DigitalCreationTime)
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
- case
24
- when @value.kind_of?(String) && !@value.empty?
25
- @write_script_lines << %Q(-MWG:CreateDate=#{@value})
26
- when @value.kind_of?(DateTime) || @value.kind_of?(Time)
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 '_tag'
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
- # = EXIF:Artist, IPTC:By-line, XMP-dc:Creator
11
- class Creator < Tag
12
- MAX_BYTESIZE = 32
13
- EXIFTOOL_TAGS = %w(Artist By-line Creator)
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
- def initialize(value_raw = [])
16
- super(Array(value_raw).flatten.map { |i| i.to_s })
17
- end
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
- @write_script_lines = []
35
- unless @value.empty?
36
- @value.each do |o|
37
- @write_script_lines << %Q(-MWG:Creator-=#{o})
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
- EXIFTOOL_TAGS = %w(DateTimeOriginal SubSecTimeOriginal DateCreated TimeCreated)
14
+ MAX_BYTESIZE = 32
15
+ EXIFTOOL_TAGS = %w(DateTimeOriginal SubSecTimeOriginal DateCreated TimeCreated).freeze
18
16
 
19
17
  private
20
18
 
21
- def generate_write_script_lines
22
- @write_script_lines = []
23
- case
24
- when @value.kind_of?(String) && !@value.empty?
25
- @write_script_lines << %Q(-MWG:DateTimeOriginal=#{@value})
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 '_tag'
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 < Tag
17
- VALID_KEYS = [:gps_latitude, :gps_latitude_ref, :gps_longitude,
18
- :gps_longitude_ref, :gps_altitude, :gps_altitude_ref]
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 validate
37
- unknown_keys = @value.keys - VALID_KEYS
38
- unknown_keys.each do |k|
39
- @errors << %(#{tag_name}: KEY '#{k}' is unknown)
40
- end
41
- missed_keys = VALID_KEYS - @value.keys
42
- missed_keys.each do |k|
43
- @errors << %(#{tag_name}: KEY '#{k}' is missed)
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
- unless @value.empty?
68
- @write_script_lines << %Q(-GPSLatitude="#{@value[:gps_latitude]}")
69
- @write_script_lines << %Q(-GPSLatitudeRef=#{@value[:gps_latitude_ref]})
70
- @write_script_lines << %Q(-GPSLongitude="#{@value[:gps_longitude]}")
71
- @write_script_lines << %Q(-GPSLongitudeRef=#{@value[:gps_longitude_ref]})
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 '_tag'
6
+ require_relative '_tag_string'
6
7
 
7
8
  module ExifTagger
8
9
  module Tag
9
10
  # ImageUniqueID, String
10
- class ImageUniqueId < Tag
11
- MAX_BYTESIZE = 32 # no limit in EXIF spec
12
- EXIFTOOL_TAGS = %w(ImageUniqueID)
11
+ class ImageUniqueId < TagString
12
+ MAX_BYTESIZE = 32
13
+ EXIFTOOL_TAGS = %w(ImageUniqueID).freeze
13
14
 
14
- def initialize(value_raw = [])
15
- super(value_raw.to_s)
16
- end
15
+ private
17
16
 
18
- def check_for_warnings(original_values: {})
17
+ def validate_vs_previous
19
18
  @warnings = []
20
- v = original_values[EXIFTOOL_TAGS[0]]
21
- if v =~ /(\d{8}-\S+)/
22
- @warnings << "#{tag_name} has original correct value: '#{v}'"
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