flickrup 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/bin/flickrup ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'flickrup'
5
+
6
+ Flickrup.run_cmd(ARGV)
@@ -0,0 +1,5 @@
1
+ module Logging
2
+ def logger
3
+ @logger ||= Logger.new(STDOUT)
4
+ end
5
+ end
@@ -0,0 +1,31 @@
1
+ require "flickrup/tagged_image"
2
+ require "flickrup/uploader"
3
+ require "flickrup/logging"
4
+
5
+ class Processor
6
+ include Logging
7
+
8
+ def initialize(config)
9
+ @config = config
10
+ end
11
+
12
+ def run(files = Dir["#{@config['watch_dir']}/*.{jpg,JPG,jpeg,JPEG}"])
13
+
14
+ logger.debug("Processing #{files.length} files")
15
+
16
+ images = files.map { |x| TaggedImage.new(x) }
17
+
18
+ tagged = images.select { |x| !(x.tags.nil? || x.tags.empty?) }
19
+
20
+ uploader = Uploader.new(@config["api_key"], @config["shared_secret"])
21
+
22
+ tagged.each { |x|
23
+ x.doUpload(uploader)
24
+ x.archive(@config["archive_dir"])
25
+ }
26
+
27
+ logger.debug("Processed #{tagged.length} valid files")
28
+
29
+ tagged.length
30
+ end
31
+ end
@@ -0,0 +1,52 @@
1
+ require 'atomic'
2
+ require "thread"
3
+ require "listen"
4
+
5
+ class QuickListener
6
+
7
+ def initialize(config)
8
+ @config = config
9
+ @changes = Atomic.new 0
10
+ @mutex = Mutex.new
11
+ @sync = ConditionVariable.new
12
+ @flickup = Flickrup.new(config)
13
+ end
14
+
15
+ def run
16
+ Thread.new { run_loop }
17
+ Listen.to(@config['watch_dir']) do |modified, added, removed|
18
+ unless modified.empty? && added.empty?
19
+ on_change
20
+ end
21
+ end
22
+ end
23
+
24
+ private
25
+ def run_loop
26
+
27
+ @mutex.synchronize do
28
+ while 1 do
29
+ reloop = @changes.swap 0
30
+
31
+ while reloop > 0 do
32
+ execute
33
+ reloop = @changes.swap 0
34
+ end
35
+
36
+ @sync.wait(@mutex)
37
+ end
38
+ end
39
+
40
+ end
41
+
42
+ def on_change
43
+ @mutex.synchronize do
44
+ @changes.set 1
45
+ @sync.signal
46
+ end
47
+ end
48
+
49
+ def execute
50
+ @flickup.run
51
+ end
52
+ end
@@ -0,0 +1,69 @@
1
+ require 'rubygems'
2
+ require 'rufus/scheduler'
3
+ require "flickrup/logging"
4
+
5
+ #modification ->
6
+ # schedule upload for 5 mins time
7
+ #
8
+ #upload run ->
9
+ # for files modified > 5 mins ago
10
+ # -> do upload
11
+ # if there are files modified < 5 mins ago
12
+ # -> schedule upload for minimum time
13
+ #
14
+ #When scheduling upload, remove all but the nearest
15
+ #When paused, upload run should be a no-op
16
+
17
+ class SlowListener
18
+ include Logging
19
+
20
+ WAIT = 5#*60 #5 min
21
+
22
+ def initialize(config)
23
+ @config = config
24
+ @scheduler = Rufus::Scheduler.start_new
25
+ @processor = Processor.new(config)
26
+ end
27
+
28
+ def run
29
+ logger.debug("Watching #{@config['watch_dir']}...")
30
+ Listen.to(@config['watch_dir']) do |modified, added, removed|
31
+ unless modified.empty? && added.empty?
32
+ on_change
33
+ end
34
+ end
35
+ end
36
+
37
+ def do_upload
38
+ logger.debug("Checking files for upload")
39
+ files = Dir["#{@config['watch_dir']}/*.{jpg,JPG,jpeg,JPEG}"]
40
+
41
+ old, new = files.partition { |x| Time.now > File.mtime(x) + WAIT }
42
+
43
+ unless old.empty?
44
+ logger.debug("Found #{old.length} stable files")
45
+ @processor.run(old)
46
+ end
47
+
48
+ unless new.empty?
49
+ logger.debug("Found #{new.length} new files")
50
+ #todo: schedule for latest
51
+ schedule
52
+ end
53
+ end
54
+
55
+ def on_change
56
+ logger.debug("Change detected")
57
+ schedule
58
+ end
59
+
60
+ def schedule
61
+ if @scheduler.jobs.empty?
62
+ logger.debug("Scheduling processing for #{WAIT} sec")
63
+ @scheduler.in WAIT do
64
+ do_upload
65
+ end
66
+ end
67
+ end
68
+
69
+ end
@@ -0,0 +1,36 @@
1
+ require 'mini_exiftool'
2
+ require 'ftools'
3
+ require 'fileutils'
4
+ require "flickrup/logging"
5
+
6
+ class TaggedImage
7
+ include Logging
8
+
9
+ attr_reader :file
10
+
11
+ def initialize(file)
12
+ @file = file
13
+ @parsed = MiniExiftool.new @file
14
+ end
15
+
16
+ def tags
17
+ @parsed.keywords.to_a
18
+ end
19
+
20
+ def doUpload(uploader)
21
+ uploader.upload(file, tags)
22
+ end
23
+
24
+ def archive(to_dir)
25
+ date_taken = @parsed.date_time_original
26
+ target_dir = File.join(
27
+ to_dir,
28
+ date_taken.strftime("%y"),
29
+ date_taken.strftime("%m")
30
+ )
31
+
32
+ File.makedirs(target_dir)
33
+ FileUtils.mv(@file, File.join(target_dir, File.basename(@file)))
34
+ end
35
+
36
+ end
@@ -0,0 +1,56 @@
1
+ require "yaml"
2
+ require 'rubygems'
3
+ require "flickraw"
4
+ require "flickrup/logging"
5
+
6
+ class Uploader
7
+ include Logging
8
+
9
+ def initialize(api_key, shared_secret)
10
+ FlickRaw.api_key= api_key
11
+ FlickRaw.shared_secret=shared_secret
12
+
13
+ @token_file = File.join(ENV['HOME'], ".flickrup")
14
+ @flickr = FlickRaw::Flickr.new
15
+
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
21
+
22
+ begin
23
+ login = @flickr.test.login
24
+ rescue FlickRaw::OAuthClient::FailedResponse => e
25
+ get_token
26
+ end
27
+
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}")
54
+ end
55
+
56
+ end
data/lib/flickrup.rb ADDED
@@ -0,0 +1,43 @@
1
+ require "yaml"
2
+ require "rubygems"
3
+ require "trollop"
4
+ require "logger"
5
+ require "flickrup/quick_listener"
6
+ require "flickrup/slow_listener"
7
+ require "flickrup/tagged_image"
8
+ require "flickrup/uploader"
9
+ require "flickrup/processor"
10
+ require "flickrup/logging"
11
+
12
+
13
+ module Flickrup
14
+
15
+ def self.run_cmd(args = ARGV)
16
+ Runner.new.run(args)
17
+ end
18
+
19
+ class Runner
20
+ include Logging
21
+
22
+ def run(args = ARGV)
23
+ opts = Trollop::options do
24
+ opt :once, "Run single pass" # flag --once, default false
25
+ opt :nowait, "Upload immediately on change, no delay"
26
+ opt :loglevel, "Logging level", :type => :string, :default => "INFO"
27
+ opt :config, "Configuration file", :type => :string, :default => './flickrup.yml'
28
+ end
29
+
30
+ logger.level = Logger::Severity.const_get(opts.loglevel)
31
+
32
+ config = YAML::load(File.open(opts.config, "r"))
33
+
34
+ if opts.once
35
+ Processor.new(config).run
36
+ elsif opts.nowait
37
+ QuickListener.new(config).run
38
+ else
39
+ SlowListener.new(config).run
40
+ end
41
+ end
42
+ end
43
+ end
metadata ADDED
@@ -0,0 +1,167 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: flickrup
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 2
10
+ version: 0.0.2
11
+ platform: ruby
12
+ authors:
13
+ - Jonathan Gilbert
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2012-12-21 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: atomic
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ hash: 23
29
+ segments:
30
+ - 1
31
+ - 0
32
+ - 0
33
+ version: 1.0.0
34
+ type: :runtime
35
+ version_requirements: *id001
36
+ - !ruby/object:Gem::Dependency
37
+ name: listen
38
+ prerelease: false
39
+ requirement: &id002 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ hash: 7
45
+ segments:
46
+ - 0
47
+ - 6
48
+ - 0
49
+ version: 0.6.0
50
+ type: :runtime
51
+ version_requirements: *id002
52
+ - !ruby/object:Gem::Dependency
53
+ name: rufus-scheduler
54
+ prerelease: false
55
+ requirement: &id003 !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ hash: 15
61
+ segments:
62
+ - 2
63
+ - 0
64
+ - 0
65
+ version: 2.0.0
66
+ type: :runtime
67
+ version_requirements: *id003
68
+ - !ruby/object:Gem::Dependency
69
+ name: mini_exiftool
70
+ prerelease: false
71
+ requirement: &id004 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ hash: 15
77
+ segments:
78
+ - 1
79
+ - 6
80
+ - 0
81
+ version: 1.6.0
82
+ type: :runtime
83
+ version_requirements: *id004
84
+ - !ruby/object:Gem::Dependency
85
+ name: flickraw
86
+ prerelease: false
87
+ requirement: &id005 !ruby/object:Gem::Requirement
88
+ none: false
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ hash: 55
93
+ segments:
94
+ - 0
95
+ - 9
96
+ - 6
97
+ version: 0.9.6
98
+ type: :runtime
99
+ version_requirements: *id005
100
+ - !ruby/object:Gem::Dependency
101
+ name: trollop
102
+ prerelease: false
103
+ requirement: &id006 !ruby/object:Gem::Requirement
104
+ none: false
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ hash: 15
109
+ segments:
110
+ - 2
111
+ - 0
112
+ - 0
113
+ version: 2.0.0
114
+ type: :runtime
115
+ version_requirements: *id006
116
+ description: Flickr auto uploading script
117
+ email: bb..jgilbert@xoxy.net
118
+ executables:
119
+ - flickrup
120
+ extensions: []
121
+
122
+ extra_rdoc_files: []
123
+
124
+ files:
125
+ - lib/flickrup/logging.rb
126
+ - lib/flickrup/processor.rb
127
+ - lib/flickrup/quick_listener.rb
128
+ - lib/flickrup/slow_listener.rb
129
+ - lib/flickrup/tagged_image.rb
130
+ - lib/flickrup/uploader.rb
131
+ - lib/flickrup.rb
132
+ - bin/flickrup
133
+ homepage: http://bitbucket.org/jgilbert/flickrup
134
+ licenses: []
135
+
136
+ post_install_message:
137
+ rdoc_options: []
138
+
139
+ require_paths:
140
+ - lib
141
+ required_ruby_version: !ruby/object:Gem::Requirement
142
+ none: false
143
+ requirements:
144
+ - - ">="
145
+ - !ruby/object:Gem::Version
146
+ hash: 3
147
+ segments:
148
+ - 0
149
+ version: "0"
150
+ required_rubygems_version: !ruby/object:Gem::Requirement
151
+ none: false
152
+ requirements:
153
+ - - ">="
154
+ - !ruby/object:Gem::Version
155
+ hash: 3
156
+ segments:
157
+ - 0
158
+ version: "0"
159
+ requirements: []
160
+
161
+ rubyforge_project:
162
+ rubygems_version: 1.8.24
163
+ signing_key:
164
+ specification_version: 3
165
+ summary: Flickr Uploader!
166
+ test_files: []
167
+