dewey 0.2.1 → 0.2.2
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.
- data/CHANGELOG.md +9 -0
- data/README.md +5 -5
- data/lib/dewey/core.rb +97 -69
- data/lib/dewey/validation.rb +54 -29
- data/lib/dewey/version.rb +2 -2
- metadata +3 -3
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
## 0.2.2 (October 27, 2010)
|
2
|
+
|
3
|
+
Changes:
|
4
|
+
|
5
|
+
- API Changes for get and put. All methods will use an options hash
|
6
|
+
rather than ordered options.
|
7
|
+
- Validation methods can accept either a string or a symbol
|
8
|
+
- More error-resistant handling of nil values passed to validation methods
|
9
|
+
|
1
10
|
## 0.2.1 (October 26, 2010)
|
2
11
|
|
3
12
|
Additions:
|
data/README.md
CHANGED
@@ -42,7 +42,7 @@ first operation.
|
|
42
42
|
### Putting a Document
|
43
43
|
|
44
44
|
document = File.new('my_document.doc')
|
45
|
-
resource = Dewey.put(document, 'My First Upload') # Returns the id when successful
|
45
|
+
resource = Dewey.put(document, :title => 'My First Upload') # Returns the id when successful
|
46
46
|
|
47
47
|
### Searching Documents
|
48
48
|
|
@@ -62,9 +62,9 @@ Upload your file
|
|
62
62
|
|
63
63
|
Get it in various formats
|
64
64
|
|
65
|
-
original = Dewey.get(id)
|
66
|
-
pdf = Dewey.get(id, :pdf)
|
67
|
-
html = Dewey.get(id, :html)
|
65
|
+
original = Dewey.get(id) #=> Tempfile
|
66
|
+
pdf = Dewey.get(id, :format => :pdf) #=> Tempfile
|
67
|
+
html = Dewey.get(id, :format => :html) #=> Tempfile
|
68
68
|
|
69
69
|
A tempfile is returned, so you'll have to move it
|
70
70
|
|
@@ -73,4 +73,4 @@ A tempfile is returned, so you'll have to move it
|
|
73
73
|
### Deleting a Document
|
74
74
|
|
75
75
|
id = Dewey.put(File.new('my_spreadsheet.xls'))
|
76
|
-
result = Dewey.delete(id) # -> true
|
76
|
+
result = Dewey.delete(id) # -> true
|
data/lib/dewey/core.rb
CHANGED
@@ -32,37 +32,40 @@ module Dewey
|
|
32
32
|
@@authenticator.authenticate!
|
33
33
|
end
|
34
34
|
|
35
|
+
# Queries the document list for a particular title. Titles can be either
|
36
|
+
# full or partial matches. Matches are returned as an array of ids.
|
37
|
+
#
|
38
|
+
# @param [String] query The title to be matched
|
39
|
+
# @param [Hash] options Search options
|
40
|
+
# @option options [Symbol] :exact Setting this to `true` will force an
|
41
|
+
# exact match, with a maximum of one id returned
|
42
|
+
#
|
43
|
+
# @return [Array] An array of matched ids. No matches return an empty array
|
35
44
|
def search(query, options = {})
|
36
|
-
authenticate! unless authenticated?
|
37
|
-
|
38
45
|
title = query.gsub(/\s+/, '+')
|
39
46
|
headers = base_headers(false)
|
40
47
|
url = "#{GOOGLE_FEED_URL}?title=#{title}"
|
41
48
|
url << "&title-exact=true" if options[:exact]
|
42
49
|
response = get_request(url, headers)
|
43
50
|
|
44
|
-
|
45
|
-
when Net::HTTPOK
|
46
|
-
extract_ids(response.body)
|
47
|
-
else
|
48
|
-
nil
|
49
|
-
end
|
51
|
+
response.kind_of?(Net::HTTPOK) ? extract_ids(response.body) : []
|
50
52
|
end
|
51
53
|
|
52
54
|
# Upload a file to the account. A successful upload will return the resource
|
53
55
|
# id, which is useful for downloading the file without doing a title search.
|
54
|
-
# * file - A File reference
|
55
|
-
# * title - An alternative title, to be used instead of the filename
|
56
56
|
#
|
57
|
-
|
58
|
-
|
59
|
-
|
57
|
+
# @param [File] file An IOStream object that responds to path, size
|
58
|
+
# @param [Hash] options Options for uploading the file
|
59
|
+
# @option options [Symbol] :title An alternative title, to be used instead
|
60
|
+
# of the filename
|
61
|
+
#
|
62
|
+
# @return [String, Boolean] The id if upload was successful, false otherwise
|
63
|
+
def put(file, options = {})
|
60
64
|
extension = File.extname(file.path).sub('.', '')
|
61
65
|
basename = File.basename(file.path, ".#{extension}")
|
62
66
|
mimetype = Dewey::Mime.mime_type(file)
|
63
67
|
service = Dewey::Mime.guess_service(mimetype)
|
64
|
-
|
65
|
-
title ||= basename
|
68
|
+
title = options[:title] || basename
|
66
69
|
|
67
70
|
raise DeweyException, "Invalid file type: #{extension}" unless Dewey::Validation.valid_upload_format?(extension, service)
|
68
71
|
|
@@ -75,46 +78,57 @@ module Dewey
|
|
75
78
|
file.rewind
|
76
79
|
|
77
80
|
response = post_request(GOOGLE_FEED_URL, file.read.to_s, headers)
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
extract_ids(response.body)
|
81
|
+
|
82
|
+
if response.kind_of?(Net::HTTPCreated)
|
83
|
+
extract_ids(response.body).first
|
82
84
|
else
|
83
85
|
false
|
84
86
|
end
|
85
87
|
end
|
86
88
|
|
87
|
-
# Download
|
88
|
-
# * rid - A resource id, for example +document:12345+
|
89
|
-
# * format - The output format, see *_EXPORT_FORMATS for possiblibilites
|
89
|
+
# Download a file. You may optionally specify a format for export.
|
90
90
|
#
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
91
|
+
# @param [String] id A resource id, for example `document:12345`
|
92
|
+
# @param [Hash] options Options for downloading the document
|
93
|
+
# @option options [Symbol] :format The output format
|
94
|
+
#
|
95
|
+
# @return [Tempfile] The downloaded file
|
96
|
+
#
|
97
|
+
# @see Dewey::Validation::DOCUMENT_EXPORT_FORMATS
|
98
|
+
# @see Dewey::Validation::SPREADSHEET_EXPORT_FORMATS
|
99
|
+
# @see Dewey::Validation::PRESENTATION_EXPORT_FORMATS
|
100
|
+
def get(id, options = {})
|
101
|
+
service, id = id.split(':')
|
102
|
+
format = options[:format].to_s
|
103
|
+
|
104
|
+
raise DeweyException, "Invalid format: #{format}" unless Dewey::Validation.valid_export_format?(format, service)
|
105
|
+
|
106
|
+
url = ''
|
107
|
+
case service
|
108
|
+
when 'document'
|
109
|
+
url << GOOGLE_DOCUMENT_URL
|
110
|
+
url << "?docID=#{id}"
|
111
|
+
when 'spreadsheet'
|
112
|
+
url << GOOGLE_SPREADSHEET_URL
|
113
|
+
url << "?key=#{id}"
|
114
|
+
end
|
115
|
+
|
116
|
+
url << "&exportFormat=#{format}" unless format.blank?
|
103
117
|
|
104
|
-
file = Tempfile.new([
|
118
|
+
file = Tempfile.new([id, format].join('.'))
|
105
119
|
file.binmode
|
106
120
|
|
107
|
-
open(url,
|
121
|
+
open(url, base_headers) { |data| file.write data.read }
|
108
122
|
|
109
123
|
file
|
110
124
|
end
|
111
125
|
|
112
|
-
# Deletes a document referenced
|
113
|
-
#
|
126
|
+
# Deletes a document referenced by id.
|
127
|
+
#
|
128
|
+
# @param [String] id An id matching a document
|
114
129
|
#
|
130
|
+
# @return [Boolean] `true` if delete was successful, `false` otherwise
|
115
131
|
def delete(id)
|
116
|
-
authenticate! unless authenticated?
|
117
|
-
|
118
132
|
headers = base_headers(false)
|
119
133
|
headers['If-Match'] = '*' # We don't care if others have modified
|
120
134
|
|
@@ -124,34 +138,49 @@ module Dewey
|
|
124
138
|
|
125
139
|
response = delete_request(url, headers)
|
126
140
|
|
127
|
-
|
128
|
-
when Net::HTTPOK
|
129
|
-
true
|
130
|
-
else
|
131
|
-
false
|
132
|
-
end
|
141
|
+
response.kind_of?(Net::HTTPOK)
|
133
142
|
end
|
134
143
|
|
135
|
-
# The same as delete, except that it will raise
|
144
|
+
# The same as delete, except that it will raise `Dewey::DeweyException` if
|
136
145
|
# the request fails.
|
137
|
-
#
|
146
|
+
#
|
147
|
+
# @see #delete
|
138
148
|
def delete!(id)
|
139
149
|
delete(id) || raise(DeweyException, "Unable to delete document")
|
140
150
|
end
|
141
151
|
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
152
|
+
[:search, :put, :get, :delete].each do |method|
|
153
|
+
aliased = "no_auto_authenticate_#{method.to_s}".to_sym
|
154
|
+
alias_method aliased, method
|
155
|
+
|
156
|
+
self.class_eval(%Q{
|
157
|
+
def #{method} *args
|
158
|
+
authenticate! unless authenticated?
|
159
|
+
#{aliased}(*args)
|
160
|
+
end
|
161
|
+
})
|
162
|
+
end
|
163
|
+
|
164
|
+
# Convenience method for `put`, `get`, `delete`.
|
165
|
+
#
|
166
|
+
# @param [File] file The file that will be converted
|
167
|
+
# @param [Hash] options Options for conversion
|
168
|
+
# @option options [Symbol] :title The title that the file will be stored
|
169
|
+
# under. Only useful if the conversion fails.
|
170
|
+
# @option options [Symbol] :format Format to convert to.
|
147
171
|
#
|
172
|
+
# @return [Tempfile] The converted file
|
173
|
+
#
|
174
|
+
# @see #put
|
175
|
+
# @see #get
|
176
|
+
# @see #delete
|
148
177
|
def convert(file, options = {})
|
149
|
-
|
150
|
-
|
178
|
+
id = put(file, options[:title])
|
179
|
+
converted = get(id, options[:format])
|
151
180
|
|
152
|
-
delete(
|
181
|
+
delete(id)
|
153
182
|
|
154
|
-
|
183
|
+
converted
|
155
184
|
end
|
156
185
|
|
157
186
|
protected
|
@@ -187,27 +216,26 @@ module Dewey
|
|
187
216
|
end
|
188
217
|
end
|
189
218
|
|
190
|
-
|
219
|
+
# A hash of default headers. Considers authentication and put/post headers.
|
220
|
+
#
|
221
|
+
# @param [Boolean] form If true the Content-Type will be set accordingly
|
222
|
+
# @return [Hash] Headers hash
|
223
|
+
def base_headers(form = true) #:nodoc:
|
191
224
|
base = {}
|
192
225
|
base['GData-Version'] = '3.0'
|
193
|
-
base['Content-Type'] = 'application/x-www-form-urlencoded' if
|
226
|
+
base['Content-Type'] = 'application/x-www-form-urlencoded' if form
|
194
227
|
base['Authorization'] = "GoogleLogin auth=#{@@authenticator.token}" if authenticated?
|
195
228
|
|
196
229
|
base
|
197
230
|
end
|
198
231
|
|
232
|
+
# Parse the XML returned to pull out one or more document ids.
|
233
|
+
#
|
234
|
+
# @param [String] response An XML feed document
|
235
|
+
# @return [Array] Array of document ids
|
199
236
|
def extract_ids(response) #:nodoc:
|
200
237
|
xml = REXML::Document.new(response)
|
201
|
-
|
202
|
-
collect('//id') { |e| "#{$1}:#{$2}" if e.text =~ /.*(document|spreadsheet|presentation)(?:%3A|:)([0-9a-zA-Z_-]+)$/ }.
|
203
|
-
reject(&:nil?)
|
204
|
-
|
205
|
-
case ids.length
|
206
|
-
when 0 then nil
|
207
|
-
when 1 then ids.first
|
208
|
-
else
|
209
|
-
ids
|
210
|
-
end
|
238
|
+
xml.elements.collect('//id') { |e| e.text.gsub('%3A', ':') }.reject(&:blank?)
|
211
239
|
end
|
212
240
|
end
|
213
241
|
end
|
data/lib/dewey/validation.rb
CHANGED
@@ -1,38 +1,63 @@
|
|
1
1
|
module Dewey
|
2
2
|
|
3
|
-
DOCUMENT_EXPORT_FORMATS =
|
4
|
-
PRESENTATION_EXPORT_FORMATS =
|
5
|
-
SPREADSHEET_EXPORT_FORMATS =
|
3
|
+
DOCUMENT_EXPORT_FORMATS = [:txt, :odt, :pdf, :html, :rtf, :doc, :png, :zip]
|
4
|
+
PRESENTATION_EXPORT_FORMATS = [:swf, :pdf, :png, :ppt]
|
5
|
+
SPREADSHEET_EXPORT_FORMATS = [:xls, :csv, :pdf, :ods, :tsv, :html]
|
6
6
|
|
7
|
+
# Utility methods to check that a format is accepted for a particular service
|
8
|
+
#
|
7
9
|
class Validation
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
10
|
+
|
11
|
+
class << self
|
12
|
+
# Determine wether or not a format is available for download.
|
13
|
+
#
|
14
|
+
# @param [Symbol] format The file format to check, i.e. `:txt`, `:doc`, `:pdf`
|
15
|
+
# @param [Symbol] service The service that would be used. Must be
|
16
|
+
# `:document`, `:presentation`, or `:spreadsheet`.
|
17
|
+
#
|
18
|
+
# @return [Boolean] `true` if the format is supported, `false` otherwise
|
19
|
+
#
|
20
|
+
# @raise [DeweyException] Raised when an unknown service is given
|
21
|
+
def valid_upload_format?(format, service = nil)
|
22
|
+
format = format.to_sym
|
23
|
+
service = default_service(service)
|
24
|
+
|
25
|
+
case service
|
26
|
+
when :document then Dewey::DOCUMENT_MIMETYPES.has_key?(format)
|
27
|
+
when :presentation then Dewey::PRESENTATION_MIMETYPES.has_key?(format)
|
28
|
+
when :spreadsheet then Dewey::SPREADSHEET_MIMETYPES.has_key?(format)
|
29
|
+
else
|
30
|
+
raise DeweyException, "Unknown service: #{service}"
|
31
|
+
end
|
20
32
|
end
|
21
|
-
end
|
22
33
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
when
|
32
|
-
|
33
|
-
|
34
|
-
|
34
|
+
# Determine whether or not a format is available for export.
|
35
|
+
#
|
36
|
+
# @param [Symbol] format The file format to check, i.e. `:txt`, `:doc`, `:pdf`
|
37
|
+
# @param [Symbol] service The service that would be used. Must be
|
38
|
+
# `:document`, `:presentation`, or `:spreadsheet`.
|
39
|
+
#
|
40
|
+
# @return [Boolean] `true` if the format is supported, `false` otherwise
|
41
|
+
#
|
42
|
+
# @raise [DeweyException] Raised when an unknown service is given
|
43
|
+
def valid_export_format?(format, service = nil)
|
44
|
+
format = format.to_sym
|
45
|
+
service = default_service(service)
|
46
|
+
|
47
|
+
case service
|
48
|
+
when :document then Dewey::DOCUMENT_EXPORT_FORMATS.include?(format)
|
49
|
+
when :presentation then Dewey::PRESENTATION_EXPORT_FORMATS.include?(format)
|
50
|
+
when :spreadsheet then Dewey::SPREADSHEET_EXPORT_FORMATS.include?(format)
|
51
|
+
else
|
52
|
+
raise DeweyException, "Unknown service: #{service}"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
protected
|
57
|
+
|
58
|
+
def default_service(service)
|
59
|
+
service.nil? ? :document : service.to_sym
|
35
60
|
end
|
36
61
|
end
|
37
62
|
end
|
38
|
-
end
|
63
|
+
end
|
data/lib/dewey/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
1
|
module Dewey
|
2
|
-
VERSION = '0.2.
|
3
|
-
end
|
2
|
+
VERSION = '0.2.2'
|
3
|
+
end
|
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
|
+
- 2
|
9
|
+
version: 0.2.2
|
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-10-
|
17
|
+
date: 2010-10-28 00:00:00 -05:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|