maciej-flickr_fu 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. data/.gitignore +13 -0
  2. data/LICENSE +22 -0
  3. data/README +147 -0
  4. data/Rakefile +73 -0
  5. data/VERSION.yml +4 -0
  6. data/flickr_fu.gemspec +117 -0
  7. data/lib/flickr/auth.rb +76 -0
  8. data/lib/flickr/base.rb +151 -0
  9. data/lib/flickr/comment.rb +16 -0
  10. data/lib/flickr/contact.rb +16 -0
  11. data/lib/flickr/contacts.rb +55 -0
  12. data/lib/flickr/errors.rb +20 -0
  13. data/lib/flickr/geo.rb +42 -0
  14. data/lib/flickr/license.rb +24 -0
  15. data/lib/flickr/location.rb +15 -0
  16. data/lib/flickr/note.rb +16 -0
  17. data/lib/flickr/people.rb +54 -0
  18. data/lib/flickr/person.rb +82 -0
  19. data/lib/flickr/photo.rb +303 -0
  20. data/lib/flickr/photo_response.rb +37 -0
  21. data/lib/flickr/photos.rb +246 -0
  22. data/lib/flickr/photoset.rb +36 -0
  23. data/lib/flickr/photosets.rb +36 -0
  24. data/lib/flickr/size.rb +16 -0
  25. data/lib/flickr/status.rb +19 -0
  26. data/lib/flickr/test.rb +31 -0
  27. data/lib/flickr/token.rb +22 -0
  28. data/lib/flickr/uploader.rb +162 -0
  29. data/lib/flickr/urls.rb +44 -0
  30. data/lib/flickr_fu.rb +48 -0
  31. data/spec/fixtures/flickr/contacts/get_list-fail-99.xml +4 -0
  32. data/spec/fixtures/flickr/contacts/get_public_list-0.xml +7 -0
  33. data/spec/fixtures/flickr/photos/geo/get_location-0.xml +11 -0
  34. data/spec/fixtures/flickr/photos/geo/get_location-fail-2.xml +4 -0
  35. data/spec/fixtures/flickr/photos/get_info-0.xml +41 -0
  36. data/spec/fixtures/flickr/photos/get_info-1.xml +19 -0
  37. data/spec/fixtures/flickr/photos/get_sizes-0.xml +10 -0
  38. data/spec/fixtures/flickr/photos/get_sizes-1.xml +8 -0
  39. data/spec/fixtures/flickr/photos/licenses/get_info.xml +12 -0
  40. data/spec/fixtures/flickr/photosets/get_list-0.xml +13 -0
  41. data/spec/fixtures/flickr/photosets/get_photos-0.xml +7 -0
  42. data/spec/fixtures/flickr/test/echo-0.xml +5 -0
  43. data/spec/fixtures/flickr/test/null-fail-99.xml +4 -0
  44. data/spec/fixtures/flickr/urls/get_group-0.xml +4 -0
  45. data/spec/fixtures/flickr/urls/get_group-fail-1.xml +4 -0
  46. data/spec/fixtures/flickr/urls/get_user_photos-0.xml +4 -0
  47. data/spec/fixtures/flickr/urls/get_user_photos-fail-1.xml +4 -0
  48. data/spec/fixtures/flickr/urls/get_user_photos-fail-2.xml +4 -0
  49. data/spec/fixtures/flickr/urls/get_user_profile-0.xml +4 -0
  50. data/spec/fixtures/flickr/urls/get_user_profile-fail-1.xml +4 -0
  51. data/spec/fixtures/flickr/urls/get_user_profile-fail-2.xml +4 -0
  52. data/spec/fixtures/flickr/urls/lookup_group-0.xml +6 -0
  53. data/spec/fixtures/flickr/urls/lookup_group-fail-1.xml +4 -0
  54. data/spec/fixtures/flickr/urls/lookup_user-0.xml +6 -0
  55. data/spec/fixtures/flickr/videos/get_info-0.xml +31 -0
  56. data/spec/fixtures/flickr/videos/get_sizes-0.xml +13 -0
  57. data/spec/flickr/base_spec.rb +97 -0
  58. data/spec/flickr/contacts_spec.rb +47 -0
  59. data/spec/flickr/errors_spec.rb +21 -0
  60. data/spec/flickr/geo_spec.rb +20 -0
  61. data/spec/flickr/photo_spec.rb +123 -0
  62. data/spec/flickr/photos_spec.rb +50 -0
  63. data/spec/flickr/photosets_spec.rb +49 -0
  64. data/spec/flickr/test_spec.rb +34 -0
  65. data/spec/flickr/urls_spec.rb +99 -0
  66. data/spec/spec.opts +4 -0
  67. data/spec/spec_helper.rb +20 -0
  68. metadata +149 -0
@@ -0,0 +1,36 @@
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
+ :title => photo[:title]}
35
+ end
36
+ end
@@ -0,0 +1,36 @@
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
+
28
+ {
29
+ :id => photoset[:id],
30
+ :num_photos => photoset[:photos],
31
+ :title => photoset.title,
32
+ :description => photoset.description
33
+ }
34
+ end
35
+
36
+ end
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -0,0 +1,4 @@
1
+ <?xml version="1.0" encoding="utf-8" ?>
2
+ <rsp stat="fail">
3
+ <err code="99" msg="Insufficient permissions. Method requires read privileges; none granted."/>
4
+ </rsp>
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="utf-8" ?>
2
+ <rsp stat="ok">
3
+ <contacts page="1" pages="1" per_page="1000" perpage="1000" total="2">
4
+ <contact nsid="40718771@N00" username="kooop" iconserver="2" iconfarm="1" ignored="0" />
5
+ <contact nsid="20039881@N00" username="wayoutwest" iconserver="1" iconfarm="1" ignored="0" />
6
+ </contacts>
7
+ </rsp>
@@ -0,0 +1,11 @@
1
+ <?xml version="1.0" encoding="utf-8" ?>
2
+ <rsp stat="ok">
3
+ <photo id="2984637736">
4
+ <location latitude="50.041376" longitude="21.999006" accuracy="16" context="0" place_id="X.5ul_ucAJtJcT0" woeid="517126">
5
+ <locality place_id="X.5ul_ucAJtJcT0" woeid="517126">Rzeszów</locality>
6
+ <county place_id="gUrbqNqYA5n4kv.erw" woeid="12591341">Rzeszów</county>
7
+ <region place_id="acDFruGYA5lyOpcIVg" woeid="12577943">Subcarpathia</region>
8
+ <country place_id="0kV97TybAphIxvm14g" woeid="23424923">Poland</country>
9
+ </location>
10
+ </photo>
11
+ </rsp>