Mnemosyne 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/LICENSE.md +22 -0
  2. data/bin/mnemosyne +137 -0
  3. metadata +63 -0
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013, Matthias Geier
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without modification,
5
+ are permitted provided that the following conditions are met:
6
+
7
+ - Redistributions of source code must retain the above copyright notice, this
8
+ list of conditions and the following disclaimer.
9
+ - Redistributions in binary form must reproduce the above copyright notice,
10
+ this list of conditions and the following disclaimer in the documentation
11
+ and/or other materials provided with the distribution.
12
+
13
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
14
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
17
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
20
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
21
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
22
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,137 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'argv_parser'
4
+
5
+ if (e = `which exiftool`).empty?
6
+ raise RuntimeError.new("No exiftool installed. 'which exiftool' failed")
7
+ end
8
+
9
+ $EXEC = e.strip
10
+
11
+ class Tagger < ArgvParser
12
+ attr_accessor :print
13
+ attr_accessor :files
14
+ attr_accessor :allowed_tags
15
+ attr_accessor :add_tags
16
+ attr_accessor :rem_tags
17
+ attr_accessor :fix
18
+ attr_accessor :clear
19
+
20
+ def get_tags(file)
21
+ result = `#{$EXEC} "#{file}"`
22
+ result = result.split("\n")
23
+ result.select!{ |s| s =~ /^(Subject|Keywords)\s*:/i }
24
+ result.map!{ |s| $1 if s =~ /^[^:]*:(.*)$/ }
25
+ return result.map{ |s| s.split(",") }.flatten.map{ |t| t.strip }.uniq
26
+ end
27
+
28
+ def set_tag(file, tag, op)
29
+ op = case op
30
+ when :remove
31
+ "-"
32
+ when :add
33
+ "+"
34
+ when :clear
35
+ ""
36
+ end
37
+ `#{$EXEC} -overwrite_original -xmp:Subject#{op}=\"#{tag}\" -iptc:Keywords#{op}=\"#{tag}\" \"#{file}\"`
38
+ end
39
+
40
+ def collect!
41
+ return unless self.files
42
+ file_tag_map = Hash[self.files.map{ |f| [f, get_tags(f)] }]
43
+ if self.allowed_tags
44
+ file_tag_map.each do |f, tags|
45
+ tags.select!{ |t| self.allowed_tags.include?(t) }
46
+ end
47
+ if self.add_tags
48
+ self.add_tags.select!{ |t| self.allowed_tags.include?(t) }
49
+ end
50
+ if self.rem_tags
51
+ self.rem_tags.select!{ |t| self.allowed_tags.include?(t) }
52
+ end
53
+ end
54
+ if self.rem_tags
55
+ self.rem_tags.each do |tag|
56
+ file_tag_map.each do |f, tags|
57
+ next unless tags.include?(tag)
58
+ tags.delete(tag)
59
+ set_tag(f, tag, :remove)
60
+ end
61
+ end
62
+ end
63
+ if self.add_tags
64
+ self.add_tags.each do |tag|
65
+ file_tag_map.each do |f, tags|
66
+ next if tags.include?(tag)
67
+ tags << tag
68
+ set_tag(f, tag, :add)
69
+ end
70
+ end
71
+ end
72
+ if self.fix or self.clear
73
+ file_tag_map.each do |f, tags|
74
+ set_tag(f, "", :clear)
75
+ end
76
+ end
77
+ if self.fix
78
+ file_tag_map.each do |f, tags|
79
+ tags.each{ |t| set_tag(f, t, :add) }
80
+ end
81
+ end
82
+ if self.clear
83
+ file_tag_map.each{ |f, tags| tag = [] }
84
+ end
85
+ if self.print
86
+ file_tag_map.each do |f, tags|
87
+ puts f
88
+ puts tags.join(", ")
89
+ puts
90
+ end
91
+ end
92
+ end
93
+ end
94
+
95
+ tagger = Tagger.new
96
+ tagger.hook("-t", "-t [tag file]", String, {}) do |t,v|
97
+ unless File.exists?(v)
98
+ raise ArgumentError.new("Tagfile foes not exist")
99
+ end
100
+ t.allowed_tags = []
101
+ File.open(v).each do |line|
102
+ t.allowed_tags << line.strip
103
+ end
104
+ end
105
+ tagger.hook("-a", "-a [tags] add tags", Array, {}) do |t,v|
106
+ t.add_tags = v.map{ |t| t.strip }
107
+ end
108
+ tagger.hook("-r", "-r [tags] remove tags", Array, {}) do |t,v|
109
+ t.rem_tags = v.map{ |t| t.strip }
110
+ end
111
+ tagger.hook("-f", "-f fix tags with tag file", nil, {}) do |t,_|
112
+ t.fix = true
113
+ end
114
+ tagger.hook("-c", "-c clear all tags", nil, {}) do |t,_|
115
+ t.clear = true
116
+ end
117
+ tagger.hook("-p", "-p print", nil, {}) do |t,_|
118
+ t.print = true
119
+ end
120
+ tagger.hook("--", "-- [file path]", String, {:mandatory => true}) do |t,v|
121
+ unless File.exists?(v)
122
+ raise ArgumentError.new("File does not exist")
123
+ end
124
+ if File.directory?(v)
125
+ v = v + "/" unless v =~ /\/$/
126
+ files = []
127
+ Dir.foreach(v) do |f|
128
+ files << v + f
129
+ end
130
+ t.files = files
131
+ else
132
+ t.files = [v]
133
+ end
134
+ t.files.select!{ |f| f =~ /\.(jpeg|jpg)$/i }
135
+ end
136
+ tagger.parse! ARGV
137
+ tagger.collect!
metadata ADDED
@@ -0,0 +1,63 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: Mnemosyne
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Matthias Geier
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-09-20 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: ArgvParser
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 1.1.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: 1.1.0
30
+ description:
31
+ email:
32
+ executables:
33
+ - mnemosyne
34
+ extensions: []
35
+ extra_rdoc_files: []
36
+ files:
37
+ - LICENSE.md
38
+ - bin/mnemosyne
39
+ homepage: https://github.com/matthias-geier/Mnemosyne
40
+ licenses: []
41
+ post_install_message:
42
+ rdoc_options: []
43
+ require_paths:
44
+ - bin
45
+ required_ruby_version: !ruby/object:Gem::Requirement
46
+ none: false
47
+ requirements:
48
+ - - ! '>='
49
+ - !ruby/object:Gem::Version
50
+ version: 1.9.3
51
+ required_rubygems_version: !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ! '>='
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ requirements: []
58
+ rubyforge_project:
59
+ rubygems_version: 1.8.23
60
+ signing_key:
61
+ specification_version: 3
62
+ summary: A exiftool-based tagger for JPG files.
63
+ test_files: []