hjw3001-flickrx 0.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.
Files changed (7) hide show
  1. data/Manifest +5 -0
  2. data/README.rdoc +38 -0
  3. data/Rakefile +14 -0
  4. data/flickrx.gemspec +29 -0
  5. data/init.rb +1 -0
  6. data/lib/flickrx.rb +878 -0
  7. metadata +64 -0
data/Manifest ADDED
@@ -0,0 +1,5 @@
1
+ init.rb
2
+ lib/flickrx.rb
3
+ Rakefile
4
+ README.rdoc
5
+ Manifest
data/README.rdoc ADDED
@@ -0,0 +1,38 @@
1
+ = Uniquify
2
+
3
+ Ruby gem implementation of Flickr API.
4
+
5
+ http://www.flickr.com/services/api/.
6
+
7
+
8
+ == Install
9
+
10
+ gem install hjw3001-flickrx --source http://gems.github.com
11
+
12
+
13
+ == Usage
14
+
15
+ TBD
16
+
17
+ == License
18
+
19
+ Copyright (c) 2009 Henry Wagner
20
+
21
+ Permission is hereby granted, free of charge, to any person obtaining
22
+ a copy of this software and associated documentation files (the
23
+ "Software"), to deal in the Software without restriction, including
24
+ without limitation the rights to use, copy, modify, merge, publish,
25
+ distribute, sublicense, and/or sell copies of the Software, and to
26
+ permit persons to whom the Software is furnished to do so, subject to
27
+ the following conditions:
28
+
29
+ The above copyright notice and this permission notice shall be
30
+ included in all copies or substantial portions of the Software.
31
+
32
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
33
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
34
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
35
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
36
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
37
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
38
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,14 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'echoe'
4
+
5
+ Echoe.new('flickrx', '0.1.0') do |p|
6
+ p.description = "Ruby implementation of Flickr API."
7
+ p.url = "http://github.com/hjw3001/flickrx"
8
+ p.author = "Henry Wagner"
9
+ p.email = "hjw3001@gmail.com"
10
+ p.ignore_pattern = ["tmp/*", "script/*"]
11
+ p.development_dependencies = []
12
+ end
13
+
14
+ Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext }
data/flickrx.gemspec ADDED
@@ -0,0 +1,29 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = %q{flickrx}
3
+ s.version = "0.1.0"
4
+
5
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
6
+ s.authors = ["Henry Wagner"]
7
+ s.date = %q{2009-02-12}
8
+ s.description = %q{Ruby implementation of Flickr API.}
9
+ s.email = %q{hjw3001@gmail.com}
10
+ s.extra_rdoc_files = ["lib/flickrx.rb", "README.rdoc"]
11
+ s.files = ["init.rb", "lib/flickrx.rb", "Rakefile", "README.rdoc", "Manifest", "flickrx.gemspec"]
12
+ s.has_rdoc = true
13
+ s.homepage = %q{http://github.com/hjw3001/flickrx}
14
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Flickrx", "--main", "README.rdoc"]
15
+ s.require_paths = ["lib"]
16
+ s.rubyforge_project = %q{flickrx}
17
+ s.rubygems_version = %q{1.2.0}
18
+ s.summary = %q{Ruby implementation of Flickr API.}
19
+
20
+ if s.respond_to? :specification_version then
21
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
22
+ s.specification_version = 2
23
+
24
+ if current_version >= 3 then
25
+ else
26
+ end
27
+ else
28
+ end
29
+ end
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'flickrx'
data/lib/flickrx.rb ADDED
@@ -0,0 +1,878 @@
1
+ ##
2
+ # Ruby API for Flickr (See http://www.flickr.com/services/api/)
3
+ # (C) 2008 Henry Wagner
4
+ # http://www.henrywagner.org/
5
+
6
+ __AUTHOR__ = "Henry Wagner"
7
+ __VERSION__ = "0.1"
8
+ __DATE__ = "2008-05-02 21:55"
9
+
10
+ require 'cgi'
11
+ require 'md5'
12
+ require 'optparse'
13
+ require 'net/http'
14
+ require 'rexml/document'
15
+ require 'yaml'
16
+ include REXML
17
+
18
+ module Flickrx
19
+
20
+ class Utils
21
+ def cleanString(source)
22
+ if source == nil
23
+ return
24
+ elsif source == "N/A" then
25
+ source = nil
26
+ elsif source.count("\"") > 0 then
27
+ list = source.split(/\"/)
28
+ source = list[1]
29
+ elsif source.count("/thumb") > 0 then
30
+ list = source.split(/thumb/)
31
+ source = list[0]
32
+ end
33
+ if (source != nil)
34
+ source = CGI::unescapeHTML(source)
35
+ end
36
+ source
37
+ end
38
+
39
+ def fixFilename(source)
40
+ if source.index('jpg') == nil then
41
+ source = source + '.jpg'
42
+ end
43
+ source
44
+ end
45
+ end
46
+
47
+ class Flickr
48
+
49
+ @@template = <<EOF
50
+ # .flickrx
51
+ #
52
+ # Please fill in fields like this:
53
+ #
54
+ # email: bla@bla.com
55
+ # password: secret
56
+ #
57
+ api_key:
58
+ secret:
59
+ EOF
60
+
61
+ attr_reader :config, :nsid, :username, :fullname
62
+
63
+ def initialize
64
+ @config = create_or_find_config
65
+ @interface = 'http://www.flickr.com/services/rest/'
66
+ @auth_url = 'http://flickr.com/services/auth/'
67
+ @nsid = ''
68
+ @username = ''
69
+ @fullname = ''
70
+ end
71
+
72
+ def get_frob
73
+ method = 'flickr.auth.getFrob'
74
+ api_sig = _get_api_sig({'method' => method})
75
+ data = _do_get(method, {
76
+ 'api_sig' => api_sig
77
+ }
78
+ )
79
+ doc = Document.new(data)
80
+ doc.elements.each('rsp/frob') { |frob|
81
+ return frob.text
82
+ }
83
+ end
84
+
85
+ ##
86
+ # perms:
87
+ # 'read', 'write', 'delete'
88
+ ##
89
+ def get_login_url(frob, perms='read')
90
+ api_sig = _get_api_sig({'frob' => frob, 'perms' => perms});
91
+ return "#{@auth_url}?api_key=#{@config['api_key']}&perms=#{perms}&frob=#{frob}&api_sig=#{api_sig}"
92
+ end
93
+
94
+ def get_token(frob)
95
+ method = 'flickr.auth.getToken'
96
+ api_sig = _get_api_sig({'frob' => frob, 'method' => method})
97
+ data = _do_get(method, {
98
+ 'api_sig' => api_sig,
99
+ 'frob' => frob
100
+ }
101
+ )
102
+ doc = Document.new(data)
103
+ doc.elements.each('rsp/auth') { |auth|
104
+ token = auth.elements['token'].text
105
+ user = auth.elements['user']
106
+ @nsid = user.attributes['nsid']
107
+ @username = user.attributes['username']
108
+ @fullname = user.attributes['fullname']
109
+ return token
110
+ }
111
+ end
112
+
113
+ def _do_get(method, *params)
114
+ params.each { |x, y|
115
+ if y.class == Array then params[x] = y.join(y) end
116
+ }
117
+ url = "#{@interface}?api_key=#{@config['api_key']}&method=#{method}#{_urlencode(params)}"
118
+ resp = Net::HTTP.get_response(URI.parse(url))
119
+ doc = Document.new(resp.body.to_s)
120
+ if doc.elements['rsp'].attributes['stat'] != 'ok'
121
+ error_code = doc.elements['rsp'].elements['err'].attributes['code']
122
+ error_msg = doc.elements['rsp'].elements['err'].attributes['msg']
123
+ msg = "ERROR[#{error_code}]: #{error_msg}"
124
+ p msg
125
+ exit
126
+ end
127
+ resp.body.to_s
128
+ end
129
+
130
+ def _urlencode(params)
131
+ ret = ''
132
+ params.each { |param|
133
+ param.each { |x, y|
134
+ ret += "&#{x}=#{y}" unless "#{y}" == nil
135
+ }
136
+ }
137
+ ret
138
+ end
139
+
140
+ def _get_api_sig(params)
141
+ ret = ''
142
+ params.sort.each { |x, y|
143
+ ret += "#{x}#{y}" unless "#{y}" == nil
144
+ }
145
+ MD5.md5("#{@config['secret']}api_key#{@config['api_key']}#{ret}")
146
+ end
147
+
148
+ protected
149
+
150
+ # Checks for the config, creates it if not found
151
+ def create_or_find_config
152
+ home = ENV['HOME'] || ENV['USERPROFILE'] || ENV['HOMEPATH']
153
+ begin
154
+ config = YAML::load open(home + "/.flickrx")
155
+ rescue
156
+ open(home + '/.flickrx','w').write(@@template)
157
+ config = YAML::load open(home + "/.flickrx")
158
+ end
159
+
160
+ if config['api_key'] == nil or config['secret'] == nil
161
+ puts "Please edit ~/.flickrx to include your flickr api_key and secret\nTextmate users: mate ~/.flickrx"
162
+ exit(0)
163
+ end
164
+
165
+ config
166
+ end
167
+
168
+ end
169
+
170
+ class Contacts < Flickr
171
+
172
+ ##
173
+ # filter:
174
+ # 'friends', 'family', 'both', 'neither'
175
+ ##
176
+ def get_list(auth_token, filter='')
177
+ method = 'flickr.contacts.getList'
178
+ api_sig = _get_api_sig(
179
+ {
180
+ 'method' => method,
181
+ 'auth_token' => config['token'],
182
+ 'filter' => filter
183
+ }
184
+ )
185
+ data = _do_get(method,
186
+ {
187
+ 'api_sig' => api_sig,
188
+ 'auth_token' => config['token'],
189
+ 'filter' => filter
190
+ }
191
+ )
192
+ doc = Document.new(data)
193
+ contacts = []
194
+ doc.elements.each('rsp/contacts/contact') { |contact|
195
+ contacts << {
196
+ 'nsid' => contact.attributes['nsid'],
197
+ 'username' => contact.attributes['username'],
198
+ 'realname' => contact.attributes['realname'],
199
+ 'friend' => contact.attributes['friend'],
200
+ 'family' => contact.attributes['family'],
201
+ 'ignored' => contact.attributes['ignored']
202
+ }
203
+ }
204
+ return contacts
205
+ end
206
+
207
+ def get_public_list(nsid)
208
+ method = 'flickr.contacts.getPublicList'
209
+ data = _do_get(method,
210
+ {
211
+ 'api_key' => config['api_key'],
212
+ 'user_id' => nsid
213
+ }
214
+ )
215
+ doc = Document.new(data)
216
+ contacts = []
217
+ doc.elements.each('rsp/contacts/contact') { |contact|
218
+ contacts << {
219
+ 'nsid' => contact.attributes['nsid'],
220
+ 'username' => contact.attributes['username'],
221
+ 'ignored' => contact.attributes['ignored']
222
+ }
223
+ }
224
+ return contacts
225
+ end
226
+ end
227
+
228
+ class Favorites < Flickr
229
+
230
+ def add(auth_token, photo_id)
231
+ method = 'flickr.favorites.add'
232
+ api_sig = _get_api_sig(
233
+ {
234
+ 'method' => method,
235
+ 'auth_token' => config['token'],
236
+ 'photo_id' => photo_id
237
+ }
238
+ )
239
+ data = _do_get(method, {
240
+ 'api_sig' => api_sig,
241
+ 'auth_token' => config['token'],
242
+ 'photo_id' => photo_id
243
+ }
244
+ )
245
+ if data
246
+ return true
247
+ end
248
+ end
249
+
250
+ ##
251
+ # extras: array that consists one or more of
252
+ # license, date_upload, date_taken, owner_name, icon_server
253
+ ##
254
+ def get_list(auth_token, nsid='', extras=[], per_page=100, page=1)
255
+ method = 'flickr.favorites.getList'
256
+ api_sig = _get_api_sig(
257
+ {
258
+ 'method' => method,
259
+ 'auth_token' => config['token'],
260
+ 'user_id' => nsid,
261
+ 'extras' => extras.join(','),
262
+ 'per_page' => per_page,
263
+ 'page' => page
264
+ }
265
+ )
266
+ data = _do_get(method,
267
+ {
268
+ 'api_sig' => api_sig,
269
+ 'auth_token' => config['token'],
270
+ 'user_id' => nsid,
271
+ 'extras' => extras.join(','),
272
+ 'per_page' => per_page,
273
+ 'page' => page
274
+ }
275
+ )
276
+ doc = Document.new(data)
277
+ photos = []
278
+ doc.elements.each('rsp/photos/photo') { |photo|
279
+ photos << {
280
+ 'id' => photo.attributes['id'],
281
+ 'owner' => photo.attributes['owner'],
282
+ 'ispublic' => photo.attributes['ispublic'],
283
+ 'isfamily' => photo.attributes['isfamily'],
284
+ 'isfriend' => photo.attributes['isfriend'],
285
+ 'title' => photo.attributes['title'],
286
+ 'license' => photo.attributes['license'],
287
+ 'owner_name' => photo.attributes['ownername'],
288
+ 'date_taken' => photo.attributes['datetaken'],
289
+ 'date_upload' => photo.attributes['dateupload']
290
+ }
291
+ }
292
+ return photos
293
+ end
294
+
295
+ ##
296
+ # extras: array that consists one or more of
297
+ # license, date_upload, date_taken, owner_name, icon_server
298
+ ##
299
+ def get_public_list(nsid, extras=[], per_page=100, page=1)
300
+ method = 'flickr.favorites.getPublicList'
301
+ data = _do_get(method,
302
+ {
303
+ 'api_key' => @config['api_key'],
304
+ 'user_id' => nsid,
305
+ 'extras' => extras.join(','),
306
+ 'per_page' => per_page,
307
+ 'page' => page
308
+ }
309
+ )
310
+ doc = Document.new(data)
311
+ photos = []
312
+ doc.elements.each('rsp/photos/photo') { |photo|
313
+ photos << {
314
+ 'id' => photo.attributes['id'],
315
+ 'owner' => photo.attributes['owner'],
316
+ 'ispublic' => photo.attributes['ispublic'],
317
+ 'isfamily' => photo.attributes['isfamily'],
318
+ 'isfriend' => photo.attributes['isfriend'],
319
+ 'title' => photo.attributes['title'],
320
+ 'license' => photo.attributes['license'],
321
+ 'owner_name' => photo.attributes['ownername'],
322
+ 'date_taken' => photo.attributes['datetaken'],
323
+ 'date_upload' => photo.attributes['dateupload']
324
+ }
325
+ }
326
+ return photos
327
+ end
328
+
329
+ def remove(auth_token, photo_id)
330
+ method = 'flickr.favorites.remove'
331
+ api_sig = _get_api_sig(
332
+ {
333
+ 'method' => method,
334
+ 'auth_token' => config['token'],
335
+ 'photo_id' => photo_id
336
+ }
337
+ )
338
+ data = _do_get(method, {
339
+ 'api_sig' => api_sig,
340
+ 'auth_token' => config['token'],
341
+ 'photo_id' => photo_id
342
+ }
343
+ )
344
+ if data
345
+ return true
346
+ end
347
+ end
348
+ end
349
+
350
+ class Group < Flickr
351
+ def poolAdd(photo_id, group_id)
352
+ puts "Adding #{photo_id} to #{group_id}"
353
+ method = 'flickr.groups.pools.add'
354
+ api_sig = _get_api_sig(
355
+ {
356
+ 'method' => method,
357
+ 'auth_token' => config['token'],
358
+ 'photo_id' => photo_id,
359
+ 'group_id' => group_id
360
+ }
361
+ )
362
+ data = _do_get(method, {
363
+ 'api_sig' => api_sig,
364
+ 'auth_token' => config['token'],
365
+ 'photo_id' => photo_id,
366
+ 'group_id' => group_id
367
+ }
368
+ )
369
+ if data
370
+ return true
371
+ end
372
+ end
373
+ end
374
+
375
+ class PhotoSets < Flickr
376
+
377
+ def addPhoto(photoset_id, photo_id)
378
+ method = 'flickr.photosets.addPhoto'
379
+ api_sig = _get_api_sig(
380
+ {
381
+ 'method' => method,
382
+ 'auth_token' => config['token'],
383
+ 'photo_id' => photo_id,
384
+ 'photoset_id' => photoset_id
385
+ }
386
+ )
387
+ data = _do_get(method, {
388
+ 'api_sig' => api_sig,
389
+ 'auth_token' => config['token'],
390
+ 'photo_id' => photo_id,
391
+ 'photoset_id' => photoset_id
392
+ }
393
+ )
394
+ if data
395
+ return true
396
+ end
397
+ end
398
+
399
+ def create(title, description, primary_photo_id)
400
+ method = 'flickr.photosets.create'
401
+ if (description != nil)
402
+ api_sig = _get_api_sig(
403
+ {
404
+ 'method' => method,
405
+ 'auth_token' => config['token'],
406
+ 'primary_photo_id' => primary_photo_id,
407
+ 'title' => title,
408
+ 'description' => description
409
+ }
410
+ )
411
+ data = _do_get(method, {
412
+ 'api_sig' => api_sig,
413
+ 'auth_token' => config['token'],
414
+ 'primary_photo_id' => primary_photo_id,
415
+ 'title' => CGI::escape(title),
416
+ 'description' => CGI::escape(description)
417
+ }
418
+ )
419
+ else
420
+ api_sig = _get_api_sig(
421
+ {
422
+ 'method' => method,
423
+ 'auth_token' => config['token'],
424
+ 'primary_photo_id' => primary_photo_id,
425
+ 'title' => title
426
+ }
427
+ )
428
+ data = _do_get(method, {
429
+ 'api_sig' => api_sig,
430
+ 'auth_token' => config['token'],
431
+ 'primary_photo_id' => primary_photo_id,
432
+ 'title' => CGI::escape(title)
433
+ }
434
+ )
435
+ end
436
+ doc = Document.new(data)
437
+ photosets = []
438
+ doc.elements.each('rsp/photoset') { |photoset|
439
+ photosets << {
440
+ 'id' => photoset.attributes['id']
441
+ }
442
+ }
443
+ return photosets
444
+ end
445
+
446
+ def delete(auth_token, photoset_id)
447
+ method = 'flickr.photosets.delete'
448
+ api_sig = _get_api_sig(
449
+ {
450
+ 'method' => method,
451
+ 'auth_token' => auth_token,
452
+ 'photoset_id' => photoset_id
453
+ }
454
+ )
455
+ data = _do_get(method, {
456
+ 'api_sig' => api_sig,
457
+ 'auth_token' => auth_token,
458
+ 'photoset_id' => photoset_id
459
+ }
460
+ )
461
+ if data
462
+ return true
463
+ end
464
+ end
465
+
466
+ def getList(user_id = nil)
467
+ method = 'flickr.photosets.getList'
468
+ api_sig = _get_api_sig(
469
+ {
470
+ 'method' => method,
471
+ 'auth_token' => config['token'],
472
+ 'user_id' => user_id
473
+ }
474
+ )
475
+ data = _do_get(method, {
476
+ 'api_sig' => api_sig,
477
+ 'auth_token' => config['token'],
478
+ 'user_id' => user_id
479
+ }
480
+ )
481
+
482
+ doc = Document.new(data)
483
+ photosets = Hash.new
484
+ doc.elements.each('rsp/photosets/photoset') { |photoset|
485
+ photosets[photoset.elements['title'].text] = {
486
+ 'id' => photoset.attributes['id']
487
+ }
488
+ # photoset.attributes['id'] => photoset.elements['title'].text
489
+ }
490
+ return photosets
491
+ end
492
+
493
+ def orderSets(photosets)
494
+ method = 'flickr.photosets.orderSets'
495
+ api_sig = _get_api_sig(
496
+ {
497
+ 'method' => method,
498
+ 'auth_token' => config['token'],
499
+ 'photoset_ids' => photosets
500
+ }
501
+ )
502
+ data = _do_get(method, {
503
+ 'api_sig' => api_sig,
504
+ 'auth_token' => config['token'],
505
+ 'photoset_ids' => photosets
506
+ }
507
+ )
508
+ if data
509
+ return true
510
+ end
511
+ end
512
+
513
+ end
514
+
515
+ class Photos < Flickr
516
+
517
+ def add_tags(auth_token, photo_id, tags)
518
+ method = 'flickr.photos.addTags'
519
+ api_sig = _get_api_sig(
520
+ {
521
+ 'method' => method,
522
+ 'auth_token' => auth_token,
523
+ 'photo_id' => photo_id,
524
+ 'tags' => tags.join(' ')
525
+ }
526
+ )
527
+ data = _do_get(method, {
528
+ 'api_sig' => api_sig,
529
+ 'auth_token' => auth_token,
530
+ 'photo_id' => photo_id,
531
+ 'tags' => tags.join(' ')
532
+ }
533
+ )
534
+ doc = Document.new(data)
535
+ photos = []
536
+ doc.elements.each('rsp/photos/photo') { |photo|
537
+ photos << {
538
+ 'id' => photo.attributes['id'],
539
+ 'owner' => photo.attributes['owner'],
540
+ 'username' => photo.attributes['username'],
541
+ 'title' => photo.attributes['title']
542
+ }
543
+ }
544
+ return photos
545
+ end
546
+
547
+ ##
548
+ # max(count) = 50
549
+ ##
550
+ def get_contacts_photos(auth_token, count=10, just_friends=0, single_photo=0, include_self=0)
551
+ method = 'flickr.photos.getContactsPhotos'
552
+ api_sig = _get_api_sig(
553
+ {
554
+ 'method' => method,
555
+ 'auth_token' => auth_token,
556
+ 'count' => count,
557
+ 'just_friends' => just_friends,
558
+ 'single_photo' => single_photo,
559
+ 'include_self' => include_self
560
+ }
561
+ )
562
+ data = _do_get(method, {
563
+ 'api_sig' => api_sig,
564
+ 'auth_token' => auth_token,
565
+ 'count' => count,
566
+ 'just_friends' => just_friends,
567
+ 'single_photo' => single_photo,
568
+ 'include_self' => include_self
569
+ }
570
+ )
571
+ doc = Document.new(data)
572
+ photos = []
573
+ doc.elements.each('rsp/photos/photo') { |photo|
574
+ photos << {
575
+ 'id' => photo.attributes['id'],
576
+ 'owner' => photo.attributes['owner'],
577
+ 'username' => photo.attributes['username'],
578
+ 'title' => photo.attributes['title']
579
+ }
580
+ }
581
+ return photos
582
+ end
583
+
584
+ ##
585
+ # max(count) = 50
586
+ ##
587
+ def get_contacts_public_photos(nsid, count=10, just_friends=0, single_photo=0, include_self=0)
588
+ method = 'flickr.photos.getContactsPublicPhotos'
589
+ data = _do_get(method, {
590
+ 'api_key' => @config['api_key'],
591
+ 'user_id' => nsid,
592
+ 'count' => count,
593
+ 'just_friends' => just_friends,
594
+ 'single_photo' => single_photo,
595
+ 'include_self' => include_self
596
+ }
597
+ )
598
+ doc = Document.new(data)
599
+ photos = []
600
+ doc.elements.each('rsp/photos/photo') { |photo|
601
+ photos << {
602
+ 'id' => photo.attributes['id'],
603
+ 'owner' => photo.attributes['owner'],
604
+ 'username' => photo.attributes['username'],
605
+ 'title' => photo.attributes['title']
606
+ }
607
+ }
608
+ return photos
609
+ end
610
+
611
+ def get_favorites(photo_id)
612
+ method = 'flickr.photos.getFavorites'
613
+ data = _do_get(method, {
614
+ 'api_key' => @config['api_key'],
615
+ 'photo_id' => photo_id
616
+ }
617
+ )
618
+ doc = Document.new(data)
619
+ doc.elements.each('rsp/photo') { |photo|
620
+ return {
621
+ 'id' => photo.attributes['id'],
622
+ 'secret' => photo.attributes['secret'],
623
+ 'server' => photo.attributes['server'],
624
+ 'farm' => photo.attributes['farm'],
625
+ 'page' => photo.attributes['page'],
626
+ 'pages' => photo.attributes['pages'],
627
+ 'perpage' => photo.attributes['perpage'],
628
+ 'total' => photo.attributes['total']
629
+ }
630
+ }
631
+ end
632
+
633
+ def get_info(photo_id)
634
+ method = 'flickr.photos.getInfo'
635
+ api_sig = _get_api_sig(
636
+ {
637
+ 'method' => method,
638
+ 'auth_token' => config['token'],
639
+ 'photo_id' => photo_id
640
+ }
641
+ )
642
+ data = _do_get(method, {
643
+ 'api_sig' => api_sig,
644
+ 'auth_token' => config['token'],
645
+ 'photo_id' => photo_id
646
+ }
647
+ )
648
+ doc = Document.new(data)
649
+ doc.elements.each('rsp/photo') { |photo|
650
+ owner = photo.elements['owner']
651
+ date = photo.elements['dates']
652
+ tags = photo.elements['tags']
653
+ tags_arr = []
654
+ photo.elements.each('tags/tag') { |tag|
655
+ tags_arr << {
656
+ 'id' => tag.attributes['id'],
657
+ 'text' => tag.text
658
+ }
659
+ }
660
+ urls = photo.elements['urls']
661
+ urls_arr = []
662
+ photo.elements.each('urls/url') { |url|
663
+ urls_arr << url.text
664
+ }
665
+ return {
666
+ 'id' => photo.attributes['id'],
667
+ 'isfavorite' => photo.attributes['isfavorite'],
668
+ 'license' => photo.attributes['license'],
669
+ 'views' => photo.attributes['views'],
670
+ 'media' => photo.attributes['media'],
671
+ 'title' => photo.elements['title'].text,
672
+ 'owner_nsid' => owner.attributes['nsid'],
673
+ 'owner_username'=> owner.attributes['username'],
674
+ 'owner_realname'=> owner.attributes['realname'],
675
+ 'owner_location'=> owner.attributes['location'],
676
+ 'date_posted' => date.attributes['posted'],
677
+ 'date_taken' => date.attributes['taken'],
678
+ 'tags' => tags_arr,
679
+ 'urls' => urls_arr
680
+ }
681
+ }
682
+ end
683
+
684
+ def search(user_id, tags, tag_mode, page = 0, per_page = 500)
685
+ method = 'flickr.photos.search'
686
+ data = _do_get(method, {
687
+ 'api_key' => @config['api_key'],
688
+ 'user_id' => user_id,
689
+ 'tags' => tags,
690
+ 'tag_mode' => tag_mode,
691
+ 'page' => page,
692
+ 'per_page' => per_page
693
+
694
+ }
695
+ )
696
+ doc = Document.new(data)
697
+ photos = []
698
+ doc.elements.each('rsp/photos/photo') { |photo|
699
+ photos << {
700
+ 'id' => photo.attributes['id'],
701
+ 'owner' => photo.attributes['owner']
702
+ }
703
+ }
704
+ return photos
705
+ end
706
+
707
+ def removeTag(auth_token, tag_id)
708
+ method = 'flickr.photos.removeTag'
709
+ api_sig = _get_api_sig(
710
+ {
711
+ 'method' => method,
712
+ 'auth_token' => config['token'],
713
+ 'tag_id' => tag_id
714
+ }
715
+ )
716
+ data = _do_get(method, {
717
+ 'api_sig' => api_sig,
718
+ 'auth_token' => config['token'],
719
+ 'tag_id' => tag_id
720
+ }
721
+ )
722
+ if data
723
+ return true
724
+ end
725
+ end
726
+
727
+ end
728
+
729
+ class People < Flickr
730
+
731
+ def getPublicPhotos(user_id)
732
+ method = 'flickr.people.getPublicPhotos'
733
+ photos = []
734
+ page = 1
735
+ pages = 0
736
+
737
+ # Find all the photos on all the pages
738
+ begin
739
+ data = _do_get(method, {
740
+ 'api_key' => @config['api_key'],
741
+ 'user_id' => user_id,
742
+ 'page' => page
743
+
744
+ }
745
+ )
746
+ doc = Document.new(data)
747
+ doc.elements.each('rsp/photos') { |object|
748
+ pages = object.attributes['pages']
749
+ puts 'page ' + object.attributes['page'] + ' of ' + pages
750
+ }
751
+ doc.elements.each('rsp/photos/photo') { |photo|
752
+ photos << {
753
+ 'id' => photo.attributes['id'],
754
+ 'owner' => photo.attributes['owner'],
755
+ 'secret' => photo.attributes['secret'],
756
+ 'server' => photo.attributes['server'],
757
+ 'farm' => photo.attributes['farm'],
758
+ 'title' => photo.attributes['title'],
759
+ 'ispublic' => photo.attributes['ispublic'],
760
+ 'isfriend' => photo.attributes['isfriend'],
761
+ 'isfamily' => photo.attributes['isfamily']
762
+ }
763
+ }
764
+ page = page + 1
765
+ end while page <= pages.to_i
766
+
767
+ return photos
768
+ end
769
+
770
+ end
771
+
772
+ class Upload < Flickr
773
+
774
+ def _to_multipart(name, value)
775
+ return "Content-Disposition: form-data; name=\"#{CGI::escape(name)}\"\r\n\r\n#{value}\r\n"
776
+ end
777
+
778
+ def _file_to_multipart(name, file, content)
779
+ return "Content-Disposition: form-data; name=\"#{CGI::escape(name)}\"; filename=\"#{file}\"\r\n" +
780
+ "Content-Transfer-Encoding: binary\r\n" +
781
+ "Content-Type: image/jpeg\r\n\r\n" + content + "\r\n"
782
+ end
783
+
784
+ def _prepare_query(params)
785
+ query = params.collect { |k, v|
786
+ if v.respond_to?(:read)
787
+ q = _file_to_multipart(k, v.path, v.read)
788
+ else
789
+ q = _to_multipart(k, v)
790
+ end
791
+ "--" + @boundary + "\r\n" + q
792
+ }.join("") + "--" + @boundary + "--"
793
+ header = {"Content-type" => "multipart/form-data, boundary=" + @boundary + " "}
794
+ return query, header
795
+ end
796
+
797
+ def upload(photo, title='', description='', tags='', is_public=1, is_friend=0, is_family=0)
798
+ @flickr_host = 'www.flickr.com'
799
+ @upload_action = '/services/upload/'
800
+ @boundary = MD5.md5(photo).to_s
801
+ file = File.new(photo, 'rb')
802
+ api_sig = _get_api_sig(
803
+ {
804
+ 'auth_token' => config['token'],
805
+ 'title' => title,
806
+ 'description' => description,
807
+ 'tags' => tags,
808
+ 'is_public' => is_public,
809
+ 'is_family' => is_family,
810
+ 'is_friend' => is_friend
811
+ }
812
+ )
813
+ params = {
814
+ 'api_key' => config['api_key'],
815
+ 'api_sig' => api_sig,
816
+ 'auth_token' => config['token'],
817
+ 'photo' => file,
818
+ 'title' => title,
819
+ 'description' => description,
820
+ 'tags' => tags,
821
+ 'is_public' => is_public,
822
+ 'is_family' => is_family,
823
+ 'is_friend' => is_friend
824
+ }
825
+ query, header = _prepare_query(params)
826
+ file.close
827
+ Net::HTTP.start(@flickr_host, 80) { |http|
828
+ http.read_timeout = 10000
829
+ http.open_timeout = 10000
830
+ response = http.post(@upload_action, query, header)
831
+ doc = Document.new(response.body)
832
+ status = doc.elements['rsp'].attributes['stat']
833
+ if status == "ok"
834
+ photoid = doc.elements['rsp/photoid'].text
835
+ return photoid
836
+ else
837
+ return false
838
+ end
839
+ }
840
+ end
841
+
842
+ def replace(photo, photo_id)
843
+ @flickr_host = 'www.flickr.com'
844
+ @upload_action = '/services/replace/'
845
+ @boundary = MD5.md5(photo).to_s
846
+ file = File.new(photo, 'rb')
847
+ api_sig = _get_api_sig(
848
+ {
849
+ 'auth_token' => config['token'],
850
+ 'photo_id' => photo_id
851
+ }
852
+ )
853
+ params = {
854
+ 'api_key' => config['api_key'],
855
+ 'api_sig' => api_sig,
856
+ 'auth_token' => config['token'],
857
+ 'photo' => file,
858
+ 'photo_id' => photo_id
859
+ }
860
+ query, header = _prepare_query(params)
861
+ file.close
862
+ Net::HTTP.start(@flickr_host, 80) { |http|
863
+ http.read_timeout = 10000
864
+ http.open_timeout = 10000
865
+ response = http.post(@upload_action, query, header)
866
+ doc = Document.new(response.body)
867
+ status = doc.elements['rsp'].attributes['stat']
868
+ if status == "ok"
869
+ photoid = doc.elements['rsp/photoid'].text
870
+ return photoid
871
+ else
872
+ return false
873
+ end
874
+ }
875
+ end
876
+
877
+ end
878
+ end
metadata ADDED
@@ -0,0 +1,64 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hjw3001-flickrx
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Henry Wagner
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-02-12 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Ruby implementation of Flickr API.
17
+ email: hjw3001@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - lib/flickrx.rb
24
+ - README.rdoc
25
+ files:
26
+ - init.rb
27
+ - lib/flickrx.rb
28
+ - Rakefile
29
+ - README.rdoc
30
+ - Manifest
31
+ - flickrx.gemspec
32
+ has_rdoc: true
33
+ homepage: http://github.com/hjw3001/flickrx
34
+ post_install_message:
35
+ rdoc_options:
36
+ - --line-numbers
37
+ - --inline-source
38
+ - --title
39
+ - Flickrx
40
+ - --main
41
+ - README.rdoc
42
+ require_paths:
43
+ - lib
44
+ required_ruby_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: "0"
49
+ version:
50
+ required_rubygems_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: "1.2"
55
+ version:
56
+ requirements: []
57
+
58
+ rubyforge_project: flickrx
59
+ rubygems_version: 1.2.0
60
+ signing_key:
61
+ specification_version: 2
62
+ summary: Ruby implementation of Flickr API.
63
+ test_files: []
64
+