net-flickr 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,65 @@
1
+ #--
2
+ # Copyright (c) 2007-2008 Ryan Grove <ryan@wonko.com>
3
+ # All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are met:
7
+ #
8
+ # * Redistributions of source code must retain the above copyright notice,
9
+ # this list of conditions and the following disclaimer.
10
+ # * Redistributions in binary form must reproduce the above copyright notice,
11
+ # this list of conditions and the following disclaimer in the documentation
12
+ # and/or other materials provided with the distribution.
13
+ # * Neither the name of this project nor the names of its contributors may be
14
+ # used to endorse or promote products derived from this software without
15
+ # specific prior written permission.
16
+ #
17
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
21
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
+ #++
28
+
29
+ module Net; class Flickr
30
+
31
+ class People
32
+
33
+ def initialize(flickr)
34
+ @flickr = flickr
35
+ end
36
+
37
+ #--
38
+ # Public Instance Methods
39
+ #++
40
+
41
+ # Looks up a Flickr user based on their email address.
42
+ #
43
+ # See http://flickr.com/services/api/flickr.people.findByEmail.html for
44
+ # details.
45
+ def find_by_email(email, args = {})
46
+ args['find_email'] = email
47
+ response = @flickr.request('flickr.people.findByEmail', args)
48
+
49
+ return Person.new(@flickr, response.at('user'))
50
+ end
51
+
52
+ # Looks up a Flickr user based on their username.
53
+ #
54
+ # See http://flickr.com/services/api/flickr.people.findByUsername.html for
55
+ # details.
56
+ def find_by_username(username, args = {})
57
+ args['username'] = username
58
+ response = @flickr.request('flickr.people.findByUsername', args)
59
+
60
+ return Person.new(@flickr, response.at('user'))
61
+ end
62
+
63
+ end
64
+
65
+ end; end
@@ -0,0 +1,251 @@
1
+ #--
2
+ # Copyright (c) 2007-2008 Ryan Grove <ryan@wonko.com>
3
+ # All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are met:
7
+ #
8
+ # * Redistributions of source code must retain the above copyright notice,
9
+ # this list of conditions and the following disclaimer.
10
+ # * Redistributions in binary form must reproduce the above copyright notice,
11
+ # this list of conditions and the following disclaimer in the documentation
12
+ # and/or other materials provided with the distribution.
13
+ # * Neither the name of this project nor the names of its contributors may be
14
+ # used to endorse or promote products derived from this software without
15
+ # specific prior written permission.
16
+ #
17
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
21
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
+ #++
28
+
29
+ module Net; class Flickr
30
+
31
+ class Person
32
+
33
+ attr_reader :id, :username
34
+
35
+ def initialize(flickr, person_xml)
36
+ @flickr = flickr
37
+
38
+ @id = person_xml['nsid']
39
+ @username = person_xml.at('username').inner_text
40
+ @infoxml = nil
41
+ end
42
+
43
+ #--
44
+ # Public Instance Methods
45
+ #++
46
+
47
+ # +true+ if this person is a Flickr admin, +false+ otherwise.
48
+ def admin?
49
+ infoxml = get_info
50
+ return infoxml['isadmin'] == '1'
51
+ end
52
+
53
+ # +true+ if this person is a contact of the calling user, +false+ otherwise.
54
+ # This method requires authentication with +read+ permission. In all other
55
+ # cases, it returns +false+.
56
+ def contact?
57
+ infoxml = get_info
58
+
59
+ if contact = infoxml['contact']
60
+ return contact == '1'
61
+ end
62
+
63
+ return false
64
+ end
65
+
66
+ # +true+ if this person is a family member of the calling user, +false+
67
+ # otherwise. This method requires authentication with +read+ permission. In
68
+ # all other cases, it returns +false+.
69
+ def family?
70
+ infoxml = get_info
71
+
72
+ if family = infoxml['family']
73
+ return family == '1'
74
+ end
75
+
76
+ return false
77
+ end
78
+
79
+ # +true+ if this person is a friend of the calling user, +false+ otherwise.
80
+ # This method requires authentication with +read+ permission. In all other
81
+ # cases, it returns +false+.
82
+ def friend?
83
+ infoxml = get_info
84
+
85
+ if friend = infoxml['friend']
86
+ return friend == '1'
87
+ end
88
+
89
+ return false
90
+ end
91
+
92
+ # Gets this person's gender (e.g., 'M'). This method requires authentication
93
+ # with +read+ permission and only returns information for contacts of the
94
+ # calling user. In all other cases, it returns +nil+.
95
+ def gender
96
+ infoxml = get_info
97
+ return infoxml['gender']
98
+ end
99
+
100
+ # TODO: Implement Flickr.person.groups
101
+ def groups
102
+ end
103
+
104
+ # Gets the URL of this person's buddy icon.
105
+ def icon_url
106
+ infoxml = get_info
107
+
108
+ icon_server = infoxml['iconserver']
109
+ icon_farm = infoxml['iconfarm']
110
+
111
+ if icon_server.to_i <= 0
112
+ return 'http://www.flickr.com/images/buddyicon.jpg'
113
+ else
114
+ return "http://farm#{icon_farm}.static.flickr.com/#{icon_server}/buddyicons/#{@id}.jpg"
115
+ end
116
+ end
117
+
118
+ # +true+ if this person is an ignored contact of the calling user, +false+
119
+ # otherwise. This method requires authentication with +read+ permission and
120
+ # only returns information for contacts of the calling user. In all other
121
+ # cases, it returns +false+.
122
+ def ignored?
123
+ infoxml = get_info
124
+
125
+ if ignored = infoxml['ignored']
126
+ return ignored == '1'
127
+ end
128
+
129
+ return false
130
+ end
131
+
132
+ # Gets this person's location.
133
+ def location
134
+ infoxml = get_info
135
+ return infoxml.at('location').inner_text
136
+ end
137
+
138
+ # Gets the mobile URL of this person's photos.
139
+ def mobile_url
140
+ infoxml = get_info
141
+ return infoxml.at('mobileurl').inner_text
142
+ end
143
+
144
+ # Gets the total number of photos uploaded by this user.
145
+ def photo_count
146
+ infoxml = get_info
147
+ return infoxml.at('photos/count').inner_text.to_i
148
+ end
149
+
150
+ # Gets the URL of this person's photo stream.
151
+ def photo_url
152
+ infoxml = get_info
153
+ return infoxml.at('photosurl').inner_text
154
+ end
155
+
156
+ # Gets the number of times this person's photo stream has been viewed. This
157
+ # method requires authentication with +read+ permission and only returns
158
+ # information for the calling user. In all other cases, it returns +nil+.
159
+ def photo_views
160
+ infoxml = get_info
161
+
162
+ if views = infoxml.at('photos/views')
163
+ return views.inner_text.to_i
164
+ end
165
+
166
+ return nil
167
+ end
168
+
169
+ # Gets a list of public photos for this person.
170
+ #
171
+ # See http://flickr.com/services/api/flickr.people.getPublicPhotos.html for
172
+ # details.
173
+ def photos(args = {})
174
+ return @flickr.photos.user(@id, args)
175
+ end
176
+
177
+ # +true+ if this person is a Flickr Pro user, +false+ otherwise.
178
+ def pro?
179
+ infoxml = get_info
180
+ return infoxml['ispro'] == '1'
181
+ end
182
+
183
+ # Gets the URL of this person's profile.
184
+ def profile_url
185
+ infoxml = get_info
186
+ return infoxml.at('profileurl').inner_text
187
+ end
188
+
189
+ # Gets this person's real name (e.g., 'John Doe').
190
+ def realname
191
+ infoxml = get_info
192
+ return infoxml.at('realname').inner_text
193
+ end
194
+
195
+ # +true+ if the calling user is a contact of this person, +false+ otherwise.
196
+ # This method requires authentication with +read+ permission. In all other
197
+ # cases, it returns +false+.
198
+ def rev_contact?
199
+ infoxml = get_info
200
+
201
+ if rev_contact = infoxml['revcontact']
202
+ return rev_contact == '1'
203
+ end
204
+
205
+ return false
206
+ end
207
+
208
+ # +true+ if this person considers the calling user family, +false+
209
+ # otherwise. This method requires authentication with +read+ permission. In
210
+ # all other cases, it returns +false+.
211
+ def rev_family?
212
+ infoxml = get_info
213
+
214
+ if rev_family = infoxml['revfamily']
215
+ return rev_family == '1'
216
+ end
217
+
218
+ return false
219
+ end
220
+
221
+ # +true+ if this person considers the calling user a friend, +false+
222
+ # otherwise. This method requires authentication with +read+ permission. In
223
+ # all other cases, it returns +false+.
224
+ def rev_friend?
225
+ infoxml = get_info
226
+
227
+ if rev_friend = infoxml['revfriend']
228
+ return rev_friend == '1'
229
+ end
230
+
231
+ return false
232
+ end
233
+
234
+ #--
235
+ # Private Instance Methods
236
+ #++
237
+
238
+ private
239
+
240
+ # Gets detailed information for this person.
241
+ def get_info
242
+ return @infoxml unless @infoxml.nil?
243
+
244
+ response = @flickr.request('flickr.people.getInfo', 'user_id' => @id)
245
+
246
+ return @infoxml = response.at('person')
247
+ end
248
+
249
+ end
250
+
251
+ end; end
@@ -0,0 +1,335 @@
1
+ #--
2
+ # Copyright (c) 2007-2008 Ryan Grove <ryan@wonko.com>
3
+ # All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are met:
7
+ #
8
+ # * Redistributions of source code must retain the above copyright notice,
9
+ # this list of conditions and the following disclaimer.
10
+ # * Redistributions in binary form must reproduce the above copyright notice,
11
+ # this list of conditions and the following disclaimer in the documentation
12
+ # and/or other materials provided with the distribution.
13
+ # * Neither the name of this project nor the names of its contributors may be
14
+ # used to endorse or promote products derived from this software without
15
+ # specific prior written permission.
16
+ #
17
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
21
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
+ #++
28
+
29
+ module Net; class Flickr
30
+
31
+ # A Flickr photo.
32
+ #
33
+ # Don't instantiate this class yourself. Use the methods in Flickr::Photos to
34
+ # retrieve photos from Flickr.
35
+ class Photo
36
+ SIZE_SUFFIX = {
37
+ :square => 's',
38
+ :thumb => 't',
39
+ :small => 'm',
40
+ :medium => nil,
41
+ :large => 'b',
42
+ :original => 'o'
43
+ }
44
+
45
+ #--
46
+ # Public Instance Methods
47
+ #++
48
+
49
+ attr_reader :id, :secret, :server, :farm
50
+
51
+ def initialize(flickr, photo_xml)
52
+ @flickr = flickr
53
+
54
+ parse_xml(photo_xml)
55
+
56
+ # Detailed photo info.
57
+ @context_xml = nil
58
+ @info_xml = nil
59
+ end
60
+
61
+ # Deletes this photo from Flickr. This method requires authentication with
62
+ # +delete+ permission.
63
+ def delete
64
+ @flickr.photos.delete(@id)
65
+ end
66
+
67
+ # Gets this photo's description.
68
+ def description
69
+ info_xml = get_info
70
+ return info_xml.at('description').inner_text
71
+ end
72
+
73
+ # Sets this photo's description. This method requires authentication with
74
+ # +write+ permission.
75
+ def description=(value)
76
+ set_meta(@title, value)
77
+ end
78
+
79
+ # flickr.photos.getExif
80
+ def exif
81
+ raise NotImplementedError
82
+ end
83
+
84
+ # Whether or not this photo is visible to family.
85
+ def family?
86
+ get_info if @is_family.nil?
87
+ return @is_family || @is_public
88
+ end
89
+
90
+ # flickr.photos.getFavorites
91
+ def favorites
92
+ raise NotImplementedError
93
+ end
94
+
95
+ # Whether or not this photo is visible to friends.
96
+ def friend?
97
+ get_info if @is_friend.nil?
98
+ return @is_friend || @is_public
99
+ end
100
+
101
+ # flickr.photos.getExif
102
+ def gps
103
+ raise NotImplementedError
104
+ end
105
+
106
+ # Gets the time this photo was last modified.
107
+ def modified
108
+ info_xml = get_info
109
+ return Time.at(info_xml.at('dates')[:lastupdate].to_i)
110
+ end
111
+
112
+ # Gets the next photo in the owner's photo stream, or +nil+ if this is the
113
+ # last photo in the stream.
114
+ def next
115
+ context_xml = get_context
116
+ next_xml = context_xml.at('nextphoto')
117
+
118
+ return Photo.new(@flickr, next_xml) if next_xml[:id] != '0'
119
+ return nil
120
+ end
121
+
122
+ # Gets the user id of this photo's owner.
123
+ def owner
124
+ @owner
125
+ end
126
+
127
+ # Gets the URL of this photo's Flickr photo page.
128
+ def page_url
129
+ return "http://www.flickr.com/photos/#{@owner}/#{@id}"
130
+ end
131
+
132
+ # flickr.photos.getAllContexts
133
+ def pools
134
+ raise NotImplementedError
135
+ end
136
+
137
+ # Gets the time this photo was posted to Flickr.
138
+ def posted
139
+ info_xml = get_info
140
+ return Time.at(info_xml.at('dates')[:posted].to_i)
141
+ end
142
+
143
+ # flickr.photos.setDates
144
+ def posted=(time)
145
+ end
146
+
147
+ # Gets the previous photo in the owner's photo stream, or +nil+ if this is
148
+ # the first photo in the stream.
149
+ def previous
150
+ context_xml = get_context
151
+ prev_xml = context_xml.at('prevphoto')
152
+
153
+ return Photo.new(@flickr, prev_xml) if prev_xml[:id] != '0'
154
+ return nil
155
+ end
156
+
157
+ alias prev previous
158
+
159
+ # Whether or not this photo is visible to the general public.
160
+ def public?
161
+ get_info if @is_public.nil?
162
+ return @is_public
163
+ end
164
+
165
+ # flickr.photos.getAllContexts
166
+ def sets
167
+ raise NotImplementedError
168
+ end
169
+
170
+ # flickr.photos.getSizes
171
+ def sizes
172
+ raise NotImplementedError
173
+ end
174
+
175
+ # Gets the source URL for this photo at one of the following specified
176
+ # sizes. Returns +nil+ if the specified _size_ is not available.
177
+ #
178
+ # [:square] 75x75px
179
+ # [:thumb] 100px on longest side
180
+ # [:small] 240px on longest side
181
+ # [:medium] 500px on longest side
182
+ # [:large] 1024px on longest side (not available for all images)
183
+ # [:original] original image in original file format
184
+ def source_url(size = :medium)
185
+ suffix = SIZE_SUFFIX[size]
186
+
187
+ case size
188
+ when :medium
189
+ return "http://farm#{@farm}.static.flickr.com/#{@server}/#{@id}_" +
190
+ "#{@secret}.jpg"
191
+
192
+ when :original
193
+ info_xml = get_info
194
+
195
+ original_secret = info_xml[:originalsecret]
196
+ original_format = info_xml[:originalformat]
197
+
198
+ return nil if original_secret.nil? || original_format.nil?
199
+ return "http://farm#{@farm}.static.flickr.com/#{@server}/#{@id}_" +
200
+ "#{original_secret}_o.#{original_format}"
201
+
202
+ else
203
+ return "http://farm#{@farm}.static.flickr.com/#{@server}/#{@id}_" +
204
+ "#{@secret}_#{suffix}.jpg"
205
+ end
206
+ end
207
+
208
+ # flickr.photos.getInfo
209
+ def tags
210
+ raise NotImplementedError
211
+ end
212
+
213
+ # Gets the time this photo was taken.
214
+ def taken
215
+ info_xml = get_info
216
+ return Time.parse(info_xml.at('dates')[:taken])
217
+ end
218
+
219
+ # flickr.photos.setDates
220
+ def taken=(time)
221
+ raise NotImplementedError
222
+ end
223
+
224
+ # flickr.photos.getExif
225
+ def tiff
226
+ raise NotImplementedError
227
+ end
228
+
229
+ # Gets this photo's title.
230
+ def title
231
+ @title
232
+ end
233
+
234
+ # Sets this photo's title. This method requires authentication with +write+
235
+ # permission.
236
+ def title=(value)
237
+ set_meta(value, description)
238
+ end
239
+
240
+ #--
241
+ # Private Instance Methods
242
+ #++
243
+
244
+ private
245
+
246
+ # Gets context information for this photo.
247
+ def get_context
248
+ @context_xml ||= @flickr.request('flickr.photos.getContext',
249
+ :photo_id => @id)
250
+ end
251
+
252
+ # Gets detailed information for this photo.
253
+ def get_info
254
+ return @info_xml unless @info_xml.nil?
255
+
256
+ response = @flickr.request('flickr.photos.getInfo', :photo_id => @id,
257
+ :secret => @secret)
258
+
259
+ @info_xml = response.at('photo')
260
+
261
+ if @is_family.nil? || @is_friend.nil? || @is_public.nil?
262
+ @is_family = @info_xml.at('visibility')[:isfamily] == '1'
263
+ @is_friend = @info_xml.at('visibility')[:isfriend] == '1'
264
+ @is_public = @info_xml.at('visibility')[:ispublic] == '1'
265
+ end
266
+
267
+ return @info_xml
268
+ end
269
+
270
+ # Parse a photo xml chunk.
271
+ def parse_xml(photo_xml)
272
+ # Convert photo_xml to an Hpricot::Elem if it isn't one already.
273
+ unless photo_xml.is_a?(Hpricot::Elem)
274
+ photo_xml = Hpricot::XML(photo_xml)
275
+ end
276
+
277
+ # Figure out what format we're dealing with, since someone at Flickr
278
+ # thought it would be fun to be inconsistent (thanks, whoever you are).
279
+ if photo_xml[:owner] && photo_xml[:ispublic]
280
+ # This is a basic XML chunk.
281
+ @id = photo_xml[:id]
282
+ @owner = photo_xml[:owner]
283
+ @secret = photo_xml[:secret]
284
+ @server = photo_xml[:server]
285
+ @farm = photo_xml[:farm]
286
+ @title = photo_xml[:title]
287
+ @is_public = photo_xml[:ispublic] == '1'
288
+ @is_friend = photo_xml[:isfriend] == '1'
289
+ @is_family = photo_xml[:isfamily] == '1'
290
+
291
+ elsif photo_xml[:url] && photo_xml[:thumb]
292
+ # This is a context XML chunk. It doesn't include visibility info.
293
+ @id = photo_xml[:id]
294
+ @secret = photo_xml[:secret]
295
+ @server = photo_xml[:server]
296
+ @farm = photo_xml[:farm]
297
+ @title = photo_xml[:title]
298
+ @is_public = nil
299
+ @is_friend = nil
300
+ @is_family = nil
301
+
302
+ elsif photo_xml[:originalsecret] && photo_xml.at('owner[@nsid]')
303
+ # This is a detailed XML chunk (probably from flickr.photos.getInfo).
304
+ @id = photo_xml[:id]
305
+ @owner = photo_xml.at('owner[@nsid]')
306
+ @secret = photo_xml[:secret]
307
+ @server = photo_xml[:server]
308
+ @farm = photo_xml[:farm]
309
+ @title = photo_xml.at(:title).inner_text
310
+ @is_public = photo_xml.at('visibility')[:ispublic] == '1'
311
+ @is_friend = photo_xml.at('visibility')[:isfriend] == '1'
312
+ @is_family = photo_xml.at('visibility')[:isfamily] == '1'
313
+ @info_xml = photo_xml
314
+ end
315
+ end
316
+
317
+ # Sets date information for this photo.
318
+ def set_dates(posted, taken, granularity = 0, args = {})
319
+ raise NotImplementedError
320
+ end
321
+
322
+ # Sets meta information for this photo.
323
+ def set_meta(title, description, args = {})
324
+ args[:photo_id] = @id
325
+ args[:title] = title
326
+ args[:description] = description
327
+
328
+ @flickr.request('flickr.photos.setMeta', args)
329
+
330
+ @info_xml = nil
331
+ end
332
+
333
+ end
334
+
335
+ end; end