flickrup 0.0.6 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,23 @@
1
+ class MachineTags
2
+ def initialize(config, context)
3
+ @config = config
4
+ end
5
+
6
+ def preupload(image, meta, config)
7
+
8
+ tags = config[:tags].split(" ")
9
+
10
+ remapped = tags.map do |x|
11
+ x.sub(/^([^:]+):([^:]+)::/,"\\1:\\2=")
12
+ end
13
+
14
+
15
+ unless tags == remapped #write back to file
16
+ meta['Keywords'] = remapped
17
+ meta['Subject'] = remapped #also write Subject XMP tag
18
+ end
19
+
20
+ config.merge({:tags => remapped.join(" ")})
21
+
22
+ end
23
+ end
@@ -0,0 +1,19 @@
1
+ class PrefixedExtension
2
+ def initialize(config)
3
+ @config = config
4
+ end
5
+
6
+ def values(prefix_key, config)
7
+ all_tags = config[:tags].split(" ")
8
+
9
+ prefix = @config[prefix_key]
10
+
11
+ (selected_tags, tags) = all_tags.partition do |x|
12
+ x.start_with?("#{prefix}")
13
+ end
14
+
15
+ selected_tags.map do |x|
16
+ x[(prefix.length)..x.length]
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,23 @@
1
+ class ReplacementTags
2
+ def initialize(config)
3
+ @config = config
4
+ end
5
+
6
+ def preupload(image, meta, config)
7
+
8
+ replacements = @config[:tag_replacements]
9
+
10
+ if replacements != nil
11
+ replacements.each do |tag_name, tag_value_replacements|
12
+ existing = meta[tag_name]
13
+
14
+ tag_value_replacements.each do |key, value|
15
+ if existing == key
16
+ meta[tag_name] = value
17
+ break
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,19 @@
1
+ require "flickrup/ext/prefixed_extension"
2
+
3
+ class TagSets < PrefixedExtension
4
+ def initialize(config, delegate, context)
5
+ super(config)
6
+ @delegate = delegate
7
+ @flickr = context[:flickr_client]
8
+ end
9
+
10
+ def upload(image, meta, config)
11
+ sets = values(:tagsetprefix, config)
12
+
13
+ uploaded = @delegate.upload(image, meta, config)
14
+
15
+ sets.each do |set|
16
+ @flickr.add_to_set(uploaded, set)
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,42 @@
1
+ require "flickrup/logging"
2
+
3
+ class Visibility < PrefixedExtension
4
+ include Logging
5
+
6
+ def initialize(config, delegate, context)
7
+ super(config)
8
+ @delegate = delegate
9
+ end
10
+
11
+ def upload(image, meta, config)
12
+ visibility = values(:visibilityprefix, config)
13
+
14
+ config_override = if visibility.length == 0
15
+ logger.debug("No visibility specified for #{image}.")
16
+ {}
17
+ elsif visibility.length == 1
18
+ config_for_visibility(visibility[0])
19
+ else #multiple visibilities
20
+ logger.warn("Multiple visibilities specified. Using the first encountered: #{visibility[0]}.")
21
+ config_for_visibility(visibility[0])
22
+ end
23
+
24
+ @delegate.upload(image, meta, config.merge(config_override))
25
+ end
26
+
27
+ def config_for_visibility(visibility)
28
+ if visibility == "offline"
29
+ logger.debug("Offline Visibility specified. Disabling upload.")
30
+ {UploaderConstants::NO_UPLOAD => true}
31
+ elsif visibility == "private"
32
+ logger.debug("Private visibility specified.")
33
+ {"is_public" => "0", "is_friend" => "0", "is_family" => "0"}
34
+ elsif visibility == "friends"
35
+ logger.debug("Friends visibility specified.")
36
+ {"is_public" => "0", "is_friend" => "1", "is_family" => "1"}
37
+ else
38
+ logger.warn("Unknown visibility #{visibility}. Ignoring.")
39
+ {}
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,79 @@
1
+ require "flickraw"
2
+
3
+ class FlickrClient
4
+
5
+ def initialize(api_key, shared_secret)
6
+ @set_name_to_id = {}
7
+ FlickRaw.api_key= api_key
8
+ FlickRaw.shared_secret=shared_secret
9
+
10
+ @token_file = File.join(ENV['HOME'], ".flickrup")
11
+ set_client(FlickRaw::Flickr.new)
12
+
13
+ if File.exist?(@token_file)
14
+ token = YAML.load_file(@token_file)
15
+ client.access_token = token["access"]
16
+ client.access_secret = token["secret"]
17
+ end
18
+
19
+ begin
20
+ login = client.test.login
21
+ rescue FlickRaw::OAuthClient::FailedResponse => e
22
+ get_token
23
+ end
24
+ end
25
+
26
+ def client
27
+ @client
28
+ end
29
+
30
+ def upload_photo(image, config)
31
+ client.upload_photo(image, config)
32
+ end
33
+
34
+ def add_to_set(photo_id, set_name)
35
+ set_id = get_set_id(set_name, photo_id)
36
+ client.photosets.addPhoto(:photoset_id => set_id, :photo_id => photo_id)
37
+ end
38
+
39
+ def get_set_id(set_name, for_photo_id)
40
+ unless @set_name_to_id.include? set_name
41
+ sets_response = client.photosets.getList #if we don't have it, refresh
42
+ @set_name_to_id = Hash[*sets_response.to_a.map{ |set|
43
+ [set['title'], set['id']]
44
+ }.flatten]
45
+ unless @set_name_to_id.include? set_name #if we still don't, create it
46
+ created = client.photosets.create(:title => set_name, :primary_photo_id => for_photo_id)
47
+ @set_name_to_id = @set_name_to_id.merge({set_name => created.id})
48
+ end
49
+ end
50
+
51
+ @set_name_to_id[set_name]
52
+ end
53
+
54
+ def get_token
55
+ token = client.get_request_token
56
+ auth_url = client.get_authorize_url(token['oauth_token'], :perms => 'write')
57
+
58
+ puts "Open this url in your process to complete the authentication process : #{auth_url}"
59
+ puts "Copy here the number given when you complete the process."
60
+ verify = gets.strip
61
+
62
+ begin
63
+ client.get_access_token(token['oauth_token'], token['oauth_token_secret'], verify)
64
+ token = {"access" => client.access_token, "secret" => client.access_secret}
65
+ login = client.test.login
66
+ puts "You are now authenticated as #{login.username}"
67
+ File.open(@token_file, 'w') { |f| f.write(token.to_yaml) }
68
+ rescue FlickRaw::OAuthClient::FailedResponse => e
69
+ puts "Authentication failed : #{e.msg}"
70
+ end
71
+
72
+ end
73
+
74
+ private
75
+ def set_client(client)
76
+ @client = client
77
+ end
78
+
79
+ end
@@ -1,6 +1,10 @@
1
1
  require "flickrup/tagged_image"
