digitalpardoe-rflickr 1.0.0.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.
@@ -0,0 +1,109 @@
1
+ # rFlickr: A Ruby based Flickr API implementation.
2
+ # Copyright (C) 2009, Alex Pardoe (digital:pardoe)
3
+ #
4
+ # Derrived from work by Trevor Schroeder, see here:
5
+ # http://rubyforge.org/projects/rflickr/.
6
+ #
7
+ # This program is free software; you can redistribute it and/or
8
+ # modify it under the terms of the GNU General Public License
9
+ # as published by the Free Software Foundation; either version 2
10
+ # of the License, or (at your option) any later version.
11
+ #
12
+ # This program is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License
18
+ # along with this program; if not, write to the Free Software
19
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
+
21
+ require 'flickr/base'
22
+
23
+ class Flickr::Method
24
+ attr_reader :name,:authenticated,:description,:response,:explanation,
25
+ :arguments, :errors
26
+
27
+ def initialize(name,authenticated,description,response,explanation)
28
+ @name = name
29
+ @authenticated = authenticated
30
+ @description = description
31
+ @response = response
32
+ @explanation = explanation
33
+ @arguments = []
34
+ @errors = []
35
+ end
36
+ end
37
+
38
+ class Flickr::MethodArgument
39
+ attr_reader :name, :optional, :description
40
+
41
+ def initialize(name,optional,description)
42
+ @name = name
43
+ @optional = optional
44
+ @description = description
45
+ end
46
+ end
47
+
48
+ class Flickr::Reflection < Flickr::APIBase
49
+ # We don't bother with caching because it's not worth it for the
50
+ # reflection API.
51
+ def getMethodInfo(method_name)
52
+ res = @flickr.call_method('flickr.reflection.getMethodInfo',
53
+ 'method_name' => method_name)
54
+ els = res.elements
55
+ att = res.root.attributes
56
+ desc = els['/method/description'] ?
57
+ els['/method/description'].text : nil
58
+ resp = els['/method/response'] ?
59
+ els['/method/response'].text : nil
60
+ expl = els['/method/explanation'] ?
61
+ els['/method/explanation'].text : nil
62
+ meth = Flickr::Method.new(att['name'],att['needslogin'].to_i==1,
63
+ desc,resp,expl)
64
+ els['/method/arguments'].each_element do |el|
65
+ att = el.attributes
66
+ arg = Flickr::MethodArgument.new(att['name'],
67
+ att['optional'].to_i == 1,el.text)
68
+ meth.arguments << arg
69
+ end
70
+ els['/method/errors'].each_element do |el|
71
+ att = el.attributes
72
+ err = XMLRPC::FaultException.new(att['code'].to_i,
73
+ el.text)
74
+ meth.errors << err
75
+ end
76
+ return meth
77
+ end
78
+
79
+ def getMethods
80
+ res = @flickr.call_method('flickr.reflection.getMethods')
81
+ list = []
82
+ res.elements['/methods'].each_element do |el|
83
+ list << el.text
84
+ end
85
+ return list
86
+ end
87
+
88
+ def missing_methods
89
+ list = []
90
+ methods = self.getMethods
91
+ methods.each do |mname|
92
+ parts = mname.split('.')
93
+ parts.shift
94
+ call = parts.pop
95
+ obj = @flickr
96
+ parts.each do |part|
97
+ if obj.respond_to?(part)
98
+ obj = obj.method(part).call
99
+ else
100
+ obj = nil
101
+ list << mname
102
+ break
103
+ end
104
+ end
105
+ list << mname if (obj && !obj.respond_to?(call))
106
+ end
107
+ return list
108
+ end
109
+ end
@@ -0,0 +1,79 @@
1
+ # rFlickr: A Ruby based Flickr API implementation.
2
+ # Copyright (C) 2009, Alex Pardoe (digital:pardoe)
3
+ #
4
+ # Derrived from work by Trevor Schroeder, see here:
5
+ # http://rubyforge.org/projects/rflickr/.
6
+ #
7
+ # This program is free software; you can redistribute it and/or
8
+ # modify it under the terms of the GNU General Public License
9
+ # as published by the Free Software Foundation; either version 2
10
+ # of the License, or (at your option) any later version.
11
+ #
12
+ # This program is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License
18
+ # along with this program; if not, write to the Free Software
19
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
+
21
+ require 'flickr/base'
22
+
23
+ class Flickr::Tags < Flickr::APIBase
24
+ def getListPhoto(photo)
25
+ photo = photo.id if photo.class == Flickr::Photo
26
+ res = @flickr.call_method('flickr.tags.getListPhoto',
27
+ 'photo_id'=>photo)
28
+ xml = res.root
29
+ phid = xml.attributes['id']
30
+ photo = (photo.class == Flickr::Photo) ? photo :
31
+ (@flickr.photo_cache_lookup(phid) ||
32
+ Flickr::Photo.new(@flickr,phid))
33
+ if xml.elements['tags']
34
+ tags = []
35
+ xml.elements['tags'].each_element do |el|
36
+ tags << Flickr::Tag.from_xml(el,photo)
37
+ end
38
+ end
39
+ photo.tags = tags
40
+ return tags
41
+ end
42
+
43
+ def getListUserPopular(user,count = nil)
44
+ user = user.nsid if user.class == Flickr::Person
45
+ args = { 'user_id' => user }
46
+ args['count'] = count if count
47
+
48
+ res = @flickr.call_method('flickr.tags.getListUserPopular',args)
49
+ tags = {}
50
+ res.elements['/who/tags'].each_element do |tag|
51
+ att = tag.attributes
52
+ tags[tag.text]=att['count'].to_i
53
+ end
54
+ return tags
55
+ end
56
+
57
+ def getListUser(user)
58
+ user = user.nsid if user.class == Flickr::Person
59
+ args = { 'user_id' => user }
60
+
61
+ res = @flickr.call_method('flickr.tags.getListUser',args)
62
+ tags = []
63
+ res.elements['/who/tags'].each_element do |tag|
64
+ tags << tag.text
65
+ end
66
+ return tags
67
+ end
68
+
69
+ def getRelated(tag)
70
+ args = { 'tag' => tag }
71
+
72
+ res = @flickr.call_method('flickr.tags.getRelated',args)
73
+ tags = []
74
+ res.elements['/tags'].each_element do |tag|
75
+ tags << tag.text
76
+ end
77
+ return tags
78
+ end
79
+ end
@@ -0,0 +1,29 @@
1
+ # rFlickr: A Ruby based Flickr API implementation.
2
+ # Copyright (C) 2009, Alex Pardoe (digital:pardoe)
3
+ #
4
+ # Derrived from work by Trevor Schroeder, see here:
5
+ # http://rubyforge.org/projects/rflickr/.
6
+ #
7
+ # This program is free software; you can redistribute it and/or
8
+ # modify it under the terms of the GNU General Public License
9
+ # as published by the Free Software Foundation; either version 2
10
+ # of the License, or (at your option) any later version.
11
+ #
12
+ # This program is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License
18
+ # along with this program; if not, write to the Free Software
19
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
+
21
+ require 'flickr/base'
22
+
23
+ class Flickr::Transform < Flickr::APIBase
24
+ def rotate(photo,degrees)
25
+ photo = photo.id if photo.class == Flickr::Photo
26
+ @flickr.call_method('flickr.photos.transform.rotate',
27
+ 'photo_id' => photo, 'degrees' => degrees)
28
+ end
29
+ end
@@ -0,0 +1,225 @@
1
+ # rFlickr: A Ruby based Flickr API implementation.
2
+ # Copyright (C) 2009, Alex Pardoe (digital:pardoe)
3
+ #
4
+ # Derrived from work by Trevor Schroeder, see here:
5
+ # http://rubyforge.org/projects/rflickr/.
6
+ #
7
+ # This program is free software; you can redistribute it and/or
8
+ # modify it under the terms of the GNU General Public License
9
+ # as published by the Free Software Foundation; either version 2
10
+ # of the License, or (at your option) any later version.
11
+ #
12
+ # This program is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License
18
+ # along with this program; if not, write to the Free Software
19
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
+
21
+ require 'flickr/base'
22
+ require 'mime/types'
23
+ require 'net/http'
24
+
25
+ class Flickr::Ticket
26
+ attr_reader :id
27
+ attr_accessor :complete, :invalid, :photoid
28
+
29
+ COMPLETE=[:incomplete,:completed,:failed]
30
+
31
+ def initialize(id,upload)
32
+ @id = id
33
+ @upload = upload
34
+ end
35
+
36
+ def check
37
+ t = @upload.checkTickets(self)[0]
38
+ self.complete = t.complete
39
+ self.invalid = t.invalid
40
+ self.photoid = t.photoid
41
+ return t
42
+ end
43
+ end
44
+
45
+ class Flickr::FormPart
46
+ attr_reader :data, :mime_type, :attributes
47
+
48
+ def initialize(name,data,mime_type=nil)
49
+ @attributes = {}
50
+ @attributes['name'] = name
51
+ @data = data
52
+ @mime_type = mime_type
53
+ end
54
+
55
+ def to_s
56
+ ([ "Content-Disposition: form-data" ] +
57
+ attributes.map{|k,v| "#{k}=\"#{v}\""}).
58
+ join('; ') + "\r\n"+
59
+ (@mime_type ? "Content-Type: #{@mime_type}\r\n" : '')+
60
+ "\r\n#{data}"
61
+ end
62
+ end
63
+
64
+ class Flickr::MultiPartForm
65
+ attr_accessor :boundary, :parts
66
+
67
+ def initialize(boundary=nil)
68
+ @boundary = boundary ||
69
+ "----------------------------Ruby#{rand(1000000000000)}"
70
+ @parts = []
71
+ end
72
+
73
+ def to_s
74
+ "--#@boundary\r\n"+
75
+ parts.map{|p| p.to_s}.join("\r\n--#@boundary\r\n")+
76
+ "\r\n--#@boundary--\r\n"
77
+ end
78
+ end
79
+
80
+ class Flickr::Upload < Flickr::APIBase
81
+
82
+ # TODO: It would probably be better if we wrapped the fault
83
+ # in something more meaningful. At the very least, a broad
84
+ # division of errors, such as retryable and fatal.
85
+ def error(el)
86
+ att = el.attributes
87
+ fe = XMLRPC::FaultException.new(att['code'].to_i,
88
+ att['msg'])
89
+ $stderr.puts "ERR: #{fe.faultString} (#{fe.faultCode})"
90
+ raise fe
91
+ end
92
+
93
+ def prepare_parts(data,mimetype,filename,title=nil,description=nil,
94
+ tags=nil, is_public=nil,is_friend=nil,is_family=nil,
95
+ sig=nil, async=nil)
96
+ parts = []
97
+ parts << Flickr::FormPart.new('title',title) if title
98
+ parts << Flickr::FormPart.new('description',description) if
99
+ description
100
+ parts << Flickr::FormPart.new('tags',tags.join(',')) if tags
101
+ parts << Flickr::FormPart.new('is_public',
102
+ is_public ? '1' : '0') if is_public != nil
103
+ parts << Flickr::FormPart.new('is_friend',
104
+ is_friend ? '1' : '0') if is_friend != nil
105
+ parts << Flickr::FormPart.new('is_family',
106
+ is_family ? '1' : '0') if is_family != nil
107
+ parts << Flickr::FormPart.new('async',
108
+ async ? '1' : '0') if async != nil
109
+
110
+ parts << Flickr::FormPart.new('api_key',@flickr.api_key)
111
+ parts << Flickr::FormPart.new('auth_token',
112
+ @flickr.auth.token.token)
113
+ parts << Flickr::FormPart.new('api_sig',sig)
114
+
115
+ parts << Flickr::FormPart.new('photo',data,mimetype)
116
+ parts.last.attributes['filename'] = filename
117
+ return parts
118
+ end
119
+
120
+ def make_signature(title=nil,description=nil, tags=nil,
121
+ is_public=nil,is_friend=nil,is_family=nil,async=nil)
122
+ args = {'api_key' => @flickr.api_key,
123
+ 'auth_token' => @flickr.auth.token.token}
124
+ args['title'] = title if title
125
+ args['description'] = description if description
126
+ args['tags'] = tags.join(',') if tags
127
+ args['is_public'] = (is_public ? '1' : '0') if is_public != nil
128
+ args['is_friend'] = (is_friend ? '1' : '0') if is_friend != nil
129
+ args['is_family'] = (is_family ? '1' : '0') if is_family != nil
130
+ args['async'] = (async ? '1' : '0') if async != nil
131
+ args['api_sig'] = @flickr.sign(args)
132
+ end
133
+
134
+ def send_form(form)
135
+ headers = {"Content-Type" =>
136
+ "multipart/form-data; boundary=" + form.boundary}
137
+
138
+ http = Net::HTTP.new('www.flickr.com', 80)
139
+ # http.read_timeout = 900 # 15 minutes max upload time
140
+ tries = 3
141
+ begin
142
+ res=http.post('/services/upload/',form.to_s,headers)
143
+ rescue Timeout::Error => err
144
+ tries -= 1
145
+ $stderr.puts "Timed out, will retry #{tries} more."
146
+ retry if tries > 0
147
+ raise err
148
+ end
149
+ return res
150
+ end
151
+
152
+ def upload_file_async(filename,title=nil,description=nil,tags=nil,
153
+ is_public=nil,is_friend=nil,is_family=nil)
154
+ mt = MIME::Types.of(filename)
155
+ f = File.open(filename,'rb')
156
+ data = f.read
157
+ f.close
158
+ return upload_image_async(data,mt,filename,title,description,
159
+ tags, is_public,is_friend,is_family)
160
+ end
161
+
162
+
163
+ def upload_file(filename,title=nil,description=nil,tags=nil,
164
+ is_public=nil,is_friend=nil,is_family=nil)
165
+ mt = MIME::Types.of(filename)
166
+ f = File.open(filename,'rb')
167
+ data = f.read
168
+ f.close
169
+ return upload_image(data,mt,filename,title,description,tags,
170
+ is_public,is_friend,is_family)
171
+ end
172
+
173
+ def upload_image_async(data,mimetype,filename,title=nil,description=nil,
174
+ tags=nil, is_public=nil,is_friend=nil,is_family=nil)
175
+ form = Flickr::MultiPartForm.new
176
+
177
+ sig = make_signature(title,description, tags, is_public,
178
+ is_friend, is_family, true)
179
+ form.parts += prepare_parts(data,mimetype,filename,title,
180
+ description, tags, is_public, is_friend,
181
+ is_family, sig, true)
182
+ res = REXML::Document.new(send_form(form).body)
183
+ error(res.elements['/rsp/err']) if res.elements['/rsp/err']
184
+ t = Flickr::Ticket.new(res.elements['/rsp/ticketid'].text, self)
185
+ @flickr.ticket_cache_store(t)
186
+ return t
187
+ end
188
+
189
+ def upload_image(data,mimetype,filename,title=nil,description=nil,
190
+ tags=nil, is_public=nil,is_friend=nil,is_family=nil)
191
+ form = Flickr::MultiPartForm.new
192
+
193
+ sig = make_signature(title,description, tags, is_public,
194
+ is_friend, is_family)
195
+ form.parts += prepare_parts(data,mimetype,filename,title,
196
+ description, tags, is_public, is_friend,
197
+ is_family, sig)
198
+ res = REXML::Document.new(send_form(form).body)
199
+ error(res.elements['/rsp/err']) if res.elements['/rsp/err']
200
+ val = res.elements['/rsp/photoid'].text
201
+ return val
202
+ end
203
+
204
+ def checkTickets(tickets)
205
+ tickets = [tickets] if tickets.class != Array
206
+ targ = tickets.map{|t|
207
+ t.id.to_s if t.class == Flickr::Ticket }.join(',')
208
+ res = @flickr.call_method('flickr.photos.upload.checkTickets',
209
+ 'tickets' => targ)
210
+ tickets = []
211
+ res.elements['/uploader'].each_element('ticket') do |tick|
212
+ att = tick.attributes
213
+ tid = att['id']
214
+ t = @flickr.ticket_cache_lookup(tid) ||
215
+ Flickr::Ticket.new(tid,self)
216
+ t.complete = Flickr::Ticket::COMPLETE[att['complete'].to_i]
217
+ t.photoid = att['photoid']
218
+ t.invalid = true if (att['invalid'] &&
219
+ (att['invalid'].to_i == 1))
220
+ @flickr.ticket_cache_store(t)
221
+ tickets << t
222
+ end
223
+ return tickets
224
+ end
225
+ end
@@ -0,0 +1,69 @@
1
+ # rFlickr: A Ruby based Flickr API implementation.
2
+ # Copyright (C) 2009, Alex Pardoe (digital:pardoe)
3
+ #
4
+ # Derrived from work by Trevor Schroeder, see here:
5
+ # http://rubyforge.org/projects/rflickr/.
6
+ #
7
+ # This program is free software; you can redistribute it and/or
8
+ # modify it under the terms of the GNU General Public License
9
+ # as published by the Free Software Foundation; either version 2
10
+ # of the License, or (at your option) any later version.
11
+ #
12
+ # This program is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License
18
+ # along with this program; if not, write to the Free Software
19
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
+
21
+ require 'flickr/base'
22
+
23
+ class Flickr::Urls < Flickr::APIBase
24
+ def getGroup(group)
25
+ group = group.nsid if group.class == Flickr::Group
26
+ res = @flickr.call_method('flickr.urls.getGroup',
27
+ 'group_id' => group)
28
+ return res.elements['/group'].attributes['url']
29
+ end
30
+
31
+ def getUserPhotos(user)
32
+ user = user.nsid if user.respond_to?(:nsid)
33
+ args = {}
34
+ args['user_id'] = user if user
35
+ res = @flickr.call_method('flickr.urls.getUserPhotos',args)
36
+ return res.elements['/user'].attributes['url']
37
+ end
38
+
39
+ def getUserProfile(user)
40
+ user = user.nsid if user.respond_to?(:nsid)
41
+ args = {}
42
+ args['user_id'] = user if user
43
+ res = @flickr.call_method('flickr.urls.getUserProfile',args)
44
+ return res.elements['/user'].attributes['url']
45
+ end
46
+
47
+ def lookupGroup(url)
48
+ res = @flickr.call_method('flickr.urls.lookupGroup','url'=>url)
49
+ els = res.elements
50
+ nsid = els['/group'].attributes['id']
51
+
52
+ g = @flickr.group_cache_lookup(nsid) ||
53
+ Flickr::Group.new(@flickr,nsid,
54
+ els['/group/groupname'].text)
55
+ @flickr.group_cache_store(g)
56
+ return g
57
+ end
58
+
59
+ def lookupUser(url)
60
+ res = @flickr.call_method('flickr.urls.lookupUser','url'=>url)
61
+ els = res.elements
62
+ nsid = els['/user'].attributes['id']
63
+ p = @flickr.person_cache_lookup(nsid) ||
64
+ Flickr::Person.new(@flickr,nsid,
65
+ els['/user/username'].text)
66
+ @flickr.person_cache_store(p)
67
+ return p
68
+ end
69
+ end