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 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
@@ -23,3 +23,6 @@
23
23
 
24
24
  [ ] why not a :force_json ?
25
25
 
26
+ [ ] couch.attach
27
+ [ ] couch.detach ?
28
+
@@ -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)
@@ -246,12 +246,23 @@ module Rufus::Jig
246
246
 
247
247
  def repack_data (data, opts)
248
248
 
249
- return data if data.nil? || data.is_a?(String)
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.to_s
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)
@@ -1,7 +1,7 @@
1
1
 
2
2
  module Rufus
3
3
  module Jig
4
- VERSION = '0.1.13'
4
+ VERSION = '0.1.14'
5
5
  end
6
6
  end
7
7
 
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.13"
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}
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
@@ -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
 
@@ -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.13
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-12 00:00:00 +09:00
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