dewey 0.2.6 → 0.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,3 +1,10 @@
1
+ ## 0.2.7 (December 12, 2010)
2
+
3
+ * Documents, Drawings and Presentations are actually downloadable again. The
4
+ Google Docs API documentation wasn't updated to reflect that the docID
5
+ param was now just id.
6
+ * Minor internal improvements
7
+
1
8
  ## 0.2.6 (November 3, 2010)
2
9
 
3
10
  * Downloaded files are automatically rewound
data/README.md CHANGED
@@ -19,17 +19,13 @@ Dewey is in alpha. It is not recommended you use this in production code.
19
19
 
20
20
  ## Authentication
21
21
 
22
- You can configure Dewey to connect with either ClientLogin or OAuth. If you choose
23
- OAuth you'll only have to authenticate the first time you connect and subsequent
24
- connections will use the saved token.
22
+ You can configure Dewey to connect with ClientLogin.
25
23
 
26
24
  ClientLogin
27
25
 
28
26
  Dewey.authentication :client, :email => 'example@gmail.com', :password => 'password'
29
27
 
30
- OAuth
31
-
32
- Dewey.authentication :oauth, :idontknowwhatgoeshereyet
28
+ AuthSub and OAuth support is planned for a future release.
33
29
 
34
30
  ## File Operations
35
31
 
@@ -72,11 +68,20 @@ A tempfile is returned, so you'll have to move it
72
68
 
73
69
  FileUtils.mv html.path, 'path/to/destination'
74
70
 
75
- Getting a document by title. Unmatched searches return nil
71
+ Getting a document by title. Since only one file will be returned at a time you
72
+ must use an exact match.
76
73
 
77
74
  Dewey.get('My Document') #=> Tempfile
78
75
  Dewey.get('No Match') #=> nil
79
76
 
77
+ Other file types are supported as well, including spreadsheets, drawings and
78
+ presentations:
79
+
80
+ Dewey.get('Mine') #=> ['presentation:12345', 'spreadsheet:12345', 'drawing:12345']
81
+ Dewey.get('presentation:12345') #=> Tempfile
82
+ Dewey.get('spreadsheet:12345') #=> Tempfile
83
+ Dewey.get('drawing:12345') #=> Tempfile
84
+
80
85
  ### Deleting a Document
81
86
 
82
87
  Deleting a document from a resource id
@@ -9,8 +9,8 @@ module Dewey
9
9
  GOOGLE_PRESENTATION_URL = GOOGLE_DOCS_URL + "/feeds/download/presentations/Export"
10
10
  GOOGLE_SPREADSHEET_URL = GOOGLE_SPRD_URL + "/feeds/download/spreadsheets/Export"
11
11
 
12
- class DeweyException < Exception; end
13
- class DeweyAuthorizationException < Exception; end
12
+ class DeweyError < StandardError; end
13
+ class DeweyAuthorizationError < StandardError; end
14
14
  end
15
15
 
16
16
  require 'dewey/core'
@@ -36,7 +36,7 @@ module Dewey
36
36
  when Net::HTTPForbidden
37
37
  false
38
38
  else
39
- raise DeweyAuthorizationException, "Unexpected response: #{response}"
39
+ raise DeweyError, "Unexpected response: #{response}"
40
40
  end
41
41
  end
42
42
 
@@ -51,6 +51,7 @@ module Dewey
51
51
  def guard(service)
52
52
  case service
53
53
  when nil then :writely
54
+ when 'document' then :writely
54
55
  when 'spreadsheet' then :wise
55
56
  else
56
57
  service.to_sym
@@ -42,7 +42,7 @@ module Dewey
42
42
  # @return [Array] An array of matched ids. No matches return an empty array
43
43
  def search(query, options = {})
44
44
  title = query.gsub(/\s+/, '+')
45
- headers = base_headers(false)
45
+ headers = base_headers
46
46
  url = "#{GOOGLE_FEED_URL}?title=#{title}"
47
47
  url << "&title-exact=true" if options[:exact]
48
48
  response = http_request(:get, url, headers)
@@ -66,11 +66,11 @@ module Dewey
66
66
  service = Dewey::Mime.guess_service(mimetype)
67
67
  title = options[:title] || basename
68
68
 
69
- raise DeweyException, "Invalid file type: #{extension}" unless Dewey::Validation.valid_upload_format?(extension, service)
69
+ raise DeweyError, "Invalid file type: #{extension}" unless Dewey::Validation.valid_upload_format?(extension, service)
70
70
 
71
71
  headers = base_headers
72
72
  headers['Content-Length'] = File.size?(file).to_s
73
- headers['Slug'] = Dewey::Utils.escape(title)
73
+ headers['Slug'] = Dewey::Utils.slug(title)
74
74
  headers['Content-Type'] = mimetype unless mimetype =~ /Can't expand summary_info/
75
75
 
76
76
  # Rewind the file in the case of multiple uploads, or conversions
@@ -89,7 +89,7 @@ module Dewey
89
89
  #
90
90
  # @see put
91
91
  def put!(file, options = {})
92
- put(file, options) || raise(DeweyException, "Unable to put document")
92
+ put(file, options) || raise(DeweyError, "Unable to put document")
93
93
  end
94
94
 
95
95
  # Download a file. You may optionally specify a format for export.
@@ -117,18 +117,18 @@ module Dewey
117
117
  case service
118
118
  when 'document'
119
119
  url << GOOGLE_DOCUMENT_URL
120
- url << "?docID=#{id}"
120
+ url << "?id=#{id}"
121
121
  when 'drawing'
122
122
  url << GOOGLE_DRAWING_URL
123
- url << "?docID=#{id}"
123
+ url << "?id=#{id}"
124
124
  when 'presentation'
125
125
  url << GOOGLE_PRESENTATION_URL
126
- url << "?docID=#{id}"
126
+ url << "?id=#{id}"
127
127
  when 'spreadsheet'
128
128
  url << GOOGLE_SPREADSHEET_URL
129
129
  url << "?key=#{id}"
130
130
  else
131
- raise DeweyException, "Invalid service: #{service}"
131
+ raise DeweyError, "Invalid service: #{service}"
132
132
  end
133
133
 
134
134
  unless format.empty?
@@ -137,15 +137,14 @@ module Dewey
137
137
  url << "&format=#{format}" if service == 'document'
138
138
  url << "&gid=#{options[:sheet]}" if service == 'spreadsheet' && options[:sheet]
139
139
  else
140
- raise DeweyException, "Invalid format: #{format}"
140
+ raise DeweyError, "Invalid format: #{format}"
141
141
  end
142
142
  end
143
143
 
144
- response = http_request(:get, url, base_headers(true, service))
144
+ response = http_request(:get, url, base_headers(service))
145
145
 
146
146
  if response.kind_of?(Net::HTTPOK)
147
- file = Tempfile.new([id, format].join('.'))
148
- file.binmode
147
+ file = Tempfile.new([id, format].join('.')).binmode
149
148
  file.write(response.body)
150
149
  file.rewind
151
150
  file
@@ -167,13 +166,13 @@ module Dewey
167
166
  def delete(query, options = {})
168
167
 
169
168
  # We use 'If-Match' => '*' to make sure we delete regardless of others
170
- headers = base_headers(false).merge({'If-Match' => '*'})
169
+ headers = base_headers.merge({'If-Match' => '*'})
171
170
  trash = options.delete(:trash) || false
172
171
  id = (is_id?(query)) ? query : search(query, :exact => true).first
173
172
 
174
173
  return false if id.nil?
175
174
 
176
- url = "#{GOOGLE_FEED_URL}/#{Dewey::Utils.escape(id)}"
175
+ url = "#{GOOGLE_FEED_URL}/#{URI.escape(id)}"
177
176
  url << "?delete=true" unless trash
178
177
 
179
178
  response = http_request(:delete, url, headers)
@@ -181,12 +180,12 @@ module Dewey
181
180
  response.kind_of?(Net::HTTPOK)
182
181
  end
183
182
 
184
- # The same as delete, except that it will raise `Dewey::DeweyException` if
183
+ # The same as delete, except that it will raise `Dewey::DeweyError` if
185
184
  # the request fails.
186
185
  #
187
186
  # @see #delete
188
187
  def delete!(query, options = {})
189
- delete(query, options) || raise(DeweyException, "Unable to delete document")
188
+ delete(query, options) || raise(DeweyError, "Unable to delete document")
190
189
  end
191
190
 
192
191
  # Convenience method for `put`, `get`, `delete`.
@@ -218,6 +217,7 @@ module Dewey
218
217
  @@authenticator
219
218
  end
220
219
 
220
+ # Perform the actual request heavy lifting
221
221
  def http_request(method, url, headers, data = nil) #:nodoc:
222
222
  url = URI.parse(url) if url.kind_of? String
223
223
 
@@ -229,22 +229,20 @@ module Dewey
229
229
  when :get
230
230
  connection.get(full_path, headers)
231
231
  when :post
232
+ headers['Content-Type'] = 'application/x-www-form-urlencoded'
232
233
  connection.post(full_path, data, headers)
233
234
  when :delete
