httmultiparty 0.1

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/README.md ADDED
@@ -0,0 +1,27 @@
1
+ <h2>Description</h2>
2
+ <p>HTTMultiParty is a thin wrapper around HTTParty to provide multipart uploads.</p>
3
+
4
+ <h2>Requirements</h2>
5
+ <ul>
6
+ <li>httparty</li>
7
+ <li>multipart-post</li>
8
+ </ul>
9
+
10
+ <h2>O RLY?</h2>
11
+ <p>To start just "include HTTMultiParty" instead of "include HTTParty" into your client class.
12
+ When you pass a query with an instance of a File as a value for a PUT or POST request, the wrapper will
13
+ use a bit of magic and multipart-post to execute a multipart upload:</p>
14
+
15
+ <h2>Example</h2>
16
+ <pre>
17
+ require 'lib/httmultiparty'
18
+ class SomeClient
19
+ include HTTMultiParty
20
+ base_uri 'http://localhost:3000'
21
+ end
22
+
23
+ response = SomeClient.post('/', :query => {
24
+ :foo => 'bar',
25
+ :somefile => File.new('README.md')
26
+ })
27
+ </pre>
@@ -0,0 +1,56 @@
1
+ gem 'httparty'
2
+ gem 'multipart-post'
3
+ require 'httparty'
4
+ require 'net/http/post/multipart'
5
+
6
+ module HTTMultiParty
7
+ def self.included(base)
8
+ base.send :include, HTTParty
9
+ base.extend ClassMethods
10
+ end
11
+
12
+ module ClassMethods
13
+ def post(path, options={})
14
+ method = Net::HTTP::Post
15
+ if query_contains_files?(options[:query])
16
+ method = MultipartPost
17
+ options[:body] = map_files_to_upload_io(options.delete(:query))
18
+ end
19
+ perform_request method, path, options
20
+ end
21
+
22
+ def put(path, options={})
23
+ method = Net::HTTP::Put
24
+ if query_contains_files?(options[:query])
25
+ method = MultipartPut
26
+ options[:body] = map_files_to_upload_io(options.delete(:query))
27
+ end
28
+ perform_request method, path, options
29
+ end
30
+
31
+ private
32
+ def query_contains_files?(query)
33
+ query.is_a?(Hash) && query.select { |k,v| v.is_a?(File) }.length > 0
34
+ end
35
+
36
+ def map_files_to_upload_io(hash)
37
+ new_special_hash = SpecialHash.new
38
+ hash.each do |k,v|
39
+ new_special_hash[k] = v.is_a?(File) ? file_to_upload_io(v) : v
40
+ end
41
+ new_special_hash
42
+ end
43
+
44
+ def file_to_upload_io(file)
45
+ filename = File.split(file.path).last
46
+ content_type = 'application/octet-stream'
47
+ UploadIO.new(file, content_type, filename)
48
+ end
49
+ end
50
+ end
51
+
52
+ dir = Pathname(__FILE__).dirname.expand_path
53
+ require dir + 'httmultiparty/multipartable'
54
+ require dir + 'httmultiparty/special_hash'
55
+ require dir + 'httmultiparty/multipart_post'
56
+ require dir + 'httmultiparty/multipart_put'
@@ -0,0 +1,5 @@
1
+ class HTTMultiParty::MultipartPost < Net::HTTP::Post
2
+ include HTTMultiParty::Multipartable
3
+ end
4
+
5
+ HTTParty::Request::SupportedHTTPMethods << HTTMultiParty::MultipartPost
@@ -0,0 +1,5 @@
1
+ class HTTMultiParty::MultipartPut < Net::HTTP::Put
2
+ include HTTMultiParty::Multipartable
3
+ end
4
+
5
+ HTTParty::Request::SupportedHTTPMethods << HTTMultiParty::MultipartPut
@@ -0,0 +1,17 @@
1
+ module HTTMultiParty::Multipartable
2
+ DEFAULT_BOUNDARY = "-----------RubyMultipartPost"
3
+ # prevent reinitialization of headers
4
+ def initialize_http_header(initheader)
5
+ super if @header.nil?
6
+ end
7
+
8
+ def body=(value)
9
+ raise RuntimeError.new('body needs to be a SpecialHash') unless value.is_a?(HTTMultiParty::SpecialHash)
10
+ boundary = DEFAULT_BOUNDARY
11
+ parts = value.map {|k,v| Parts::Part.new(boundary, k, v)}
12
+ parts << Parts::EpiloguePart.new(boundary)
13
+ self.set_content_type("multipart/form-data", { "boundary" => boundary })
14
+ self.content_length = parts.inject(0) {|sum,i| sum + i.length }
15
+ self.body_stream = CompositeReadIO.new(*parts.map(&:to_io))
16
+ end
17
+ end
@@ -0,0 +1,8 @@
1
+ # SpecialHash is a hash that is pretending to be not a Hash.
2
+ # its just a cheap way to get around the query normalization
3
+ # happening in HTTParty::Request#body in lib/httparty/request.rb:118
4
+ class HTTMultiParty::SpecialHash < Hash
5
+ def is_a?(klass)
6
+ klass == ::Hash ? false : super
7
+ end
8
+ end
@@ -0,0 +1,3 @@
1
+ module HTTMultiParty
2
+ VERSION = '0.1'
3
+ end
metadata ADDED
@@ -0,0 +1,130 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: httmultiparty
3
+ version: !ruby/object:Gem::Version
4
+ hash: 9
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 1
9
+ version: "0.1"
10
+ platform: ruby
11
+ authors:
12
+ - Johannes Wagener
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2011-01-16 00:00:00 -08:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: httparty
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ hash: 3
29
+ segments:
30
+ - 0
31
+ version: "0"
32
+ type: :runtime
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: multipart-post
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ none: false
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ hash: 3
43
+ segments:
44
+ - 0
45
+ version: "0"
46
+ type: :runtime
47
+ version_requirements: *id002
48
+ - !ruby/object:Gem::Dependency
49
+ name: rspec
50
+ prerelease: false
51
+ requirement: &id003 !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ hash: 3
57
+ segments:
58
+ - 0
59
+ version: "0"
60
+ type: :development
61
+ version_requirements: *id003
62
+ - !ruby/object:Gem::Dependency
63
+ name: fakeweb
64
+ prerelease: false
65
+ requirement: &id004 !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ hash: 3
71
+ segments:
72
+ - 0
73
+ version: "0"
74
+ type: :development
75
+ version_requirements: *id004
76
+ description: HTTMultiParty is a thin wrapper around HTTParty to provide multipart uploads.
77
+ email:
78
+ - johannes@wagener.cc
79
+ executables: []
80
+
81
+ extensions: []
82
+
83
+ extra_rdoc_files: []
84
+
85
+ files:
86
+ - lib/httmultiparty/multipart_post.rb
87
+ - lib/httmultiparty/multipart_put.rb
88
+ - lib/httmultiparty/multipartable.rb
89
+ - lib/httmultiparty/special_hash.rb
90
+ - lib/httmultiparty/version.rb
91
+ - lib/httmultiparty.rb
92
+ - README.md
93
+ has_rdoc: true
94
+ homepage: http://github.com/jwagener/httmultiparty
95
+ licenses: []
96
+
97
+ post_install_message:
98
+ rdoc_options: []
99
+
100
+ require_paths:
101
+ - lib
102
+ required_ruby_version: !ruby/object:Gem::Requirement
103
+ none: false
104
+ requirements:
105
+ - - ">="
106
+ - !ruby/object:Gem::Version
107
+ hash: 3
108
+ segments:
109
+ - 0
110
+ version: "0"
111
+ required_rubygems_version: !ruby/object:Gem::Requirement
112
+ none: false
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ hash: 23
117
+ segments:
118
+ - 1
119
+ - 3
120
+ - 6
121
+ version: 1.3.6
122
+ requirements: []
123
+
124
+ rubyforge_project:
125
+ rubygems_version: 1.3.7
126
+ signing_key:
127
+ specification_version: 3
128
+ summary: HTTMultiParty is a thin wrapper around HTTParty to provide multipart uploads.
129
+ test_files: []
130
+