rufus-jig 0.1.13 → 0.1.14

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,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