flickrrb 1.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/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