google-picasa 0.0.1
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.
- data/.gitignore +4 -0
- data/Gemfile +4 -0
- data/Rakefile +1 -0
- data/google-picasa.gemspec +24 -0
- data/lib/google-picasa/version.rb +5 -0
- data/lib/google-picasa.rb +577 -0
- metadata +51 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Rakefile
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require "bundler/gem_tasks"
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
|
3
|
+
require "google-picasa/version"
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |s|
|
|
6
|
+
s.name = "google-picasa"
|
|
7
|
+
s.version = Google::Picasa::VERSION
|
|
8
|
+
s.authors = ["Dmitry Trager"]
|
|
9
|
+
s.email = ["dmitry@trager.ru"]
|
|
10
|
+
s.homepage = "http://code.google.com/p/picasaonrails"
|
|
11
|
+
s.summary = %q{Ruby wrapper for Picasa API}
|
|
12
|
+
s.description = %q{Access Picasa Web Album using pure Ruby code.}
|
|
13
|
+
|
|
14
|
+
s.rubyforge_project = "google-picasa"
|
|
15
|
+
|
|
16
|
+
s.files = `git ls-files`.split("\n")
|
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
|
19
|
+
s.require_paths = ["lib"]
|
|
20
|
+
|
|
21
|
+
# specify any dependencies here; for example:
|
|
22
|
+
# s.add_development_dependency "rspec"
|
|
23
|
+
# s.add_runtime_dependency "rest-client"
|
|
24
|
+
end
|
|
@@ -0,0 +1,577 @@
|
|
|
1
|
+
require 'rubygems'
|
|
2
|
+
require 'cgi'
|
|
3
|
+
require 'net/https'
|
|
4
|
+
require 'net/http'
|
|
5
|
+
require 'xmlsimple'
|
|
6
|
+
require 'multipartpost'
|
|
7
|
+
require 'google-picasa/version'
|
|
8
|
+
|
|
9
|
+
module Google
|
|
10
|
+
module Picasa
|
|
11
|
+
|
|
12
|
+
class PicasaSession
|
|
13
|
+
attr_accessor :auth_key
|
|
14
|
+
attr_accessor :user_id
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
class Picasa
|
|
18
|
+
attr_accessor :picasa_session
|
|
19
|
+
|
|
20
|
+
def login(email, password)
|
|
21
|
+
url = "https://www.google.com/accounts/ClientLogin"
|
|
22
|
+
source = "MyCompany-TestProject-1.0.0" # source will be of CompanyName-ProjectName-ProjectVersion format
|
|
23
|
+
|
|
24
|
+
uri = URI.parse(url)
|
|
25
|
+
|
|
26
|
+
request = Net::HTTP.new(uri.host, uri.port)
|
|
27
|
+
request.use_ssl = true
|
|
28
|
+
request.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
|
29
|
+
response, data = request.post(uri.path, "accountType=HOSTED_OR_GOOGLE&Email=#{email}&Passwd=#{password}&service=lh2&source=#{source}")
|
|
30
|
+
|
|
31
|
+
authMatch = Regexp.compile("(Auth=)([A-Za-z0-9_\-]+)\n").match(data.to_s)
|
|
32
|
+
if authMatch
|
|
33
|
+
authorizationKey = authMatch[2].to_s # substring that matched the pattern ([A-Za-z0-9_\-]+)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
self.picasa_session = PicasaSession.new
|
|
37
|
+
self.picasa_session.auth_key = authorizationKey
|
|
38
|
+
self.picasa_session.user_id = email
|
|
39
|
+
|
|
40
|
+
return authorizationKey
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def init(user_id, auth_key)
|
|
44
|
+
self.picasa_session = PicasaSession.new
|
|
45
|
+
self.picasa_session.auth_key = auth_key
|
|
46
|
+
self.picasa_session.user_id = user_id
|
|
47
|
+
|
|
48
|
+
return authorizationKey
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def album(options = {})
|
|
52
|
+
|
|
53
|
+
if(options[:name] == nil)
|
|
54
|
+
return nil
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
albums = self.albums(options)
|
|
58
|
+
for album in albums
|
|
59
|
+
if(album.name == options[:name])
|
|
60
|
+
return album
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
return nil
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def albums(options = {})
|
|
68
|
+
|
|
69
|
+
userId = options[:user_id] == nil ? self.picasa_session.user_id : options[:user_id]
|
|
70
|
+
access = options[:access] == nil ? "public" : options[:access]
|
|
71
|
+
url = "http://picasaweb.google.com/data/feed/api/user/#{userId}?kind=album&access=#{access}"
|
|
72
|
+
|
|
73
|
+
uri = URI.parse(url)
|
|
74
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
|
75
|
+
|
|
76
|
+
headers = {"Authorization" => "GoogleLogin auth=#{self.picasa_session.auth_key}"}
|
|
77
|
+
|
|
78
|
+
response, xml_response = http.get(uri.path, headers)
|
|
79
|
+
|
|
80
|
+
#xml_response = Net::HTTP.get_response(URI.parse(url)).body.to_s
|
|
81
|
+
albums = create_albums_from_xml(xml_response)
|
|
82
|
+
|
|
83
|
+
return albums
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def photos(options = {})
|
|
87
|
+
|
|
88
|
+
options[:user_id] = options[:user_id].nil? ? self.picasa_session.user_id : options[:user_id]
|
|
89
|
+
options[:album] = options[:album].nil? ? "" : options[:album]
|
|
90
|
+
|
|
91
|
+
album = Album.new
|
|
92
|
+
album.picasa_session = self.picasa_session
|
|
93
|
+
photos = album.photos(options)
|
|
94
|
+
|
|
95
|
+
return photos
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def create_album(options = {})
|
|
99
|
+
|
|
100
|
+
title = options[:title].nil? ? "" : options[:title]
|
|
101
|
+
summary = options[:summary].nil? ? "" : options[:summary]
|
|
102
|
+
location = options[:location].nil? ? "" : options[:location]
|
|
103
|
+
access = options[:access].nil? ? "public" : options[:access]
|
|
104
|
+
commentable = options[:commentable].nil? ? "true" : options[:commentable].to_s
|
|
105
|
+
keywords = options[:keywords].nil? ? "" : options[:keywords]
|
|
106
|
+
time_i = (Time.now).to_i
|
|
107
|
+
|
|
108
|
+
createAlbumRequestXml = "<entry xmlns='http://www.w3.org/2005/Atom'
|
|
109
|
+
xmlns:media='http://search.yahoo.com/mrss/'
|
|
110
|
+
xmlns:gphoto='http://schemas.google.com/photos/2007'>
|
|
111
|
+
<title type='text'>#{title}</title>
|
|
112
|
+
<summary type='text'>#{summary}</summary>
|
|
113
|
+
<gphoto:location>#{location}</gphoto:location>
|
|
114
|
+
<gphoto:access>#{access}</gphoto:access>
|
|
115
|
+
<gphoto:commentingEnabled>#{commentable}</gphoto:commentingEnabled>
|
|
116
|
+
<gphoto:timestamp>#{time_i}</gphoto:timestamp>
|
|
117
|
+
<media:group>
|
|
118
|
+
<media:keywords>#{keywords}</media:keywords>
|
|
119
|
+
</media:group>
|
|
120
|
+
<category scheme='http://schemas.google.com/g/2005#kind'
|
|
121
|
+
term='http://schemas.google.com/photos/2007#album'></category>
|
|
122
|
+
</entry>"
|
|
123
|
+
|
|
124
|
+
url = "http://picasaweb.google.com/data/feed/api/user/#{self.picasa_session.user_id}"
|
|
125
|
+
|
|
126
|
+
uri = URI.parse(url)
|
|
127
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
|
128
|
+
|
|
129
|
+
headers = {"Content-Type" => "application/atom+xml", "Authorization" => "GoogleLogin auth=#{self.picasa_session.auth_key}"}
|
|
130
|
+
|
|
131
|
+
response, data = http.post(uri.path, createAlbumRequestXml, headers)
|
|
132
|
+
|
|
133
|
+
album = create_album_from_xml(data)
|
|
134
|
+
return album
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def load_album(album_url)
|
|
138
|
+
uri = URI.parse(album_url)
|
|
139
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
|
140
|
+
|
|
141
|
+
headers = {"Authorization" => "GoogleLogin auth=#{self.picasa_session.auth_key}"}
|
|
142
|
+
|
|
143
|
+
response, album_entry_xml_response = http.get(uri.path, headers)
|
|
144
|
+
|
|
145
|
+
if(response.code == "200")
|
|
146
|
+
#parse the entry xml element and get the photo object
|
|
147
|
+
album = self.create_album_from_xml(album_entry_xml_response)
|
|
148
|
+
return album
|
|
149
|
+
else
|
|
150
|
+
return nil
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def load_album_with_id(album_id)
|
|
155
|
+
album_url = "http://picasaweb.google.com/data/entry/api/user/#{self.picasa_session.user_id}/albumid/#{album_id}"
|
|
156
|
+
|
|
157
|
+
return load_album(album_url)
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def load_photo(photo_url)
|
|
161
|
+
uri = URI.parse(photo_url)
|
|
162
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
|
163
|
+
|
|
164
|
+
headers = {"Authorization" => "GoogleLogin auth=#{self.picasa_session.auth_key}"}
|
|
165
|
+
|
|
166
|
+
response, photo_entry_xml_response = http.get(uri.path, headers)
|
|
167
|
+
|
|
168
|
+
if(response.code == "200")
|
|
169
|
+
#parse the entry xml element and get the photo object
|
|
170
|
+
photo = self.create_photo_from_xml(photo_entry_xml_response)
|
|
171
|
+
return photo
|
|
172
|
+
else
|
|
173
|
+
return nil
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def load_photo_with_id(photo_id, album_id)
|
|
178
|
+
photo_url = "http://picasaweb.google.com/data/entry/api/user/#{self.picasa_session.user_id}/albumid/#{album_id}/photoid/#{photo_id}"
|
|
179
|
+
|
|
180
|
+
return load_photo(photo_url)
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def post_photo(image_data = nil, options = {})
|
|
184
|
+
summary = options[:summary] == nil ? "" : options[:summary]
|
|
185
|
+
album_name = options[:album] == nil ? "" : options[:album]
|
|
186
|
+
album_id = options[:album_id] == nil ? "" : options[:album_id]
|
|
187
|
+
local_file_name = options[:local_file_name] == nil ? "" : options[:local_file_name]
|
|
188
|
+
title = options[:title] == nil ? local_file_name : options[:title]
|
|
189
|
+
|
|
190
|
+
if(image_data == nil)
|
|
191
|
+
return nil
|
|
192
|
+
# Or throw an exception in next update
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
if(album_id != "")
|
|
196
|
+
url = "http://picasaweb.google.com/data/feed/api/user/#{self.picasa_session.user_id}/albumid/#{album_id}"
|
|
197
|
+
else
|
|
198
|
+
url = "http://picasaweb.google.com/data/feed/api/user/#{self.picasa_session.user_id}/album/#{album_name}"
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
uri = URI.parse(url)
|
|
202
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
|
203
|
+
|
|
204
|
+
headers = {"Content-Type" => "image/jpeg",
|
|
205
|
+
"Authorization" => "GoogleLogin auth=#{self.picasa_session.auth_key}",
|
|
206
|
+
"Slug" => title, "Content-Transfer-Encoding" => "binary"}
|
|
207
|
+
|
|
208
|
+
response, data = http.post(uri.path, image_data, headers)
|
|
209
|
+
photo = self.create_photo_from_xml(data)
|
|
210
|
+
|
|
211
|
+
return photo
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
def delete_photo(photo)
|
|
215
|
+
url = photo.edit_url
|
|
216
|
+
|
|
217
|
+
uri = URI.parse(url)
|
|
218
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
|
219
|
+
|
|
220
|
+
headers = {"Authorization" => "GoogleLogin auth=#{self.picasa_session.auth_key}"}
|
|
221
|
+
|
|
222
|
+
response, data = http.delete(uri.path, headers)
|
|
223
|
+
|
|
224
|
+
if(response.code == "200")
|
|
225
|
+
return true
|
|
226
|
+
else
|
|
227
|
+
return false
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
def delete_album(album)
|
|
233
|
+
url = album.edit_url
|
|
234
|
+
|
|
235
|
+
uri = URI.parse(url)
|
|
236
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
|
237
|
+
|
|
238
|
+
headers = {"Authorization" => "GoogleLogin auth=#{self.picasa_session.auth_key}"}
|
|
239
|
+
|
|
240
|
+
response, data = http.delete(uri.path, headers)
|
|
241
|
+
|
|
242
|
+
if(response.code == "200")
|
|
243
|
+
return true
|
|
244
|
+
else
|
|
245
|
+
return false
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
def create_albums_from_xml(xml_response)
|
|
251
|
+
albums = []
|
|
252
|
+
#response_hash = XmlSimple.xml_in(xml_response, { 'ForceArray' => false })
|
|
253
|
+
#puts response_hash.inspect
|
|
254
|
+
|
|
255
|
+
Picasa.entries(xml_response).each do |entry|
|
|
256
|
+
#parse the entry xml element and get the album object
|
|
257
|
+
album = Picasa.parse_album_entry(entry)
|
|
258
|
+
|
|
259
|
+
#enter session values in album object
|
|
260
|
+
album.picasa_session = PicasaSession.new
|
|
261
|
+
album.picasa_session.auth_key = self.picasa_session.auth_key
|
|
262
|
+
album.picasa_session.user_id = self.picasa_session.user_id
|
|
263
|
+
|
|
264
|
+
albums << album
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
return albums
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
def create_album_from_xml(xml_response)
|
|
271
|
+
album = nil
|
|
272
|
+
|
|
273
|
+
#parse the entry xml element and get the album object
|
|
274
|
+
album = Picasa.parse_album_entry(XmlSimple.xml_in(xml_response, { 'ForceArray' => false }))
|
|
275
|
+
|
|
276
|
+
#enter session values in album object
|
|
277
|
+
album.picasa_session = PicasaSession.new
|
|
278
|
+
album.picasa_session.auth_key = self.picasa_session.auth_key
|
|
279
|
+
album.picasa_session.user_id = self.picasa_session.user_id
|
|
280
|
+
|
|
281
|
+
return album
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
def create_photo_from_xml(xml_response)
|
|
285
|
+
photo = nil
|
|
286
|
+
|
|
287
|
+
#parse the entry xml element and get the photo object
|
|
288
|
+
photo = Picasa.parse_photo_entry(XmlSimple.xml_in(xml_response, { 'ForceArray' => false }))
|
|
289
|
+
|
|
290
|
+
#enter session values in photo object
|
|
291
|
+
photo.picasa_session = PicasaSession.new
|
|
292
|
+
photo.picasa_session.auth_key = self.picasa_session.auth_key
|
|
293
|
+
photo.picasa_session.user_id = self.picasa_session.user_id
|
|
294
|
+
|
|
295
|
+
return photo
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
def self.entries(xml_response)
|
|
299
|
+
document = XmlSimple.xml_in(xml_response, { 'ForceArray' => false });
|
|
300
|
+
return [] if (!document['totalResults'].nil? && document['totalResults'].to_i == 0)
|
|
301
|
+
|
|
302
|
+
entries = (document['totalResults']).to_i > 1 ? document["entry"] : [document["entry"]]
|
|
303
|
+
return entries.compact
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
def self.parse_album_entry(album_entry_xml)
|
|
307
|
+
#album_hash = XmlSimple.xml_in(album_entry_xml.to_s, { 'ForceArray' => false })
|
|
308
|
+
album_hash = album_entry_xml
|
|
309
|
+
|
|
310
|
+
album = Album.new
|
|
311
|
+
album.xml = album_entry_xml.to_s
|
|
312
|
+
|
|
313
|
+
album.id = album_hash["id"][1]
|
|
314
|
+
album.name = album_hash["name"]
|
|
315
|
+
album.user = album_hash["user"]
|
|
316
|
+
album.number_of_photos = album_hash["numphotos"]
|
|
317
|
+
album.number_of_comments = album_hash["commentCount"]
|
|
318
|
+
album.is_commentable = album_hash["commentingEnabled"] == true ? true : false
|
|
319
|
+
album.access = album_hash["access"]
|
|
320
|
+
|
|
321
|
+
album.author_name = album_hash["author"]["name"]
|
|
322
|
+
album.author_uri = album_hash["author"]["uri"]
|
|
323
|
+
|
|
324
|
+
album.title = album_hash["group"]["title"]["content"]
|
|
325
|
+
album.title_type = album_hash["group"]["title"]["type"]
|
|
326
|
+
album.description = album_hash["group"]["description"]["content"]
|
|
327
|
+
album.description_type = album_hash["group"]["description"]["type"]
|
|
328
|
+
album.image_url = album_hash["group"]["content"]["url"]
|
|
329
|
+
album.image_type = album_hash["group"]["content"]["type"]
|
|
330
|
+
album.thumbnail = Thumbnail.new()
|
|
331
|
+
album.thumbnail.url = album_hash["group"]["thumbnail"]["url"]
|
|
332
|
+
album.thumbnail.width = album_hash["group"]["thumbnail"]["width"]
|
|
333
|
+
album.thumbnail.height = album_hash["group"]["thumbnail"]["height"]
|
|
334
|
+
|
|
335
|
+
# make self xml url
|
|
336
|
+
links_from_hash = album_hash["link"]
|
|
337
|
+
if(links_from_hash.respond_to?(:each))
|
|
338
|
+
links_from_hash.each do |link|
|
|
339
|
+
if(link["rel"] == "self")
|
|
340
|
+
album.self_xml_url = link["href"]
|
|
341
|
+
elsif(link["rel"] == "edit")
|
|
342
|
+
album.edit_url = link["href"]
|
|
343
|
+
end
|
|
344
|
+
end
|
|
345
|
+
else
|
|
346
|
+
album.self_xml_url = nil
|
|
347
|
+
album.edit_url = nil
|
|
348
|
+
end
|
|
349
|
+
|
|
350
|
+
return album
|
|
351
|
+
end
|
|
352
|
+
|
|
353
|
+
def self.parse_photo_entry(photo_entry_xml)
|
|
354
|
+
#photo_hash = XmlSimple.xml_in(photo_entry_xml.to_s, { 'ForceArray' => false })
|
|
355
|
+
photo_hash = photo_entry_xml
|
|
356
|
+
|
|
357
|
+
photo = Photo.new
|
|
358
|
+
photo.xml = photo_entry_xml.to_s
|
|
359
|
+
|
|
360
|
+
photo.id = photo_hash["id"][1]
|
|
361
|
+
photo.album_id = photo_hash["albumid"]
|
|
362
|
+
photo.version_number = photo_hash["version"]
|
|
363
|
+
photo.is_commentable = photo_hash["commentingEnabled"]
|
|
364
|
+
photo.size = photo_hash["size"]
|
|
365
|
+
photo.client = photo_hash["client"]
|
|
366
|
+
photo.title = photo_hash["group"]["title"]["content"]
|
|
367
|
+
photo.description = photo_hash["group"]["description"]["content"]
|
|
368
|
+
photo.url = photo_hash["group"]["content"]["url"]
|
|
369
|
+
photo.width = photo_hash["group"]["content"]["width"]
|
|
370
|
+
photo.height = photo_hash["group"]["content"]["height"]
|
|
371
|
+
photo.type = photo_hash["group"]["content"]["type"]
|
|
372
|
+
photo.medium = photo_hash["group"]["content"]["medium"]
|
|
373
|
+
|
|
374
|
+
# make thumbnails
|
|
375
|
+
photo.thumbnails = []
|
|
376
|
+
thumbnails_from_hash = photo_hash["group"]["thumbnail"]
|
|
377
|
+
if(thumbnails_from_hash.respond_to?(:each))
|
|
378
|
+
thumbnails_from_hash.each do |thumb|
|
|
379
|
+
thumbnail = Thumbnail.new
|
|
380
|
+
thumbnail.url = thumb["url"]
|
|
381
|
+
thumbnail.width = thumb["width"]
|
|
382
|
+
thumbnail.height = thumb["height"]
|
|
383
|
+
|
|
384
|
+
photo.thumbnails << thumbnail
|
|
385
|
+
end
|
|
386
|
+
else
|
|
387
|
+
|
|
388
|
+
end
|
|
389
|
+
|
|
390
|
+
# make self xml url
|
|
391
|
+
links_from_hash = photo_hash["link"]
|
|
392
|
+
if(links_from_hash.respond_to?(:each))
|
|
393
|
+
links_from_hash.each do |link|
|
|
394
|
+
if(link["rel"] == "self")
|
|
395
|
+
photo.self_xml_url = link["href"]
|
|
396
|
+
elsif(link["rel"] == "edit")
|
|
397
|
+
photo.edit_url = link["href"]
|
|
398
|
+
end
|
|
399
|
+
end
|
|
400
|
+
else
|
|
401
|
+
photo.self_xml_url = nil
|
|
402
|
+
photo.edit_url = nil
|
|
403
|
+
end
|
|
404
|
+
|
|
405
|
+
return photo
|
|
406
|
+
end
|
|
407
|
+
|
|
408
|
+
end
|
|
409
|
+
|
|
410
|
+
class Album
|
|
411
|
+
attr_accessor :picasa_session
|
|
412
|
+
|
|
413
|
+
attr_accessor :id, :name
|
|
414
|
+
attr_accessor :user
|
|
415
|
+
attr_accessor :title, :title_type
|
|
416
|
+
attr_accessor :description, :description_type
|
|
417
|
+
attr_accessor :access
|
|
418
|
+
attr_accessor :author_name, :author_uri
|
|
419
|
+
attr_accessor :number_of_photos, :number_of_comments
|
|
420
|
+
attr_accessor :is_commentable
|
|
421
|
+
attr_accessor :image_url, :image_type
|
|
422
|
+
attr_accessor :thumbnail
|
|
423
|
+
attr_accessor :xml
|
|
424
|
+
attr_accessor :self_xml_url, :edit_url
|
|
425
|
+
|
|
426
|
+
def initialize()
|
|
427
|
+
thumbnail = Thumbnail.new()
|
|
428
|
+
end
|
|
429
|
+
|
|
430
|
+
def photos(options = {})
|
|
431
|
+
|
|
432
|
+
userId = options[:user_id].nil? ? self.user : options[:user_id]
|
|
433
|
+
albumName = options[:album].nil? ? self.name : options[:album]
|
|
434
|
+
albumId = options[:album_id].nil? ? self.id : options[:album_id]
|
|
435
|
+
|
|
436
|
+
if(albumId != nil && albumId != "")
|
|
437
|
+
url = "http://picasaweb.google.com/data/feed/api/user/#{userId}/albumid/#{albumId}?kind=photo"
|
|
438
|
+
else
|
|
439
|
+
url = "http://picasaweb.google.com/data/feed/api/user/#{userId}/album/#{albumName}?kind=photo"
|
|
440
|
+
end
|
|
441
|
+
|
|
442
|
+
uri = URI.parse(url)
|
|
443
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
|
444
|
+
|
|
445
|
+
headers = {"Authorization" => "GoogleLogin auth=#{self.picasa_session.auth_key}"}
|
|
446
|
+
|
|
447
|
+
response, xml_response = http.get(uri.path, headers)
|
|
448
|
+
photos = self.create_photos_from_xml(xml_response)
|
|
449
|
+
|
|
450
|
+
return photos
|
|
451
|
+
end
|
|
452
|
+
|
|
453
|
+
def create_photos_from_xml(xml_response)
|
|
454
|
+
photos = []
|
|
455
|
+
#response_hash = XmlSimple.xml_in(xml_response, { 'ForceArray' => false })
|
|
456
|
+
#puts response_hash.inspect
|
|
457
|
+
|
|
458
|
+
Picasa.entries(xml_response).each do |entry|
|
|
459
|
+
#parse the entry xml element and get the photo object
|
|
460
|
+
photo = Picasa.parse_photo_entry(entry)
|
|
461
|
+
|
|
462
|
+
#enter session values in photo object
|
|
463
|
+
photo.picasa_session = PicasaSession.new
|
|
464
|
+
photo.picasa_session.auth_key = self.picasa_session.auth_key
|
|
465
|
+
photo.picasa_session.user_id = self.picasa_session.user_id
|
|
466
|
+
|
|
467
|
+
photos << photo
|
|
468
|
+
end
|
|
469
|
+
|
|
470
|
+
return photos
|
|
471
|
+
end
|
|
472
|
+
|
|
473
|
+
end
|
|
474
|
+
|
|
475
|
+
class Photo
|
|
476
|
+
attr_accessor :picasa_session
|
|
477
|
+
|
|
478
|
+
attr_accessor :id
|
|
479
|
+
attr_accessor :title, :description
|
|
480
|
+
attr_accessor :album_id
|
|
481
|
+
attr_accessor :size
|
|
482
|
+
attr_accessor :client
|
|
483
|
+
attr_accessor :is_commentable, :number_of_comments
|
|
484
|
+
attr_accessor :url, :width, :height, :type, :medium
|
|
485
|
+
attr_accessor :thumbnails
|
|
486
|
+
attr_accessor :xml
|
|
487
|
+
attr_accessor :version_number
|
|
488
|
+
attr_accessor :self_xml_url, :edit_url
|
|
489
|
+
|
|
490
|
+
def initialize()
|
|
491
|
+
thumbnails = []
|
|
492
|
+
end
|
|
493
|
+
|
|
494
|
+
def update()
|
|
495
|
+
|
|
496
|
+
updatePhotoXml = "<entry xmlns='http://www.w3.org/2005/Atom'
|
|
497
|
+
xmlns:media='http://search.yahoo.com/mrss/'
|
|
498
|
+
xmlns:gphoto='http://schemas.google.com/photos/2007'>
|
|
499
|
+
<title type='text'>#{self.title}</title>
|
|
500
|
+
<summary type='text'>#{self.description}</summary>
|
|
501
|
+
<gphoto:checksum></gphoto:checksum>
|
|
502
|
+
<gphoto:client></gphoto:client>
|
|
503
|
+
<gphoto:rotation>#{0}</gphoto:rotation>
|
|
504
|
+
<gphoto:timestamp>#{Time.new.to_i.to_s}</gphoto:timestamp>
|
|
505
|
+
<gphoto:commentingEnabled>#{self.is_commentable.to_s}</gphoto:commentingEnabled>
|
|
506
|
+
<category scheme='http://schemas.google.com/g/2005#kind'
|
|
507
|
+
term='http://schemas.google.com/photos/2007#photo'></category>
|
|
508
|
+
</entry>"
|
|
509
|
+
|
|
510
|
+
url = "http://picasaweb.google.com/data/entry/api/user/#{self.picasa_session.user_id}/albumid/#{self.album_id}/photoid/#{self.id}/#{self.version_number}"
|
|
511
|
+
|
|
512
|
+
uri = URI.parse(url)
|
|
513
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
|
514
|
+
|
|
515
|
+
headers = {"Content-Type" => "application/atom+xml", "Authorization" => "GoogleLogin auth=#{self.picasa_session.auth_key}"}
|
|
516
|
+
|
|
517
|
+
response, data = http.put(uri.path, updatePhotoXml, headers)
|
|
518
|
+
|
|
519
|
+
if(response.code == "200")
|
|
520
|
+
#parse the entry xml element and get the photo object
|
|
521
|
+
#new_photo = Picasa.parse_photo_entry(data)
|
|
522
|
+
new_photo = Picasa.parse_photo_entry(XmlSimple.xml_in(data.to_s, { 'ForceArray' => false }))
|
|
523
|
+
self.version_number = new_photo.version_number
|
|
524
|
+
|
|
525
|
+
return true
|
|
526
|
+
else
|
|
527
|
+
return false
|
|
528
|
+
end
|
|
529
|
+
end
|
|
530
|
+
|
|
531
|
+
def move_to_album(picasa_album_id)
|
|
532
|
+
|
|
533
|
+
updatePhotoXml = "<entry xmlns='http://www.w3.org/2005/Atom'
|
|
534
|
+
xmlns:media='http://search.yahoo.com/mrss/'
|
|
535
|
+
xmlns:gphoto='http://schemas.google.com/photos/2007'>
|
|
536
|
+
<title type='text'>#{self.title}</title>
|
|
537
|
+
<summary type='text'>#{self.description}</summary>
|
|
538
|
+
<gphoto:albumid>#{picasa_album_id}</gphoto:albumid>
|
|
539
|
+
<gphoto:checksum></gphoto:checksum>
|
|
540
|
+
<gphoto:client></gphoto:client>
|
|
541
|
+
<gphoto:rotation>#{0}</gphoto:rotation>
|
|
542
|
+
<gphoto:timestamp>#{Time.new.to_i.to_s}</gphoto:timestamp>
|
|
543
|
+
<gphoto:commentingEnabled>#{self.is_commentable.to_s}</gphoto:commentingEnabled>
|
|
544
|
+
<category scheme='http://schemas.google.com/g/2005#kind'
|
|
545
|
+
term='http://schemas.google.com/photos/2007#photo'></category>
|
|
546
|
+
</entry>"
|
|
547
|
+
|
|
548
|
+
url = "http://picasaweb.google.com/data/entry/api/user/#{self.picasa_session.user_id}/albumid/#{self.album_id}/photoid/#{self.id}/#{self.version_number}"
|
|
549
|
+
|
|
550
|
+
uri = URI.parse(url)
|
|
551
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
|
552
|
+
|
|
553
|
+
headers = {"Content-Type" => "application/atom+xml", "Authorization" => "GoogleLogin auth=#{self.picasa_session.auth_key}"}
|
|
554
|
+
|
|
555
|
+
response, data = http.put(uri.path, updatePhotoXml, headers)
|
|
556
|
+
|
|
557
|
+
if(response.code == "200")
|
|
558
|
+
#parse the entry xml element and get the photo object
|
|
559
|
+
new_photo = Picasa.parse_photo_entry(XmlSimple.xml_in(data.to_s, { 'ForceArray' => false }))
|
|
560
|
+
self.version_number = new_photo.version_number
|
|
561
|
+
self.album_id = new_photo.album_id
|
|
562
|
+
|
|
563
|
+
return true
|
|
564
|
+
else
|
|
565
|
+
return false
|
|
566
|
+
end
|
|
567
|
+
|
|
568
|
+
end
|
|
569
|
+
|
|
570
|
+
end
|
|
571
|
+
|
|
572
|
+
class Thumbnail
|
|
573
|
+
attr_accessor :url, :width, :height
|
|
574
|
+
end
|
|
575
|
+
|
|
576
|
+
end
|
|
577
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: google-picasa
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.1
|
|
5
|
+
prerelease:
|
|
6
|
+
platform: ruby
|
|
7
|
+
authors:
|
|
8
|
+
- Dmitry Trager
|
|
9
|
+
autorequire:
|
|
10
|
+
bindir: bin
|
|
11
|
+
cert_chain: []
|
|
12
|
+
date: 2011-11-26 00:00:00.000000000Z
|
|
13
|
+
dependencies: []
|
|
14
|
+
description: Access Picasa Web Album using pure Ruby code.
|
|
15
|
+
email:
|
|
16
|
+
- dmitry@trager.ru
|
|
17
|
+
executables: []
|
|
18
|
+
extensions: []
|
|
19
|
+
extra_rdoc_files: []
|
|
20
|
+
files:
|
|
21
|
+
- .gitignore
|
|
22
|
+
- Gemfile
|
|
23
|
+
- Rakefile
|
|
24
|
+
- google-picasa.gemspec
|
|
25
|
+
- lib/google-picasa.rb
|
|
26
|
+
- lib/google-picasa/version.rb
|
|
27
|
+
homepage: http://code.google.com/p/picasaonrails
|
|
28
|
+
licenses: []
|
|
29
|
+
post_install_message:
|
|
30
|
+
rdoc_options: []
|
|
31
|
+
require_paths:
|
|
32
|
+
- lib
|
|
33
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
34
|
+
none: false
|
|
35
|
+
requirements:
|
|
36
|
+
- - ! '>='
|
|
37
|
+
- !ruby/object:Gem::Version
|
|
38
|
+
version: '0'
|
|
39
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
40
|
+
none: false
|
|
41
|
+
requirements:
|
|
42
|
+
- - ! '>='
|
|
43
|
+
- !ruby/object:Gem::Version
|
|
44
|
+
version: '0'
|
|
45
|
+
requirements: []
|
|
46
|
+
rubyforge_project: google-picasa
|
|
47
|
+
rubygems_version: 1.8.10
|
|
48
|
+
signing_key:
|
|
49
|
+
specification_version: 3
|
|
50
|
+
summary: Ruby wrapper for Picasa API
|
|
51
|
+
test_files: []
|