rufus-doric 0.1.9 → 0.1.10
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.txt +6 -0
- data/README.rdoc +5 -0
- data/TODO.txt +2 -0
- data/lib/rufus/doric/model.rb +57 -5
- data/lib/rufus/doric/version.rb +1 -1
- data/rufus-doric.gemspec +4 -2
- data/test/al_vetro.png +0 -0
- data/test/ut_17_model_and_attachments.rb +192 -0
- data/test/ut_1_model.rb +0 -31
- metadata +5 -3
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
data/TODO.txt
CHANGED
data/lib/rufus/doric/model.rb
CHANGED
@@ -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
|
-
|
312
|
+
extname = File.extname(attname)
|
313
|
+
attname = attachments.find { |a| a.match(/^#{attname}/) } if extname == ''
|
260
314
|
|
261
|
-
db.
|
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)
|
data/lib/rufus/doric/version.rb
CHANGED
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.
|
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-
|
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
|
-
version: 0.1.
|
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-
|
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
|