2
2
  require "flickrup/uploader"
3
3
  require "flickrup/logging"
4
+ require "flickrup/ext/tag_sets"
5
+ require "flickrup/ext/replacement_tags"
6
+ require "flickrup/ext/machine_tags"
7
+ require "flickrup/ext/visibility"
4
8
 
5
9
  class Processor
6
10
  include Logging
@@ -10,10 +14,10 @@ class Processor
10
14
  end
11
15
 
12
16
  def paused
13
- Dir["#{@config['watch_dir']}/paused"].length > 0
17
+ Dir["#{@config[:watch_dir]}/paused"].length > 0
14
18
  end
15
19
 
16
- def run(files = Dir["#{@config['watch_dir']}/*.{jpg,JPG,jpeg,JPEG}"])
20
+ def run(files = Dir["#{@config[:watch_dir]}/*.{jpg,JPG,jpeg,JPEG}"])
17
21
 
18
22
  logger.debug("Processing #{files.length} files")
19
23
 
@@ -26,15 +30,15 @@ class Processor
26
30
 
27
31
  tagged = images.select { |x| !(x.tags.nil? || x.tags.empty?) }
28
32
 
29
- uploader = Uploader.new(@config["api_key"], @config["shared_secret"])
33
+ uploader = get_uploader
30
34
 
