net-flickr 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +25 -0
- data/lib/net/flickr.rb +218 -0
- data/lib/net/flickr/auth.rb +139 -0
- data/lib/net/flickr/errors.rb +35 -0
- data/lib/net/flickr/list.rb +135 -0
- data/lib/net/flickr/people.rb +65 -0
- data/lib/net/flickr/person.rb +251 -0
- data/lib/net/flickr/photo.rb +335 -0
- data/lib/net/flickr/photolist.rb +53 -0
- data/lib/net/flickr/photos.rb +189 -0
- data/lib/net/flickr/tag.rb +55 -0
- metadata +77 -0
@@ -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
|