flickrrb 1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc ADDED
@@ -0,0 +1,29 @@
1
+ = Flickrrb
2
+
3
+ Flickrrb is a library to access flickr[http://flickr.com] api in a simple way.
4
+ It tries to map the methods described in {the official api documentation}[http://www.flickr.com/services/api].
5
+
6
+
7
+ = Installation
8
+ gem install flickrrb
9
+
10
+ = Usage
11
+
12
+ input = IO::popen('pbpaste').read
13
+
14
+ # matches the photo id eg 3249240923
15
+ # or the url eg http://www.flickr.com/photos/jump_leads/3249240923/
16
+ photo_id = input.match('/?(\d+)/?$')[1]
17
+
18
+ flickr = Flickr.new :api_key => "9d96d3ae6145f12660896ae23b33f949"#, :debug => true
19
+ sizes = flickr.photos.getSizes(:photo_id => photo_id)
20
+
21
+ sizes.each do |s|
22
+ p "#{s.label} - #{s.source}"
23
+ end
24
+
25
+ == Todo
26
+ * Access sizes nicely.
27
+ * Maybe use JSON instead of xml responses.
28
+ * Auth.
29
+ * Handle ids nicer.
data/Rakefile ADDED
@@ -0,0 +1,32 @@
1
+ require 'rake/testtask'
2
+ require 'rake/rdoctask'
3
+ #require 'rake/packagetask'
4
+ require 'rake/gempackagetask'
5
+
6
+
7
+ Rake::TestTask.new 'test' do |t|
8
+ t.pattern = 'test/*.rb'
9
+ end
10
+
11
+ spec = Gem::Specification.new do |s|
12
+ s.summary = "Another Flickr Interface."
13
+ s.description = "A simple interface to the Flickr public API."
14
+ s.name = "flickrrb"
15
+ s.author = "Henry Maddocks"
16
+ s.email = "henry.maddocks@gmail.com"
17
+ s.homepage = ""
18
+ s.version = "1.0"
19
+ s.files = FileList["lib/flickrrb.rb", "copying.txt", "README.rdoc", "Rakefile", "test/*.rb"].to_a
20
+ s.test_files = FileList["test/*.rb"].to_a
21
+ end
22
+
23
+ Rake::RDocTask.new do |rd|
24
+ rd.rdoc_files.include "README.rdoc", "lib/flickrrb.rb"
25
+ rd.options << "--inline-source"
26
+ end
27
+
28
+ Rake::GemPackageTask.new spec do |p|
29
+ p.need_tar_gz = true
30
+ end
31
+
32
+ task 'default' => ['test']
data/copying.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2009 Henry Maddocks
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/lib/flickrrb.rb ADDED
@@ -0,0 +1,248 @@
1
+ require 'net/http'
2
+ require 'cgi'
3
+ require 'rexml/document'
4
+
5
+ class APIException < StandardError; end
6
+
7
+ class Flickr
8
+ FlickrMethod = Struct.new(:name, :args)
9
+
10
+ def initialize option = {} #api_key, debug = false
11
+ @debug = option[:debug].nil? ? false : option[:debug]
12
+
13
+ @flickr_client = FlickrClient.new option[:http], @debug
14
+ @api_key = option[:api_key]
15
+ @method = []
16
+ end
17
+
18
+ def method_missing name, *args
19
+ # raise APIException, "Args must be a hash" unless args.first.kind_of?(Hash)
20
+ m = FlickrMethod.new(name, args.first)
21
+ @method << m
22
+ unless args.empty?
23
+ p @method if @debug == true
24
+ begin
25
+ command = build_command
26
+ @method = []
27
+ @flickr_client.send(command)
28
+ rescue
29
+ @method = []
30
+ raise
31
+ end
32
+ else
33
+ self
34
+ end
35
+ end
36
+
37
+ # private
38
+
39
+ def build_command
40
+ method = "flickr"
41
+ args = {}
42
+
43
+ @method.each do |m|
44
+ method << ".#{m.name.to_s}"
45
+ args.merge!(m.args) unless m.args.nil?
46
+ end
47
+
48
+ a = args.keys.collect do |k|
49
+ "#{k.to_s}=#{CGI.escape(args[k])}"
50
+ end.join('&')
51
+
52
+ "?method=#{method}&api_key=#{@api_key}&#{a}"
53
+ end
54
+
55
+ def send command
56
+ @flickr_client.send command
57
+ end
58
+
59
+ class Group
60
+ attr :id
61
+ attr :name
62
+ attr :description
63
+ attr :members
64
+
65
+ def initialize xml
66
+ if xml.elements['name'].nil?
67
+ init_from_attributes xml
68
+ else
69
+ init_from_elements xml
70
+ end
71
+ end
72
+
73
+ def init_from_attributes xml
74
+ @id = xml.attributes['nsid']
75
+ @name = xml.attributes['name']
76
+ end
77
+
78
+ def init_from_elements xml
79
+ @id = xml.attributes['id']
80
+ @name = xml.elements['name'].text
81
+ @description = xml.elements['description'].text
82
+ @members = xml.elements['members'].text
83
+ end
84
+ end
85
+
86
+ class Photo
87
+ attr :id
88
+ attr :owner_real_name
89
+ attr :owner_user_name
90
+ attr :owner
91
+ attr :title
92
+ attr :candownload
93
+ attr :description
94
+ attr :tags
95
+ attr :date
96
+
97
+ def initialize xml
98
+ @id = xml.attributes['id']
99
+ @owner_user_name = xml.attributes['ownername']
100
+ @owner = xml.attributes['owner']
101
+ @title = xml.attributes['title']
102
+
103
+ if @title.nil?
104
+ @owner_real_name = xml.elements['owner'].attributes['realname']
105
+ @owner_user_name = xml.elements['owner'].attributes['username']
106
+ @owner = xml.elements['owner'].attributes['nsid']
107
+ @title = xml.elements['title'].text
108
+ @description = xml.elements['description'].text
109
+ @date = xml.elements['dates'].attributes['taken']
110
+
111
+ @tags = []
112
+ xml.elements.each('tags/tag') do |t|
113
+ @tags << t.text
114
+ end
115
+ end
116
+
117
+ # <usage candownload='1' canblog='0' canprint='0'/>
118
+ end
119
+
120
+ def inspect
121
+ "id; #{@id}\n \
122
+ title; #{@title}\n \
123
+ description; #{@description}\n \
124
+ user name; #{@owner_user_name}\n \
125
+ real name; #{@owner_real_name}\n \
126
+ date; #{@date}\n \
127
+ tags; #{@tags.inspect}"
128
+ end
129
+ end
130
+
131
+ class Size
132
+ attr :label
133
+ attr :width
134
+ attr :height
135
+ attr :source
136
+ attr :url
137
+
138
+ def initialize xml
139
+ @label = xml.attributes['label']
140
+ @width = xml.attributes['width']
141
+ @height = xml.attributes['height']
142
+ @source = xml.attributes['source']
143
+ @url = xml.attributes['url']
144
+ end
145
+ end
146
+
147
+ class Person
148
+ attr :id
149
+ attr :username
150
+ attr :realname
151
+ attr :ispro
152
+ attr :location
153
+ attr :photosurl
154
+ attr :profileurl
155
+ attr :photos_count
156
+
157
+ def initialize xml
158
+ @id = xml.attributes['id']
159
+ @ispro = xml.attributes['ispro']
160
+ @username = xml.elements['username'].text
161
+ unless xml.elements['realname'].nil?
162
+ @realname = xml.elements['realname'].text
163
+ @location = xml.elements['location'].text
164
+ @photosurl = xml.elements['photosurl'].text
165
+ @profileurl = xml.elements['profileurl'].text
166
+ @photos_count = xml.elements['photos'].elements['count'].text
167
+ end
168
+ end
169
+ end
170
+
171
+ class FlickrClient
172
+ def initialize http = nil, debug = false
173
+ flickr_url = URI.parse "http://api.flickr.com/"
174
+
175
+ if http.nil?
176
+ @flickr_client = Net::HTTP.new flickr_url.host, flickr_url.port
177
+ else
178
+ @flickr_client = http
179
+ end
180
+ @debug = debug
181
+ end
182
+
183
+ def send command
184
+ p "/services/rest/#{command}" if @debug
185
+ build_response(@flickr_client.get("/services/rest/#{command}").body)
186
+ end
187
+
188
+ def build_response xml
189
+ p xml if @debug
190
+ doc = REXML::Document.new(xml, { 'ForceArray' => false })
191
+ raise APIException, "Invalid response from Flickr" if doc.root.nil?
192
+ resp = []
193
+ if doc.root.attributes["stat"] == "ok"
194
+ doc.root.elements.each {|e| resp << self.__send__(e.name.to_sym, e)}
195
+ else
196
+ handle_error doc
197
+ end
198
+
199
+ resp.first
200
+ end
201
+
202
+ def handle_error xml
203
+ # This is a bit ugly!
204
+ message = xml.elements['rsp'].elements['err'].attributes['msg']
205
+ raise APIException, message
206
+ end
207
+
208
+ def groups xml
209
+ xml.elements.collect do |g|
210
+ group g
211
+ end
212
+ end
213
+
214
+ def group xml
215
+ Group.new xml
216
+ end
217
+
218
+ def photos xml
219
+ pages = xml.attributes['pages']
220
+ total = xml.attributes['total']
221
+ photos = xml.elements.collect do |p|
222
+ Photo.new p
223
+ end
224
+
225
+ return photos, pages.to_i, total.to_i
226
+ end
227
+
228
+ def photo xml
229
+ Photo.new xml
230
+ end
231
+
232
+ def sizes xml
233
+ xml.elements.collect do |p|
234
+ Size.new p
235
+ end
236
+ end
237
+
238
+ def user xml
239
+ Person.new xml
240
+ end
241
+
242
+ def person xml
243
+ Person.new xml
244
+ end
245
+ end
246
+
247
+ end
248
+
@@ -0,0 +1,225 @@
1
+ require 'test/unit'
2
+ require 'flickrrb'
3
+
4
+ class Test_Flickr < Test::Unit::TestCase
5
+ def setup
6
+ api_key = "ef7e560f32e57e0f5328db98a93b5ac9"
7
+ @flickr = Flickr.new :api_key => api_key
8
+ end
9
+
10
+ def test_api_key_exception
11
+ flickr = Flickr.new :api_key => "bad_key"
12
+ assert_raise APIException do
13
+ flickr.photos.getInfo(:photo_id => '1848466274')
14
+ end
15
+ end
16
+
17
+ def test_groups_pools_getPhotos
18
+ groups_photos, pages, total = @flickr.groups.pools.getPhotos :user_id => "12656878@N06", :group_id => "99404851@N00"
19
+
20
+ assert_equal 12, groups_photos.length
21
+ assert_equal 1, pages
22
+ assert_equal 12, total
23
+
24
+
25
+ groups_photos.each do |photo|
26
+ assert_equal 'Henry Maddocks', photo.owner_user_name
27
+ end
28
+ end
29
+
30
+ def test_create_objects
31
+ xml = <<EOS
32
+ <?xml version="1.0" encoding="utf-8" ?> \
33
+ <rsp stat="ok"> \
34
+ <photos page="1" pages="1" perpage="100" total="4"> \
35
+ <photo id="1848466274" owner="12656878@N06" secret="cec90f64ba" server="2402" farm="3" title="IMG_5631_2_3" ispublic="1" isfriend="0" isfamily="0" ownername="henry.maddocks" dateadded="1194217745" /> \
36
+ <photo id="1847626991" owner="12656878@N06" secret="a4d0774b17" server="2022" farm="3" title="IMG_5574_5_6" ispublic="1" isfriend="0" isfamily="0" ownername="henry.maddocks" dateadded="1194128771" /> \
37
+ <photo id="1847633163" owner="12656878@N06" secret="5089075c7a" server="2008" farm="3" title="IMG_5598_599_600" ispublic="1" isfriend="0" isfamily="0" ownername="henry.maddocks" dateadded="1194128720" /> \
38
+ <photo id="1848469604" owner="12656878@N06" secret="e0f8cfeab2" server="2140" farm="3" title="IMG_5646_7_8" ispublic="1" isfriend="0" isfamily="0" ownername="henry.maddocks" dateadded="1194128674" /> \
39
+ </photos> \
40
+ </rsp>
41
+ EOS
42
+
43
+ flickr = Flickr::FlickrClient.new
44
+
45
+ photos, pages, total = flickr.build_response xml
46
+
47
+ assert_equal 4, photos.length
48
+ assert_equal 1, pages
49
+ assert_equal 4, total
50
+ assert_equal "IMG_5598_599_600", photos[2].title
51
+ end
52
+
53
+ def test_photos_getInfo
54
+ photo = @flickr.photos.getInfo(:photo_id => '1848466274')
55
+
56
+ assert_equal "1848466274", photo.id
57
+ assert_equal "IMG_5631_2_3", photo.title
58
+
59
+ end
60
+
61
+ def test_get_sizes
62
+ sizes = @flickr.photos.getSizes(:photo_id => '1848466274')
63
+
64
+ assert_equal 5, sizes.length
65
+ assert_equal 1280, sizes[4].width.to_i
66
+ assert_equal 'Original', sizes[4].label
67
+ end
68
+
69
+ def test_get_people_by_user_name
70
+ me = @flickr.people.findByUsername(:username => 'Henry Maddocks')
71
+ assert_equal '12656878@N06', me.id
72
+
73
+ b = @flickr.people.findByUsername(:username => 'Brenda Anderson')
74
+ assert_equal '69005233@N00', b.id
75
+ end
76
+
77
+ def test_all_together
78
+ groups_photos, pages, total = @flickr.groups.pools.getPhotos :user_id => "12656878@N06", :group_id => "99404851@N00"
79
+
80
+ groups_photos.each do |photo|
81
+ @flickr.photos.getSizes(:photo_id => photo.id)
82
+ end
83
+
84
+ assert true
85
+ end
86
+
87
+ def test_photo_xml
88
+ data = <<EOS
89
+ <photo id="2733" secret="123456" server="12" isfavorite="0" license="3" rotation="90" originalsecret="1bc09ce34a" originalformat="png">
90
+ <owner nsid="12037949754@N01" username="Bees" realname="Cal Henderson" location="Bedford, UK" />
91
+ <title>orford_castle_taster</title>
92
+ <description>hello!</description>
93
+ <visibility ispublic="1" isfriend="0" isfamily="0" />
94
+ <dates posted="1100897479" taken="2004-11-19 12:51:19" takengranularity="0" lastupdate="1093022469" />
95
+ <permissions permcomment="3" permaddmeta="2" />
96
+ <editability cancomment="1" canaddmeta="1" />
97
+ <comments>1</comments>
98
+ <notes>
99
+ <note id="313" author="12037949754@N01" authorname="Bees" x="10" y="10" w="50" h="50">foo</note>
100
+ </notes>
101
+ <tags>
102
+ <tag id="1234" author="12037949754@N01" raw="woo yay">wooyay</tag>
103
+ <tag id="1235" author="12037949754@N01" raw="hoopla">hoopla</tag>
104
+ </tags>
105
+ <urls>
106
+ <url type="photopage">http://www.flickr.com/photos/bees/2733/</url>
107
+ </urls>
108
+ </photo>
109
+ EOS
110
+
111
+ xml = REXML::Document.new data
112
+ photo = Flickr::Photo.new xml.root
113
+
114
+ assert_equal 'orford_castle_taster', photo.title
115
+ assert_equal 'hello!', photo.description
116
+ assert_equal ['wooyay', 'hoopla'], photo.tags
117
+ assert_equal 'Cal Henderson', photo.owner_real_name
118
+ assert_equal 'Bees', photo.owner_user_name
119
+ assert_equal '12037949754@N01', photo.owner
120
+ assert_equal '2733', photo.id
121
+
122
+ end
123
+
124
+ def test_people_getInfo
125
+ data = <<EOS
126
+ <person nsid='12656878@N06' iconfarm='2' id='12656878@N06' ispro='0' isadmin='0' iconserver='1011'>
127
+ <username>henry.maddocks</username>
128
+ <realname>Henry Maddocks</realname>
129
+ <mbox_sha1sum>4e20b6c8b0fade15dcb37181c65de45b6205cecc</mbox_sha1sum>
130
+ <location>Wellington, New Zealand</location>
131
+ <photosurl>http://www.flickr.com/photos/12656878@N06/</photosurl>
132
+ <profileurl>http://www.flickr.com/people/12656878@N06/</profileurl>
133
+ <mobileurl>http://m.flickr.com/photostream.gne?id=12611556</mobileurl>
134
+ <photos>
135
+ <firstdatetaken>2005-09-24 16:20:11</firstdatetaken>
136
+ <firstdate>1188878270</firstdate>
137
+ <count>57</count>
138
+ </photos>
139
+ </person>
140
+ EOS
141
+
142
+ xml = REXML::Document.new data
143
+ me = Flickr::Person.new xml.root
144
+
145
+ assert_equal '12656878@N06', me.id
146
+ assert_equal 'henry.maddocks', me.username
147
+ assert_equal 'Henry Maddocks', me.realname
148
+ assert_equal 'Wellington, New Zealand', me.location
149
+
150
+ end
151
+
152
+ # def test_simple_search
153
+ # assert_nothing_raised {@digitalNZ.search "Karori photograph"}
154
+ # end
155
+ #
156
+
157
+
158
+ def test_exception
159
+ assert_raise APIException do
160
+ me = @flickr.people.getInfo(:xxxx => '12656878@N06')
161
+ end
162
+
163
+ assert_raise APIException do
164
+ me = @flickr.people.getInfo('12656878@N06')
165
+ end
166
+
167
+ assert_nothing_raised {@flickr.people.getInfo :user_id => '12656878@N06'}
168
+ end
169
+
170
+ def test_group_getInfo
171
+ data = <<EOS
172
+ <group id="34427465497@N01" iconserver="1" lang="en-us" ispoolmoderated="0">
173
+ <name>GNEverybody</name>
174
+ <description>The group for GNE players</description>
175
+ <members>69</members>
176
+ <privacy>3</privacy>
177
+ <throttle count="10" mode="month" remaining="3"/>
178
+ </group>
179
+ EOS
180
+
181
+ xml = REXML::Document.new data
182
+ group = Flickr::Group.new xml.root
183
+
184
+ assert_equal "34427465497@N01", group.id
185
+ assert_equal "GNEverybody", group.name
186
+ assert_equal "The group for GNE players", group.description
187
+ assert_equal "69", group.members
188
+
189
+ end
190
+
191
+ def test_invalid_response
192
+ xml =""
193
+ flickr = Flickr::FlickrClient.new
194
+
195
+ assert_raise APIException do
196
+ flickr.build_response xml
197
+ end
198
+ end
199
+
200
+ def test_groups
201
+ xml = <<EOS
202
+ <?xml version="1.0" encoding="utf-8" ?>
203
+ <rsp stat="ok">
204
+ <groups>
205
+ <group nsid="34427469792@N01" name="FlickrCentral" admin="0" eighteenplus="0" />
206
+ <group nsid="37996584485@N01" name="Motorcycles" admin="0" eighteenplus="0" />
207
+ <group nsid="41894169203@N01" name="Wellington, New Zealand" admin="0" eighteenplus="0" />
208
+ <group nsid="51035612836@N01" name="Flickr API" admin="0" eighteenplus="0" />
209
+ <group nsid="52240148330@N01" name="BEER" admin="0" eighteenplus="0" />
210
+ <group nsid="52241691728@N01" name="Glitch Art" admin="0" eighteenplus="0" />
211
+ <group nsid="55475894@N00" name="* Vanishing Points *" admin="0" eighteenplus="0" />
212
+ </groups>
213
+ </rsp>
214
+ EOS
215
+
216
+ flickr = Flickr::FlickrClient.new
217
+
218
+ groups = flickr.build_response xml
219
+ assert_equal 7, groups.length
220
+ assert_equal 'Wellington, New Zealand', groups[2].name
221
+ assert_equal '41894169203@N01', groups[2].id
222
+
223
+ end
224
+
225
+ end
@@ -0,0 +1,25 @@
1
+ # photo_gne_test.rb
2
+
3
+ $:.push("/Users/henry/bin")
4
+
5
+ require 'test/unit'
6
+ require 'photo_gne.rb'
7
+
8
+ class Test_Flickr < Test::Unit::TestCase
9
+ def test_url
10
+ assert_equal 4254104021, parse_id("http://farm5.static.flickr.com/4024/4254104021_4a69ed0cc0_b.jpg")
11
+ assert_equal 4254104021, parse_id("http://farm5.static.flickr.com/4024/4254104021_4a69ed0cc0.jpg")
12
+ end
13
+
14
+ def test_integer
15
+ assert_equal 4254104021, parse_id("4254104021")
16
+ end
17
+
18
+ def test_partial
19
+ assert_equal 4254104021, parse_id("4254104021_4a69ed0cc0.jpg")
20
+ assert_equal 4254104021, parse_id("4254104021_4a69ed0cc0_b.jpg")
21
+ assert_equal 4254104021, parse_id("4254104021_4a69ed0cc0_b")
22
+ assert_equal 4254104021, parse_id("4254104021_4a69ed0cc0")
23
+ end
24
+
25
+ end
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: flickrrb
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 1
7
+ - 0
8
+ version: "1.0"
9
+ platform: ruby
10
+ authors:
11
+ - Henry Maddocks
12
+ autorequire:
13
+ bindir: bin
14
+ cert_chain: []
15
+
16
+ date: 2010-04-26 00:00:00 +12:00
17
+ default_executable:
18
+ dependencies: []
19
+
20
+ description: A simple interface to the Flickr public API.
21
+ email: henry.maddocks@gmail.com
22
+ executables: []
23
+
24
+ extensions: []
25
+
26
+ extra_rdoc_files: []
27
+
28
+ files:
29
+ - lib/flickrrb.rb
30
+ - copying.txt
31
+ - README.rdoc
32
+ - Rakefile
33
+ - test/flickrrb_test.rb
34
+ - test/photo_gne_test.rb
35
+ has_rdoc: true
36
+ homepage: ""
37
+ licenses: []
38
+
39
+ post_install_message:
40
+ rdoc_options: []
41
+
42
+ require_paths:
43
+ - lib
44
+ required_ruby_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ segments:
49
+ - 0
50
+ version: "0"
51
+ required_rubygems_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ segments:
56
+ - 0
57
+ version: "0"
58
+ requirements: []
59
+
60
+ rubyforge_project:
61
+ rubygems_version: 1.3.6
62
+ signing_key:
63
+ specification_version: 3
64
+ summary: Another Flickr Interface.
65
+ test_files:
66
+ - test/flickrrb_test.rb
67
+ - test/photo_gne_test.rb