31
35
  if @config[:dryrun]
32
36
  logger.info("Would now upload & move #{tagged.length} files, pausing for 5 secs instead")
33
37
  sleep 5
34
38
  else
35
39
  tagged.each { |x|
36
- x.doUpload(uploader)
37
- x.archive(@config["archive_dir"])
40
+ x.doUpload(get_preupload_handlers, uploader)
41
+ x.archive(@config[:archive_dir])
38
42
  }
39
43
  end
40
44
 
@@ -42,4 +46,25 @@ class Processor
42
46
 
43
47
  tagged.length
44
48
  end
49
+
50
+ private
51
+ def get_uploader
52
+ flickr_client = FlickrClient.new(@config[:api_key], @config[:shared_secret])
53
+
54
+ context = {:flickr_client => flickr_client}
55
+
56
+ uploader = Uploader.new(flickr_client)
57
+
58
+ upload_handlers.reduce(uploader) do |result, clazz|
59
+ clazz.new(@config, result, context)
60
+ end
61
+ end
62
+
63
+ def get_preupload_handlers
64
+ [MachineTags.new(@config, {}), ReplacementTags.new(@config)]
65
+ end
66
+
67
+ def upload_handlers() [TagSets, Visibility] end
68
+
45
69
  end
70
+
@@ -33,7 +33,7 @@ class SlowListener
33
33
 
34
34
  def run
35
35
  logger.debug("Watching #{@config['watch_dir']}...")
36
- Listen.to(@config['watch_dir']) do |modified, added, _|
36
+ Listen.to(@config[:watch_dir]) do |modified, added, _|
37
37
  unless modified.empty? && added.empty?
38
38
  on_change
39
39
  end
@@ -45,7 +45,7 @@ class SlowListener
45
45
 
46
46
  @processing.set PROCESSING
47
47
 
48
- files = Dir["#{@config['watch_dir']}/*.{jpg,JPG,jpeg,JPEG}"]
48
+ files = Dir["#{@config[:watch_dir]}/*.{jpg,JPG,jpeg,JPEG}"]
49
49
 
50
50
  old, new = files.partition { |x| Time.now > File.mtime(x) + @wait }
51
51
 
@@ -17,8 +17,23 @@ class TaggedImage
17
17
  @parsed.keywords.to_a
18
18
  end
19
19
 
20
- def doUpload(uploader)
21
- uploader.upload(file, tags)
20
+ def doUpload(preupload_handlers, uploader)
21
+
22
+ config = preupload_handlers.reduce({:tags => tags.join(" ")}) do |config, handler|
23
+ handler.preupload(file, self, config)
24
+ end
25
+
26
+ #maybe save afterwards
27
+ if @parsed.changed?
28
+ @parsed.save!
29
+ end
30
+
31
+ uploader.upload(file, self, config)
32
+
33
+ #maybe save afterwards
34
+ if @parsed.changed?
35
+ @parsed.save!
36
+ end
22
37
  end
23
38
 
24
39
  def archive(to_dir)
@@ -32,6 +47,17 @@ class TaggedImage
32
47
 
33
48
  File.makedirs(target_dir)
34
49
  FileUtils.mv(@file, File.join(target_dir, File.basename(@file)))
50
+ logger.info("Archived #{File.basename(@file)} to #{target_dir}")
51
+ end
52
+
53
+ # Returns the value of a tag.
54
+ def [] tag
55
+ @parsed[tag]
56
+ end
57
+
58
+ # Set the value of a tag.
59
+ def []=(tag, val)
60
+ @parsed[tag] = val
35
61
  end
36
62
 
37
63
  end
@@ -1,56 +1,35 @@
1
1
  require "yaml"
2
2
  require 'rubygems'
3
- require "flickraw"
4
3
  require "flickrup/logging"
4
+ require "flickrup/flickr_client"
5
+
6
+ module UploaderConstants
7
+ NO_UPLOAD = :no_upload
8
+ end
5
9
 
6
10
  class Uploader
7
11
  include Logging
