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.
Files changed (68) hide show
  1. data/.gitignore +13 -0
  2. data/LICENSE +22 -0
  3. data/README +182 -0
  4. data/Rakefile +73 -0
  5. data/VERSION.yml +4 -0
  6. data/lib/flickr/auth.rb +76 -0
  7. data/lib/flickr/base.rb +151 -0
  8. data/lib/flickr/comment.rb +16 -0
  9. data/lib/flickr/contact.rb +16 -0
  10. data/lib/flickr/contacts.rb +55 -0
  11. data/lib/flickr/errors.rb +20 -0
  12. data/lib/flickr/geo.rb +42 -0
  13. data/lib/flickr/license.rb +24 -0
  14. data/lib/flickr/location.rb +15 -0
  15. data/lib/flickr/note.rb +16 -0
  16. data/lib/flickr/people.rb +54 -0
  17. data/lib/flickr/person.rb +82 -0
  18. data/lib/flickr/photo.rb +333 -0
  19. data/lib/flickr/photo_response.rb +37 -0
  20. data/lib/flickr/photos.rb +277 -0
  21. data/lib/flickr/photoset.rb +37 -0
  22. data/lib/flickr/photosets.rb +39 -0
  23. data/lib/flickr/size.rb +16 -0
  24. data/lib/flickr/status.rb +19 -0
  25. data/lib/flickr/test.rb +31 -0
  26. data/lib/flickr/token.rb +22 -0
  27. data/lib/flickr/uploader.rb +162 -0
  28. data/lib/flickr/urls.rb +44 -0
  29. data/lib/flickr_fu.rb +51 -0
  30. data/spec/fixtures/flickr/contacts/get_list-fail-99.xml +4 -0
  31. data/spec/fixtures/flickr/contacts/get_public_list-0.xml +7 -0
  32. data/spec/fixtures/flickr/photos/geo/get_location-0.xml +11 -0
  33. data/spec/fixtures/flickr/photos/geo/get_location-fail-2.xml +4 -0
  34. data/spec/fixtures/flickr/photos/get_info-0.xml +41 -0
  35. data/spec/fixtures/flickr/photos/get_info-1.xml +19 -0
  36. data/spec/fixtures/flickr/photos/get_sizes-0.xml +10 -0
  37. data/spec/fixtures/flickr/photos/get_sizes-1.xml +8 -0
  38. data/spec/fixtures/flickr/photos/licenses/get_info.xml +12 -0
  39. data/spec/fixtures/flickr/photosets/get_list-0.xml +13 -0
  40. data/spec/fixtures/flickr/photosets/get_photos-0.xml +7 -0
  41. data/spec/fixtures/flickr/test/echo-0.xml +5 -0
  42. data/spec/fixtures/flickr/test/null-fail-99.xml +4 -0
  43. data/spec/fixtures/flickr/urls/get_group-0.xml +4 -0
  44. data/spec/fixtures/flickr/urls/get_group-fail-1.xml +4 -0
  45. data/spec/fixtures/flickr/urls/get_user_photos-0.xml +4 -0
  46. data/spec/fixtures/flickr/urls/get_user_photos-fail-1.xml +4 -0
  47. data/spec/fixtures/flickr/urls/get_user_photos-fail-2.xml +4 -0
  48. data/spec/fixtures/flickr/urls/get_user_profile-0.xml +4 -0
  49. data/spec/fixtures/flickr/urls/get_user_profile-fail-1.xml +4 -0
  50. data/spec/fixtures/flickr/urls/get_user_profile-fail-2.xml +4 -0
  51. data/spec/fixtures/flickr/urls/lookup_group-0.xml +6 -0
  52. data/spec/fixtures/flickr/urls/lookup_group-fail-1.xml +4 -0
  53. data/spec/fixtures/flickr/urls/lookup_user-0.xml +6 -0
  54. data/spec/fixtures/flickr/videos/get_info-0.xml +31 -0
  55. data/spec/fixtures/flickr/videos/get_sizes-0.xml +13 -0
  56. data/spec/flickr/base_spec.rb +97 -0
  57. data/spec/flickr/contacts_spec.rb +47 -0
  58. data/spec/flickr/errors_spec.rb +21 -0
  59. data/spec/flickr/geo_spec.rb +20 -0
  60. data/spec/flickr/photo_spec.rb +140 -0
  61. data/spec/flickr/photos_spec.rb +50 -0
  62. data/spec/flickr/photosets_spec.rb +49 -0
  63. data/spec/flickr/test_spec.rb +34 -0
  64. data/spec/flickr/urls_spec.rb +99 -0
  65. data/spec/spec.opts +4 -0
  66. data/spec/spec_helper.rb +20 -0
  67. data/tomk32-flickr_fu.gemspec +121 -0
  68. metadata +151 -0
data/.gitignore ADDED
@@ -0,0 +1,13 @@
1
+ rdoc
2
+ .DS_Store
3
+ *.gem
4
+ demo*
5
+ *~
6
+ *.sw*
7
+ .specification
8
+ nbproject/
9
+ doc/rspec_report.html
10
+ doc/rspec_profile.txt
11
+ spec/spec.local.opts
12
+ coverage/
13
+ pkg/
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
@@ -0,0 +1,4 @@
1
+ ---
2
+ :major: 0
3
+ :minor: 3
4
+ :patch: 0
@@ -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
@@ -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