phtools 0.8.1 → 0.10.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/TODO.md +4 -3
- data/exe/phfixdto +42 -0
- data/exe/phfixfmd +1 -1
- data/exe/phgettags +39 -0
- data/exe/phls +9 -5
- data/exe/phrename +1 -1
- data/lib/phfixdto.rb +62 -0
- data/lib/phfixfmd.rb +1 -2
- data/lib/phgettags.rb +58 -0
- data/lib/phtools/exif_tagger/error.rb +11 -0
- data/lib/phtools/exif_tagger/tag_collection.rb +103 -0
- data/lib/phtools/exif_tagger/tag_writer.rb +79 -0
- data/lib/phtools/exif_tagger/tags/_tag.rb +111 -0
- data/lib/phtools/exif_tagger/tags/_tag_date.rb +45 -0
- data/lib/phtools/exif_tagger/tags/city.rb +39 -0
- data/lib/phtools/exif_tagger/tags/coded_character_set.rb +38 -0
- data/lib/phtools/exif_tagger/tags/collections.rb +45 -0
- data/lib/phtools/exif_tagger/tags/copyright.rb +39 -0
- data/lib/phtools/exif_tagger/tags/country.rb +40 -0
- data/lib/phtools/exif_tagger/tags/country_code.rb +38 -0
- data/lib/phtools/exif_tagger/tags/create_date.rb +32 -0
- data/lib/phtools/exif_tagger/tags/creator.rb +44 -0
- data/lib/phtools/exif_tagger/tags/date_time_original.rb +32 -0
- data/lib/phtools/exif_tagger/tags/gps_created.rb +78 -0
- data/lib/phtools/exif_tagger/tags/image_unique_id.rb +47 -0
- data/lib/phtools/exif_tagger/tags/keywords.rb +49 -0
- data/lib/phtools/exif_tagger/tags/location.rb +40 -0
- data/lib/phtools/exif_tagger/tags/modify_date.rb +26 -0
- data/lib/phtools/exif_tagger/tags/state.rb +40 -0
- data/lib/phtools/exif_tagger/tags/world_region.rb +38 -0
- data/lib/phtools/exif_tagger/tags.rb +11 -0
- data/lib/phtools/exif_tagger.rb +8 -0
- data/lib/phtools/version.rb +1 -1
- data/lib/phtools.rb +4 -4
- metadata +31 -4
- data/lib/phfixdate.rb +0 -13
- data/lib/phmtags.rb +0 -13
@@ -0,0 +1,38 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
# (c) ANB Andrew Bizyaev
|
4
|
+
|
5
|
+
require_relative '_tag'
|
6
|
+
|
7
|
+
module ExifTagger
|
8
|
+
module Tag
|
9
|
+
# -IPTC:CodedCharacterSet, string[0,32]!
|
10
|
+
class CodedCharacterSet < Tag
|
11
|
+
MAX_BYTESIZE = 32
|
12
|
+
EXIFTOOL_TAGS = %w(CodedCharacterSet)
|
13
|
+
|
14
|
+
def initialize(value_raw = '')
|
15
|
+
super(value_raw.to_s)
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
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
|
+
def generate_write_script_lines
|
31
|
+
@write_script_lines = []
|
32
|
+
unless @value.empty?
|
33
|
+
@write_script_lines << %Q(-IPTC:CodedCharacterSet=#{@value})
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
# (c) ANB Andrew Bizyaev
|
4
|
+
|
5
|
+
require_relative '_tag'
|
6
|
+
|
7
|
+
module ExifTagger
|
8
|
+
module Tag
|
9
|
+
# Collections (struct+)
|
10
|
+
# CollectionName
|
11
|
+
# 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
|
18
|
+
|
19
|
+
private
|
20
|
+
|
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
|
34
|
+
end
|
35
|
+
|
36
|
+
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
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
# (c) ANB Andrew Bizyaev
|
4
|
+
|
5
|
+
require_relative '_tag'
|
6
|
+
|
7
|
+
module ExifTagger
|
8
|
+
module Tag
|
9
|
+
# NMG:Copyright, string[0,128]
|
10
|
+
# = EXIF:Copyright IPTC:CopyrightNotice XMP-dc:Rights
|
11
|
+
class Copyright < Tag
|
12
|
+
MAX_BYTESIZE = 128
|
13
|
+
EXIFTOOL_TAGS = %w(Copyright CopyrightNotice Rights)
|
14
|
+
|
15
|
+
def initialize(value_raw = '')
|
16
|
+
super(value_raw.to_s)
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
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
|
+
def generate_write_script_lines
|
32
|
+
@write_script_lines = []
|
33
|
+
unless @value.empty?
|
34
|
+
@write_script_lines << %Q(-MWG:Copyright=#{@value})
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
# (c) ANB Andrew Bizyaev
|
4
|
+
|
5
|
+
require_relative '_tag'
|
6
|
+
|
7
|
+
module ExifTagger
|
8
|
+
module Tag
|
9
|
+
# MWG:Country, String[0,64]
|
10
|
+
# = IPTC:Country-PrimaryLocationName XMP-photoshop:Country
|
11
|
+
# XMP-iptcExt:LocationShownCountryName
|
12
|
+
class Country < Tag
|
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
|
19
|
+
|
20
|
+
private
|
21
|
+
|
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
|
+
def generate_write_script_lines
|
33
|
+
@write_script_lines = []
|
34
|
+
unless @value.empty?
|
35
|
+
@write_script_lines << %Q(-MWG:Country=#{@value})
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
# (c) ANB Andrew Bizyaev
|
4
|
+
|
5
|
+
require_relative '_tag'
|
6
|
+
|
7
|
+
module ExifTagger
|
8
|
+
module Tag
|
9
|
+
# XMP-iptcExt:LocationShownCountryCode, String
|
10
|
+
class CountryCode < Tag
|
11
|
+
MAX_BYTESIZE = 32
|
12
|
+
EXIFTOOL_TAGS = %w(LocationShownCountryCode)
|
13
|
+
|
14
|
+
def initialize(value_raw = '')
|
15
|
+
super(value_raw.to_s)
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
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
|
+
def generate_write_script_lines
|
31
|
+
@write_script_lines = []
|
32
|
+
unless @value.empty?
|
33
|
+
@write_script_lines << %Q(-XMP-iptcExt:LocationShownCountryCode=#{@value})
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
# (c) ANB Andrew Bizyaev
|
4
|
+
|
5
|
+
require_relative '_tag_date'
|
6
|
+
|
7
|
+
module ExifTagger
|
8
|
+
module Tag
|
9
|
+
# -MWG:CreateDate:
|
10
|
+
# EXIF:CreateDate
|
11
|
+
# EXIF:SubSecTimeDigitized
|
12
|
+
# IPTC:DigitalCreationDate
|
13
|
+
# IPTC:DigitalCreationTime
|
14
|
+
# XMP-xmp:CreateDate
|
15
|
+
# creation date of the digital representation
|
16
|
+
class CreateDate < TagDate
|
17
|
+
EXIFTOOL_TAGS = %w(CreateDate SubSecTimeDigitized DigitalCreationDate DigitalCreationTime)
|
18
|
+
|
19
|
+
private
|
20
|
+
|
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: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
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
# (c) ANB Andrew Bizyaev
|
4
|
+
|
5
|
+
require_relative '_tag'
|
6
|
+
|
7
|
+
module ExifTagger
|
8
|
+
module Tag
|
9
|
+
# 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)
|
14
|
+
|
15
|
+
def initialize(value_raw = [])
|
16
|
+
super(Array(value_raw).flatten.map { |i| i.to_s })
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
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
|
+
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})
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
# (c) ANB Andrew Bizyaev
|
4
|
+
|
5
|
+
require_relative '_tag_date'
|
6
|
+
|
7
|
+
module ExifTagger
|
8
|
+
module Tag
|
9
|
+
# -MWG:DateTimeOriginal:
|
10
|
+
# EXIF:DateTimeOriginal
|
11
|
+
# EXIF:SubSecTimeOriginal
|
12
|
+
# IPTC:DateCreated
|
13
|
+
# IPTC:TimeCreated
|
14
|
+
# XMP-photoshop:DateCreated
|
15
|
+
# creation date of the intellectual content being shown
|
16
|
+
class DateTimeOriginal < TagDate
|
17
|
+
EXIFTOOL_TAGS = %w(DateTimeOriginal SubSecTimeOriginal DateCreated TimeCreated)
|
18
|
+
|
19
|
+
private
|
20
|
+
|
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')})
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
# (c) ANB Andrew Bizyaev
|
4
|
+
|
5
|
+
require_relative '_tag'
|
6
|
+
|
7
|
+
module ExifTagger
|
8
|
+
module Tag
|
9
|
+
# GPS tags are used for camera location according to MWG 2.0)
|
10
|
+
# GPSLatitude (rational64u[3])
|
11
|
+
# GPSLatitudeRef (string[2] 'N' = North, 'S' = South)
|
12
|
+
# GPSLongitude (rational64u[3])
|
13
|
+
# GPSLongitudeRef (string[2] 'E' = East, 'W' = West)
|
14
|
+
# GPSAltitude (rational64u)
|
15
|
+
# 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]
|
19
|
+
EXIFTOOL_TAGS = %w(
|
20
|
+
GPSPosition
|
21
|
+
GPSLatitude
|
22
|
+
GPSLatitudeRef
|
23
|
+
GPSLongitude
|
24
|
+
GPSLongitudeRef
|
25
|
+
GPSAltitude
|
26
|
+
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
|
33
|
+
|
34
|
+
private
|
35
|
+
|
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})
|
57
|
+
end
|
58
|
+
end
|
59
|
+
unless @errors.empty?
|
60
|
+
@value_invalid << @value
|
61
|
+
@value = {}
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
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
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
# (c) ANB Andrew Bizyaev
|
4
|
+
|
5
|
+
require_relative '_tag'
|
6
|
+
|
7
|
+
module ExifTagger
|
8
|
+
module Tag
|
9
|
+
# ImageUniqueID, String
|
10
|
+
class ImageUniqueId < Tag
|
11
|
+
MAX_BYTESIZE = 32 # no limit in EXIF spec
|
12
|
+
EXIFTOOL_TAGS = %w(ImageUniqueID)
|
13
|
+
|
14
|
+
def initialize(value_raw = [])
|
15
|
+
super(value_raw.to_s)
|
16
|
+
end
|
17
|
+
|
18
|
+
def check_for_warnings(original_values: {})
|
19
|
+
@warnings = []
|
20
|
+
v = original_values[EXIFTOOL_TAGS[0]]
|
21
|
+
if v =~ /(\d{8}-\S+)/
|
22
|
+
@warnings << "#{tag_name} has original correct value: '#{v}'"
|
23
|
+
end
|
24
|
+
@warnings.freeze
|
25
|
+
end
|
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
|
+
def generate_write_script_lines
|
40
|
+
@write_script_lines = []
|
41
|
+
unless @value.empty?
|
42
|
+
@write_script_lines << %Q(-ImageUniqueID=#{@value})
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
# (c) ANB Andrew Bizyaev
|
4
|
+
|
5
|
+
require_relative '_tag'
|
6
|
+
|
7
|
+
module ExifTagger
|
8
|
+
module Tag
|
9
|
+
# MWG:Keywords, string[0,64]+, List of Strings
|
10
|
+
# = IPTC:Keywords, XMP-dc:Subject
|
11
|
+
class Keywords < Tag
|
12
|
+
MAX_BYTESIZE = 64
|
13
|
+
EXIFTOOL_TAGS = %w(Keywords Subject)
|
14
|
+
|
15
|
+
def initialize(value_raw = [])
|
16
|
+
super(Array(value_raw).flatten.map { |i| i.to_s })
|
17
|
+
end
|
18
|
+
|
19
|
+
def check_for_warnings(original_values: {})
|
20
|
+
@warnings = []
|
21
|
+
@warnings.freeze
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def validate
|
27
|
+
@value.each do |v|
|
28
|
+
bsize = v.bytesize
|
29
|
+
if bsize > MAX_BYTESIZE
|
30
|
+
@errors << %{#{tag_name}: '#{v}' } +
|
31
|
+
%{is #{bsize - MAX_BYTESIZE} bytes longer than allowed #{MAX_BYTESIZE}}
|
32
|
+
@value_invalid << v
|
33
|
+
end
|
34
|
+
end
|
35
|
+
@value = @value - @value_invalid
|
36
|
+
end
|
37
|
+
|
38
|
+
def generate_write_script_lines
|
39
|
+
@write_script_lines = []
|
40
|
+
unless @value.empty?
|
41
|
+
@value.each do |o|
|
42
|
+
@write_script_lines << %Q(-MWG:Keywords-=#{o})
|
43
|
+
@write_script_lines << %Q(-MWG:Keywords+=#{o})
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
# (c) ANB Andrew Bizyaev
|
4
|
+
|
5
|
+
require_relative '_tag'
|
6
|
+
|
7
|
+
module ExifTagger
|
8
|
+
module Tag
|
9
|
+
# MWG:Location, String[0,32]
|
10
|
+
# = IPTC:Sub-location + XMP-iptcCore:Location
|
11
|
+
# + XMP-iptcExt:LocationShownSublocation
|
12
|
+
class Location < Tag
|
13
|
+
MAX_BYTESIZE = 32
|
14
|
+
EXIFTOOL_TAGS = %w(Sub-location Location LocationShownSublocation)
|
15
|
+
|
16
|
+
def initialize(value_raw = [])
|
17
|
+
super(value_raw.to_s)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
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
|
+
def generate_write_script_lines
|
33
|
+
@write_script_lines = []
|
34
|
+
unless @value.empty?
|
35
|
+
@write_script_lines << %Q(-MWG:Location=#{@value})
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
# (c) ANB Andrew Bizyaev
|
4
|
+
|
5
|
+
require_relative '_tag_date'
|
6
|
+
|
7
|
+
module ExifTagger
|
8
|
+
module Tag
|
9
|
+
# -EXIF:ModifyDate=now
|
10
|
+
class ModifyDate < TagDate
|
11
|
+
EXIFTOOL_TAGS = %w(ModifyDate)
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def generate_write_script_lines
|
16
|
+
@write_script_lines = []
|
17
|
+
case
|
18
|
+
when @value.kind_of?(String) && !@value.empty?
|
19
|
+
@write_script_lines << %Q(-EXIF:ModifyDate=#{@value})
|
20
|
+
when @value.kind_of?(DateTime) || @value.kind_of?(Time)
|
21
|
+
@write_script_lines << %Q(-EXIF:ModifyDate=#{@value.strftime('%F %T')})
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
# (c) ANB Andrew Bizyaev
|
4
|
+
|
5
|
+
require_relative '_tag'
|
6
|
+
|
7
|
+
module ExifTagger
|
8
|
+
module Tag
|
9
|
+
# MWG:State, String[0,32]
|
10
|
+
# = IPTC:Province-State + XMP-photoshop:State
|
11
|
+
# + XMP-iptcExt:LocationShownProvinceState
|
12
|
+
class State < Tag
|
13
|
+
MAX_BYTESIZE = 32
|
14
|
+
EXIFTOOL_TAGS = %w(Province-State State LocationShownProvinceState)
|
15
|
+
|
16
|
+
def initialize(value_raw = [])
|
17
|
+
super(value_raw.to_s)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
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
|
+
def generate_write_script_lines
|
33
|
+
@write_script_lines = []
|
34
|
+
unless @value.empty?
|
35
|
+
@write_script_lines << %Q(-MWG:State=#{@value})
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
# (c) ANB Andrew Bizyaev
|
4
|
+
|
5
|
+
require_relative '_tag'
|
6
|
+
|
7
|
+
module ExifTagger
|
8
|
+
module Tag
|
9
|
+
# -XMP-iptcExt:LocationShownWorldRegion, String
|
10
|
+
class WorldRegion < Tag
|
11
|
+
MAX_BYTESIZE = 64 # No limit in XMP spec
|
12
|
+
EXIFTOOL_TAGS = %w(LocationShownWorldRegion)
|
13
|
+
|
14
|
+
def initialize(value_raw = [])
|
15
|
+
super(value_raw.to_s)
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
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
|
+
def generate_write_script_lines
|
31
|
+
@write_script_lines = []
|
32
|
+
unless @value.empty?
|
33
|
+
@write_script_lines << %Q(-XMP-iptcExt:LocationShownWorldRegion=#{@value})
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
# (c) ANB Andrew Bizyaev
|
4
|
+
|
5
|
+
require 'active_support/core_ext/string/inflections'
|
6
|
+
Dir.glob(File.join(__dir__, 'tags', '*.rb')).each { |f| require_relative f }
|
7
|
+
|
8
|
+
# ExifTagger helper methods
|
9
|
+
module ExifTagger
|
10
|
+
TAGS_SUPPORTED = (Tag.constants - [:Tag, :TagDate]).map { |i| i.to_s.underscore.to_sym }
|
11
|
+
end
|
data/lib/phtools/version.rb
CHANGED