google-picasa 0.0.5 → 0.0.6

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