dewey 0.2.6 → 0.2.7
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +7 -0
- data/README.md +12 -7
- data/lib/dewey.rb +2 -2
- data/lib/dewey/client_auth.rb +2 -1
- data/lib/dewey/core.rb +20 -22
- data/lib/dewey/utils.rb +13 -15
- data/lib/dewey/validation.rb +4 -4
- data/lib/dewey/version.rb +1 -1
- metadata +3 -3
data/CHANGELOG.md
CHANGED
@@ -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
|
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.
|
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
|
data/lib/dewey.rb
CHANGED
@@ -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
|
13
|
-
class
|
12
|
+
class DeweyError < StandardError; end
|
13
|
+
class DeweyAuthorizationError < StandardError; end
|
14
14
|
end
|
15
15
|
|
16
16
|
require 'dewey/core'
|
data/lib/dewey/client_auth.rb
CHANGED
@@ -36,7 +36,7 @@ module Dewey
|
|
36
36
|
when Net::HTTPForbidden
|
37
37
|
false
|
38
38
|
else
|
39
|
-
raise
|
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
|
data/lib/dewey/core.rb
CHANGED
@@ -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
|
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
|
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.
|
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(
|
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 << "?
|
120
|
+
url << "?id=#{id}"
|
121
121
|
when 'drawing'
|
122
122
|
url << GOOGLE_DRAWING_URL
|
123
|
-
url << "?
|
123
|
+
url << "?id=#{id}"
|
124
124
|
when 'presentation'
|
125
125
|
url << GOOGLE_PRESENTATION_URL
|
126
|
-
url << "?
|
126
|
+
url << "?id=#{id}"
|
127
127
|
when 'spreadsheet'
|
128
128
|
url << GOOGLE_SPREADSHEET_URL
|
129
129
|
url << "?key=#{id}"
|
130
130
|
else
|
131
|
-
raise
|
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
|
140
|
+
raise DeweyError, "Invalid format: #{format}"
|
141
141
|
end
|
142
142
|
end
|
143
143
|
|
144
|
-
response = http_request(:get, url, base_headers(
|
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
|
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}/#{
|
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::
|
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(
|
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 [
|
241
|
+
# @param [String] service The document type or service eg. (document/writely)
|
243
242
|
# @return [Hash] Headers hash
|
244
|
-
def base_headers(
|
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
|
262
|
+
string =~ /^[a-z]+:.+$/
|
265
263
|
end
|
266
264
|
end
|
267
265
|
end
|
data/lib/dewey/utils.rb
CHANGED
@@ -1,19 +1,17 @@
|
|
1
1
|
module Dewey
|
2
2
|
module Utils #:nodoc:
|
3
|
-
#
|
4
|
-
def
|
5
|
-
|
6
|
-
|
7
|
-
|
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 :
|
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
|
data/lib/dewey/validation.rb
CHANGED
@@ -18,7 +18,7 @@ module Dewey
|
|
18
18
|
#
|
19
19
|
# @return [Boolean] `true` if the format is supported, `false` otherwise
|
20
20
|
#
|
21
|
-
# @raise [
|
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
|
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 [
|
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
|
55
|
+
raise DeweyError, "Unknown service: #{service}"
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
data/lib/dewey/version.rb
CHANGED
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 2
|
8
|
-
-
|
9
|
-
version: 0.2.
|
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-
|
17
|
+
date: 2010-12-12 00:00:00 -06:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|