flickrup 0.0.6 → 0.0.8

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.
@@ -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