rufus-jig 0.1.13 → 0.1.14
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.txt +7 -0
- data/README.rdoc +14 -0
- data/Rakefile +2 -0
- data/TODO.txt +3 -0
- data/lib/rufus/jig/couch.rb +84 -0
- data/lib/rufus/jig/http.rb +27 -4
- data/lib/rufus/jig/version.rb +1 -1
- data/rufus-jig.gemspec +10 -2
- data/test/ct_4_attachments.rb +126 -0
- data/test/server.rb +4 -0
- data/test/tweet.png +0 -0
- data/test/ut_1_http_post.rb +20 -0
- data/test/ut_3_http_put.rb +17 -0
- metadata +24 -2
data/CHANGELOG.txt
CHANGED
@@ -2,6 +2,13 @@
|
|
2
2
|
= rufus-jig CHANGELOG.txt
|
3
3
|
|
4
4
|
|
5
|
+
== rufus-jig - 0.1.14 released 2010/02/25
|
6
|
+
|
7
|
+
- temporary fallback to net/http for Couch#attach and patron
|
8
|
+
- implemented Rufus::Jig::Couch#attach and #detach
|
9
|
+
warning : Patron as of 0.4.5 is not OK with PUTting attachments
|
10
|
+
|
11
|
+
|
5
12
|
== rufus-jig - 0.1.13 released 2010/02/12
|
6
13
|
|
7
14
|
- implemented Rufus::Jig::Couch#post
|
data/README.rdoc
CHANGED
@@ -94,8 +94,22 @@ put and delete return nil in case of success and true (conflict) or and exceptio
|
|
94
94
|
|
95
95
|
c.delete(doc1['_id'], doc1['_rev'])
|
96
96
|
|
97
|
+
# ...
|
98
|
+
|
99
|
+
c.attach(
|
100
|
+
doc0, 'picture', File.read('espresso.jpg'), :content_type => 'image/jpeg')
|
101
|
+
# or
|
102
|
+
c.attach(
|
103
|
+
doc0['_id'], doc0['_rev'], 'picture', File.read('espresso.jpg'), :content_type => 'image/jpeg')
|
104
|
+
|
105
|
+
picture = c.get('coffe0/picture')
|
106
|
+
|
107
|
+
c.detach('coffee0', '1-x-newrevision-whatever', 'picture')
|
108
|
+
|
97
109
|
...
|
98
110
|
|
111
|
+
Warning : Patron, as of 0.4.5 is timing out when PUTting images.
|
112
|
+
|
99
113
|
|
100
114
|
== rdoc
|
101
115
|
|
data/Rakefile
CHANGED
@@ -41,8 +41,10 @@ Jeweler::Tasks.new do |gem|
|
|
41
41
|
|
42
42
|
gem.add_dependency 'rufus-lru'
|
43
43
|
gem.add_dependency 'rufus-json'
|
44
|
+
gem.add_development_dependency 'rake'
|
44
45
|
gem.add_development_dependency 'yard'
|
45
46
|
gem.add_development_dependency 'jeweler'
|
47
|
+
gem.add_development_dependency 'patron'
|
46
48
|
|
47
49
|
# gemspec spec : http://www.rubygems.org/read/chapter/20
|
48
50
|
end
|
data/TODO.txt
CHANGED
data/lib/rufus/jig/couch.rb
CHANGED
@@ -25,6 +25,10 @@
|
|
25
25
|
|
26
26
|
module Rufus::Jig
|
27
27
|
|
28
|
+
#
|
29
|
+
# A class wrapping an instance of Rufus::Jig::Http and providing
|
30
|
+
# CouchDB-oriented http verbs.
|
31
|
+
#
|
28
32
|
class Couch
|
29
33
|
|
30
34
|
attr_reader :http
|
@@ -134,6 +138,86 @@ module Rufus::Jig
|
|
134
138
|
@http.post(path, doc, opts)
|
135
139
|
end
|
136
140
|
|
141
|
+
# Attaches a file to a couch document.
|
142
|
+
#
|
143
|
+
# couch.attach(
|
144
|
+
# doc['_id'], doc['_rev'], 'my_picture', data,
|
145
|
+
# :content_type => 'image/jpeg')
|
146
|
+
#
|
147
|
+
# or
|
148
|
+
#
|
149
|
+
# couch.attach(
|
150
|
+
# doc, 'my_picture', data,
|
151
|
+
# :content_type => 'image/jpeg')
|
152
|
+
#
|
153
|
+
def attach (doc_id, doc_rev, attachment_name, data, opts=nil)
|
154
|
+
|
155
|
+
if opts.nil?
|
156
|
+
opts = data
|
157
|
+
data = attachment_name
|
158
|
+
attachment_name = doc_rev
|
159
|
+
doc_rev = doc_id['_rev']
|
160
|
+
doc_id = doc_id['_id']
|
161
|
+
end
|
162
|
+
|
163
|
+
attachment_name = attachment_name.gsub(/\//, '%2F')
|
164
|
+
|
165
|
+
ct = opts[:content_type]
|
166
|
+
|
167
|
+
raise(ArgumentError.new(
|
168
|
+
":content_type option must be specified"
|
169
|
+
)) unless ct
|
170
|
+
|
171
|
+
opts[:cache] = false
|
172
|
+
|
173
|
+
path = adjust("#{doc_id}/#{attachment_name}?rev=#{doc_rev}")
|
174
|
+
|
175
|
+
if @http.variant == :patron
|
176
|
+
#
|
177
|
+
# patron, as of 0.4.5 has difficulties when PUTting attachements
|
178
|
+
# this is a fallback to net/http
|
179
|
+
#
|
180
|
+
require 'net/http'
|
181
|
+
http = Net::HTTP.new(@http.host, @http.port)
|
182
|
+
req = Net::HTTP::Put.new(path)
|
183
|
+
req['User-Agent'] =
|
184
|
+
"rufus-jig #{Rufus::Jig::VERSION} (patron 0.4.5 fallback to net/http)"
|
185
|
+
req['Content-Type'] =
|
186
|
+
opts[:content_type]
|
187
|
+
req.body = data
|
188
|
+
res = http.start { |h| h.request(req) }
|
189
|
+
status = res.code.to_i
|
190
|
+
raise Rufus::Jig::HttpError.new(status, res.body) \
|
191
|
+
unless [ 200, 201 ].include?(status)
|
192
|
+
return nil
|
193
|
+
end
|
194
|
+
|
195
|
+
@http.put(path, data, opts)
|
196
|
+
end
|
197
|
+
|
198
|
+
# Detaches a file from a couch document.
|
199
|
+
#
|
200
|
+
# couch.detach(doc['_id'], doc['_rev'], 'my_picture')
|
201
|
+
#
|
202
|
+
# or
|
203
|
+
#
|
204
|
+
# couch.detach(doc, 'my_picture')
|
205
|
+
#
|
206
|
+
def detach (doc_id, doc_rev, attachment_name=nil)
|
207
|
+
|
208
|
+
if attachment_name.nil?
|
209
|
+
attachment_name = doc_rev
|
210
|
+
doc_rev = doc_id['_rev']
|
211
|
+
doc_id = doc_id['_id']
|
212
|
+
end
|
213
|
+
|
214
|
+
attachment_name = attachment_name.gsub(/\//, '%2F')
|
215
|
+
|
216
|
+
path = adjust("#{doc_id}/#{attachment_name}?rev=#{doc_rev}")
|
217
|
+
|
218
|
+
@http.delete(path)
|
219
|
+
end
|
220
|
+
|
137
221
|
protected
|
138
222
|
|
139
223
|
def adjust (path)
|
data/lib/rufus/jig/http.rb
CHANGED
@@ -246,12 +246,23 @@ module Rufus::Jig
|
|
246
246
|
|
247
247
|
def repack_data (data, opts)
|
248
248
|
|
249
|
-
return
|
249
|
+
return nil unless data
|
250
250
|
|
251
|
-
return Rufus::Json.encode(data) \
|
252
|
-
if (opts['Content-Type'] || '').match(/^application\/json/)
|
253
251
|
|
254
|
-
data.
|
252
|
+
data = if data.is_a?(String)
|
253
|
+
data
|
254
|
+
elsif (opts['Content-Type'] || '').match(/^application\/json/)
|
255
|
+
Rufus::Json.encode(data)
|
256
|
+
else
|
257
|
+
data.to_s
|
258
|
+
end
|
259
|
+
|
260
|
+
#opts['Content-Length'] =
|
261
|
+
# (data.respond_to?(:bytesize) ? data.bytesize : data.size).to_s
|
262
|
+
#
|
263
|
+
# Patron doesn't play well with custom lengths : "56, 56" issue
|
264
|
+
|
265
|
+
data
|
255
266
|
end
|
256
267
|
|
257
268
|
def do_cache (method, path, response, body, opts)
|
@@ -306,6 +317,10 @@ if defined?(Patron) # gem install patron
|
|
306
317
|
Thread.current[key] = nil
|
307
318
|
end
|
308
319
|
|
320
|
+
def variant
|
321
|
+
:patron
|
322
|
+
end
|
323
|
+
|
309
324
|
protected
|
310
325
|
|
311
326
|
def key
|
@@ -394,6 +409,10 @@ elsif defined?( EventMachine::HttpRequest )
|
|
394
409
|
@em_ua = opts[:user_agent] || "#{self.class} #{Rufus::Jig::VERSION} (em)"
|
395
410
|
end
|
396
411
|
|
412
|
+
def variant
|
413
|
+
:em
|
414
|
+
end
|
415
|
+
|
397
416
|
protected
|
398
417
|
|
399
418
|
def do_get( path, data, opts )
|
@@ -496,6 +515,10 @@ else
|
|
496
515
|
@mutex = Mutex.new
|
497
516
|
end
|
498
517
|
|
518
|
+
def variant
|
519
|
+
:net
|
520
|
+
end
|
521
|
+
|
499
522
|
protected
|
500
523
|
|
501
524
|
def do_get (path, data, opts)
|
data/lib/rufus/jig/version.rb
CHANGED
data/rufus-jig.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{rufus-jig}
|
8
|
-
s.version = "0.1.
|
8
|
+
s.version = "0.1.14"
|
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", "Kenneth Kalmer"]
|
12
|
-
s.date = %q{2010-02-
|
12
|
+
s.date = %q{2010-02-25}
|
13
13
|
s.description = %q{
|
14
14
|
Json Interwebs Get.
|
15
15
|
|
@@ -44,8 +44,10 @@ Gem::Specification.new do |s|
|
|
44
44
|
"test/ct_1_couchdb.rb",
|
45
45
|
"test/ct_2_couchdb_options.rb",
|
46
46
|
"test/ct_3_couchdb_views.rb",
|
47
|
+
"test/ct_4_attachments.rb",
|
47
48
|
"test/server.rb",
|
48
49
|
"test/test.rb",
|
50
|
+
"test/tweet.png",
|
49
51
|
"test/ut_0_http_get.rb",
|
50
52
|
"test/ut_1_http_post.rb",
|
51
53
|
"test/ut_2_http_delete.rb",
|
@@ -71,19 +73,25 @@ Gem::Specification.new do |s|
|
|
71
73
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
72
74
|
s.add_runtime_dependency(%q<rufus-lru>, [">= 0"])
|
73
75
|
s.add_runtime_dependency(%q<rufus-json>, [">= 0"])
|
76
|
+
s.add_development_dependency(%q<rake>, [">= 0"])
|
74
77
|
s.add_development_dependency(%q<yard>, [">= 0"])
|
75
78
|
s.add_development_dependency(%q<jeweler>, [">= 0"])
|
79
|
+
s.add_development_dependency(%q<patron>, [">= 0"])
|
76
80
|
else
|
77
81
|
s.add_dependency(%q<rufus-lru>, [">= 0"])
|
78
82
|
s.add_dependency(%q<rufus-json>, [">= 0"])
|
83
|
+
s.add_dependency(%q<rake>, [">= 0"])
|
79
84
|
s.add_dependency(%q<yard>, [">= 0"])
|
80
85
|
s.add_dependency(%q<jeweler>, [">= 0"])
|
86
|
+
s.add_dependency(%q<patron>, [">= 0"])
|
81
87
|
end
|
82
88
|
else
|
83
89
|
s.add_dependency(%q<rufus-lru>, [">= 0"])
|
84
90
|
s.add_dependency(%q<rufus-json>, [">= 0"])
|
91
|
+
s.add_dependency(%q<rake>, [">= 0"])
|
85
92
|
s.add_dependency(%q<yard>, [">= 0"])
|
86
93
|
s.add_dependency(%q<jeweler>, [">= 0"])
|
94
|
+
s.add_dependency(%q<patron>, [">= 0"])
|
87
95
|
end
|
88
96
|
end
|
89
97
|
|
@@ -0,0 +1,126 @@
|
|
1
|
+
|
2
|
+
#
|
3
|
+
# testing rufus-jig
|
4
|
+
#
|
5
|
+
# Wed Feb 24 17:29:39 JST 2010
|
6
|
+
#
|
7
|
+
|
8
|
+
require File.join(File.dirname(__FILE__), 'couch_base')
|
9
|
+
|
10
|
+
|
11
|
+
class CtAttachmentsTest < Test::Unit::TestCase
|
12
|
+
|
13
|
+
def setup
|
14
|
+
|
15
|
+
h = Rufus::Jig::Http.new('127.0.0.1', 5984)
|
16
|
+
begin
|
17
|
+
h.delete('/rufus_jig_test')
|
18
|
+
rescue Exception => e
|
19
|
+
#p e
|
20
|
+
end
|
21
|
+
|
22
|
+
h.put('/rufus_jig_test', '')
|
23
|
+
h.close
|
24
|
+
|
25
|
+
@c = Rufus::Jig::Couch.new('127.0.0.1', 5984, 'rufus_jig_test')
|
26
|
+
|
27
|
+
@c.put('_id' => 'thedoc', 'function' => 'recipient for attachements')
|
28
|
+
@d = @c.get('thedoc')
|
29
|
+
end
|
30
|
+
|
31
|
+
def teardown
|
32
|
+
|
33
|
+
@c.close
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_missing_content_type
|
37
|
+
|
38
|
+
assert_raise ArgumentError do
|
39
|
+
|
40
|
+
@c.attach(
|
41
|
+
'thedoc/message', 'this is a message', :content_type => 'text/plain')
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_attach
|
46
|
+
|
47
|
+
r = @c.attach(
|
48
|
+
'thedoc', @d['_rev'], 'message', 'this is a message',
|
49
|
+
:content_type => 'text/plain')
|
50
|
+
|
51
|
+
#assert_not_equal @d['_rev'], r['_rev']
|
52
|
+
|
53
|
+
assert_equal 'this is a message', @c.get('thedoc/message')
|
54
|
+
|
55
|
+
assert_not_equal @d['_rev'], @c.get('thedoc')['_rev']
|
56
|
+
|
57
|
+
r = @c.http.get('/rufus_jig_test/thedoc/message', :raw => true)
|
58
|
+
|
59
|
+
assert_equal 200, r.status
|
60
|
+
assert_equal 'text/plain', r.headers['Content-Type']
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_attach_with_doc
|
64
|
+
|
65
|
+
@c.attach(
|
66
|
+
@d, 'message', 'this is a message', :content_type => 'text/plain')
|
67
|
+
|
68
|
+
assert_equal 'this is a message', @c.get('thedoc/message')
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_wrong_rev_on_attach
|
72
|
+
|
73
|
+
assert_raise Rufus::Jig::HttpError do
|
74
|
+
@c.attach(
|
75
|
+
'thedoc', '1-745aeb1d8eccafa88e635b813507608c',
|
76
|
+
'message', 'this is a message',
|
77
|
+
:content_type => 'text/plain')
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_attach_image
|
82
|
+
|
83
|
+
image = File.read(File.join(File.dirname(__FILE__), 'tweet.png'))
|
84
|
+
|
85
|
+
@c.attach(
|
86
|
+
'thedoc', @d['_rev'], 'image', image, :content_type => 'image/png')
|
87
|
+
|
88
|
+
r = @c.http.get('/rufus_jig_test/thedoc/image', :raw => true)
|
89
|
+
|
90
|
+
assert_equal 200, r.status
|
91
|
+
assert_equal 'image/png', r.headers['Content-Type']
|
92
|
+
|
93
|
+
#File.open('out.png', 'wb') { |f| f.write(r.body) }
|
94
|
+
end
|
95
|
+
|
96
|
+
def test_detach
|
97
|
+
|
98
|
+
attach_image
|
99
|
+
|
100
|
+
d = @c.get('thedoc')
|
101
|
+
|
102
|
+
r = @c.detach('thedoc', d['_rev'], 'image')
|
103
|
+
|
104
|
+
assert_not_equal d['_rev'], r['_rev']
|
105
|
+
|
106
|
+
assert_nil @c.get('thedoc/image')
|
107
|
+
end
|
108
|
+
|
109
|
+
def test_detach_fail
|
110
|
+
|
111
|
+
attach_image
|
112
|
+
|
113
|
+
assert_equal true, @c.detach(@d, 'image')
|
114
|
+
end
|
115
|
+
|
116
|
+
protected
|
117
|
+
|
118
|
+
def attach_image
|
119
|
+
|
120
|
+
image = File.read(File.join(File.dirname(__FILE__), 'tweet.png'))
|
121
|
+
|
122
|
+
@c.attach(
|
123
|
+
'thedoc', @d['_rev'], 'image', image, :content_type => 'image/png')
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
data/test/server.rb
CHANGED
@@ -94,6 +94,8 @@ end
|
|
94
94
|
|
95
95
|
post '/documents' do
|
96
96
|
|
97
|
+
#p env
|
98
|
+
|
97
99
|
did = (Time.now.to_f * 1000).to_i.to_s
|
98
100
|
doc = env['rack.input'].read
|
99
101
|
|
@@ -113,6 +115,8 @@ end
|
|
113
115
|
|
114
116
|
put '/documents/:id' do
|
115
117
|
|
118
|
+
#p env
|
119
|
+
|
116
120
|
doc = env['rack.input'].read
|
117
121
|
|
118
122
|
DOCS[params[:id]] = [ request.content_type, doc ]
|
data/test/tweet.png
ADDED
Binary file
|
data/test/ut_1_http_post.rb
CHANGED
@@ -53,5 +53,25 @@ class UtHttpPostTest < Test::Unit::TestCase
|
|
53
53
|
|
54
54
|
assert_equal 1, @h.cache.size
|
55
55
|
end
|
56
|
+
|
57
|
+
def test_post_long_stuff
|
58
|
+
|
59
|
+
data = 'x' * 1000
|
60
|
+
|
61
|
+
b = @h.post('/documents', data, :content_type => 'text/plain')
|
62
|
+
|
63
|
+
r = @h.last_response
|
64
|
+
|
65
|
+
assert_equal 201, r.status
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_post_image
|
69
|
+
|
70
|
+
data = File.read(File.join(File.dirname(__FILE__), 'tweet.png'))
|
71
|
+
|
72
|
+
b = @h.post('/documents', data, :content_type => 'image/png')
|
73
|
+
|
74
|
+
assert_equal 201, @h.last_response.status
|
75
|
+
end
|
56
76
|
end
|
57
77
|
|
data/test/ut_3_http_put.rb
CHANGED
@@ -84,5 +84,22 @@ class UtHttpPutTest < Test::Unit::TestCase
|
|
84
84
|
|
85
85
|
assert_equal true, r
|
86
86
|
end
|
87
|
+
|
88
|
+
def test_put_long_stuff
|
89
|
+
|
90
|
+
data = 'x' * 5000
|
91
|
+
|
92
|
+
b = @h.put('/documents/abcd', data, :content_type => 'image/png')
|
93
|
+
|
94
|
+
assert_equal 201, @h.last_response.status
|
95
|
+
end
|
96
|
+
|
97
|
+
#def test_put_image
|
98
|
+
# data = File.read(File.join(File.dirname(__FILE__), 'tweet.png'))
|
99
|
+
# b = @h.put('/documents/img0', data, :content_type => 'image/png')
|
100
|
+
# assert_equal 201, @h.last_response.status
|
101
|
+
#end
|
102
|
+
#
|
103
|
+
# currently disabled since Patron 0.4.5 times out on that one
|
87
104
|
end
|
88
105
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rufus-jig
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.14
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Mettraux
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2010-02-
|
13
|
+
date: 2010-02-25 00:00:00 +09:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -33,6 +33,16 @@ dependencies:
|
|
33
33
|
- !ruby/object:Gem::Version
|
34
34
|
version: "0"
|
35
35
|
version:
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rake
|
38
|
+
type: :development
|
39
|
+
version_requirement:
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
requirements:
|
42
|
+
- - ">="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: "0"
|
45
|
+
version:
|
36
46
|
- !ruby/object:Gem::Dependency
|
37
47
|
name: yard
|
38
48
|
type: :development
|
@@ -53,6 +63,16 @@ dependencies:
|
|
53
63
|
- !ruby/object:Gem::Version
|
54
64
|
version: "0"
|
55
65
|
version:
|
66
|
+
- !ruby/object:Gem::Dependency
|
67
|
+
name: patron
|
68
|
+
type: :development
|
69
|
+
version_requirement:
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: "0"
|
75
|
+
version:
|
56
76
|
description: "\n Json Interwebs Get.\n\n An HTTP client, greedy with JSON content, GETting conditionally.\n\n Uses Patron and Yajl-ruby whenever possible.\n "
|
57
77
|
email: jmettraux@gmail.com
|
58
78
|
executables: []
|
@@ -84,8 +104,10 @@ files:
|
|
84
104
|
- test/ct_1_couchdb.rb
|
85
105
|
- test/ct_2_couchdb_options.rb
|
86
106
|
- test/ct_3_couchdb_views.rb
|
107
|
+
- test/ct_4_attachments.rb
|
87
108
|
- test/server.rb
|
88
109
|
- test/test.rb
|
110
|
+
- test/tweet.png
|
89
111
|
- test/ut_0_http_get.rb
|
90
112
|
- test/ut_1_http_post.rb
|
91
113
|
- test/ut_2_http_delete.rb
|