8
12
 
9
- def initialize(api_key, shared_secret)
10
- FlickRaw.api_key= api_key
11
- FlickRaw.shared_secret=shared_secret
13
+ def initialize(flickr_client)
14
+ @flickr = flickr_client
15
+ end
12
16
 
13
- @token_file = File.join(ENV['HOME'], ".flickrup")
14
- @flickr = FlickRaw::Flickr.new
17
+ def upload(image, meta, config)
15
18
 
16
- if File.exist?(@token_file)
17
- token = YAML.load_file(@token_file)
18
- @flickr.access_token = token["access"]
19
- @flickr.access_secret = token["secret"]
20
- end
19
+ if config[UploaderConstants::NO_UPLOAD]
20
+ logger.info("Skipping upload of #{image} as marked as NO_UPLOAD")
21
+ else
22
+ logger.debug("Uploading #{image} with tags #{config[:tags]}")
21
23
 
22
- begin
23
- login = @flickr.test.login
24
- rescue FlickRaw::OAuthClient::FailedResponse => e
25
- get_token
24
+ begin
25
+ rv = @flickr.upload_photo(image, config)
26
+ logger.debug("Uploaded #{image}")
27
+ rescue StandardError => err
28
+ logger.error("Failed to upload #{image}: #{err}")
29
+ end
26
30
  end
27
31
 
28
- end
29
-
30
- def get_token
31
- token = @flickr.get_request_token
32
- auth_url = @flickr.get_authorize_url(token['oauth_token'], :perms => 'write')
33
-
34
- puts "Open this url in your process to complete the authentication process : #{auth_url}"
35
- puts "Copy here the number given when you complete the process."
36
- verify = gets.strip
37
-
38
- begin
39
- @flickr.get_access_token(token['oauth_token'], token['oauth_token_secret'], verify)
40
- token = {"access" => @flickr.access_token, "secret" => @flickr.access_secret}
41
- login = @flickr.test.login
42
- puts "You are now authenticated as #{login.username}"
43
- File.open(@token_file, 'w') { |f| f.write(token.to_yaml) }
44
- rescue FlickRaw::OAuthClient::FailedResponse => e
45
- puts "Authentication failed : #{e.msg}"
46
- end
47
-
48
- end
49
-
50
- def upload(image, tags)
51
- logger.debug("Uploading #{image} with tags #{tags.join(",")}")
52
- @flickr.upload_photo(image, :tags => tags.join(" "))
53
- logger.debug("Uploaded #{image}")
32
+ rv
54
33
  end
55
34
 
56
35
  end
data/lib/flickrup.rb CHANGED
@@ -31,7 +31,8 @@ module Flickrup
31
31
 
32
32
  logger.level = Logger::Severity.const_get(opts.loglevel)
33
33
 
34
- config = YAML::load(File.open(opts.config, "r")).merge opts
34
+ #load config, symbolise, merge with command line config
35
+ config = YAML::load(File.open(opts.config, "r")).inject({}){|memo,(k,v)| memo[k.to_sym] = v; memo}.merge opts
35
36
 
36
37
  if opts.once
37
38
  Processor.new(config).run
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flickrup
3
3
  version: !ruby/object:Gem::Version
4
- hash: 19
4
+ hash: 15
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 6
10
- version: 0.0.6
9
+ - 8
10
+ version: 0.0.8
11
11
  platform: ruby
12
12
  authors:
13
13
  - Jonathan Gilbert
@@ -138,6 +138,12 @@ extensions: []
138
138
  extra_rdoc_files: []
139
139
 
140
140
  files:
141
+ - lib/flickrup/ext/machine_tags.rb
142
+ - lib/flickrup/ext/prefixed_extension.rb
143
+ - lib/flickrup/ext/replacement_tags.rb
144
+ - lib/flickrup/ext/tag_sets.rb
145
+ - lib/flickrup/ext/visibility.rb
146
+ - lib/flickrup/flickr_client.rb
141
147
  - lib/flickrup/logging.rb
142
148
  - lib/flickrup/processor.rb
143
149
  - lib/flickrup/quick_listener.rb