caring-r2flickr 0.1.1.7

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,102 @@
1
+ require 'flickr/base'
2
+
3
+ class Flickr::PhotoSets < Flickr::APIBase
4
+ # photoset can be a PhotoSet or a a photoset id
5
+ # photo can be a Photo or a photo id
6
+ def addPhoto(photoset,photo)
7
+ photo = photo.id if photo.class == Flickr::Photo
8
+ photoset = photoset.id if photoset.class == Flickr::PhotoSet
9
+
10
+ @flickr.call_method('flickr.photosets.addPhoto',
11
+ 'photoset_id' => photoset, 'photo_id' => photo)
12
+ end
13
+
14
+ def create(title,primary_photo, description = nil)
15
+ primary_photo = primary_photo.id if
16
+ primary_photo.class == Flickr::Photo
17
+ args = { 'title' => title, 'primary_photo_id' => primary_photo }
18
+ args['description'] = description if description
19
+ res = @flickr.call_method('flickr.photosets.create',args)
20
+ id = res.elements['/photoset'].attributes['id']
21
+ url = res.elements['/photoset'].attributes['url']
22
+ set = Flickr::PhotoSet.new(id,@flickr)
23
+ set.title = title
24
+ set.url = url
25
+ @flickr.photoset_cache_store(set)
26
+ return set
27
+ end
28
+
29
+ def delete(photoset)
30
+ photoset = photoset.id if photoset.class == Flickr::PhotoSet
31
+ @flickr.call_method('flickr.photosets.delete',
32
+ 'photoset_id' => photoset)
33
+ end
34
+
35
+ def editMeta(photoset,title,description=nil)
36
+ photoset = photoset.id if photoset.class == Flickr::PhotoSet
37
+ args = {'photoset_id' => photoset, 'title' => title}
38
+ args['description' ] = description if description
39
+ @flickr.call_method('flickr.photosets.editMeta',args)
40
+ end
41
+
42
+ def editPhotos(photoset,primary_photo,photos)
43
+ photoset = photoset.id if photoset.class == Flickr::PhotoSet
44
+ primary_photo = primary_photo.id if
45
+ primary_photo.class == Flickr::Photo
46
+ photos=photos.map{|p| p.id if p.class==Flickr::Photo}.join(',')
47
+ args = {'photoset_id' => photoset,
48
+ 'primary_photo_id' => primary_photo,
49
+ 'photo_ids' => photos }
50
+ @flickr.call_method('flickr.photosets.editPhotos',args)
51
+ end
52
+
53
+ def getContext(photo,photoset)
54
+ photoset = photoset.id if photoset.class == Flickr::PhotoSet
55
+ photo = photo.id if photo.class == Flickr::Photo
56
+ res = @flickr.call_method('flickr.photosets.getContext',
57
+ 'photo_id' => photo, 'photoset_id' => photoset)
58
+ return Flickr::Context.from_xml(res,@flickr)
59
+ end
60
+
61
+ def getList(user=nil)
62
+ user = user.nsid if user.respond_to?(:nsid)
63
+ args = {}
64
+ args['user_id'] = user if user
65
+ res = @flickr.call_method('flickr.photosets.getList',args)
66
+ list = []
67
+ res.elements['/photosets'].each_element do |el|
68
+ list << Flickr::PhotoSet.from_xml(el,@flickr)
69
+ end
70
+ return list
71
+ end
72
+
73
+ def removePhoto(photoset,photo)
74
+ photoset = photoset.id if photoset.class == Flickr::PhotoSet
75
+ photo = photo.id if photo.class == Flickr::Photo
76
+ @flickr.call_method('flickr.photosets.removePhoto',
77
+ 'photo_id' => photo, 'photoset_id' => photoset)
78
+ end
79
+
80
+ def getPhotos(photoset,extras=nil)
81
+ photoset = photoset.id if photoset.class == Flickr::PhotoSet
82
+ extras = extras.join(',') if extras.class == Array
83
+ args = { 'photoset_id' => photoset }
84
+ args['extras'] = extras if extras
85
+ res = @flickr.call_method('flickr.photosets.getPhotos',args)
86
+ return Flickr::PhotoSet.from_xml(res.root,@flickr)
87
+ end
88
+
89
+ def getInfo(photoset)
90
+ photoset = photoset.id if photoset.class == Flickr::PhotoSet
91
+ res = @flickr.call_method('flickr.photosets.getInfo',
92
+ 'photoset_id' => photoset)
93
+ return Flickr::PhotoSet.from_xml(res.root,@flickr)
94
+ end
95
+
96
+ def orderSets(photosets)
97
+ photosets=photosets.map { |ps|
98
+ (ps.class==Flickr::PhotoSet) ? ps.id : ps}.join(',')
99
+ @flickr.call_method('flickr.photosets.orderSets',
100
+ 'photoset_ids' => photosets)
101
+ end
102
+ end
@@ -0,0 +1,73 @@
1
+ require 'flickr/groups'
2
+
3
+ class Flickr::Pools < Flickr::APIBase
4
+
5
+ def initialize(flickr,groups)
6
+ super(flickr)
7
+ @groups = groups
8
+ end
9
+
10
+ # photo can be a Photo or photo_id
11
+ # group can be a Group or group_id
12
+ def add(photo,group)
13
+ group = group.nsid if group.class == Flickr::Group
14
+ photo = photo.id if photo.class == Flickr::Photo
15
+ @flickr.call_method('flickr.groups.pools.add',
16
+ 'group_id' => group, 'photo_id' => photo)
17
+ end
18
+
19
+ # photo can be a Photo or photo_id
20
+ # group can be a Group or group_id
21
+ def remove(photo,group)
22
+ group = group.nsid if group.class == Flickr::Group
23
+ photo = photo.id if photo.class == Flickr::Photo
24
+ @flickr.call_method('flickr.groups.pools.add',
25
+ 'group_id' => group, 'photo_id' => photo)
26
+ end
27
+
28
+ # photo can be a Photo or photo_id
29
+ # group can be a Group or group_id
30
+ def getContext(photo,group)
31
+ group = group.nsid if group.class == Flickr::Group
32
+ photo = photo.id if photo.class == Flickr::Photo
33
+ res = @flickr.call_method('flickr.groups.pools.getContex',
34
+ 'group_id' => group, 'photo_id' => photo)
35
+ return Flickr::Context.from_xml(res)
36
+ end
37
+
38
+ def getGroups
39
+ res = @flickr.call_method('flickr.groups.pools.getGroups')
40
+ list = []
41
+
42
+ res.elements['/groups'].each_element do |el|
43
+ att = el.attributes
44
+ nsid = att['nsid']
45
+ g = @flickr.group_cache_lookup(nsid) ||
46
+ Flickr::Group.new(@flickr,nsid,att['name'])
47
+ g.name = att['name']
48
+ g.admin = att['admin'].to_i == 1
49
+ g.privacy = Flickr::Group::PRIVACY[att['privacy'].to_i]
50
+ g.photo_count = att['photos'].to_i
51
+ g.iconserver = att['iconserver'].to_i
52
+
53
+ @flickr.group_cache_store(g)
54
+ list << g
55
+ end
56
+
57
+ return list
58
+ end
59
+
60
+ def getPhotos(group,tags=nil,extras=nil,per_page=nil,page=nil)
61
+ group = group.nsid if group.class == Flickr::Group
62
+ group = group.id.to_s if group.class == Flickr::PhotoPool
63
+ args = { 'group_id' => group }
64
+ args['tags'] = tags.map{|t| t.clean if t.class ==
65
+ Flick::Tag}.join(',') if tags
66
+ args['extras'] = extras.join(',') if extras.class == Array
67
+ args['per_page'] = per_page if per_page
68
+ args['page'] = page if page
69
+
70
+ res = @flickr.call_method('flickr.groups.pools.getPhotos', args)
71
+ return Flickr::PhotoList.from_xml(res,@flickr)
72
+ end
73
+ end
@@ -0,0 +1,89 @@
1
+ require 'flickr/base'
2
+
3
+ class Flickr::Method
4
+ attr_reader :name, :authenticated, :description, :response, :explanation,
5
+ :arguments, :errors
6
+
7
+ def initialize(name,authenticated,description,response,explanation)
8
+ @name = name
9
+ @authenticated = authenticated
10
+ @description = description
11
+ @response = response
12
+ @explanation = explanation
13
+ @arguments = []
14
+ @errors = []
15
+ end
16
+ end
17
+
18
+ class Flickr::MethodArgument
19
+ attr_reader :name, :optional, :description
20
+
21
+ def initialize(name,optional,description)
22
+ @name = name
23
+ @optional = optional
24
+ @description = description
25
+ end
26
+ end
27
+
28
+ class Flickr::Reflection < Flickr::APIBase
29
+ # We don't bother with caching because it's not worth it for the
30
+ # reflection API.
31
+ def getMethodInfo(method_name)
32
+ res = @flickr.call_method('flickr.reflection.getMethodInfo',
33
+ 'method_name' => method_name)
34
+ els = res.elements
35
+ att = res.root.attributes
36
+ desc = els['/method/description'] ?
37
+ els['/method/description'].text : nil
38
+ resp = els['/method/response'] ?
39
+ els['/method/response'].text : nil
40
+ expl = els['/method/explanation'] ?
41
+ els['/method/explanation'].text : nil
42
+ meth = Flickr::Method.new(att['name'],att['needslogin'].to_i==1,
43
+ desc,resp,expl)
44
+ els['/method/arguments'].each_element do |el|
45
+ att = el.attributes
46
+ arg = Flickr::MethodArgument.new(att['name'],
47
+ att['optional'].to_i == 1,el.text)
48
+ meth.arguments << arg
49
+ end
50
+ els['/method/errors'].each_element do |el|
51
+ att = el.attributes
52
+ err = XMLRPC::FaultException.new(att['code'].to_i,
53
+ el.text)
54
+ meth.errors << err
55
+ end
56
+ return meth
57
+ end
58
+
59
+ def getMethods
60
+ res = @flickr.call_method('flickr.reflection.getMethods')
61
+ list = []
62
+ res.elements['/methods'].each_element do |el|
63
+ list << el.text
64
+ end
65
+ return list
66
+ end
67
+
68
+ def missing_methods
69
+ list = []
70
+ methods = self.getMethods
71
+ methods.each do |mname|
72
+ parts = mname.split('.')
73
+ parts.shift
74
+ call = parts.pop
75
+ obj = @flickr
76
+ parts.each do |part|
77
+ if obj.respond_to?(part)
78
+ obj = obj.method(part).call
79
+ else
80
+ obj = nil
81
+ list << mname
82
+ break
83
+ end
84
+ end
85
+ list << mname if (obj && !obj.respond_to?(call))
86
+ end
87
+ return list
88
+ end
89
+ end
@@ -0,0 +1,59 @@
1
+ require 'flickr/base'
2
+
3
+ class Flickr::Tags < Flickr::APIBase
4
+ def getListPhoto(photo)
5
+ photo = photo.id if photo.class == Flickr::Photo
6
+ res = @flickr.call_method('flickr.tags.getListPhoto',
7
+ 'photo_id'=>photo)
8
+ xml = res.root
9
+ phid = xml.attributes['id']
10
+ photo = (photo.class == Flickr::Photo) ? photo :
11
+ (@flickr.photo_cache_lookup(phid) ||
12
+ Flickr::Photo.new(@flickr,phid))
13
+ if xml.elements['tags']
14
+ tags = []
15
+ xml.elements['tags'].each_element do |el|
16
+ tags << Flickr::Tag.from_xml(el,photo)
17
+ end
18
+ end
19
+ photo.tags = tags
20
+ return tags
21
+ end
22
+
23
+ def getListUserPopular(user,count = nil)
24
+ user = user.nsid if user.class == Flickr::Person
25
+ args = { 'user_id' => user }
26
+ args['count'] = count if count
27
+
28
+ res = @flickr.call_method('flickr.tags.getListUserPopular',args)
29
+ tags = {}
30
+ res.elements['/who/tags'].each_element do |tag|
31
+ att = tag.attributes
32
+ tags[tag.text]=att['count'].to_i
33
+ end
34
+ return tags
35
+ end
36
+
37
+ def getListUser(user)
38
+ user = user.nsid if user.class == Flickr::Person
39
+ args = { 'user_id' => user }
40
+
41
+ res = @flickr.call_method('flickr.tags.getListUser',args)
42
+ tags = []
43
+ res.elements['/who/tags'].each_element do |tag|
44
+ tags << tag.text
45
+ end
46
+ return tags
47
+ end
48
+
49
+ def getRelated(tag)
50
+ args = { 'tag' => tag }
51
+
52
+ res = @flickr.call_method('flickr.tags.getRelated',args)
53
+ tags = []
54
+ res.elements['/tags'].each_element do |tag|
55
+ tags << tag.text
56
+ end
57
+ return tags
58
+ end
59
+ end
@@ -0,0 +1,20 @@
1
+ require 'flickr/base'
2
+
3
+ class Flickr::Test < Flickr::APIBase
4
+
5
+ # This has to be a Hash
6
+ def echo(args)
7
+ return @flickr.call_method('flickr.test.echo',args)
8
+ end
9
+
10
+ def login
11
+ res = @flickr.call_method('flickr.test.login')
12
+ nsid = res.elements['/user'].attributes['id']
13
+ name = res.elements['/user/username'].text
14
+ p = @flickr.person_cache_lookup(nsid) ||
15
+ Flickr::Person.new(@flickr,nsid,name)
16
+ p.name = name
17
+ @flickr.person_cache_store(p)
18
+ return p
19
+ end
20
+ end
@@ -0,0 +1,33 @@
1
+ require 'flickr/base'
2
+
3
+ class Flickr::BaseTokenCache < Flickr::APIBase
4
+
5
+ def load_token
6
+ nil
7
+ end
8
+
9
+ def cache_token(token)
10
+ nil
11
+ end
12
+
13
+ end
14
+
15
+ class Flickr::FileTokenCache < Flickr::BaseTokenCache
16
+
17
+ def initialize(filename)
18
+ @cache_file = filename
19
+ end
20
+
21
+ def load_token
22
+ token = nil
23
+ File.open(@cache_file,'r'){ |f| token = f.read }
24
+ @token = Flickr::Token.from_xml(REXML::Document.new(token))
25
+ rescue Errno::ENOENT
26
+ nil
27
+ end
28
+
29
+ def cache_token(token)
30
+ File.open(@cache_file,'w'){ |f| f.write token.to_xml } if token
31
+ end
32
+
33
+ end
@@ -0,0 +1,11 @@
1
+ require 'flickr/base'
2
+
3
+ class Flickr::Transform < Flickr::APIBase
4
+
5
+ def rotate(photo,degrees)
6
+ photo = photo.id if photo.class == Flickr::Photo
7
+ @flickr.call_method('flickr.photos.transform.rotate',
8
+ 'photo_id' => photo, 'degrees' => degrees)
9
+ end
10
+
11
+ end
@@ -0,0 +1,205 @@
1
+ require 'flickr/base'
2
+ require 'mime/types'
3
+ require 'net/http'
4
+
5
+ class Flickr::Ticket
6
+
7
+ attr_reader :id
8
+ attr_accessor :complete, :invalid, :photoid
9
+
10
+ COMPLETE=[:incomplete,:completed,:failed]
11
+
12
+ def initialize(id,upload)
13
+ @id = id
14
+ @upload = upload
15
+ end
16
+
17
+ def check
18
+ t = @upload.checkTickets(self)[0]
19
+ self.complete = t.complete
20
+ self.invalid = t.invalid
21
+ self.photoid = t.photoid
22
+ return t
23
+ end
24
+ end
25
+
26
+ class Flickr::FormPart
27
+ attr_reader :data, :mime_type, :attributes
28
+
29
+ def initialize(name,data,mime_type=nil)
30
+ @attributes = {}
31
+ @attributes['name'] = name
32
+ @data = data
33
+ @mime_type = mime_type
34
+ end
35
+
36
+ def to_s
37
+ ([ "Content-Disposition: form-data" ] +
38
+ attributes.map{|k,v| "#{k}=\"#{v}\""}).
39
+ join('; ') + "\r\n"+
40
+ (@mime_type ? "Content-Type: #{@mime_type}\r\n" : '')+
41
+ "\r\n#{data}"
42
+ end
43
+ end
44
+
45
+ class Flickr::MultiPartForm
46
+ attr_accessor :boundary, :parts
47
+
48
+ def initialize(boundary=nil)
49
+ @boundary = boundary ||
50
+ "----------------------------Ruby#{rand(1000000000000)}"
51
+ @parts = []
52
+ end
53
+
54
+ def to_s
55
+ "--#@boundary\r\n" + parts.map{|p| p.to_s}.join("\r\n--#@boundary\r\n") +
56
+ "\r\n--#@boundary--\r\n"
57
+ end
58
+
59
+ end
60
+
61
+ class Flickr::Upload < Flickr::APIBase
62
+
63
+ # TODO: It would probably be better if we wrapped the fault
64
+ # in something more meaningful. At the very least, a broad
65
+ # division of errors, such as retryable and fatal.
66
+ def error(el)
67
+ att = el.attributes
68
+ fe = XMLRPC::FaultException.new(att['code'].to_i,
69
+ att['msg'])
70
+ $stderr.puts "ERR: #{fe.faultString} (#{fe.faultCode})"
71
+ raise fe
72
+ end
73
+
74
+ def prepare_parts(data,mimetype,filename,title=nil,description=nil,
75
+ tags=nil, is_public=nil,is_friend=nil,is_family=nil,
76
+ sig=nil, async=nil)
77
+ parts = []
78
+ parts << Flickr::FormPart.new('title',title) if title
79
+ parts << Flickr::FormPart.new('description',description) if
80
+ description
81
+ parts << Flickr::FormPart.new('tags',tags.join(',')) if tags
82
+ parts << Flickr::FormPart.new('is_public',
83
+ is_public ? '1' : '0') if is_public != nil
84
+ parts << Flickr::FormPart.new('is_friend',
85
+ is_friend ? '1' : '0') if is_friend != nil
86
+ parts << Flickr::FormPart.new('is_family',
87
+ is_family ? '1' : '0') if is_family != nil
88
+ parts << Flickr::FormPart.new('async',
89
+ async ? '1' : '0') if async != nil
90
+
91
+ parts << Flickr::FormPart.new('api_key',@flickr.api_key)
92
+ parts << Flickr::FormPart.new('auth_token',
93
+ @flickr.auth.token.token)
94
+ parts << Flickr::FormPart.new('api_sig',sig)
95
+
96
+ parts << Flickr::FormPart.new('photo',data,mimetype)
97
+ parts.last.attributes['filename'] = filename
98
+ return parts
99
+ end
100
+
101
+ def make_signature(title=nil,description=nil, tags=nil,
102
+ is_public=nil,is_friend=nil,is_family=nil,async=nil)
103
+ args = {'api_key' => @flickr.api_key,
104
+ 'auth_token' => @flickr.auth.token.token}
105
+ args['title'] = title if title
106
+ args['description'] = description if description
107
+ args['tags'] = tags.join(',') if tags
108
+ args['is_public'] = (is_public ? '1' : '0') if is_public != nil
109
+ args['is_friend'] = (is_friend ? '1' : '0') if is_friend != nil
110
+ args['is_family'] = (is_family ? '1' : '0') if is_family != nil
111
+ args['async'] = (async ? '1' : '0') if async != nil
112
+ args['api_sig'] = @flickr.sign(args)
113
+ end
114
+
115
+ def send_form(form)
116
+ headers = {"Content-Type" => "multipart/form-data; boundary=" + form.boundary}
117
+
118
+ http = Net::HTTP.new('www.flickr.com', 80)
119
+ # http.read_timeout = 900 # 15 minutes max upload time
120
+ tries = 3
121
+ begin
122
+ res=http.post('/services/upload/',form.to_s,headers)
123
+ rescue Timeout::Error => err
124
+ tries -= 1
125
+ $stderr.puts "Timed out, will retry #{tries} more."
126
+ retry if tries > 0
127
+ raise err
128
+ end
129
+ return res
130
+ end
131
+
132
+ def upload_file_async(filename,title=nil,description=nil,tags=nil,
133
+ is_public=nil,is_friend=nil,is_family=nil)
134
+ mt = MIME::Types.of(filename)
135
+ f = File.open(filename,'rb')
136
+ data = f.read
137
+ f.close
138
+ return upload_image_async(data,mt,filename,title,description,
139
+ tags, is_public,is_friend,is_family)
140
+ end
141
+
142
+
143
+ def upload_file(filename,title=nil,description=nil,tags=nil,
144
+ is_public=nil,is_friend=nil,is_family=nil)
145
+ mt = MIME::Types.of(filename)
146
+ f = File.open(filename,'rb')
147
+ data = f.read
148
+ f.close
149
+ return upload_image(data,mt,filename,title,description,tags,
150
+ is_public,is_friend,is_family)
151
+ end
152
+
153
+ def upload_image_async(data,mimetype,filename,title=nil,description=nil,
154
+ tags=nil, is_public=nil,is_friend=nil,is_family=nil)
155
+ form = Flickr::MultiPartForm.new
156
+
157
+ sig = make_signature(title,description, tags, is_public,
158
+ is_friend, is_family, true)
159
+ form.parts += prepare_parts(data,mimetype,filename,title,
160
+ description, tags, is_public, is_friend,
161
+ is_family, sig, true)
162
+ res = REXML::Document.new(send_form(form).body)
163
+ error(res.elements['/rsp/err']) if res.elements['/rsp/err']
164
+ t = Flickr::Ticket.new(res.elements['/rsp/ticketid'].text, self)
165
+ @flickr.ticket_cache_store(t)
166
+ return t
167
+ end
168
+
169
+ def upload_image(data,mimetype,filename,title=nil,description=nil,
170
+ tags=nil, is_public=nil,is_friend=nil,is_family=nil)
171
+ form = Flickr::MultiPartForm.new
172
+
173
+ sig = make_signature(title,description, tags, is_public,
174
+ is_friend, is_family)
175
+ form.parts += prepare_parts(data,mimetype,filename,title,
176
+ description, tags, is_public, is_friend,
177
+ is_family, sig)
178
+ res = REXML::Document.new(send_form(form).body)
179
+ error(res.elements['/rsp/err']) if res.elements['/rsp/err']
180
+ val = res.elements['/rsp/photoid'].text
181
+ return val
182
+ end
183
+
184
+ def checkTickets(tickets)
185
+ tickets = [tickets] if tickets.class != Array
186
+ targ = tickets.map{|t|
187
+ t.id.to_s if t.class == Flickr::Ticket }.join(',')
188
+ res = @flickr.call_method('flickr.photos.upload.checkTickets',
189
+ 'tickets' => targ)
190
+ tickets = []
191
+ res.elements['/uploader'].each_element('ticket') do |tick|
192
+ att = tick.attributes
193
+ tid = att['id']
194
+ t = @flickr.ticket_cache_lookup(tid) ||
195
+ Flickr::Ticket.new(tid,self)
196
+ t.complete = Flickr::Ticket::COMPLETE[att['complete'].to_i]
197
+ t.photoid = att['photoid']
198
+ t.invalid = true if (att['invalid'] &&
199
+ (att['invalid'].to_i == 1))
200
+ @flickr.ticket_cache_store(t)
201
+ tickets << t
202
+ end
203
+ return tickets
204
+ end
205
+ end