picasa 0.5.4 → 0.6.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.
Files changed (89) hide show
  1. data/.gitignore +2 -0
  2. data/.travis.yml +4 -9
  3. data/Gemfile +4 -4
  4. data/README.md +4 -12
  5. data/extra/Thorfile +0 -3
  6. data/lib/picasa.rb +1 -8
  7. data/lib/picasa/api/album.rb +11 -11
  8. data/lib/picasa/api/base.rb +0 -3
  9. data/lib/picasa/api/comment.rb +6 -8
  10. data/lib/picasa/api/photo.rb +9 -9
  11. data/lib/picasa/api/tag.rb +6 -8
  12. data/lib/picasa/client.rb +2 -2
  13. data/lib/picasa/connection.rb +14 -51
  14. data/lib/picasa/exceptions.rb +1 -0
  15. data/lib/picasa/file.rb +8 -0
  16. data/lib/picasa/http.rb +28 -0
  17. data/lib/picasa/presenter/album.rb +15 -15
  18. data/lib/picasa/presenter/album_list.rb +10 -10
  19. data/lib/picasa/presenter/comment.rb +6 -6
  20. data/lib/picasa/presenter/comment_list.rb +10 -10
  21. data/lib/picasa/presenter/media.rb +5 -5
  22. data/lib/picasa/presenter/photo.rb +15 -15
  23. data/lib/picasa/presenter/tag.rb +3 -3
  24. data/lib/picasa/presenter/tag_list.rb +10 -10
  25. data/lib/picasa/utils.rb +11 -13
  26. data/lib/picasa/version.rb +1 -1
  27. data/picasa.gemspec +2 -1
  28. data/test/api/album_test.rb +163 -20
  29. data/test/api/comment_test.rb +95 -10
  30. data/test/api/photo_test.rb +27 -11
  31. data/test/api/tag_test.rb +84 -13
  32. data/test/cassettes/album-404.yml +52 -0
  33. data/test/cassettes/album-create.yml +107 -0
  34. data/test/cassettes/album-destroy.yml +55 -0
  35. data/test/cassettes/album-list.yml +85 -0
  36. data/test/cassettes/album-show.yml +123 -0
  37. data/test/cassettes/auth-failed.yml +50 -0
  38. data/test/cassettes/auth-success.yml +64 -0
  39. data/test/cassettes/comment-400.yml +56 -0
  40. data/test/cassettes/comment-create.yml +88 -0
  41. data/test/cassettes/comment-destroy.yml +53 -0
  42. data/test/cassettes/comment-list.yml +87 -0
  43. data/test/cassettes/photo-412.yml +58 -0
  44. data/test/cassettes/photo-create.yml +1908 -0
  45. data/test/cassettes/photo-destroy.yml +55 -0
  46. data/test/cassettes/tag-create.yml +85 -0
  47. data/test/cassettes/tag-destroy.yml +53 -0
  48. data/test/cassettes/tag-list.yml +79 -0
  49. data/test/client_test.rb +10 -10
  50. data/test/connection_test.rb +0 -35
  51. data/test/helper.rb +21 -7
  52. data/test/utils_test.rb +0 -6
  53. metadata +37 -40
  54. data/test/fixtures/album/album-create.txt +0 -21
  55. data/test/fixtures/album/album-list-with-tag.txt +0 -105
  56. data/test/fixtures/album/album-list.txt +0 -105
  57. data/test/fixtures/album/album-show-with-max-results.txt +0 -131
  58. data/test/fixtures/album/album-show-with-tag-and-many-photos.txt +0 -156
  59. data/test/fixtures/album/album-show-with-tag-and-one-photo.txt +0 -105
  60. data/test/fixtures/album/album-show.txt +0 -169
  61. data/test/fixtures/auth/success.txt +0 -14
  62. data/test/fixtures/comment/comment-list.txt +0 -65
  63. data/test/fixtures/exceptions/forbidden.txt +0 -12
  64. data/test/fixtures/exceptions/not_found.txt +0 -14
  65. data/test/fixtures/exceptions/precondition_failed.txt +0 -14
  66. data/test/fixtures/json.txt +0 -435
  67. data/test/fixtures/photo/photo-created.txt +0 -21
  68. data/test/fixtures/photo/photo-list-all-with-q.txt +0 -556
  69. data/test/fixtures/photo/photo-list-all.txt +0 -623
  70. data/test/fixtures/photo/photo-list-user.txt +0 -388
  71. data/test/fixtures/presenters/album_list.xml +0 -88
  72. data/test/fixtures/presenters/album_show.xml +0 -152
  73. data/test/fixtures/presenters/album_show_with_one_photo.xml +0 -88
  74. data/test/fixtures/presenters/comment_list.xml +0 -48
  75. data/test/fixtures/presenters/tag_list.xml +0 -51
  76. data/test/fixtures/tag/tag-list.txt +0 -68
  77. data/test/presenter/album_list_test.rb +0 -67
  78. data/test/presenter/album_test.rb +0 -189
  79. data/test/presenter/author_test.rb +0 -17
  80. data/test/presenter/base_test.rb +0 -50
  81. data/test/presenter/comment_list_test.rb +0 -67
  82. data/test/presenter/comment_test.rb +0 -56
  83. data/test/presenter/content_test.rb +0 -18
  84. data/test/presenter/link_test.rb +0 -21
  85. data/test/presenter/media_test.rb +0 -29
  86. data/test/presenter/photo_test.rb +0 -90
  87. data/test/presenter/tag_list_test.rb +0 -67
  88. data/test/presenter/tag_test.rb +0 -48
  89. data/test/presenter/thumbnail_test.rb +0 -24
data/.gitignore CHANGED
@@ -4,6 +4,8 @@
4
4
  .bundle
5
5
  .config
6
6
  .yardoc
7
+ .rbenv-version
8
+ .rbenv-gemsets
7
9
  Gemfile.lock
8
10
  InstalledFiles
9
11
  _yardoc
data/.travis.yml CHANGED
@@ -3,13 +3,8 @@ notifications:
3
3
  rvm:
4
4
  - 1.8.7
5
5
  - 1.9.3
6
- env:
7
- - XML_PARSER=rexml
8
- - XML_PARSER=nokogiri
9
- - XML_PARSER=libxml
10
- # does not work yet
11
- # - XML_PARSER=ox
12
6
 
13
- matrix:
14
- allow_failures:
15
- - env: XML_PARSER=rexml
7
+ env:
8
+ - JSON_PARSER=oj
9
+ - JSON_PARSER=yajl
10
+ - JSON_PARSER=json_pure
data/Gemfile CHANGED
@@ -7,7 +7,7 @@ gem "rake"
7
7
  gem "minitest", "3.5.0", :platform => :ruby_18
8
8
  gem "debugger", :platform => :ruby_19
9
9
 
10
- # xml parsers
11
- gem "nokogiri"
12
- gem "libxml-ruby"
13
- gem "ox"
10
+ # JSON parsers
11
+ gem "oj"
12
+ gem "yajl-ruby"
13
+ gem "json_pure"
data/README.md CHANGED
@@ -37,7 +37,7 @@ client = Picasa::Client.new(user_id: "some.user@gmail.com", password: "secret")
37
37
  Or by setting custom authorization header, i.e. taken from OAuth authentication:
38
38
 
39
39
  ```ruby
40
- client = Picasa::Client.new(user_id: "some.user@gmail.com", authorization_header: "OAuth token")
40
+ client = Picasa::Client.new(user_id: "some.user@gmail.com", authorization_header: "Bearer access-token")
41
41
  ```
42
42
 
43
43
  ### Proxy
@@ -78,18 +78,9 @@ If you run out of quota and want to resize images to fit Picasa free storage lim
78
78
  thor imagery:resize path-to-folder-with-photos
79
79
  ```
80
80
 
81
- ## Caveats
81
+ ### Boost
82
82
 
83
- Currently picasa wont work with `ox` xml parser.
84
-
85
- Using `rexml` parser wont return `etag` attribute properly.
86
-
87
- I recommend to use `libxml` or `nokogiri`.
88
- You can set it by:
89
-
90
- ```ruby
91
- MultiXml.parser = :libxml
92
- ```
83
+ Picasa uses gzipped requests to speedup fetching results. Benchmarks are available on [Vinicius Teles gist](https://gist.github.com/4012466)
93
84
 
94
85
  ## Continuous Integration
95
86
  [![Build Status](https://secure.travis-ci.org/morgoth/picasa.png)](http://travis-ci.org/morgoth/picasa)
@@ -102,6 +93,7 @@ MultiXml.parser = :libxml
102
93
  * [Javier Guerra](https://github.com/javierg)
103
94
  * [Eiichi Takebuchi](https://github.com/GRGSIBERIA)
104
95
  * [TADA Tadashi](https://github.com/tdtds)
96
+ * [Vinicius Teles](https://github.com/viniciusteles)
105
97
 
106
98
  ## Copyright
107
99
 
data/extra/Thorfile CHANGED
@@ -1,9 +1,6 @@
1
1
  require "picasa"
2
2
  require "thread"
3
3
 
4
- # Temporary requirement
5
- MultiXml.parser = :libxml
6
-
7
4
  class Imagery < Thor
8
5
  include Thor::Actions
9
6
 
data/lib/picasa.rb CHANGED
@@ -1,8 +1,7 @@
1
- require "multi_xml"
2
-
3
1
  require "picasa/version"
4
2
  require "picasa/utils"
5
3
  require "picasa/exceptions"
4
+ require "picasa/http"
6
5
  require "picasa/connection"
7
6
  require "picasa/client"
8
7
  require "picasa/file"
@@ -25,9 +24,3 @@ require "picasa/presenter/photo"
25
24
  require "picasa/presenter/tag"
26
25
  require "picasa/presenter/tag_list"
27
26
  require "picasa/presenter/thumbnail"
28
-
29
- module Picasa
30
- API_URL = "https://picasaweb.google.com"
31
- API_AUTH_URL = "https://www.google.com"
32
- API_VERSION = "2"
33
- end
@@ -13,10 +13,10 @@ module Picasa
13
13
  #
14
14
  # @return [Presenter::AlbumList]
15
15
  def list(options = {})
16
- uri = URI.parse("/data/feed/api/user/#{user_id}")
17
- response = Connection.new.get(:path => uri.path, :query => options, :headers => auth_header)
16
+ path = "/data/feed/api/user/#{user_id}"
17
+ response = Connection.new.get(:path => path, :query => options, :headers => auth_header)
18
18
 
19
- Presenter::AlbumList.new(MultiXml.parse(response.body)["feed"])
19
+ Presenter::AlbumList.new(response.parsed_response["feed"])
20
20
  end
21
21
 
22
22
  # Returns photo list for given album
@@ -30,10 +30,10 @@ module Picasa
30
30
  # @return [Presenter::Album]
31
31
  # @raise [NotFoundError] raised when album cannot be found
32
32
  def show(album_id, options = {})
33
- uri = URI.parse("/data/feed/api/user/#{user_id}/albumid/#{album_id}")
34
- response = Connection.new.get(:path => uri.path, :query => options, :headers => auth_header)
33
+ path = "/data/feed/api/user/#{user_id}/albumid/#{album_id}"
34
+ response = Connection.new.get(:path => path, :query => options, :headers => auth_header)
35
35
 
36
- Presenter::Album.new(MultiXml.parse(response.body)["feed"])
36
+ Presenter::Album.new(response.parsed_response["feed"])
37
37
  end
38
38
 
39
39
  # Creates album
@@ -52,10 +52,10 @@ module Picasa
52
52
  params[:access] ||= "private"
53
53
 
54
54
  template = Template.new(:new_album, params)
55
- uri = URI.parse("/data/feed/api/user/#{user_id}")
56
- response = Connection.new.post(:path => uri.path, :body => template.render, :headers => auth_header)
55
+ path = "/data/feed/api/user/#{user_id}"
56
+ response = Connection.new.post(:path => path, :body => template.render, :headers => auth_header)
57
57
 
58
- Presenter::Album.new(MultiXml.parse(response.body)["entry"])
58
+ Presenter::Album.new(response.parsed_response["entry"])
59
59
  end
60
60
 
61
61
  # Destroys given album
@@ -69,8 +69,8 @@ module Picasa
69
69
  # @raise [PreconditionFailedError] raised when ETag does not match
70
70
  def destroy(album_id, options = {})
71
71
  headers = auth_header.merge({"If-Match" => options.fetch(:etag, "*")})
72
- uri = URI.parse("/data/entry/api/user/#{user_id}/albumid/#{album_id}")
73
- Connection.new.delete(:path => uri.path, :headers => headers)
72
+ path = "/data/entry/api/user/#{user_id}/albumid/#{album_id}"
73
+ Connection.new.delete(:path => path, :headers => headers)
74
74
  true
75
75
  end
76
76
  alias :delete :destroy
@@ -7,9 +7,6 @@ module Picasa
7
7
  # @option credentials [String] :user_id google username/email
8
8
  # @option credentials [String] :authorization_header header for authenticating requests
9
9
  def initialize(credentials = {})
10
- if MultiXml.parser.to_s == "MultiXml::Parsers::Ox"
11
- raise StandardError, "MultiXml parser is set to :ox - picasa gem will not work with it currently, use one of: :libxml, :nokogiri, :rexml"
12
- end
13
10
  @user_id = credentials.fetch(:user_id)
14
11
  @authorization_header = credentials[:authorization_header]
15
12
  end
@@ -19,10 +19,9 @@ module Picasa
19
19
  path << "/albumid/#{album_id}" if album_id
20
20
  path << "/photoid/#{photo_id}" if photo_id
21
21
 
22
- uri = URI.parse(path)
23
- response = Connection.new.get(:path => uri.path, :query => options.merge(:kind => "comment"), :headers => auth_header)
22
+ response = Connection.new.get(:path => path, :query => options.merge(:kind => "comment"), :headers => auth_header)
24
23
 
25
- Presenter::CommentList.new(MultiXml.parse(response.body)["feed"])
24
+ Presenter::CommentList.new(response.parsed_response["feed"])
26
25
  end
27
26
 
28
27
  # Creates a comment for a photo.
@@ -42,10 +41,9 @@ module Picasa
42
41
 
43
42
  template = Template.new("new_comment", params)
44
43
 
45
- uri = URI.parse(path)
46
- response = Connection.new.post(:path => uri.path, :body => template.render, :headers => auth_header)
44
+ response = Connection.new.post(:path => path, :body => template.render, :headers => auth_header)
47
45
 
48
- Presenter::Comment.new(MultiXml.parse(response.body)["entry"])
46
+ Presenter::Comment.new(response.parsed_response["entry"])
49
47
  end
50
48
 
51
49
  # Removes a comment from given photo.
@@ -60,8 +58,8 @@ module Picasa
60
58
  album_id = params.delete(:album_id) || raise(ArgumentError, "You must specify album_id")
61
59
  photo_id = params.delete(:photo_id) || raise(ArgumentError, "You must specify photo_id")
62
60
 
63
- uri = URI.parse("/data/entry/api/user/#{user_id}/albumid/#{album_id}/photoid/#{photo_id}/commentid/#{comment_id}")
64
- Connection.new.delete(:path => uri.path, :headers => auth_header)
61
+ path = "/data/entry/api/user/#{user_id}/albumid/#{album_id}/photoid/#{photo_id}/commentid/#{comment_id}"
62
+ Connection.new.delete(:path => path, :headers => auth_header)
65
63
  true
66
64
  end
67
65
  alias :delete :destroy
@@ -13,19 +13,19 @@ module Picasa
13
13
  # @option options [String] :binary binary data (i.e. File.open("my-photo.png", "rb").read)
14
14
  # @option options [String] :content_type ["image/jpeg", "image/png", "image/bmp", "image/gif"] content type of given image
15
15
  def create(album_id, params = {})
16
- file = params[:file_path] ? File.new(params.delete(:file_path)) : nil
16
+ file = params[:file_path] ? File.new(params.delete(:file_path)) : File::Null.new
17
17
  params[:boundary] ||= "===============PicasaRubyGem=="
18
- params[:title] ||= (file && file.name) || raise(ArgumentError.new("title must be specified"))
19
- params[:binary] ||= (file && file.binary) || raise(ArgumentError.new("binary must be specified"))
20
- params[:content_type] ||= (file && file.content_type) || raise(ArgumentError.new("content_type must be specified"))
18
+ params[:title] ||= file.name || raise(ArgumentError.new("title must be specified"))
19
+ params[:binary] ||= file.binary || raise(ArgumentError.new("binary must be specified"))
20
+ params[:content_type] ||= file.content_type || raise(ArgumentError.new("content_type must be specified"))
21
21
 
22
22
  template = Template.new(:new_photo, params)
23
23
  headers = auth_header.merge({"Content-Type" => "multipart/related; boundary=\"#{params[:boundary]}\""})
24
24
 
25
- uri = URI.parse("/data/feed/api/user/#{user_id}/albumid/#{album_id}")
26
- response = Connection.new.post(:path => uri.path, :body => template.render, :headers => headers)
25
+ path = "/data/feed/api/user/#{user_id}/albumid/#{album_id}"
26
+ response = Connection.new.post(:path => path, :body => template.render, :headers => headers)
27
27
 
28
- Presenter::Photo.new(MultiXml.parse(response.body)["entry"])
28
+ Presenter::Photo.new(response.parsed_response["entry"])
29
29
  end
30
30
 
31
31
  # Destroys given photo
@@ -40,8 +40,8 @@ module Picasa
40
40
  # @raise [PreconditionFailedError] raised when ETag does not match
41
41
  def destroy(album_id, photo_id, options = {})
42
42
  headers = auth_header.merge({"If-Match" => options.fetch(:etag, "*")})
43
- uri = URI.parse("/data/entry/api/user/#{user_id}/albumid/#{album_id}/photoid/#{photo_id}")
44
- Connection.new.delete(:path => uri.path, :headers => headers)
43
+ path = "/data/entry/api/user/#{user_id}/albumid/#{album_id}/photoid/#{photo_id}"
44
+ Connection.new.delete(:path => path, :headers => headers)
45
45
  true
46
46
  end
47
47
  alias :delete :destroy
@@ -19,10 +19,9 @@ module Picasa
19
19
  path << "/albumid/#{album_id}" if album_id
20
20
  path << "/photoid/#{photo_id}" if photo_id
21
21
 
22
- uri = URI.parse(path)
23
- response = Connection.new.get(:path => uri.path, :query => options.merge(:kind => "tag"), :headers => auth_header)
22
+ response = Connection.new.get(:path => path, :query => options.merge(:kind => "tag"), :headers => auth_header)
24
23
 
25
- Presenter::TagList.new(MultiXml.parse(response.body)["feed"])
24
+ Presenter::TagList.new(response.parsed_response["feed"])
26
25
  end
27
26
 
28
27
  # Creates a tag for a photo.
@@ -42,10 +41,9 @@ module Picasa
42
41
 
43
42
  template = Template.new("new_tag", params)
44
43
 
45
- uri = URI.parse(path)
46
- response = Connection.new.post(:path => uri.path, :body => template.render, :headers => auth_header)
44
+ response = Connection.new.post(:path => path, :body => template.render, :headers => auth_header)
47
45
 
48
- Presenter::Tag.new(MultiXml.parse(response.body)["entry"])
46
+ Presenter::Tag.new(response.parsed_response["entry"])
49
47
  end
50
48
 
51
49
  # Removes a tag from given photo.
@@ -60,8 +58,8 @@ module Picasa
60
58
  album_id = params.delete(:album_id) || raise(ArgumentError, "You must specify album_id")
61
59
  photo_id = params.delete(:photo_id) || raise(ArgumentError, "You must specify photo_id")
62
60
 
63
- uri = URI.parse("/data/entry/api/user/#{user_id}/albumid/#{album_id}/photoid/#{photo_id}/tag/#{tag_id}")
64
- Connection.new.delete(:path => uri.path, :headers => auth_header)
61
+ path = "/data/entry/api/user/#{user_id}/albumid/#{album_id}/photoid/#{photo_id}/tag/#{tag_id}"
62
+ Connection.new.delete(:path => path, :headers => auth_header)
65
63
  true
66
64
  end
67
65
  alias :delete :destroy
data/lib/picasa/client.rb CHANGED
@@ -63,7 +63,7 @@ module Picasa
63
63
  # @return [String]
64
64
  def authenticate
65
65
  response = Connection.new.post(
66
- :host => API_AUTH_URL,
66
+ :host => HTTP::API_AUTH_URL,
67
67
  :headers => {"Content-Type" => "application/x-www-form-urlencoded"},
68
68
  :path => "/accounts/ClientLogin",
69
69
  :body => Utils.inline_query(
@@ -71,7 +71,7 @@ module Picasa
71
71
  "Email" => user_id,
72
72
  "Passwd" => password,
73
73
  "service" => "lh2",
74
- "source" => "ruby-gem-v#{VERSION}"
74
+ "source" => "ruby-gem-picasa-v#{VERSION}"
75
75
  )
76
76
  )
77
77
 
@@ -1,6 +1,3 @@
1
- require "net/https"
2
- require "uri"
3
-
4
1
  module Picasa
5
2
  class Connection
6
3
  # @param [Hash] params request arguments
@@ -9,13 +6,9 @@ module Picasa
9
6
  # @option params [String] :query request url query
10
7
  # @option params [String] :headers request headers
11
8
  def get(params = {})
12
- params[:host] ||= API_URL
13
- params[:headers] ||= {}
14
- params[:query] ||= {}
15
-
16
- path = path_with_query(params[:path], params[:query])
17
- request = Net::HTTP::Get.new(path, headers.merge(params[:headers]))
18
- handle_response(http(params[:host]).request(request))
9
+ # FIXME: how to add headers to default ones instead of replacing?
10
+ params[:headers] = Picasa::HTTP.headers.merge(params[:headers]) if params.has_key?(:headers)
11
+ exec_request(params) { |uri, options| HTTP.get(uri, options) }
19
12
  end
20
13
 
21
14
  # @param [Hash] params request arguments
@@ -25,12 +18,10 @@ module Picasa
25
18
  # @option params [String] :query request url query
26
19
  # @option params [String] :headers request headers
27
20
  def post(params = {})
28
- params[:host] ||= API_URL
29
21
  params[:headers] ||= {}
30
-
31
- request = Net::HTTP::Post.new(params[:path], headers.merge(params[:headers]))
32
- request.body = params[:body]
33
- handle_response(http(params[:host]).request(request))
22
+ params[:headers]["Content-Type"] ||= "application/atom+xml"
23
+ params[:headers] = Picasa::HTTP.headers.merge(params[:headers])
24
+ exec_request(params) { |uri, options| HTTP.post(uri, options) }
34
25
  end
35
26
 
36
27
  # @param [Hash] params request arguments
@@ -39,36 +30,24 @@ module Picasa
39
30
  # @option params [String] :query request url query
40
31
  # @option params [String] :headers request headers
41
32
  def delete(params = {})
42
- params[:host] ||= API_URL
43
- params[:headers] ||= {}
44
-
45
- request = Net::HTTP::Delete.new(params[:path], headers.merge(params[:headers]))
46
- handle_response(http(params[:host]).request(request))
47
- end
48
-
49
- def path_with_query(path, query = {})
50
- path = path + "?" + Utils.inline_query(query) unless query.empty?
51
- URI.parse(path).to_s
33
+ params[:headers] = Picasa::HTTP.headers.merge(params[:headers]) if params.has_key?(:headers)
34
+ exec_request(params) { |uri, options| HTTP.delete(uri, options) }
52
35
  end
53
36
 
54
37
  private
55
38
 
56
- def http(url = API_URL)
57
- uri = URI.parse(url)
58
-
59
- if proxy?
60
- http = Net::HTTP::Proxy(proxy_uri.host, proxy_uri.port, proxy_uri.user, proxy_uri.password).new(uri.host, uri.port)
61
- else
62
- http = Net::HTTP.new(uri.host, uri.port)
63
- end
64
- http.use_ssl = true
65
- http
39
+ def exec_request(params, &block)
40
+ uri = "#{params.delete(:host)}#{params.delete(:path)}"
41
+ params.delete_if { |key, value| value.nil? || value.empty? }
42
+ handle_response(yield(uri, params))
66
43
  end
67
44
 
68
45
  def handle_response(response)
69
46
  case response.code.to_i
70
47
  when 200...300
71
48
  response
49
+ when 400
50
+ raise BadRequestError.new(response.body, response)
72
51
  when 403
73
52
  raise ForbiddenError.new(response.body, response)
74
53
  when 404
@@ -79,21 +58,5 @@ module Picasa
79
58
  raise ResponseError.new(response.body, response)
80
59
  end
81
60
  end
82
-
83
- def headers
84
- {
85
- "User-Agent" => "ruby-gem-v#{VERSION}",
86
- "GData-Version" => API_VERSION,
87
- "Content-Type" => "application/atom+xml"
88
- }
89
- end
90
-
91
- def proxy_uri
92
- @proxy_uri ||= URI.parse(ENV["https_proxy"] || ENV["HTTPS_PROXY"])
93
- end
94
-
95
- def proxy?
96
- ENV.has_key?("https_proxy") || ENV.has_key?("HTTPS_PROXY")
97
- end
98
61
  end
99
62
  end
@@ -15,6 +15,7 @@ module Picasa
15
15
  end
16
16
  end
17
17
 
18
+ class BadRequestError < ResponseError; end
18
19
  class NotFoundError < ResponseError; end
19
20
  class ForbiddenError < ResponseError; end
20
21
  class PreconditionFailedError < ResponseError; end
data/lib/picasa/file.rb CHANGED
@@ -1,5 +1,13 @@
1
1
  module Picasa
2
2
  class File
3
+ class Null
4
+ def path; end
5
+ def name; end
6
+ def extension; end
7
+ def binary; end
8
+ def content_type; end
9
+ end
10
+
3
11
  attr_reader :path
4
12
 
5
13
  def initialize(path)
@@ -0,0 +1,28 @@
1
+ require "httparty"
2
+ require "uri"
3
+
4
+ module Picasa
5
+ class HTTP
6
+ include HTTParty
7
+
8
+ API_URL = "https://picasaweb.google.com"
9
+ API_AUTH_URL = "https://www.google.com"
10
+ API_VERSION = "2"
11
+
12
+ def self.proxy
13
+ proxy_uri = URI.parse(ENV["https_proxy"] || ENV["HTTPS_PROXY"] || "")
14
+ [proxy_uri.host, proxy_uri.port, proxy_uri.user, proxy_uri.password]
15
+ end
16
+
17
+ format :json
18
+ default_params :alt => :json
19
+
20
+ headers "User-Agent" => "ruby-gem-picasa-v#{VERSION} (gzip)",
21
+ "GData-Version" => API_VERSION,
22
+ "Accept-Encoding" => "gzip, deflate"
23
+
24
+ base_uri API_URL
25
+
26
+ http_proxy *proxy
27
+ end
28
+ end