rufus-doric 0.1.9 → 0.1.10

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.txt CHANGED
@@ -2,6 +2,12 @@
2
2
  = rufus-doric CHANGELOG.txt
3
3
 
4
4
 
5
+ == rufus-doric - 0.1.10 not yet released
6
+
7
+ - model attachment :x for properties like attachments (#att and #att=(x))
8
+ - model#read(attachment_name)
9
+
10
+
5
11
  == rufus-doric - 0.1.9 released 2010/05/13
6
12
 
7
13
  - model#detach(attachment_name)
data/README.rdoc CHANGED
@@ -184,6 +184,11 @@ this
184
184
  will load the documents (and their attachements) into http://127.0.0.1:5984/doric_test
185
185
 
186
186
 
187
+ == credits
188
+
189
+ Claudio Petasecca Donati - for his help about attachments
190
+
191
+
187
192
  == license
188
193
 
189
194
  MIT
data/TODO.txt CHANGED
@@ -15,3 +15,5 @@
15
15
 
16
16
  [ ] view_by 'x', 'emit' ==> view 'x', 'emit' ==> Model.x(key)...
17
17
 
18
+ [ ] credit Claudio !!
19
+
@@ -23,6 +23,7 @@
23
23
  #++
24
24
 
25
25
  require 'cgi'
26
+ require 'base64'
26
27
  require 'mime/types'
27
28
 
28
29
 
@@ -104,6 +105,18 @@ module Doric
104
105
  @_id_field
105
106
  end
106
107
 
108
+ def self.attachment (attachment_name)
109
+
110
+ class_eval %{
111
+ def #{attachment_name}
112
+ read('#{attachment_name}')
113
+ end
114
+ def #{attachment_name}= (data, opts={})
115
+ attach('#{attachment_name}', data, opts)
116
+ end
117
+ }
118
+ end
119
+
107
120
  # Creates a by_{key} method.
108
121
  #
109
122
  # If a func (a String) is passed, a {key} method is created that
@@ -254,13 +267,52 @@ module Doric
254
267
  raise(SaveFailed.new(self.class.doric_type, _id)) unless r.nil?
255
268
  end
256
269
 
257
- def attach (attname, data)
270
+ def attach (attname, data, opts={})
271
+
272
+ extname = File.extname(attname)
273
+ basename = File.basename(attname, extname)
274
+ mime = ::MIME::Types.type_for(attname).first
275
+
276
+ if data.is_a?(File)
277
+ mime = ::MIME::Types.type_for(data.path).first
278
+ data = data.read
279
+ elsif data.is_a?(Array)
280
+ data, mime = data
281
+ mime = ::MIME::Types[mime].first
282
+ end
283
+
284
+ raise ArgumentError.new("couldn't determine mime type") unless mime
285
+
286
+ attname = "#{attname}.#{mime.extensions.first}" if extname == ''
287
+
288
+ if @h['_rev'] # document has already been saved
289
+
290
+ db.attach(
291
+ @h['_id'], @h['_rev'], attname, data, :content_type => mime.to_s)
292
+
293
+ else # document hasn't yet been saved, inline attachment...
294
+
295
+ (@h['_attachments'] ||= {})[attname] = {
296
+ 'content_type' => mime.to_s,
297
+ 'data' => Base64.encode64(data).gsub(/[\r\n]/, '')
298
+ }
299
+ end
300
+ end
301
+
302
+ # Reads an attachment
303
+ #
304
+ # model.read('icon')
305
+ # model.read('user_picture.jpg')
306
+ # model.read(:user_picture)
307
+ #
308
+ def read (attname)
309
+
310
+ attname = attname.to_s
258
311
 
259
- doc = db.get(@h['_id'])
312
+ extname = File.extname(attname)
313
+ attname = attachments.find { |a| a.match(/^#{attname}/) } if extname == ''
260
314
 
261
- db.attach(
262
- doc, attname, data,
263
- :content_type => ::MIME::Types.type_for(attname).first.to_s)
315
+ db.get("#{@h['_id']}/#{attname}")
264
316
  end
265
317
 
266
318
  def detach (attname)
@@ -1,7 +1,7 @@
1
1
 
2
2
  module Rufus
3
3
  module Doric
4
- VERSION = '0.1.9'
4
+ VERSION = '0.1.10'
5
5
  end
6
6
  end
7
7
 
data/rufus-doric.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{rufus-doric}
8
- s.version = "0.1.9"
8
+ s.version = "0.1.10"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["John Mettraux"]
12
- s.date = %q{2010-05-13}
12
+ s.date = %q{2010-05-14}
13
13
  s.description = %q{
14
14
  something at the intersection of Rails3, CouchDB and rufus-jig
15
15
  }
@@ -34,6 +34,7 @@ something at the intersection of Rails3, CouchDB and rufus-jig
34
34
  "lib/rufus/doric/value.rb",
35
35
  "lib/rufus/doric/version.rb",
36
36
  "rufus-doric.gemspec",
37
+ "test/al_vetro.png",
37
38
  "test/base.rb",
38
39
  "test/fixtures/test/doric/69247b__picture.jpg",
39
40
  "test/fixtures/test/doric/69249__picture.jpg",
@@ -53,6 +54,7 @@ something at the intersection of Rails3, CouchDB and rufus-jig
53
54
  "test/ut_14_model_default_id.rb",
54
55
  "test/ut_15_model_view_by_and.rb",
55
56
  "test/ut_16_model_custom_view.rb",
57
+ "test/ut_17_model_and_attachments.rb",
56
58
  "test/ut_1_model.rb",
57
59
  "test/ut_2_model_view.rb",
58
60
  "test/ut_3_model_lint.rb",
data/test/al_vetro.png ADDED
Binary file
@@ -0,0 +1,192 @@
1
+
2
+ #
3
+ # testing rufus-doric
4
+ #
5
+ # Thu May 13 08:53:01 JST 2010
6
+ #
7
+
8
+ require File.join(File.dirname(__FILE__), 'base')
9
+
10
+ require 'rufus/doric'
11
+
12
+
13
+ class Thing < Rufus::Doric::Model
14
+
15
+ db :doric
16
+
17
+ doric_type :things
18
+ _id_field :name
19
+ h_accessor :name
20
+ end
21
+
22
+ class Folder < Rufus::Doric::Model
23
+
24
+ db :doric
25
+
26
+ doric_type :folders
27
+ _id_field :name
28
+ h_accessor :name
29
+
30
+ attachment :icon
31
+ end
32
+
33
+
34
+ class UtModelAndAttachmentsTest < Test::Unit::TestCase
35
+
36
+ def setup
37
+
38
+ Rufus::Doric.db('doric').delete('.')
39
+ Rufus::Doric.db('doric').put('.')
40
+
41
+ Rufus::Doric.db('doric').http.cache.clear
42
+ # CouchDB feeds the same etags for views, even after a db has
43
+ # been deleted and put back, so have to do that 'forgetting'
44
+ end
45
+
46
+ #def teardown
47
+ #end
48
+
49
+ def test_attach_pre_save
50
+
51
+ txt = File.read(__FILE__)
52
+
53
+ t = Thing.new('name' => 'that_piece_of_code')
54
+ t.attach('this_code.txt', txt)
55
+ t.save!
56
+
57
+ t = Thing.find('that_piece_of_code')
58
+
59
+ assert_equal [ 'this_code.txt' ], t.attachments
60
+ assert_equal txt, t.db.get('that_piece_of_code/this_code.txt')
61
+ end
62
+
63
+ def test_attach
64
+
65
+ txt = File.read(__FILE__)
66
+
67
+ t = Thing.new('name' => 'piece_of_code')
68
+ t.save!
69
+
70
+ t = Thing.find('piece_of_code')
71
+
72
+ assert_equal [], t.attachments
73
+
74
+ t.attach('code.txt', txt)
75
+
76
+ t = Thing.find('piece_of_code')
77
+
78
+ assert_equal [ 'code.txt' ], t.attachments
79
+ assert_equal txt, t.db.get('piece_of_code/code.txt')
80
+ end
81
+
82
+ def test_detect_and_attach_pre_save
83
+
84
+ t = Thing.new('name' => 'al_vetro_pre')
85
+ t.attach('result', File.new(path_to('al_vetro.png')))
86
+ t.save!
87
+
88
+ t = Thing.find('al_vetro_pre')
89
+
90
+ assert_equal [ 'result.png' ], t.attachments
91
+ assert_equal "\x89PNG\r\n\x1A", t.read('result')[0, 7]
92
+ assert_equal "\x89PNG\r\n\x1A", t.read('result.png')[0, 7]
93
+ end
94
+
95
+ def test_detect_and_attach
96
+
97
+ t = Thing.new('name' => 'al_vetro')
98
+ t.save!
99
+
100
+ t = Thing.find('al_vetro')
101
+ t.attach('result', File.new(path_to('al_vetro.png')))
102
+
103
+ t = Thing.find('al_vetro')
104
+
105
+ assert_equal [ 'result.png' ], t.attachments
106
+ assert_equal "\x89PNG\r\n\x1A", t.read('result')[0, 7]
107
+ assert_equal "\x89PNG\r\n\x1A", t.read('result.png')[0, 7]
108
+ end
109
+
110
+ def test_detach
111
+
112
+ t = Thing.new('name' => 'ms_excel')
113
+ t.save!
114
+
115
+ t = Thing.find('ms_excel')
116
+ t.attach('code.txt', File.read(__FILE__))
117
+
118
+ t = Thing.find('ms_excel')
119
+
120
+ assert_equal [ 'code.txt' ], t.attachments
121
+
122
+ t.detach('code.txt')
123
+
124
+ assert_equal [], Thing.find('ms_excel').attachments
125
+ end
126
+
127
+ def test_named_attachment_pre_save
128
+
129
+ f = Folder.new('name' => 'summer')
130
+ f.icon = File.new(File.join(File.dirname(__FILE__), 'al_vetro.png'))
131
+ f.save!
132
+
133
+ f = Folder.find('summer')
134
+ assert_equal [ 'icon.png' ], f.attachments
135
+
136
+ assert_equal "\x89PNG\r\n\x1A", f.icon[0, 7]
137
+ end
138
+
139
+ def test_named_attachment
140
+
141
+ f = Folder.new('name' => 'winter')
142
+ f.save!
143
+
144
+ f = Folder.find('winter')
145
+ f.icon = File.new(path_to('al_vetro.png'))
146
+
147
+ f = Folder.find('winter')
148
+ assert_equal [ 'icon.png' ], f.attachments
149
+
150
+ assert_equal "\x89PNG\r\n\x1A", f.icon[0, 7]
151
+ end
152
+
153
+ def test_read
154
+
155
+ t = Thing.new('name' => 'some_thing')
156
+ t.attach('toto.txt', File.read(__FILE__))
157
+ t.save!
158
+
159
+ t = Thing.find('some_thing')
160
+
161
+ assert_equal "\n#\n# testing r", t.read('toto.txt')[0, 14]
162
+ assert_equal "\n#\n# testing r", t.read('toto')[0, 14]
163
+ assert_equal "\n#\n# testing r", t.read(:toto)[0, 14]
164
+ end
165
+
166
+ def test_string_attachment_missing_content_type
167
+
168
+ assert_raise ArgumentError do
169
+ f = Folder.new('name' => 'spring')
170
+ f.icon = File.read(path_to('al_vetro.png'))
171
+ end
172
+ end
173
+
174
+ def test_string_attachment
175
+
176
+ f = Folder.new('name' => 'spring')
177
+ f.icon = [ File.read(path_to('al_vetro.png')), 'text/plain' ]
178
+ f.save!
179
+
180
+ f = Folder.find('spring')
181
+
182
+ assert_equal [ 'icon.txt' ], f.attachments
183
+ end
184
+
185
+ protected
186
+
187
+ def path_to (local_item)
188
+
189
+ File.join(File.dirname(__FILE__), local_item)
190
+ end
191
+ end
192
+
data/test/ut_1_model.rb CHANGED
@@ -187,36 +187,5 @@ class UtModelTest < Test::Unit::TestCase
187
187
 
188
188
  assert_equal 'art', c.name
189
189
  end
190
-
191
- def test_attach
192
-
193
- txt = File.read(__FILE__)
194
-
195
- t = Thing.new('name' => 'piece_of_code')
196
- t.save!
197
-
198
- assert_equal [], t.attachments
199
-
200
- t.attach('code.txt', txt)
201
-
202
- t = Thing.find('piece_of_code')
203
-
204
- assert_equal [ 'code.txt' ], t.attachments
205
- assert_equal txt, t.db.get('piece_of_code/code.txt')
206
- end
207
-
208
- def test_detach
209
-
210
- t = Thing.new('name' => 'ms_excel')
211
- t.save!
212
- t.attach('code.txt', File.read(__FILE__))
213
- t = Thing.find('ms_excel')
214
-
215
- assert_equal [ 'code.txt' ], t.attachments
216
-
217
- t.detach('code.txt')
218
-
219
- assert_equal [], Thing.find('ms_excel').attachments
220
- end
221
190
  end
222
191
 
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 1
8
- - 9
9
- version: 0.1.9
8
+ - 10
9
+ version: 0.1.10
10
10
  platform: ruby
11
11
  authors:
12
12
  - John Mettraux
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-05-13 00:00:00 +09:00
17
+ date: 2010-05-14 00:00:00 +09:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -121,6 +121,7 @@ files:
121
121
  - lib/rufus/doric/value.rb
122
122
  - lib/rufus/doric/version.rb
123
123
  - rufus-doric.gemspec
124
+ - test/al_vetro.png
124
125
  - test/base.rb
125
126
  - test/fixtures/test/doric/69247b__picture.jpg
126
127
  - test/fixtures/test/doric/69249__picture.jpg
@@ -140,6 +141,7 @@ files:
140
141
  - test/ut_14_model_default_id.rb
141
142
  - test/ut_15_model_view_by_and.rb
142
143
  - test/ut_16_model_custom_view.rb
144
+ - test/ut_17_model_and_attachments.rb
143
145
  - test/ut_1_model.rb
144
146
  - test/ut_2_model_view.rb
145
147
  - test/ut_3_model_lint.rb