tomk32-flickr_fu 0.3.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.
- data/.gitignore +13 -0
- data/LICENSE +22 -0
- data/README +182 -0
- data/Rakefile +73 -0
- data/VERSION.yml +4 -0
- data/lib/flickr/auth.rb +76 -0
- data/lib/flickr/base.rb +151 -0
- data/lib/flickr/comment.rb +16 -0
- data/lib/flickr/contact.rb +16 -0
- data/lib/flickr/contacts.rb +55 -0
- data/lib/flickr/errors.rb +20 -0
- data/lib/flickr/geo.rb +42 -0
- data/lib/flickr/license.rb +24 -0
- data/lib/flickr/location.rb +15 -0
- data/lib/flickr/note.rb +16 -0
- data/lib/flickr/people.rb +54 -0
- data/lib/flickr/person.rb +82 -0
- data/lib/flickr/photo.rb +333 -0
- data/lib/flickr/photo_response.rb +37 -0
- data/lib/flickr/photos.rb +277 -0
- data/lib/flickr/photoset.rb +37 -0
- data/lib/flickr/photosets.rb +39 -0
- data/lib/flickr/size.rb +16 -0
- data/lib/flickr/status.rb +19 -0
- data/lib/flickr/test.rb +31 -0
- data/lib/flickr/token.rb +22 -0
- data/lib/flickr/uploader.rb +162 -0
- data/lib/flickr/urls.rb +44 -0
- data/lib/flickr_fu.rb +51 -0
- data/spec/fixtures/flickr/contacts/get_list-fail-99.xml +4 -0
- data/spec/fixtures/flickr/contacts/get_public_list-0.xml +7 -0
- data/spec/fixtures/flickr/photos/geo/get_location-0.xml +11 -0
- data/spec/fixtures/flickr/photos/geo/get_location-fail-2.xml +4 -0
- data/spec/fixtures/flickr/photos/get_info-0.xml +41 -0
- data/spec/fixtures/flickr/photos/get_info-1.xml +19 -0
- data/spec/fixtures/flickr/photos/get_sizes-0.xml +10 -0
- data/spec/fixtures/flickr/photos/get_sizes-1.xml +8 -0
- data/spec/fixtures/flickr/photos/licenses/get_info.xml +12 -0
- data/spec/fixtures/flickr/photosets/get_list-0.xml +13 -0
- data/spec/fixtures/flickr/photosets/get_photos-0.xml +7 -0
- data/spec/fixtures/flickr/test/echo-0.xml +5 -0
- data/spec/fixtures/flickr/test/null-fail-99.xml +4 -0
- data/spec/fixtures/flickr/urls/get_group-0.xml +4 -0
- data/spec/fixtures/flickr/urls/get_group-fail-1.xml +4 -0
- data/spec/fixtures/flickr/urls/get_user_photos-0.xml +4 -0
- data/spec/fixtures/flickr/urls/get_user_photos-fail-1.xml +4 -0
- data/spec/fixtures/flickr/urls/get_user_photos-fail-2.xml +4 -0
- data/spec/fixtures/flickr/urls/get_user_profile-0.xml +4 -0
- data/spec/fixtures/flickr/urls/get_user_profile-fail-1.xml +4 -0
- data/spec/fixtures/flickr/urls/get_user_profile-fail-2.xml +4 -0
- data/spec/fixtures/flickr/urls/lookup_group-0.xml +6 -0
- data/spec/fixtures/flickr/urls/lookup_group-fail-1.xml +4 -0
- data/spec/fixtures/flickr/urls/lookup_user-0.xml +6 -0
- data/spec/fixtures/flickr/videos/get_info-0.xml +31 -0
- data/spec/fixtures/flickr/videos/get_sizes-0.xml +13 -0
- data/spec/flickr/base_spec.rb +97 -0
- data/spec/flickr/contacts_spec.rb +47 -0
- data/spec/flickr/errors_spec.rb +21 -0
- data/spec/flickr/geo_spec.rb +20 -0
- data/spec/flickr/photo_spec.rb +140 -0
- data/spec/flickr/photos_spec.rb +50 -0
- data/spec/flickr/photosets_spec.rb +49 -0
- data/spec/flickr/test_spec.rb +34 -0
- data/spec/flickr/urls_spec.rb +99 -0
- data/spec/spec.opts +4 -0
- data/spec/spec_helper.rb +20 -0
- data/tomk32-flickr_fu.gemspec +121 -0
- metadata +151 -0
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2008 CommonThread, LLC
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person
|
4
|
+
obtaining a copy of this software and associated documentation
|
5
|
+
files (the "Software"), to deal in the Software without
|
6
|
+
restriction, including without limitation the rights to use,
|
7
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
copies of the Software, and to permit persons to whom the
|
9
|
+
Software is furnished to do so, subject to the following
|
10
|
+
conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be
|
13
|
+
included in all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
17
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
19
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
20
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
21
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
22
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
data/README
ADDED
@@ -0,0 +1,182 @@
|
|
1
|
+
= flickr-fu
|
2
|
+
|
3
|
+
== Contact
|
4
|
+
|
5
|
+
Author: Ben Wyrosdick
|
6
|
+
Email: ben [at] commonthread.com
|
7
|
+
Lighthouse: http://commonthread.lighthouseapp.com/projects/12069-flickr_fu/overview
|
8
|
+
Main Repository: http://github.com/commonthread/flickr_fu/tree/master
|
9
|
+
|
10
|
+
== Getting Started
|
11
|
+
|
12
|
+
You need to first get an API key as detailed here:
|
13
|
+
|
14
|
+
http://www.flickr.com/services/api/misc.api_keys.html
|
15
|
+
|
16
|
+
== Installation
|
17
|
+
|
18
|
+
sudo gem install flickr-fu
|
19
|
+
|
20
|
+
== Documentation
|
21
|
+
|
22
|
+
RDoc Documentation can be found here:
|
23
|
+
|
24
|
+
http://www.commonthread.com/projects/flickr_fu/rdoc/
|
25
|
+
|
26
|
+
== Example flickr.yml
|
27
|
+
--- !map:HashWithIndifferentAccess
|
28
|
+
key: "YOUR KEY"
|
29
|
+
secret: "YOUR SECRET"
|
30
|
+
token_cache: "token_cache.yml"
|
31
|
+
|
32
|
+
== Authorization
|
33
|
+
|
34
|
+
To authorise your application to access Flickr using your API key you will
|
35
|
+
need to access a specific URL.
|
36
|
+
|
37
|
+
To generate this URL run the following and when presented with the URL
|
38
|
+
access it from your browser. Confirm the application has permission at
|
39
|
+
the level you have specified.
|
40
|
+
|
41
|
+
Note that flickr has different types of keys. If you use one for a webapplication,
|
42
|
+
which is most likely, you need to define a callback and somehow make sure that
|
43
|
+
you connect the parameter :frob that flickr send via the callback is assigned
|
44
|
+
to the right user account. The best way to do this is to loop over all the current
|
45
|
+
user's flickr accounts and try flickr.auth.token with the :frob.
|
46
|
+
|
47
|
+
Finally, cache the token (this will create the token cache file)
|
48
|
+
|
49
|
+
If you have an invalid API key you will see errors such as:
|
50
|
+
|
51
|
+
"100: Invalid API Key"
|
52
|
+
|
53
|
+
If you don't follow the process below to authorise your application
|
54
|
+
you will see errors such as:
|
55
|
+
|
56
|
+
"98: Login failed / Invalid auth token" or
|
57
|
+
"99: User not logged in / Insufficient permissions"
|
58
|
+
|
59
|
+
== Authorization Example for non-webapplication
|
60
|
+
|
61
|
+
require 'flickr_fu'
|
62
|
+
|
63
|
+
flickr = Flickr.new('flickr.yml')
|
64
|
+
|
65
|
+
puts "visit the following url, then click <enter> once you have authorized:"
|
66
|
+
|
67
|
+
# request write permissions
|
68
|
+
puts flickr.auth.url(:write)
|
69
|
+
|
70
|
+
gets
|
71
|
+
|
72
|
+
flickr.auth.cache_token
|
73
|
+
|
74
|
+
== Authorization Example for a webapplication
|
75
|
+
|
76
|
+
flickr.auth.token also contains the nsid and username, this
|
77
|
+
example only stores the token and no other userdata.
|
78
|
+
All you need in the views is a button or link to FlickrController.create
|
79
|
+
|
80
|
+
require 'flickr_fu'
|
81
|
+
class FlickrController < ActionController::Base
|
82
|
+
def create
|
83
|
+
flickr = Flickr.new('flickr.yml')
|
84
|
+
redirect_to flickr.auth.url(:write)
|
85
|
+
end
|
86
|
+
def flickr_callback
|
87
|
+
flickr = Flickr.new('flickr.yml')
|
88
|
+
flickr.auth.frob = params[:frob]
|
89
|
+
current_user.update_attribute :flickr_token, flickr.auth.token.token
|
90
|
+
end
|
91
|
+
def something_else_with_flickr
|
92
|
+
flickr = Flickr.new(YAML.load_file('flickr.yml').merge(:token => current_user.flickr_token))
|
93
|
+
# now you have full access on the user's data :)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
=== User creation on the fly
|
98
|
+
|
99
|
+
To use the userdata in flickr.auth.token and create
|
100
|
+
an account with it on the fly try following flickr_callback
|
101
|
+
|
102
|
+
def flickr_callback
|
103
|
+
flickr = Flickr.new('flickr.yml')
|
104
|
+
flickr.auth.frob = params[:frob]
|
105
|
+
if(!logged_in?)
|
106
|
+
# no user yet for this flickr id, create a new user
|
107
|
+
if (current_user = User.find_by_flickr_nsid(flickr.auth.token.user_id))).nil?
|
108
|
+
current_user = User.new do |user|
|
109
|
+
user.login = flickr.auth.token.username
|
110
|
+
user.real_name = flickr.auth.token.user_real_name
|
111
|
+
user.flickr_nsid = flickr.auth.token.user_id
|
112
|
+
user.flickr_token = flickr.auth.token.token
|
113
|
+
end
|
114
|
+
else # we have a user for that flick account, login and update token
|
115
|
+
current_user.flickr_token = flickr.auth.token.token
|
116
|
+
end
|
117
|
+
if(current_user.save)
|
118
|
+
flash[:notice] = 'Registered and logged in via flickr'
|
119
|
+
redirect_to '/'
|
120
|
+
else
|
121
|
+
// probably you validate for the presence of an email address?
|
122
|
+
flash[:error] = 'Logged in via flickr but some user data is missing'
|
123
|
+
@user = current_user
|
124
|
+
render :action => 'users/new'
|
125
|
+
end
|
126
|
+
else
|
127
|
+
current_user.update_attribute :flickr_token, flickr.auth.token.token
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
== Search Example
|
132
|
+
|
133
|
+
require 'flickr_fu'
|
134
|
+
|
135
|
+
flickr = Flickr.new('flickr.yml')
|
136
|
+
|
137
|
+
photos = flickr.photos.search(:tags => 'ruby-flickr')
|
138
|
+
|
139
|
+
puts "found #{photos.size} photo(s)"
|
140
|
+
|
141
|
+
photos.each do |photo|
|
142
|
+
puts photo.title
|
143
|
+
puts photo.description unless [nil, ''].include?(photo.description)
|
144
|
+
[:square, :thumbnail, :small, :medium, :large, :original].each do |size|
|
145
|
+
puts "#{size}: #{photo.url(size)}"
|
146
|
+
end
|
147
|
+
puts "comments: #{photo.comments.size}"
|
148
|
+
photo.comments.each do |comment|
|
149
|
+
intro = "#{comment.author_name} says - "
|
150
|
+
puts "#{intro}\"#{comment.comment.gsub("\n", "\n"+(" "*intro.length))}\""
|
151
|
+
end
|
152
|
+
puts "notes: #{photo.notes.size}"
|
153
|
+
photo.notes.each do |note|
|
154
|
+
puts "[#{note.x},#{note.y} ~ #{note.width}x#{note.height}] - \"#{note.note}\""
|
155
|
+
end
|
156
|
+
puts
|
157
|
+
puts
|
158
|
+
end
|
159
|
+
|
160
|
+
== Another Search Example
|
161
|
+
|
162
|
+
If searching for photos by user id then you need to specify the 'alias' - without
|
163
|
+
intervention this is usually set by Flickr and is an alphanumeric string.
|
164
|
+
|
165
|
+
To find out the user id for a given user, you can use the tool at:
|
166
|
+
|
167
|
+
http://idgettr.com/
|
168
|
+
|
169
|
+
And replace the line in the above sample to query on user id:
|
170
|
+
|
171
|
+
photos = flickr.photos.search(:user_id => 'your_user_id_here')
|
172
|
+
|
173
|
+
== Patch Contributers
|
174
|
+
|
175
|
+
Chris Ledet
|
176
|
+
Maciej Biłas
|
177
|
+
Mike Perham
|
178
|
+
Chris Anderton
|
179
|
+
Luke Francl
|
180
|
+
Thomas R. Koll
|
181
|
+
P. Mark Anderson
|
182
|
+
Josh Nichols
|
data/Rakefile
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/rdoctask'
|
3
|
+
|
4
|
+
# Gem building
|
5
|
+
begin
|
6
|
+
begin
|
7
|
+
require 'jeweler'
|
8
|
+
rescue LoadError
|
9
|
+
require 'rubygems'
|
10
|
+
require 'jeweler'
|
11
|
+
end
|
12
|
+
Jeweler::Tasks.new do |s|
|
13
|
+
s.name = "flickr_fu"
|
14
|
+
s.summary = "Provides a ruby interface to flickr via the REST api"
|
15
|
+
s.email = "ben@commonthread.com"
|
16
|
+
s.homepage = "http://github.com/commonthread/flickr_fu"
|
17
|
+
s.description = "Provides a ruby interface to flickr via the REST api"
|
18
|
+
s.authors = ["Ben Wyrosdick", "Maciej Bilas"]
|
19
|
+
s.rdoc_options = ["--main", "README"]
|
20
|
+
s.extra_rdoc_files = ["README"]
|
21
|
+
s.add_dependency("mime-types", ["> 0.0.0"])
|
22
|
+
s.add_dependency("xml-magic", ["> 0.0.0"])
|
23
|
+
s.files.exclude("spec/spec.local.opts")
|
24
|
+
end
|
25
|
+
rescue LoadError
|
26
|
+
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
27
|
+
end
|
28
|
+
|
29
|
+
desc 'Generate documentation for flickr_fu.'
|
30
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
31
|
+
rdoc.rdoc_dir = 'rdoc'
|
32
|
+
rdoc.title = 'flickr_fu'
|
33
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
34
|
+
rdoc.rdoc_files.include('README')
|
35
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
36
|
+
end
|
37
|
+
|
38
|
+
# RSpec support
|
39
|
+
begin
|
40
|
+
require 'spec'
|
41
|
+
rescue LoadError
|
42
|
+
require 'rubygems'
|
43
|
+
require 'spec'
|
44
|
+
end
|
45
|
+
begin
|
46
|
+
require 'spec/rake/spectask'
|
47
|
+
rescue LoadError
|
48
|
+
puts <<-EOS
|
49
|
+
To use rspec for testing you must install rspec gem:
|
50
|
+
gem install rspec
|
51
|
+
EOS
|
52
|
+
exit(0)
|
53
|
+
end
|
54
|
+
|
55
|
+
task :default => :spec
|
56
|
+
|
57
|
+
spec_common = Proc.new do |t|
|
58
|
+
t.spec_opts = ['--options', "spec/spec.opts"]
|
59
|
+
t.spec_opts << ['--options', "spec/spec.local.opts" ] if File.exist?(File.dirname(__FILE__) + "/spec/spec.local.opts")
|
60
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
61
|
+
end
|
62
|
+
|
63
|
+
desc "Run the specs under spec/models"
|
64
|
+
Spec::Rake::SpecTask.new do |t|
|
65
|
+
spec_common.call(t)
|
66
|
+
end
|
67
|
+
|
68
|
+
desc "Analyze code coverage with tests"
|
69
|
+
Spec::Rake::SpecTask.new("rcov") do |t|
|
70
|
+
spec_common.call(t)
|
71
|
+
t.rcov = true
|
72
|
+
t.rcov_opts = ["-x", "/var/lib", "-x", "spec/", "-T"]
|
73
|
+
end
|
data/VERSION.yml
ADDED
data/lib/flickr/auth.rb
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
class Flickr::Auth < Flickr::Base
|
2
|
+
def initialize(flickr)
|
3
|
+
@flickr = flickr
|
4
|
+
end
|
5
|
+
|
6
|
+
# get or return a frob to use for authentication
|
7
|
+
def frob
|
8
|
+
@frob ||= get_frob
|
9
|
+
end
|
10
|
+
|
11
|
+
# set the frob
|
12
|
+
def frob= frob
|
13
|
+
@frob=frob
|
14
|
+
end
|
15
|
+
|
16
|
+
# generates the authorization url to allow access to a flickr account.
|
17
|
+
#
|
18
|
+
# Params
|
19
|
+
# * perms (Optional)
|
20
|
+
# sets the permision level to grant on the flickr account.
|
21
|
+
# :read - permission to read private information (DEFAULT)
|
22
|
+
# :write - permission to add, edit and delete photo metadata (includes 'read')
|
23
|
+
# :delete - permission to delete photos (includes 'write' and 'read')
|
24
|
+
#
|
25
|
+
def url(perms = :read)
|
26
|
+
options = {:api_key => @flickr.api_key, :perms => perms, :frob => self.frob}
|
27
|
+
@flickr.sign_request(options)
|
28
|
+
Flickr::Base::AUTH_ENDPOINT + "?" + options.collect{|k,v| "#{k}=#{v}"}.join('&')
|
29
|
+
end
|
30
|
+
|
31
|
+
# gets the token object for the current frob
|
32
|
+
#
|
33
|
+
# Params
|
34
|
+
# * pass_through (Optional)
|
35
|
+
# Boolean value that determines if a call will be made to flickr to find a taken for the current frob if empty
|
36
|
+
#
|
37
|
+
def token(pass_through = true)
|
38
|
+
@token ||= get_token(pass_through) rescue nil
|
39
|
+
end
|
40
|
+
|
41
|
+
# saves the current token to the cache file if token exists
|
42
|
+
#
|
43
|
+
# Param
|
44
|
+
# * filename (Optional)
|
45
|
+
# filename of the cache file. defaults to the file passed into Flickr.new
|
46
|
+
#
|
47
|
+
def cache_token(filename = @flickr.token_cache)
|
48
|
+
if filename and self.token
|
49
|
+
cache_file = File.open(filename, 'w+')
|
50
|
+
cache_file.puts self.token.to_yaml
|
51
|
+
cache_file.close
|
52
|
+
true
|
53
|
+
else
|
54
|
+
false
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
def get_frob
|
60
|
+
rsp = @flickr.send_request('flickr.auth.getFrob')
|
61
|
+
|
62
|
+
rsp.frob.to_s
|
63
|
+
end
|
64
|
+
|
65
|
+
def get_token(pass_through)
|
66
|
+
if @flickr.token
|
67
|
+
@flickr.token
|
68
|
+
elsif @flickr.token_cache and File.exists?(@flickr.token_cache)
|
69
|
+
YAML.load_file(@flickr.token_cache)
|
70
|
+
elsif pass_through
|
71
|
+
rsp = @flickr.send_request('flickr.auth.getToken', {:frob => self.frob})
|
72
|
+
|
73
|
+
Token.new(:token => rsp.auth.token.to_s, :permisions => rsp.auth.perms.to_s, :user_id => rsp.auth.user[:nsid], :username => rsp.auth.user[:username], :user_real_name => rsp.auth.user[:fullname])
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
data/lib/flickr/base.rb
ADDED
@@ -0,0 +1,151 @@
|
|
1
|
+
module Flickr
|
2
|
+
def self.new(*params)
|
3
|
+
Flickr::Base.new(*params)
|
4
|
+
end
|
5
|
+
|
6
|
+
class Base
|
7
|
+
attr_reader :api_key, :api_secret, :token_cache, :token
|
8
|
+
|
9
|
+
REST_ENDPOINT = 'http://api.flickr.com/services/rest/'
|
10
|
+
AUTH_ENDPOINT = 'http://flickr.com/services/auth/'
|
11
|
+
UPLOAD_ENDPOINT = 'http://api.flickr.com/services/upload/'
|
12
|
+
|
13
|
+
# create a new flickr object
|
14
|
+
#
|
15
|
+
# You can either pass a hash with the following attributes:
|
16
|
+
#
|
17
|
+
# * :key (Required)
|
18
|
+
# the API key
|
19
|
+
# * :secret (Required)
|
20
|
+
# the API secret
|
21
|
+
# * :token (Optional)
|
22
|
+
# Flickr::Auth::Token object
|
23
|
+
#
|
24
|
+
# or:
|
25
|
+
#
|
26
|
+
# * config_file (Required)
|
27
|
+
# yaml file to load configuration from
|
28
|
+
# * options (Optional)
|
29
|
+
# hash containing any of the two options
|
30
|
+
# * token_cache
|
31
|
+
# location of the token cache file. This will override the setting in the config file
|
32
|
+
# * environment
|
33
|
+
# section in the config file that flickr_fu should look for the API key and secret
|
34
|
+
# Useful when using with Rails
|
35
|
+
#
|
36
|
+
# Config Example (yaml file)
|
37
|
+
# ---
|
38
|
+
# key: YOUR_API_KEY
|
39
|
+
# secret: YOUR_API_SECRET
|
40
|
+
# token_cache: token.yml
|
41
|
+
#
|
42
|
+
# Example config file with two environments:
|
43
|
+
# ---
|
44
|
+
# development:
|
45
|
+
# key: YOUR_DEVELOPMENT_API_KEY
|
46
|
+
# secret: YOUR_DEVELOPMENT_API_SECRET
|
47
|
+
# production:
|
48
|
+
# key: YOUR_PRODUCTION_API_KEY
|
49
|
+
# secret: YOUR_PRODUCTION_API_SECRET
|
50
|
+
def initialize(config_param, options_param = {})
|
51
|
+
if options_param.is_a? String
|
52
|
+
options = {:token_cache => options_param}
|
53
|
+
else
|
54
|
+
options = options_param
|
55
|
+
end
|
56
|
+
if config_param.is_a? String
|
57
|
+
config = YAML.load_file(config_param)
|
58
|
+
config = config[options[:environment]] if options.has_key? :environment
|
59
|
+
else
|
60
|
+
config = config_param
|
61
|
+
end
|
62
|
+
@api_key = config[:key] || config["key"]
|
63
|
+
@api_secret = config[:secret] || config["secret"]
|
64
|
+
@token_cache = options[:token_cache] || config["token_cache"]
|
65
|
+
@token = config[:token] || options[:token]
|
66
|
+
raise 'config file must contain an api key and secret' unless @api_key and @api_secret
|
67
|
+
raise 'you cannot specify both the token and token_cache' if @token and @token_cache
|
68
|
+
end
|
69
|
+
|
70
|
+
# sends a request to the flickr REST api
|
71
|
+
#
|
72
|
+
# Params
|
73
|
+
# * method (Required)
|
74
|
+
# name of the flickr method (ex. flickr.photos.search)
|
75
|
+
# * options (Optional)
|
76
|
+
# hash of query parameters, you do not need to include api_key, api_sig or auth_token because these are added automatically
|
77
|
+
# * http_method (Optional)
|
78
|
+
# choose between a GET and POST http request. Valid options are:
|
79
|
+
# :get (DEFAULT)
|
80
|
+
# :post
|
81
|
+
# * endpoint (Optional)
|
82
|
+
# url of the api endpoint
|
83
|
+
#
|
84
|
+
def send_request(method, options = {}, http_method = :get, endpoint = REST_ENDPOINT)
|
85
|
+
options.merge!(:api_key => @api_key, :method => method)
|
86
|
+
sign_request(options)
|
87
|
+
|
88
|
+
rsp = request_over_http(options, http_method, endpoint)
|
89
|
+
|
90
|
+
rsp = '<rsp stat="ok"></rsp>' if rsp == ""
|
91
|
+
xm = XmlMagic.new(rsp)
|
92
|
+
|
93
|
+
if xm[:stat] == 'ok'
|
94
|
+
xm
|
95
|
+
else
|
96
|
+
raise Flickr::Errors.error_for(xm.err[:code].to_i, xm.err[:msg])
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
# alters your api parameters to include a signiture and authorization token
|
101
|
+
#
|
102
|
+
# Params
|
103
|
+
# * options (Required)
|
104
|
+
# the hash of parameters to be passed to the send_request
|
105
|
+
# * authorize (Optional)
|
106
|
+
# boolean value to determine if the call with include an auth_token (Defaults to true)
|
107
|
+
#
|
108
|
+
def sign_request(options, authorize = true)
|
109
|
+
options.merge!(:auth_token => self.auth.token(false).to_s, :api_key => @api_key) if authorize and self.auth.token(false)
|
110
|
+
options.delete(:api_sig)
|
111
|
+
options.merge!(:api_sig => Digest::MD5.hexdigest(@api_secret + options.to_a.sort_by{|k| k[0].to_s}.flatten.join)) if @api_secret
|
112
|
+
end
|
113
|
+
|
114
|
+
# creates and/or returns the Flickr::Test object
|
115
|
+
def test() @test ||= Flickr::Test.new(self) end
|
116
|
+
|
117
|
+
# creates and/or returns the Flickr::Photos object
|
118
|
+
def photos() @photos ||= Flickr::Photos.new(self) end
|
119
|
+
|
120
|
+
# creates and/or returns the Flickr::Photos object
|
121
|
+
def photosets() @photosets ||= Flickr::Photosets.new(self) end
|
122
|
+
|
123
|
+
# creates and/or returns the Flickr::People object
|
124
|
+
def people() @people ||= Flickr::People.new(self) end
|
125
|
+
|
126
|
+
# creates and/or returns the Flickr::Auth object
|
127
|
+
def auth() @auth ||= Flickr::Auth.new(self) end
|
128
|
+
|
129
|
+
# creates and/or returns the Flickr::Uploader object
|
130
|
+
def uploader() @uploader ||= Flickr::Uploader.new(self) end
|
131
|
+
|
132
|
+
# creates and/or returns the Flickr::Contacts object
|
133
|
+
def contacts() @contacts ||= Flickr::Contacts.new(self) end
|
134
|
+
|
135
|
+
# creates and/or returns the Flickr::Urls object
|
136
|
+
def urls() @urls ||= Flickr::Urls.new(self) end
|
137
|
+
|
138
|
+
protected
|
139
|
+
|
140
|
+
# For easier testing. You can mock this method with a XML file you're expecting to receive
|
141
|
+
def request_over_http(options, http_method, endpoint)
|
142
|
+
if http_method == :get
|
143
|
+
api_call = endpoint + "?" + options.collect{|k,v| "#{k}=#{CGI.escape(v.to_s)}"}.join('&')
|
144
|
+
Net::HTTP.get(URI.parse(api_call))
|
145
|
+
else
|
146
|
+
Net::HTTP.post_form(URI.parse(endpoint), options).body
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|
151
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# wrapping class to hold a flickr comment
|
2
|
+
#
|
3
|
+
class Flickr::Photos::Comment
|
4
|
+
attr_accessor :id, :comment, :author, :author_name, :created_at, :permalink
|
5
|
+
|
6
|
+
# create a new instance of a flickr comment.
|
7
|
+
#
|
8
|
+
# Params
|
9
|
+
# * attributes (Required)
|
10
|
+
# a hash of attributes used to set the initial values of the comment object
|
11
|
+
def initialize(attributes)
|
12
|
+
attributes.each do |k,v|
|
13
|
+
send("#{k}=", v)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# wrapping class to hold a flickr contact
|
2
|
+
#
|
3
|
+
class Flickr::Contacts::Contact
|
4
|
+
attr_accessor :nsid, :friend, :family, :iconfarm, :iconserver, :location, :username, :ignored, :realname, :path_alias
|
5
|
+
|
6
|
+
# create a new instance of a flickr note.
|
7
|
+
#
|
8
|
+
# Params
|
9
|
+
# * attributes (Required)
|
10
|
+
# a hash of attributes used to set the initial values of the contact object
|
11
|
+
def initialize(attributes)
|
12
|
+
attributes.each do |k,v|
|
13
|
+
send("#{k}=", v)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
class Flickr::Contacts < Flickr::Base
|
2
|
+
def initialize(flickr)
|
3
|
+
@flickr = flickr
|
4
|
+
end
|
5
|
+
|
6
|
+
# Get a user's public contact list.
|
7
|
+
#
|
8
|
+
# Params
|
9
|
+
# * id (Required)
|
10
|
+
# the nsid of the user to get information for
|
11
|
+
#
|
12
|
+
def get_public_list(id, options={})
|
13
|
+
options.merge!({:user_id => id})
|
14
|
+
rsp = @flickr.send_request('flickr.contacts.getPublicList', options)
|
15
|
+
collect_contacts(rsp)
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
# Get the authorized user's contact list.
|
20
|
+
#
|
21
|
+
def get_list(options={})
|
22
|
+
rsp = @flickr.send_request('flickr.contacts.getList', options)
|
23
|
+
collect_contacts(rsp)
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
protected
|
28
|
+
def collect_contacts(rsp)
|
29
|
+
contacts = []
|
30
|
+
return contacts unless rsp
|
31
|
+
if rsp.contacts.contact
|
32
|
+
rsp.contacts.contact.each do |contact|
|
33
|
+
attributes = create_attributes(contact)
|
34
|
+
contacts << Contact.new(attributes)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
return contacts
|
38
|
+
end
|
39
|
+
|
40
|
+
def create_attributes(contact)
|
41
|
+
{
|
42
|
+
:nsid => contact[:nsid],
|
43
|
+
:path_alias => contact[:path_alias],
|
44
|
+
:username => contact[:username],
|
45
|
+
:iconfarm => contact[:iconfarm],
|
46
|
+
:iconserver => contact[:iconserver],
|
47
|
+
:ignored => contact[:ignored],
|
48
|
+
:friend => contact[:friend],
|
49
|
+
:family => contact[:family],
|
50
|
+
:realname => contact[:realname],
|
51
|
+
:location => contact[:location]
|
52
|
+
}
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Flickr
|
2
|
+
class Error < RuntimeError
|
3
|
+
attr_accessor :code
|
4
|
+
end
|
5
|
+
|
6
|
+
|
7
|
+
class Errors
|
8
|
+
|
9
|
+
# Method used for raising the appropriate error class for a given error code.
|
10
|
+
# Currently raises only Flickr::Error
|
11
|
+
def self.error_for(code, message)
|
12
|
+
raise RuntimeError.new("Internal error. Flickr API error not identified or unknown error.") if (code.nil? || message.nil? || message.empty?)
|
13
|
+
raise RuntimeError.new("Internal error. Unknown error.") if code.to_i == 0 # We assume that error code 0 is never returned
|
14
|
+
e = Flickr::Error.new("#{code}: #{message}")
|
15
|
+
e.code = code
|
16
|
+
raise e
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
data/lib/flickr/geo.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
class Flickr::Photos::Geo < Flickr::Base
|
2
|
+
|
3
|
+
def initialize(flickr)
|
4
|
+
@flickr = flickr
|
5
|
+
end
|
6
|
+
|
7
|
+
# Get the geo data (latitude and longitude and the accuracy level) of a photo.
|
8
|
+
#
|
9
|
+
# Params
|
10
|
+
# * photo_id (Required)
|
11
|
+
#
|
12
|
+
# Returns Flickr::Photos::Location object containing photo location
|
13
|
+
# or nil if photo is not geotagged.
|
14
|
+
def get_location(photo_id)
|
15
|
+
# begin
|
16
|
+
rsp = @flickr.send_request('flickr.photos.geo.getLocation', {:photo_id => photo_id})
|
17
|
+
Flickr::Photos::Location.new(:latitude => rsp.photo.location[:latitude].to_f,
|
18
|
+
:longitude => rsp.photo.location[:longitude].to_f, :accuracy => rsp.photo.location[:accuracy].to_i)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Sets the geo data(latitude and longitude and the accuracy level) of a photo.
|
22
|
+
#
|
23
|
+
# Params
|
24
|
+
# * photo_id (Required)
|
25
|
+
# * latittude (Requried)
|
26
|
+
# * longitude (Required)
|
27
|
+
# * accuracy (Optional)
|
28
|
+
#
|
29
|
+
# Returns true if successful, raises an error otherwise.
|
30
|
+
def set_location(photo_id, lat, lon, accuracy = nil)
|
31
|
+
request_options = {:photo_id => photo_id, :lat => lat, :lon => lon}
|
32
|
+
request_options[:accuracy] = accuracy if !accuracy.nil?
|
33
|
+
@flickr.send_request('flickr.photos.geo.setLocation', request_options, :post)
|
34
|
+
true
|
35
|
+
end
|
36
|
+
|
37
|
+
def remove_location(photo_id)
|
38
|
+
request_options = {:photo_id => photo_id}
|
39
|
+
@flickr.send_request('flickr.photos.geo.removeLocation', request_options, :post)
|
40
|
+
true
|
41
|
+
end
|
42
|
+
end
|