fotonauts-flickr_fu 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +13 -0
- data/LICENSE +22 -0
- data/README +147 -0
- data/Rakefile +73 -0
- data/VERSION.yml +4 -0
- data/flickr_fu.gemspec +117 -0
- data/lib/flickr/auth.rb +76 -0
- data/lib/flickr/base.rb +151 -0
- data/lib/flickr/comment.rb +16 -0
- data/lib/flickr/contact.rb +16 -0
- data/lib/flickr/contacts.rb +55 -0
- data/lib/flickr/errors.rb +20 -0
- data/lib/flickr/geo.rb +42 -0
- data/lib/flickr/license.rb +24 -0
- data/lib/flickr/location.rb +15 -0
- data/lib/flickr/note.rb +16 -0
- data/lib/flickr/people.rb +54 -0
- data/lib/flickr/person.rb +82 -0
- data/lib/flickr/photo.rb +321 -0
- data/lib/flickr/photo_response.rb +37 -0
- data/lib/flickr/photos.rb +252 -0
- data/lib/flickr/photoset.rb +37 -0
- data/lib/flickr/photosets.rb +39 -0
- data/lib/flickr/size.rb +16 -0
- data/lib/flickr/status.rb +19 -0
- data/lib/flickr/test.rb +31 -0
- data/lib/flickr/token.rb +22 -0
- data/lib/flickr/uploader.rb +162 -0
- data/lib/flickr/urls.rb +44 -0
- data/lib/flickr_fu.rb +48 -0
- data/spec/fixtures/flickr/contacts/get_list-fail-99.xml +4 -0
- data/spec/fixtures/flickr/contacts/get_public_list-0.xml +7 -0
- data/spec/fixtures/flickr/photos/geo/get_location-0.xml +11 -0
- data/spec/fixtures/flickr/photos/geo/get_location-fail-2.xml +4 -0
- data/spec/fixtures/flickr/photos/get_info-0.xml +41 -0
- data/spec/fixtures/flickr/photos/get_info-1.xml +19 -0
- data/spec/fixtures/flickr/photos/get_sizes-0.xml +10 -0
- data/spec/fixtures/flickr/photos/get_sizes-1.xml +8 -0
- data/spec/fixtures/flickr/photos/licenses/get_info.xml +12 -0
- data/spec/fixtures/flickr/photosets/get_list-0.xml +13 -0
- data/spec/fixtures/flickr/photosets/get_photos-0.xml +7 -0
- data/spec/fixtures/flickr/test/echo-0.xml +5 -0
- data/spec/fixtures/flickr/test/null-fail-99.xml +4 -0
- data/spec/fixtures/flickr/urls/get_group-0.xml +4 -0
- data/spec/fixtures/flickr/urls/get_group-fail-1.xml +4 -0
- data/spec/fixtures/flickr/urls/get_user_photos-0.xml +4 -0
- data/spec/fixtures/flickr/urls/get_user_photos-fail-1.xml +4 -0
- data/spec/fixtures/flickr/urls/get_user_photos-fail-2.xml +4 -0
- data/spec/fixtures/flickr/urls/get_user_profile-0.xml +4 -0
- data/spec/fixtures/flickr/urls/get_user_profile-fail-1.xml +4 -0
- data/spec/fixtures/flickr/urls/get_user_profile-fail-2.xml +4 -0
- data/spec/fixtures/flickr/urls/lookup_group-0.xml +6 -0
- data/spec/fixtures/flickr/urls/lookup_group-fail-1.xml +4 -0
- data/spec/fixtures/flickr/urls/lookup_user-0.xml +6 -0
- data/spec/fixtures/flickr/videos/get_info-0.xml +31 -0
- data/spec/fixtures/flickr/videos/get_sizes-0.xml +13 -0
- data/spec/flickr/base_spec.rb +97 -0
- data/spec/flickr/contacts_spec.rb +47 -0
- data/spec/flickr/errors_spec.rb +21 -0
- data/spec/flickr/geo_spec.rb +20 -0
- data/spec/flickr/photo_spec.rb +140 -0
- data/spec/flickr/photos_spec.rb +50 -0
- data/spec/flickr/photosets_spec.rb +49 -0
- data/spec/flickr/test_spec.rb +34 -0
- data/spec/flickr/urls_spec.rb +99 -0
- data/spec/spec.opts +4 -0
- data/spec/spec_helper.rb +20 -0
- metadata +176 -0
@@ -0,0 +1,252 @@
|
|
1
|
+
class Flickr::Photos < Flickr::Base
|
2
|
+
def initialize(flickr)
|
3
|
+
@flickr = flickr
|
4
|
+
end
|
5
|
+
|
6
|
+
# Return a list of photos matching some criteria. Only photos visible to the calling user will be returned. To return private or semi-private photos,
|
7
|
+
# the caller must be authenticated with 'read' permissions, and have permission to view the photos. Unauthenticated calls will only return public photos.
|
8
|
+
#
|
9
|
+
# == Authentication
|
10
|
+
# This method does not require authentication.
|
11
|
+
#
|
12
|
+
# == Options
|
13
|
+
# * user_id (Optional)
|
14
|
+
# The NSID of the user who's photo to search. If this parameter isn't passed then everybody's public photos will be searched. A value of "me" will
|
15
|
+
# search against the calling user's photos for authenticated calls.
|
16
|
+
# * tags (Optional)
|
17
|
+
# A comma-delimited list of tags. Photos with one or more of the tags listed will be returned.
|
18
|
+
# * tag_mode (Optional)
|
19
|
+
# Either 'any' for an OR combination of tags, or 'all' for an AND combination. Defaults to 'any' if not specified.
|
20
|
+
# * text (Optional)
|
21
|
+
# A free text search. Photos who's title, description or tags contain the text will be returned.
|
22
|
+
# * min_upload_date (Optional)
|
23
|
+
# Minimum upload date. Photos with an upload date greater than or equal to this value will be returned. The date should be in the form of a unix timestamp.
|
24
|
+
# * max_upload_date (Optional)
|
25
|
+
# Maximum upload date. Photos with an upload date less than or equal to this value will be returned. The date should be in the form of a unix timestamp.
|
26
|
+
# * min_taken_date (Optional)
|
27
|
+
# Minimum taken date. Photos with an taken date greater than or equal to this value will be returned. The date should be in the form of a mysql datetime.
|
28
|
+
# * max_taken_date (Optional)
|
29
|
+
# Maximum taken date. Photos with an taken date less than or equal to this value will be returned. The date should be in the form of a mysql datetime.
|
30
|
+
# * license (Optional)
|
31
|
+
# The license id for photos (for possible values see the flickr.photos.licenses.getInfo method). Multiple licenses may be comma-separated.
|
32
|
+
# * sort (Optional)
|
33
|
+
# The order in which to sort returned photos. Deafults to date-posted-desc. The possible values are: date-posted-asc, date-posted-desc, date-taken-asc,
|
34
|
+
# date-taken-desc, interestingness-desc, interestingness-asc, and relevance.
|
35
|
+
# * privacy_filter (Optional)
|
36
|
+
# Return photos only matching a certain privacy level. This only applies when making an authenticated call to view photos you own. Valid values are:
|
37
|
+
# 1 public photos
|
38
|
+
# 2 private photos visible to friends
|
39
|
+
# 3 private photos visible to family
|
40
|
+
# 4 private photos visible to friends & family
|
41
|
+
# 5 completely private photos
|
42
|
+
# * bbox (Optional)
|
43
|
+
# A comma-delimited list of 4 values defining the Bounding Box of the area that will be searched.
|
44
|
+
#
|
45
|
+
# The 4 values represent the bottom-left corner of the box and the top-right corner, minimum_longitude, minimum_latitude, maximum_longitude, maximum_latitude.
|
46
|
+
#
|
47
|
+
# Longitude has a range of -180 to 180 , latitude of -90 to 90. Defaults to -180, -90, 180, 90 if not specified.
|
48
|
+
#
|
49
|
+
# Unlike standard photo queries, geo (or bounding box) queries will only return 250 results per page.
|
50
|
+
#
|
51
|
+
# Geo queries require some sort of limiting agent in order to prevent the database from crying. This is basically like the check against "parameterless searches"
|
52
|
+
# for queries without a geo component.
|
53
|
+
#
|
54
|
+
# A tag, for instance, is considered a limiting agent as are user defined min_date_taken and min_date_upload parameters — If no limiting factor is passed we
|
55
|
+
# return only photos added in the last 12 hours (though we may extend the limit in the future).
|
56
|
+
# * accuracy (Optional)
|
57
|
+
# Recorded accuracy level of the location information. Current range is 1-16 :
|
58
|
+
# World level is 1
|
59
|
+
# Country is ~3
|
60
|
+
# Region is ~6
|
61
|
+
# City is ~11
|
62
|
+
# Street is ~16
|
63
|
+
# Defaults to maximum value if not specified.
|
64
|
+
# * safe_search (Optional)
|
65
|
+
# Safe search setting:
|
66
|
+
# 1 for safe.
|
67
|
+
# 2 for moderate.
|
68
|
+
# 3 for restricted.
|
69
|
+
# (Please note: Un-authed calls can only see Safe content.)
|
70
|
+
# * content_type (Optional)
|
71
|
+
# Content Type setting:
|
72
|
+
# 1 for photos only.
|
73
|
+
# 2 for screenshots only.
|
74
|
+
# 3 for 'other' only.
|
75
|
+
# 4 for photos and screenshots.
|
76
|
+
# 5 for screenshots and 'other'.
|
77
|
+
# 6 for photos and 'other'.
|
78
|
+
# 7 for photos, screenshots, and 'other' (all).
|
79
|
+
# * machine_tags (Optional)
|
80
|
+
# Aside from passing in a fully formed machine tag, there is a special syntax for searching on specific properties :
|
81
|
+
# Find photos using the 'dc' namespace : "machine_tags" => "dc:"
|
82
|
+
# Find photos with a title in the 'dc' namespace : "machine_tags" => "dc:title="
|
83
|
+
# Find photos titled "mr. camera" in the 'dc' namespace : "machine_tags" => "dc:title=\"mr. camera\"
|
84
|
+
# Find photos whose value is "mr. camera" : "machine_tags" => "*:*=\"mr. camera\""
|
85
|
+
# Find photos that have a title, in any namespace : "machine_tags" => "*:title="
|
86
|
+
# Find photos that have a title, in any namespace, whose value is "mr. camera" : "machine_tags" => "*:title=\"mr. camera\""
|
87
|
+
# Find photos, in the 'dc' namespace whose value is "mr. camera" : "machine_tags" => "dc:*=\"mr. camera\""
|
88
|
+
# Multiple machine tags may be queried by passing a comma-separated list. The number of machine tags you can pass in a single query depends on
|
89
|
+
# the tag mode (AND or OR) that you are querying with. "AND" queries are limited to (16) machine tags. "OR" queries are limited to (8).
|
90
|
+
# * machine_tag_mode (Required)
|
91
|
+
# Either 'any' for an OR combination of tags, or 'all' for an AND combination. Defaults to 'any' if not specified.
|
92
|
+
# * group_id (Optional)
|
93
|
+
# The id of a group who's pool to search. If specified, only matching photos posted to the group's pool will be returned.
|
94
|
+
# * woe_id (Optional)
|
95
|
+
# A 32-bit identifier that uniquely represents spatial entities. (not used if bbox argument is present). Experimental.
|
96
|
+
#
|
97
|
+
# Geo queries require some sort of limiting agent in order to prevent the database from crying. This is basically like the check against "parameterless searches"
|
98
|
+
# for queries without a geo component.
|
99
|
+
#
|
100
|
+
# A tag, for instance, is considered a limiting agent as are user defined min_date_taken and min_date_upload parameters &emdash; If no limiting factor is passed
|
101
|
+
# we return only photos added in the last 12 hours (though we may extend the limit in the future).
|
102
|
+
# * place_id (Optional)
|
103
|
+
# A Flickr place id. (not used if bbox argument is present). Experimental.
|
104
|
+
#
|
105
|
+
# Geo queries require some sort of limiting agent in order to prevent the database from crying. This is basically like the check against "parameterless searches"
|
106
|
+
# for queries without a geo component.
|
107
|
+
#
|
108
|
+
# A tag, for instance, is considered a limiting agent as are user defined min_date_taken and min_date_upload parameters &emdash; If no limiting factor is passed
|
109
|
+
# we return only photos added in the last 12 hours (though we may extend the limit in the future).
|
110
|
+
# * per_page (Optional)
|
111
|
+
# Number of photos to return per page. If this argument is omitted, it defaults to 100. The maximum allowed value is 500.
|
112
|
+
# * page (Optional)
|
113
|
+
# The page of results to return. If this argument is omitted, it defaults to 1.
|
114
|
+
# * media (Optional)
|
115
|
+
# The type of media to search for. 'photo', 'video', or 'both' are allowed arguments, with 'both' being the default.
|
116
|
+
#
|
117
|
+
def search(options)
|
118
|
+
if options[:extras].nil?
|
119
|
+
# let the caller choose which extras to query.
|
120
|
+
# search request can be twice faster when we ask for less options.
|
121
|
+
options[:extras] = "license,date_upload,date_taken,owner_name,icon_server,original_format,last_update,geo,tags,machine_tags,o_dims,views,media"
|
122
|
+
end
|
123
|
+
|
124
|
+
rsp = @flickr.send_request('flickr.photos.search', options)
|
125
|
+
|
126
|
+
returning PhotoResponse.new(:page => rsp.photos[:page].to_i,
|
127
|
+
:pages => rsp.photos[:pages].to_i,
|
128
|
+
:per_page => rsp.photos[:perpage].to_i,
|
129
|
+
:total => rsp.photos[:total].to_i,
|
130
|
+
:photos => [],
|
131
|
+
:api => self,
|
132
|
+
:method => 'search',
|
133
|
+
:options => options) do |photos|
|
134
|
+
rsp.photos.photo.each do |photo|
|
135
|
+
attributes = create_attributes(photo)
|
136
|
+
|
137
|
+
photos << Photo.new(@flickr, attributes)
|
138
|
+
end if rsp.photos.photo
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
# Returns a list of the latest public photos uploaded to flickr.
|
143
|
+
#
|
144
|
+
# == Authentication
|
145
|
+
# This method does not require authentication.
|
146
|
+
#
|
147
|
+
# == Options
|
148
|
+
# * per_page (Optional)
|
149
|
+
# Number of photos to return per page. If this argument is omitted, it defaults to 100. The maximum allowed value is 500.
|
150
|
+
# * page (Optional)
|
151
|
+
# The page of results to return. If this argument is omitted, it defaults to 1.
|
152
|
+
# * media (Optional)
|
153
|
+
# The type of media to search for. 'photo', 'video', or 'both' are allowed arguments, with 'both' being the default.
|
154
|
+
#
|
155
|
+
def get_recent(options = {})
|
156
|
+
options.merge!({:extras => "license,date_upload,date_taken,owner_name,icon_server,original_format,last_update,geo,tags,machine_tags,o_dims,views,media"})
|
157
|
+
|
158
|
+
rsp = @flickr.send_request('flickr.photos.getRecent', options)
|
159
|
+
|
160
|
+
returning PhotoResponse.new(:page => rsp.photos[:page].to_i,
|
161
|
+
:pages => rsp.photos[:pages].to_i,
|
162
|
+
:per_page => rsp.photos[:perpage].to_i,
|
163
|
+
:total => rsp.photos[:total].to_i,
|
164
|
+
:photos => [], :api => self,
|
165
|
+
:method => 'flickr.photos.getRecent',
|
166
|
+
:options => options) do |photos|
|
167
|
+
rsp.photos.photo.each do |photo|
|
168
|
+
attributes = create_attributes(photo)
|
169
|
+
|
170
|
+
photos << Photo.new(@flickr, attributes)
|
171
|
+
end if rsp.photos.photo
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
def interesting(options)
|
176
|
+
options.merge!({:extras => "license,date_upload,date_taken,owner_name,icon_server,original_format,last_update,geo,tags,machine_tags,o_dims,views,media"})
|
177
|
+
|
178
|
+
rsp = @flickr.send_request('flickr.interestingness.getList', options)
|
179
|
+
|
180
|
+
returning PhotoResponse.new(:page => rsp.photos[:page].to_i,
|
181
|
+
:pages => rsp.photos[:pages].to_i,
|
182
|
+
:per_page => rsp.photos[:perpage].to_i,
|
183
|
+
:total => rsp.photos[:total].to_i,
|
184
|
+
:photos => [],
|
185
|
+
:api => self,
|
186
|
+
:method => 'flickr.interestingness.getList',
|
187
|
+
:options => options) do |photos|
|
188
|
+
rsp.photos.photo.each do |photo|
|
189
|
+
attributes = create_attributes(photo)
|
190
|
+
|
191
|
+
|
192
|
+
photos << Photo.new(@flickr, attributes)
|
193
|
+
end if rsp.photos.photo
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
def licenses
|
198
|
+
@licenses ||= begin
|
199
|
+
rsp = @flickr.send_request('flickr.photos.licenses.getInfo')
|
200
|
+
|
201
|
+
returning Hash.new do |licenses|
|
202
|
+
rsp.licenses.license.each do |license|
|
203
|
+
licenses[license[:id].to_i] = Flickr::Photos::License.new(:id => license[:id].to_i, :name => license[:name], :url => license[:url])
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
# creates and/or returns the Flickr::Photos::Geo object
|
210
|
+
def geo
|
211
|
+
@geo ||= Flickr::Photos::Geo.new(@flickr)
|
212
|
+
end
|
213
|
+
|
214
|
+
# Returns a Flickr::Photos::Photo object of the given id.
|
215
|
+
# Raises an error if photo not found
|
216
|
+
def find_by_id(photo_id)
|
217
|
+
rsp = @flickr.send_request('flickr.photos.getInfo', :photo_id => photo_id)
|
218
|
+
Photo.new(@flickr, :id => rsp.photo[:id].to_i, :owner => rsp.photo.owner,
|
219
|
+
:secret => rsp.photo[:secret], :server => rsp.photo[:server].to_i, :farm => rsp.photo[:farm],
|
220
|
+
:title => rsp.photo.title,
|
221
|
+
:is_public => rsp.photo.visibility[:public], :is_friend => rsp.photo.visibility[:is_friend], :is_family => rsp.photo.visibility[:is_family])
|
222
|
+
end
|
223
|
+
|
224
|
+
protected
|
225
|
+
def create_attributes(photo)
|
226
|
+
{:id => photo[:id],
|
227
|
+
:owner => photo[:owner],
|
228
|
+
:secret => photo[:secret],
|
229
|
+
:server => photo[:server],
|
230
|
+
:farm => photo[:farm],
|
231
|
+
:title => photo[:title],
|
232
|
+
:is_public => photo[:ispublic],
|
233
|
+
:is_friend => photo[:isfriend],
|
234
|
+
:is_family => photo[:isfamily],
|
235
|
+
:license_id => photo[:license].to_i,
|
236
|
+
:uploaded_at => (Time.at(photo[:dateupload].to_i) rescue nil),
|
237
|
+
:taken_at => (Time.parse(photo[:datetaken]) rescue nil),
|
238
|
+
:owner_name => photo[:ownername],
|
239
|
+
:icon_server => photo[:icon_server],
|
240
|
+
:original_format => photo[:originalformat],
|
241
|
+
:updated_at => (Time.at(photo[:lastupdate].to_i) rescue nil),
|
242
|
+
:geo => photo[:geo],
|
243
|
+
:tags => photo[:tags],
|
244
|
+
:machine_tags => photo[:machine_tags],
|
245
|
+
:o_dims => photo[:o_dims],
|
246
|
+
:o_height => photo[:o_height],
|
247
|
+
:o_width => photo[:o_width],
|
248
|
+
:views => photo[:views].to_i,
|
249
|
+
:media => photo[:media]}
|
250
|
+
end
|
251
|
+
|
252
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
class Flickr::Photosets::Photoset
|
2
|
+
attr_accessor :id,:num_photos,:title,:description
|
3
|
+
|
4
|
+
def initialize(flickr, attributes)
|
5
|
+
@flickr = flickr
|
6
|
+
attributes.each do |k,v|
|
7
|
+
send("#{k}=", v)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def get_photos(options={})
|
12
|
+
options = options.merge(:photoset_id=>id)
|
13
|
+
rsp = @flickr.send_request('flickr.photosets.getPhotos', options)
|
14
|
+
collect_photos(rsp)
|
15
|
+
end
|
16
|
+
|
17
|
+
protected
|
18
|
+
def collect_photos(rsp)
|
19
|
+
photos = []
|
20
|
+
return photos unless rsp
|
21
|
+
if rsp.photoset.photo
|
22
|
+
rsp.photoset.photo.each do |photo|
|
23
|
+
attributes = create_attributes(photo)
|
24
|
+
photos << Flickr::Photos::Photo.new(@flickr,attributes)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
return photos
|
28
|
+
end
|
29
|
+
|
30
|
+
def create_attributes(photo)
|
31
|
+
{:id => photo[:id],
|
32
|
+
:secret => photo[:secret],
|
33
|
+
:server => photo[:server],
|
34
|
+
:farm => photo[:farm],
|
35
|
+
:title => photo[:title]}
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
class Flickr::Photosets < Flickr::Base
|
2
|
+
def initialize(flickr)
|
3
|
+
@flickr = flickr
|
4
|
+
end
|
5
|
+
|
6
|
+
# Get the authorized user's contact list.
|
7
|
+
#
|
8
|
+
def get_list(options={})
|
9
|
+
rsp = @flickr.send_request('flickr.photosets.getList', options)
|
10
|
+
collect_photosets(rsp)
|
11
|
+
end
|
12
|
+
|
13
|
+
protected
|
14
|
+
def collect_photosets(rsp)
|
15
|
+
photosets = []
|
16
|
+
return photosets unless rsp
|
17
|
+
if rsp.photosets.photoset
|
18
|
+
rsp.photosets.photoset.each do |photoset|
|
19
|
+
attributes = create_attributes(photoset)
|
20
|
+
photosets << Photoset.new(@flickr, attributes)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
return photosets
|
24
|
+
end
|
25
|
+
|
26
|
+
def create_attributes(photoset)
|
27
|
+
# comment by : smeevil
|
28
|
+
#
|
29
|
+
# for some reason it was needed to call to_s on photoset.title and photoset.description
|
30
|
+
# without this it will not set the value correctly
|
31
|
+
{
|
32
|
+
:id => photoset[:id],
|
33
|
+
:num_photos => photoset[:photos],
|
34
|
+
:title => photoset.title.to_s,
|
35
|
+
:description => photoset.description.to_s
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
data/lib/flickr/size.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# wrapping class to hold a flickr size
|
2
|
+
#
|
3
|
+
class Flickr::Photos::Size
|
4
|
+
attr_accessor :label, :width, :height, :source, :url
|
5
|
+
|
6
|
+
# create a new instance of a flickr size.
|
7
|
+
#
|
8
|
+
# Params
|
9
|
+
# * attributes (Required)
|
10
|
+
# a hash of attributes used to set the initial values of the size object
|
11
|
+
def initialize(attributes)
|
12
|
+
attributes.each do |k,v|
|
13
|
+
send("#{k}=", v)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# wrapper class to hold a flickr upload status object.
|
2
|
+
#
|
3
|
+
class Flickr::Uploader::Status
|
4
|
+
attr_accessor :nsid, :is_pro, :username, :max_bandwidth, :used_bandwidth, :remaining_bandwidth, :max_filesize, :max_videosize, :sets_created, :sets_remaining
|
5
|
+
|
6
|
+
# create a new instance of a flickr upload status object.
|
7
|
+
#
|
8
|
+
# Params
|
9
|
+
# * flickr (Required)
|
10
|
+
# the flickr object
|
11
|
+
# * attributes (Required)
|
12
|
+
# a hash of attributes used to set the initial values of the status object
|
13
|
+
def initialize(flickr, attributes)
|
14
|
+
@flickr = flickr
|
15
|
+
attributes.each do |k,v|
|
16
|
+
send("#{k}=", v)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/flickr/test.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
class Flickr::Test
|
2
|
+
def initialize(flickr)
|
3
|
+
@flickr = flickr
|
4
|
+
end
|
5
|
+
|
6
|
+
# A testing method which checks if the caller is logged in then returns their username.
|
7
|
+
#
|
8
|
+
def login
|
9
|
+
rsp = @flickr.send_request('flickr.test.login')
|
10
|
+
rsp.user.username.to_s
|
11
|
+
end
|
12
|
+
|
13
|
+
# A testing method which echo's all parameters back in the response.
|
14
|
+
#
|
15
|
+
# pass any number of options as a hash and it will be returned
|
16
|
+
#
|
17
|
+
def echo(options = {})
|
18
|
+
rsp = @flickr.send_request('flickr.test.echo', options)
|
19
|
+
|
20
|
+
options
|
21
|
+
end
|
22
|
+
|
23
|
+
# Null test
|
24
|
+
#
|
25
|
+
# Returns true unless there is an error
|
26
|
+
#
|
27
|
+
def null
|
28
|
+
rsp = @flickr.send_request('flickr.test.null')
|
29
|
+
true
|
30
|
+
end
|
31
|
+
end
|
data/lib/flickr/token.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# wrapping class to hold a flickr size
|
2
|
+
#
|
3
|
+
class Flickr::Auth::Token
|
4
|
+
attr_accessor :token, :permisions, :user_id, :username, :user_real_name
|
5
|
+
|
6
|
+
# create a new instance of a flickr auth token.
|
7
|
+
#
|
8
|
+
# Params
|
9
|
+
# * attributes (Required)
|
10
|
+
# a hash of attributes used to set the initial values of the token object
|
11
|
+
def initialize(attributes)
|
12
|
+
attributes.each do |k,v|
|
13
|
+
send("#{k}=", v) if respond_to?("#{k}=")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# overide the default to_s to output the text of the token
|
18
|
+
#
|
19
|
+
def to_s
|
20
|
+
self.token.to_s
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,162 @@
|
|
1
|
+
class Flickr::Uploader < Flickr::Base
|
2
|
+
def initialize(flickr)
|
3
|
+
@flickr = flickr
|
4
|
+
end
|
5
|
+
|
6
|
+
# upload a photo to flickr
|
7
|
+
#
|
8
|
+
# Params
|
9
|
+
# * filename (Required)
|
10
|
+
# path to the file to upload
|
11
|
+
# * options (Optional)
|
12
|
+
# options to attach to the photo (See Below)
|
13
|
+
#
|
14
|
+
# Options
|
15
|
+
# * title (Optional)
|
16
|
+
# The title of the photo.
|
17
|
+
# * description (Optional)
|
18
|
+
# A description of the photo. May contain some limited HTML.
|
19
|
+
# * tags (Optional)
|
20
|
+
# A space-seperated list of tags to apply to the photo.
|
21
|
+
# * privacy (Optional)
|
22
|
+
# Specifies who can view the photo. valid valus are:
|
23
|
+
# :public
|
24
|
+
# :private
|
25
|
+
# :friends
|
26
|
+
# :family
|
27
|
+
# :friends_and_family
|
28
|
+
# * safety_level (Optional)
|
29
|
+
# sets the safety level of the photo. valid values are:
|
30
|
+
# :safe
|
31
|
+
# :moderate
|
32
|
+
# :restricted
|
33
|
+
# * content_type (Optional)
|
34
|
+
# tells what type of image you are uploading. valid values are:
|
35
|
+
# :photo
|
36
|
+
# :screenshot
|
37
|
+
# :other
|
38
|
+
# * hidden (Optional)
|
39
|
+
# boolean that determines if the photo shows up in global searches
|
40
|
+
#
|
41
|
+
def upload(filename, options = {})
|
42
|
+
upload_data(File.new(filename, 'rb').read, MIME::Types.of(filename), options.merge(:filename => filename))
|
43
|
+
end
|
44
|
+
|
45
|
+
# upload a photo to flickr
|
46
|
+
#
|
47
|
+
# Params
|
48
|
+
# * photo (Required)
|
49
|
+
# image stored in a variable
|
50
|
+
# * mimetype (Required)
|
51
|
+
# mime type of the image
|
52
|
+
# * options (Optional)
|
53
|
+
# see upload method
|
54
|
+
#
|
55
|
+
def upload_data(photo, mimetype, options = {})
|
56
|
+
filename = options.delete(:filename) || Time.now.to_s
|
57
|
+
options = upload_options(options)
|
58
|
+
@flickr.sign_request(options)
|
59
|
+
|
60
|
+
form = Flickr::Uploader::MultiPartForm.new
|
61
|
+
|
62
|
+
options.each do |k,v|
|
63
|
+
form.parts << Flickr::Uploader::FormPart.new(k.to_s, v.to_s)
|
64
|
+
end
|
65
|
+
|
66
|
+
form.parts << Flickr::Uploader::FormPart.new('photo', photo, mimetype, filename)
|
67
|
+
|
68
|
+
headers = {"Content-Type" => "multipart/form-data; boundary=" + form.boundary}
|
69
|
+
|
70
|
+
rsp = Net::HTTP.start('api.flickr.com').post("/services/upload/", form.to_s, headers).body
|
71
|
+
|
72
|
+
xm = XmlMagic.new(rsp)
|
73
|
+
|
74
|
+
if xm[:stat] == 'ok'
|
75
|
+
xm
|
76
|
+
else
|
77
|
+
raise "#{xm.err[:code]}: #{xm.err[:msg]}"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# Returns information for the calling user related to photo uploads.
|
82
|
+
#
|
83
|
+
# * Bandwidth and filesize numbers are provided in bytes.
|
84
|
+
# * Bandwidth is specified in bytes per month.
|
85
|
+
# * Pro accounts display 99 for the number of remaining sets, since they have unlimited sets. Free accounts will display either 3, 2, 1, or 0.
|
86
|
+
#
|
87
|
+
def status
|
88
|
+
rsp = @flickr.send_request('flickr.people.getUploadStatus')
|
89
|
+
|
90
|
+
Flickr::Uploader::Status.new(@flickr, :nsid => rsp.user[:id],
|
91
|
+
:is_pro => (rsp.user[:ispro] == "1" ? true : false),
|
92
|
+
:username => rsp.user.username.to_s,
|
93
|
+
:max_bandwidth => rsp.user.bandwidth[:maxbytes],
|
94
|
+
:used_bandwidth => rsp.user.bandwidth[:usedbytes],
|
95
|
+
:remaining_bandwidth => rsp.user.bandwidth[:remainingbytes],
|
96
|
+
:max_filesize => rsp.user.filesize[:maxbytes],
|
97
|
+
:max_videosize => rsp.user.videosize[:maxbytes],
|
98
|
+
:sets_created => rsp.user.sets[:created].to_i,
|
99
|
+
:sets_remaining => (rsp.user[:ispro] == "1" ? 99 : rsp.user.sets[:remaining].to_i))
|
100
|
+
end
|
101
|
+
|
102
|
+
protected
|
103
|
+
|
104
|
+
def upload_options(options)
|
105
|
+
upload_options = { :api_key => @flickr.api_key }
|
106
|
+
upload_options.merge!({:title => options[:title], :description => options[:description], :tags => options[:tags]})
|
107
|
+
[ :is_public, :is_friend, :is_family, :async ].each { |key| upload_options[key] = options[key] ? '1' : '0' }
|
108
|
+
|
109
|
+
upload_options[:safety_level] = case options[:safety_level]
|
110
|
+
when :safe then '1'
|
111
|
+
when :moderate then '2'
|
112
|
+
when :restricted then '3'
|
113
|
+
end if options.has_key?(:safety_level)
|
114
|
+
|
115
|
+
upload_options[:content_type] = case options[:content_type]
|
116
|
+
when :photo then '1'
|
117
|
+
when :screenshot then '2'
|
118
|
+
when :other then '3'
|
119
|
+
end if options.has_key?(:content_type)
|
120
|
+
|
121
|
+
upload_options[:hidden] = options.has_key?(:hidden) ? '2' : '1'
|
122
|
+
upload_options
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
|
127
|
+
class Flickr::Uploader::FormPart
|
128
|
+
attr_reader :data, :mime_type, :attributes, :filename
|
129
|
+
|
130
|
+
def initialize(name, data, mime_type = nil, filename = nil)
|
131
|
+
@attributes = {}
|
132
|
+
@attributes['name'] = name
|
133
|
+
@attributes['filename'] = filename if filename
|
134
|
+
@data = data
|
135
|
+
@mime_type = mime_type
|
136
|
+
@filename = filename
|
137
|
+
end
|
138
|
+
|
139
|
+
def to_s
|
140
|
+
([ "Content-Disposition: form-data" ] +
|
141
|
+
attributes.map{|k,v| "#{k}=\"#{v}\""}).
|
142
|
+
join('; ') + "\r\n"+
|
143
|
+
(@mime_type ? "Content-Type: #{@mime_type}\r\n" : '')+
|
144
|
+
"\r\n#{data}"
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
|
149
|
+
class Flickr::Uploader::MultiPartForm
|
150
|
+
attr_accessor :boundary, :parts
|
151
|
+
|
152
|
+
def initialize(boundary=nil)
|
153
|
+
@boundary = boundary || "----------------------------Ruby#{rand(1000000000000)}"
|
154
|
+
@parts = []
|
155
|
+
end
|
156
|
+
|
157
|
+
def to_s
|
158
|
+
"--#@boundary\r\n" +
|
159
|
+
parts.map{|p| p.to_s}.join("\r\n--#@boundary\r\n")+
|
160
|
+
"\r\n--#@boundary--\r\n"
|
161
|
+
end
|
162
|
+
end
|
data/lib/flickr/urls.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
# Wrapping class that holds methods in the flickr.urls namespace
|
2
|
+
class Flickr::Urls < Flickr::Base
|
3
|
+
def initialize(flickr)
|
4
|
+
@flickr = flickr
|
5
|
+
end
|
6
|
+
|
7
|
+
def get_group group_id
|
8
|
+
rsp = @flickr.send_request('flickr.urls.getGroup', {:group_id => group_id})
|
9
|
+
rsp.group[:url]
|
10
|
+
end
|
11
|
+
|
12
|
+
def get_user_photos user_id
|
13
|
+
rsp = @flickr.send_request('flickr.urls.getUserPhotos', {:user_id => user_id})
|
14
|
+
rsp.user[:url]
|
15
|
+
end
|
16
|
+
|
17
|
+
def get_user_profile user_id
|
18
|
+
rsp = @flickr.send_request('flickr.urls.getUserProfile', {:user_id => user_id})
|
19
|
+
rsp.user[:url]
|
20
|
+
end
|
21
|
+
|
22
|
+
def lookup_group url #, options = {}
|
23
|
+
#options.symbolize_keys!
|
24
|
+
#options.reverse_merge!({:include_groupname => false})
|
25
|
+
rsp = @flickr.send_request('flickr.urls.lookupGroup', {:url => url})
|
26
|
+
#if options[:include_groupname]
|
27
|
+
#[rsp.group[:id], {:groupname => rsp.group.groupname}]
|
28
|
+
#else
|
29
|
+
rsp.group[:id]
|
30
|
+
#end
|
31
|
+
end
|
32
|
+
|
33
|
+
def lookup_user url
|
34
|
+
rsp = @flickr.send_request('flickr.urls.lookupUser', {:url => url})
|
35
|
+
user_id = UserLookupResult.new(rsp.user[:id])
|
36
|
+
user_id.username = rsp.user.username
|
37
|
+
user_id
|
38
|
+
end
|
39
|
+
|
40
|
+
class UserLookupResult < String
|
41
|
+
attr_accessor :username
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
data/lib/flickr_fu.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'xml_magic'
|
3
|
+
require 'net/http'
|
4
|
+
require 'cgi'
|
5
|
+
require 'uri'
|
6
|
+
require 'open-uri'
|
7
|
+
require 'mime/types'
|
8
|
+
require 'digest/md5'
|
9
|
+
require 'yaml'
|
10
|
+
require 'time'
|
11
|
+
require 'date'
|
12
|
+
|
13
|
+
# base must load first
|
14
|
+
[ "base",
|
15
|
+
"test",
|
16
|
+
"auth",
|
17
|
+
"token",
|
18
|
+
"photos",
|
19
|
+
"photo",
|
20
|
+
"photo_response",
|
21
|
+
"photosets",
|
22
|
+
"photoset",
|
23
|
+
"comment",
|
24
|
+
"note",
|
25
|
+
"size",
|
26
|
+
"uploader",
|
27
|
+
"status",
|
28
|
+
"people",
|
29
|
+
"person",
|
30
|
+
"license",
|
31
|
+
"errors",
|
32
|
+
"contacts",
|
33
|
+
"contact",
|
34
|
+
"geo",
|
35
|
+
"location",
|
36
|
+
"urls" ].each do |file|
|
37
|
+
require File.join(File.dirname(__FILE__), 'flickr', file)
|
38
|
+
end
|
39
|
+
|
40
|
+
include CommonThread::XML
|
41
|
+
|
42
|
+
class Object
|
43
|
+
# returning allows you to pass an object to a block that you can manipulate returning the manipulated object
|
44
|
+
def returning(value)
|
45
|
+
yield(value)
|
46
|
+
value
|
47
|
+
end
|
48
|
+
end
|