picasa 0.5.4 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
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