234
235
  connection.delete(full_path, headers)
235
- else
236
- raise DeweyException, "Invalid request type. Valid options are :get, :post and :delete"
237
236
  end
238
237
  end
239
238
 
240
239
  # A hash of default headers. Considers authentication and put/post headers.
241
240
  #
242
- # @param [Boolean] form If true the Content-Type will be set accordingly
241
+ # @param [String] service The document type or service eg. (document/writely)
243
242
  # @return [Hash] Headers hash
244
- def base_headers(form = true, service = nil) #:nodoc:
243
+ def base_headers(service = nil) #:nodoc:
245
244
  base = {}
246
245
  base['GData-Version'] = '3.0'
247
- base['Content-Type'] = 'application/x-www-form-urlencoded' if form
248
246
  base['Authorization'] = "GoogleLogin auth=#{authenticator.token(service)}"
249
247
 
250
248
  base
@@ -261,7 +259,7 @@ module Dewey
261
259
 
262
260
  # Is the string an id or a search query?
263
261
  def is_id?(string)
264
- string.match(/^[a-z]+:.+$/)
262
+ string =~ /^[a-z]+:.+$/
265
263
  end
266
264
  end
267
265
  end
@@ -1,19 +1,17 @@
1
1
  module Dewey
2
2
  module Utils #:nodoc:
3
- # Performs URI escaping. (Stolen from Camping via Rake).
4
- def escape(s)
5
- s.to_s.gsub(/([^ a-zA-Z0-9_.-]+)/n) {
6
- '%'+$1.unpack('H2' * bytesize($1)).join('%').upcase
7
- }.tr(' ', '+')
3
+ # Perform string escaping for Atom slugs
4
+ def slug(string)
5
+ string.chars.to_a.map do |char|
6
+ decimal = char.unpack('U').join('').to_i
7
+ if decimal < 32 || decimal > 126 || decimal == 37
8
+ char = "%#{char.unpack('H2').join('%').upcase}"
9
+ end
10
+
11
+ char
12
+ end.join('')
8
13
  end
9
-
10
- module_function :escape
11
-
12
- # Return the bytesize of String; uses String#length under Ruby 1.8
13
- def bytesize(string)
14
- string.bytesize
15
- end
16
-
17
- module_function :bytesize
14
+
15
+ module_function :slug
18
16
  end
19
- end
17
+ end
@@ -18,7 +18,7 @@ module Dewey
18
18
  #
19
19
  # @return [Boolean] `true` if the format is supported, `false` otherwise
20
20
  #
21
- # @raise [DeweyException] Raised when an unknown service is given
21
+ # @raise [DeweyError] Raised when an unknown service is given
22
22
  def valid_upload_format?(format, service = nil)
23
23
  format = format.to_sym
24
24
  service = default_service(service)
@@ -29,7 +29,7 @@ module Dewey
29
29
  when :presentation then Dewey::PRESENTATION_MIMETYPES.has_key?(format)
30
30
  when :spreadsheet then Dewey::SPREADSHEET_MIMETYPES.has_key?(format)
31
31
  else
32
- raise DeweyException, "Unknown service: #{service}"
32
+ raise DeweyError, "Unknown service: #{service}"
33
33
  end
34
34
  end
35
35
 
@@ -41,7 +41,7 @@ module Dewey
41
41
  #
42
42
  # @return [Boolean] `true` if the format is supported, `false` otherwise
43
43
  #
44
- # @raise [DeweyException] Raised when an unknown service is given
44
+ # @raise [DeweyError] Raised when an unknown service is given
45
45
  def valid_export_format?(format, service = nil)
46
46
  format = format.to_sym
47
47
  service = default_service(service)
@@ -52,7 +52,7 @@ module Dewey
52
52
  when :presentation then Dewey::PRESENTATION_EXPORT_FORMATS.include?(format)
53
53
  when :spreadsheet then Dewey::SPREADSHEET_EXPORT_FORMATS.include?(format)
54
54
  else
55
- raise DeweyException, "Unknown service: #{service}"
55
+ raise DeweyError, "Unknown service: #{service}"
56
56
  end
57
57
  end
58
58
 
@@ -1,3 +1,3 @@
1
1
  module Dewey
2
- VERSION = '0.2.6'
2
+ VERSION = '0.2.7'
3
3
  end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 2
8
- - 6
9
- version: 0.2.6
8
+ - 7
9
+ version: 0.2.7
10
10
  platform: ruby
11
11
  authors:
12
12
  - Parker Selbert
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-11-03 00:00:00 -05:00
17
+ date: 2010-12-12 00:00:00 -06:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency