flickr_fu 0.1.6

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/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,110 @@
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
+ == Authorization
27
+
28
+ To authorise your application to access Flickr using your API key you will
29
+ need to access a specific URL.
30
+
31
+ To generate this URL run the following and when presented with the URL
32
+ access it from your browser. Confirm the application has permission at
33
+ the level you have specified.
34
+
35
+ Finally, cache the token (this will create the token cache file)
36
+
37
+ If you have an invalid API key you will see errors such as:
38
+
39
+ "100: Invalid API Key"
40
+
41
+ If you don't follow the process below to authorise your application
42
+ you will see errors such as:
43
+
44
+ "98: Login failed / Invalid auth token" or
45
+ "99: User not logged in / Insufficient permissions"
46
+
47
+ == Authorization Example
48
+
49
+ require 'flickr_fu'
50
+
51
+ flickr = Flickr.new('flickr.yml')
52
+
53
+ puts "visit the following url, then click <enter> once you have authorized:"
54
+
55
+ # request write permissions
56
+ puts flickr.auth.url(:write)
57
+
58
+ gets
59
+
60
+ flickr.auth.cache_token
61
+
62
+ == Search Example
63
+
64
+ require 'flickr_fu'
65
+
66
+ flickr = Flickr.new('flickr.yml')
67
+
68
+ photos = flickr.photos.search(:tags => 'ruby-flickr')
69
+
70
+ puts "found #{photos.size} photo(s)"
71
+
72
+ photos.each do |photo|
73
+ puts photo.title
74
+ puts photo.description unless [nil, ''].include?(photo.description)
75
+ [:square, :thumbnail, :small, :medium, :large, :original].each do |size|
76
+ puts "#{size}: #{photo.url(size)}"
77
+ end
78
+ puts "comments: #{photo.comments.size}"
79
+ photo.comments.each do |comment|
80
+ intro = "#{comment.author_name} says - "
81
+ puts "#{intro}\"#{comment.comment.gsub("\n", "\n"+(" "*intro.length))}\""
82
+ end
83
+ puts "notes: #{photo.notes.size}"
84
+ photo.notes.each do |note|
85
+ puts "[#{note.x},#{note.y} ~ #{note.width}x#{note.height}] - \"#{note.note}\""
86
+ end
87
+ puts
88
+ puts
89
+ end
90
+
91
+ == Another Search Example
92
+
93
+ If searching for photos by user id then you need to specify the 'alias' - without
94
+ intervention this is usually set by Flickr and is an alphanumeric string.
95
+
96
+ To find out the user id for a given user, you can use the tool at:
97
+
98
+ http://idgettr.com/
99
+
100
+ And replace the line in the above sample to query on user id:
101
+
102
+ photos = flickr.photos.search(:user_id => 'your_user_id_here')
103
+
104
+ == Patch Contributers
105
+
106
+ Chris Ledet
107
+ Maciej Biłas
108
+ Mike Perham
109
+ Chris Anderton
110
+ Luke Francl
@@ -0,0 +1,22 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+
5
+ desc 'Default: run unit tests.'
6
+ task :default => :test
7
+
8
+ desc 'Test the contact_info plugin.'
9
+ Rake::TestTask.new(:test) do |t|
10
+ t.libs << 'lib'
11
+ t.pattern = 'test/**/*_test.rb'
12
+ t.verbose = true
13
+ end
14
+
15
+ desc 'Generate documentation for the contact_info plugin.'
16
+ Rake::RDocTask.new(:rdoc) do |rdoc|
17
+ rdoc.rdoc_dir = 'rdoc'
18
+ rdoc.title = 'ruby-flickr'
19
+ rdoc.options << '--line-numbers' << '--inline-source'
20
+ rdoc.rdoc_files.include('README')
21
+ rdoc.rdoc_files.include('lib/**/*.rb')
22
+ end
@@ -0,0 +1,35 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = "flickr_fu"
3
+ s.version = "0.1.6"
4
+ s.date = "2008-09-12"
5
+ s.summary = "Provides a ruby interface to flickr via the REST api"
6
+ s.email = "ben@commonthread.com"
7
+ s.homepage = "http://github.com/commonthread/flickr_fu"
8
+ s.description = "Provides a ruby interface to flickr via the REST api"
9
+ s.has_rdoc = true
10
+ s.authors = ["Ben Wyrosdick"]
11
+ s.files = ["README",
12
+ "LICENSE",
13
+ "Rakefile",
14
+ "flickr_fu.gemspec",
15
+ "lib/flickr/auth.rb",
16
+ "lib/flickr/base.rb",
17
+ "lib/flickr/comment.rb",
18
+ "lib/flickr/license.rb",
19
+ "lib/flickr/note.rb",
20
+ "lib/flickr/people.rb",
21
+ "lib/flickr/person.rb",
22
+ "lib/flickr/photo.rb",
23
+ "lib/flickr/photo_response.rb",
24
+ "lib/flickr/photos.rb",
25
+ "lib/flickr/size.rb",
26
+ "lib/flickr/status.rb",
27
+ "lib/flickr/test.rb",
28
+ "lib/flickr/token.rb",
29
+ "lib/flickr/uploader.rb",
30
+ "lib/flickr_fu.rb"]
31
+ s.rdoc_options = ["--main", "README"]
32
+ s.extra_rdoc_files = ["README"]
33
+ s.add_dependency("mime-types", ["> 0.0.0"])
34
+ s.add_dependency("xml-magic", ["> 0.0.0"])
35
+ end
@@ -0,0 +1,69 @@
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
+ # generates the authorization url to allow access to a flickr account.
12
+ #
13
+ # Params
14
+ # * perms (Optional)
15
+ # sets the permision level to grant on the flickr account.
16
+ # :read - permission to read private information (DEFAULT)
17
+ # :write - permission to add, edit and delete photo metadata (includes 'read')
18
+ # :delete - permission to delete photos (includes 'write' and 'read')
19
+ #
20
+ def url(perms = :read)
21
+ options = {:api_key => @flickr.api_key, :perms => perms, :frob => self.frob}
22
+ @flickr.sign_request(options)
23
+ Flickr::Base::AUTH_ENDPOINT + "?" + options.collect{|k,v| "#{k}=#{v}"}.join('&')
24
+ end
25
+
26
+ # gets the token object for the current frob
27
+ #
28
+ # Params
29
+ # * pass_through (Optional)
30
+ # Boolean value that determines if a call will be made to flickr to find a taken for the current frob if empty
31
+ #
32
+ def token(pass_through = true)
33
+ @token ||= get_token(pass_through) rescue nil
34
+ end
35
+
36
+ # saves the current token to the cache file if token exists
37
+ #
38
+ # Param
39
+ # * filename (Optional)
40
+ # filename of the cache file. defaults to the file passed into Flickr.new
41
+ #
42
+ def cache_token(filename = @flickr.token_cache)
43
+ if filename and self.token
44
+ cache_file = File.open(filename, 'w+')
45
+ cache_file.puts self.token.to_yaml
46
+ cache_file.close
47
+ true
48
+ else
49
+ false
50
+ end
51
+ end
52
+
53
+ private
54
+ def get_frob
55
+ rsp = @flickr.send_request('flickr.auth.getFrob')
56
+
57
+ rsp.frob.to_s
58
+ end
59
+
60
+ def get_token(pass_through)
61
+ if @flickr.token_cache and File.exists?(@flickr.token_cache)
62
+ YAML.load_file(@flickr.token_cache)
63
+ elsif pass_through
64
+ rsp = @flickr.send_request('flickr.auth.getToken', {:frob => self.frob})
65
+
66
+ 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])
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,102 @@
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
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
+ # Params
16
+ # * config_file (Required)
17
+ # yaml file to load configuration from
18
+ # * token_cache (Optional)
19
+ # location of the token cache file. This will override the setting in the config file
20
+ #
21
+ # Config Example (yaml file)
22
+ #
23
+ # ---
24
+ # key: YOUR_API_KEY
25
+ # secret: YOUR_API_SECRET
26
+ # token_cache: token.yml
27
+ #
28
+ def initialize(config_file, token_cache = nil)
29
+ config = YAML.load_file(config_file)
30
+
31
+ @api_key = config['key']
32
+ @api_secret = config['secret']
33
+ @token_cache = token_cache || config['token_cache']
34
+
35
+ raise 'flickr config file must contain an api key and secret' unless @api_key and @api_secret
36
+ end
37
+
38
+ # sends a request to the flcikr REST api
39
+ #
40
+ # Params
41
+ # * method (Required)
42
+ # name of the flickr method (ex. flickr.photos.search)
43
+ # * options (Optional)
44
+ # hash of query parameters, you do not need to include api_key, api_sig or auth_token because these are added automatically
45
+ # * http_method (Optional)
46
+ # choose between a GET and POST http request. Valid options are:
47
+ # :get (DEFAULT)
48
+ # :post
49
+ # * endpoint (Optional)
50
+ # url of the api endpoint
51
+ #
52
+ def send_request(method, options = {}, http_method = :get, endpoint = REST_ENDPOINT)
53
+ options.merge!(:api_key => @api_key, :method => method)
54
+ sign_request(options)
55
+
56
+ if http_method == :get
57
+ api_call = endpoint + "?" + options.collect{|k,v| "#{k}=#{CGI.escape(v.to_s)}"}.join('&')
58
+ rsp = Net::HTTP.get(URI.parse(api_call))
59
+ else
60
+ rsp = Net::HTTP.post_form(URI.parse(endpoint), options).body
61
+ end
62
+
63
+ rsp = '<rsp stat="ok"></rsp>' if rsp == ""
64
+ xm = XmlMagic.new(rsp)
65
+
66
+ if xm[:stat] == 'ok'
67
+ xm
68
+ else
69
+ raise "#{xm.err[:code]}: #{xm.err[:msg]}"
70
+ end
71
+ end
72
+
73
+ # alters your api parameters to include a signiture and authorization token
74
+ #
75
+ # Params
76
+ # * options (Required)
77
+ # the hash of parameters to be passed to the send_request
78
+ # * authorize (Optional)
79
+ # boolean value to determine if the call with include an auth_token (Defaults to true)
80
+ #
81
+ def sign_request(options, authorize = true)
82
+ options.merge!(:auth_token => self.auth.token(false).to_s, :api_key => @api_key) if authorize and self.auth.token(false)
83
+ options.delete(:api_sig)
84
+ options.merge!(:api_sig => Digest::MD5.hexdigest(@api_secret + options.to_a.sort_by{|k| k[0].to_s}.flatten.join)) if @api_secret
85
+ end
86
+
87
+ # creates and/or returns the Flickr::Test object
88
+ def test() @test ||= Flickr::Test.new(self) end
89
+
90
+ # creates and/or returns the Flickr::Photos object
91
+ def photos() @photos ||= Flickr::Photos.new(self) end
92
+
93
+ # creates and/or returns the Flickr::People object
94
+ def people() @people ||= Flickr::People.new(self) end
95
+
96
+ # creates and/or returns the Flickr::Auth object
97
+ def auth() @auth ||= Flickr::Auth.new(self) end
98
+
99
+ # creates and/or returns the Flickr::Uploader object
100
+ def uploader() @uploader ||= Flickr::Uploader.new(self) end
101
+ end
102
+ 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,14 @@
1
+ class Flickr::Photos::License
2
+ attr_accessor :id, :name, :url
3
+
4
+ # create a new instance of a flickr photo license.
5
+ #
6
+ # Params
7
+ # * attributes (Required)
8
+ # a hash of attributes used to set the initial values of the license object
9
+ def initialize(attributes)
10
+ attributes.each do |k,v|
11
+ send("#{k}=", v)
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,16 @@
1
+ # wrapping class to hold a flickr note
2
+ #
3
+ class Flickr::Photos::Note
4
+ attr_accessor :id, :note, :author, :author_name, :x, :y, :width, :height
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 note object
11
+ def initialize(attributes)
12
+ attributes.each do |k,v|
13
+ send("#{k}=", v)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,54 @@
1
+ class Flickr::People < Flickr::Base
2
+ def initialize(flickr)
3
+ @flickr = flickr
4
+ end
5
+
6
+ # Get information about a user.
7
+ #
8
+ # Params
9
+ # * id (Required)
10
+ # the nsid of the user to get information for
11
+ #
12
+ def find_by_id(id)
13
+ rsp = @flickr.send_request('flickr.people.getInfo', {:user_id => id})
14
+
15
+ Person.new(@flickr, :nsid => rsp.person[:nsid],
16
+ :is_admin => (rsp.person[:isadmin] == "1" ? true : false),
17
+ :is_pro => (rsp.person[:ispro] == "1" ? true : false),
18
+ :icon_server => rsp.person[:iconserver],
19
+ :icon_farm => rsp.person[:iconfarm],
20
+ :username => rsp.person.username.to_s,
21
+ :realname => rsp.person.realname.to_s,
22
+ :mbox_sha1sum => rsp.person.mbox_sha1sum.to_s,
23
+ :location => rsp.person.location.to_s,
24
+ :photos_url => rsp.person.photosurl.to_s,
25
+ :profile_url => rsp.person.profileurl.to_s,
26
+ :photo_count => rsp.person.photos.count.to_s.to_i,
27
+ :photo_first_upload => (Time.at(rsp.person.photos.firstdate.to_s.to_i) rescue nil),
28
+ :photo_first_taken => (Time.parse(rsp.person.photos.firstdatetaken.to_s) rescue nil))
29
+ end
30
+
31
+ # Get information about a user.
32
+ #
33
+ # Params
34
+ # * username (Required)
35
+ # the username of the user to get information for
36
+ #
37
+ def find_by_username(username)
38
+ rsp = @flickr.send_request('flickr.people.findByUsername', {:username => username})
39
+
40
+ find_by_id(rsp.user[:nsid])
41
+ end
42
+
43
+ # Get information about a user.
44
+ #
45
+ # Params
46
+ # * email (Required)
47
+ # the email of the user to get information for
48
+ #
49
+ def find_by_email(email)
50
+ rsp = @flickr.send_request('flickr.people.findByEmail', {:find_email => email})
51
+
52
+ find_by_id(rsp.user[:nsid])
53
+ end
54
+ end