dewey 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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) # -> Tempfile
66
- pdf = Dewey.get(id, :pdf) # -> Tempfile
67
- html = Dewey.get(id, :html) # -> Tempfile
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
@@ -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
- case response
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
- def put(file, title = nil)
58
- authenticate! unless authenticated?
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
- case response
80
- when Net::HTTPCreated
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, or export more accurately, a file to a specified format
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
- def get(rid, format = nil)
92
- authenticate! unless authenticated?
93
-
94
- spreadsheet = !! rid.match(/^spreadsheet/)
95
- id = rid.sub(/[a-z]+:/, '')
96
-
97
- url = ''
98
- url << (spreadsheet ? GOOGLE_SPREADSHEET_URL : GOOGLE_DOCUMENT_URL)
99
- url << (spreadsheet ? "?key=#{id}" : "?docID=#{id}")
100
- url << "&exportFormat=#{format.to_s}" unless format.nil?
101
-
102
- headers = base_headers
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([rid, format].join('.'))
118
+ file = Tempfile.new([id, format].join('.'))
105
119
  file.binmode
106
120
 
107
- open(url, headers) { |data| file.write data.read }
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 either by resource id.
113
- # * id - A resource id or exact file name matching a document in the account
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
- case response
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 +Dewey::DeweyException+ if
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
- # Convenience method for +put+, +get+, +delete+. Returns a Tempfile
143
- # with in the provided type. Note that if you omit the format option it will
144
- # simply upload the file and return it.
145
- # * file - The file that will be converted
146
- # * options - Takes :title and :format. See +upload+ for title, and +download+ for format.
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
- rid = put(file, options[:title])
150
- con = get(rid, options[:format])
178
+ id = put(file, options[:title])
179
+ converted = get(id, options[:format])
151
180
 
152
- delete(rid)
181
+ delete(id)
153
182
 
154
- con
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
- def base_headers(put_or_post = true) #:nodoc:
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 put_or_post
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
- ids = xml.elements.
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
@@ -1,38 +1,63 @@
1
1
  module Dewey
2
2
 
3
- DOCUMENT_EXPORT_FORMATS = %w(txt odt pdf html rtf doc png zip)
4
- PRESENTATION_EXPORT_FORMATS = %w(swf pdf png ppt)
5
- SPREADSHEET_EXPORT_FORMATS = %W(xls csv pdf ods tsv html)
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
- # Determine wether or not a format is available for download.
9
- #
10
- # * format - The file format to check, i.e. 'txt', 'doc', 'pdf'
11
- # * service - The service that would be used. Must be document, presentation,
12
- # or spreadsheet.
13
- def self.valid_upload_format?(format, service = :document)
14
- case service
15
- when :document then Dewey::DOCUMENT_MIMETYPES.has_key?(format.to_sym)
16
- when :presentation then Dewey::PRESENTATION_MIMETYPES.has_key?(format.to_sym)
17
- when :spreadsheet then Dewey::SPREADSHEET_MIMETYPES.has_key?(format.to_sym)
18
- else
19
- raise DeweyException, "Unknown service: #{service}"
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
- # Determine whether or not a format is available for export.
24
- #
25
- # * format - The file format to check, i.e. 'txt', 'doc', 'pdf'
26
- # * service - The service that would be used. Must be document, presentation,
27
- # or spreadsheet.
28
- def self.valid_export_format?(format, service = :document)
29
- case service
30
- when :document then Dewey::DOCUMENT_EXPORT_FORMATS.include?(format)
31
- when :presentation then Dewey::PRESENTATION_EXPORT_FORMATS.include?(format)
32
- when :spreadsheet then Dewey::SPREADSHEET_EXPORT_FORMATS.include?(format)
33
- else
34
- raise DeweyException, "Unknown service: #{service}"
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
@@ -1,3 +1,3 @@
1
1
  module Dewey
2
- VERSION = '0.2.1'
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
- - 1
9
- version: 0.2.1
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-26 00:00:00 -05:00
17
+ date: 2010-10-28 00:00:00 -05:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency