rocket_pants 1.2.1 → 1.3.0
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/lib/rocket_pants.rb +5 -1
- data/lib/rocket_pants/base.rb +2 -0
- data/lib/rocket_pants/cache_middleware.rb +3 -3
- data/lib/rocket_pants/controller/header_metadata.rb +38 -0
- data/lib/rocket_pants/controller/linking.rb +41 -0
- data/lib/rocket_pants/controller/respondable.rb +18 -4
- data/lib/rocket_pants/railtie.rb +4 -2
- data/lib/rocket_pants/test_helper.rb +1 -1
- metadata +4 -2
data/lib/rocket_pants.rb
CHANGED
@@ -32,17 +32,21 @@ module RocketPants
|
|
32
32
|
autoload :JSONP, 'rocket_pants/controller/jsonp'
|
33
33
|
autoload :Rescuable, 'rocket_pants/controller/rescuable'
|
34
34
|
autoload :Respondable, 'rocket_pants/controller/respondable'
|
35
|
+
autoload :HeaderMetadata, 'rocket_pants/controller/header_metadata'
|
36
|
+
autoload :Linking, 'rocket_pants/controller/linking'
|
35
37
|
autoload :Versioning, 'rocket_pants/controller/versioning'
|
36
38
|
autoload :FormatVerification, 'rocket_pants/controller/format_verification'
|
37
39
|
autoload :UrlFor, 'rocket_pants/controller/url_for'
|
38
40
|
|
39
|
-
mattr_accessor :caching_enabled
|
41
|
+
mattr_accessor :caching_enabled, :header_metadata
|
40
42
|
self.caching_enabled = false
|
43
|
+
self.header_metadata = false
|
41
44
|
|
42
45
|
mattr_writer :cache
|
43
46
|
|
44
47
|
class << self
|
45
48
|
alias caching_enabled? caching_enabled
|
49
|
+
alias header_metadata? header_metadata
|
46
50
|
|
47
51
|
def cache
|
48
52
|
@@cache ||= Moneta::Memory.new
|
data/lib/rocket_pants/base.rb
CHANGED
@@ -2,6 +2,7 @@ module RocketPants
|
|
2
2
|
class CacheMiddleware
|
3
3
|
|
4
4
|
NOT_MODIFIED = [304, {}, []]
|
5
|
+
DIVIDER = ":"
|
5
6
|
|
6
7
|
def initialize(app)
|
7
8
|
@app = app
|
@@ -29,7 +30,6 @@ module RocketPants
|
|
29
30
|
|
30
31
|
def has_valid_etag?
|
31
32
|
return false if (etags = request_etags).blank?
|
32
|
-
debug ""
|
33
33
|
etags.any? do |etag|
|
34
34
|
cache_key, value = extract_cache_key_and_value etag
|
35
35
|
debug "Processing cache key for path #{request_path}"
|
@@ -39,7 +39,7 @@ module RocketPants
|
|
39
39
|
end
|
40
40
|
|
41
41
|
def extract_cache_key_and_value(etag)
|
42
|
-
etag.to_s.split(
|
42
|
+
etag.to_s.split(DIVIDER, 2)
|
43
43
|
end
|
44
44
|
|
45
45
|
def fresh?(key, value)
|
@@ -48,7 +48,7 @@ module RocketPants
|
|
48
48
|
|
49
49
|
def request_etags
|
50
50
|
stored = @env['HTTP_IF_NONE_MATCH']
|
51
|
-
stored.present? && stored.to_s.scan(/"([^"]+)"/)
|
51
|
+
stored.present? && stored.to_s.scan(/"([^"]+)"/).flatten.select { |i| i.include?(DIVIDER) }
|
52
52
|
end
|
53
53
|
|
54
54
|
def debug(message)
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module RocketPants
|
2
|
+
module HeaderMetadata
|
3
|
+
|
4
|
+
# Given a hash of request metadata, will:
|
5
|
+
# 1. Write out the headers for the current metadata
|
6
|
+
# 2. Return the hash, suitable for merging into the response hash
|
7
|
+
# 3. Start a dance party.
|
8
|
+
#
|
9
|
+
# @param [Hash{Symbol => Object}] metadata the hash of the request metadata.
|
10
|
+
# @return [Hash{Symbol => Object}] the passed in metadata
|
11
|
+
def expose_metadata(metadata)
|
12
|
+
metadata_headers { build_header_hash(metadata) }
|
13
|
+
super # Call any other versions of the method.
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
# Given a block which returns a Hash, will call and merge the block iff header metadata
|
18
|
+
# is enabled. This is to avoid the overhead of generating headers on every request when
|
19
|
+
# it's disabled.
|
20
|
+
def metadata_headers(&blk)
|
21
|
+
headers.merge! blk.call if RocketPants.header_metadata?
|
22
|
+
end
|
23
|
+
|
24
|
+
def build_header_hash(options, hash = {}, prefix = 'X-Api')
|
25
|
+
options.each_pair do |k, v|
|
26
|
+
current = "#{prefix}-#{k.to_s.titleize.tr(" ", "-")}"
|
27
|
+
if v.is_a?(Hash)
|
28
|
+
build_header_hash v, hash, current
|
29
|
+
else
|
30
|
+
value = Array(v).join(", ")
|
31
|
+
hash[current] = value if value.present?
|
32
|
+
end
|
33
|
+
end
|
34
|
+
hash
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module RocketPants
|
2
|
+
module Linking
|
3
|
+
|
4
|
+
# Generates a Link: header with the specified rel, uri and attributes.
|
5
|
+
# @param [String, Symbol] rel the relation of the given link
|
6
|
+
# @param [String] uri the full uri to the specified link resource
|
7
|
+
# @param [Hash] attributes any other attributes for the link
|
8
|
+
def link(rel, uri, attributes = {})
|
9
|
+
headers['Link'] ||= []
|
10
|
+
attributes = {:rel => rel}.merge(attributes)
|
11
|
+
link = "<#{uri}>"
|
12
|
+
attributes.each_pair { |k, v| link << "; #{k}=\"#{v}\"" }
|
13
|
+
headers['Link'] << link
|
14
|
+
end
|
15
|
+
|
16
|
+
# Lets you add a series of links for the current resource.
|
17
|
+
# @param [Hash{Symbol => String}] links a hash of links. Those with nil as the value are skipped.
|
18
|
+
def links(links = {})
|
19
|
+
links.each_pair do |rel, uri|
|
20
|
+
link rel, uri if uri
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# Hook method - Implement this to link to the current resource and we'll automatically add header links.
|
25
|
+
def page_url(page)
|
26
|
+
nil
|
27
|
+
end
|
28
|
+
|
29
|
+
def expose_metadata(metadata)
|
30
|
+
super.tap do |meta|
|
31
|
+
if RocketPants.header_metadata? && (pagination = meta[:pagination])
|
32
|
+
links :next => (pagination[:next] && page_url(pagination[:next])),
|
33
|
+
:prev => (pagination[:previous] && page_url(pagination[:previous])),
|
34
|
+
:last => (pagination[:pages] && page_url(pagination[:pages])),
|
35
|
+
:first => page_url(1)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
@@ -96,10 +96,11 @@ module RocketPants
|
|
96
96
|
def collection(collection, options = {})
|
97
97
|
pre_process_exposed_object collection, :collection, false
|
98
98
|
options = options.reverse_merge(:compact => true)
|
99
|
+
meta = expose_metadata(:count => collection.length)
|
99
100
|
render_json({
|
100
101
|
:response => normalise_object(collection, options),
|
101
102
|
:count => collection.length
|
102
|
-
}, options)
|
103
|
+
}.merge(meta), options)
|
103
104
|
post_process_exposed_object collection, :collection, false
|
104
105
|
end
|
105
106
|
|
@@ -107,11 +108,13 @@ module RocketPants
|
|
107
108
|
def paginated(collection, options = {})
|
108
109
|
pre_process_exposed_object collection, :paginated, false
|
109
110
|
options = options.reverse_merge(:compact => true)
|
110
|
-
|
111
|
-
:response => normalise_object(collection, options),
|
111
|
+
meta = expose_metadata({
|
112
112
|
:count => collection.length,
|
113
113
|
:pagination => Respondable.extract_pagination(collection)
|
114
|
-
}
|
114
|
+
})
|
115
|
+
render_json({
|
116
|
+
:response => normalise_object(collection, options),
|
117
|
+
}.merge(meta), options)
|
115
118
|
post_process_exposed_object collection, :paginated, false
|
116
119
|
end
|
117
120
|
|
@@ -146,5 +149,16 @@ module RocketPants
|
|
146
149
|
def post_process_exposed_object(resource, type, singular)
|
147
150
|
end
|
148
151
|
|
152
|
+
# Given a hash of request metadata, will:
|
153
|
+
# 1. Do anything special with the request metadata
|
154
|
+
# 2. Return the hash, suitable for merging into the response hash
|
155
|
+
# 3. Start a dance party.
|
156
|
+
#
|
157
|
+
# @param [Hash{Symbol => Object}] metadata the hash of the request metadata.
|
158
|
+
# @return [Hash{Symbol => Object}] the passed in metadata
|
159
|
+
def expose_metadata(metadata)
|
160
|
+
metadata
|
161
|
+
end
|
162
|
+
|
149
163
|
end
|
150
164
|
end
|
data/lib/rocket_pants/railtie.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
module RocketPants
|
2
2
|
class Railtie < Rails::Railtie
|
3
3
|
|
4
|
-
config.rocket_pants
|
5
|
-
config.rocket_pants.use_caching
|
4
|
+
config.rocket_pants = ActiveSupport::OrderedOptions.new
|
5
|
+
config.rocket_pants.use_caching = nil
|
6
|
+
config.rocket_pants.header_metadata = nil
|
6
7
|
|
7
8
|
config.i18n.railties_load_path << File.expand_path('../locale/en.yml', __FILE__)
|
8
9
|
|
@@ -14,6 +15,7 @@ module RocketPants
|
|
14
15
|
rp_config = app.config.rocket_pants
|
15
16
|
rp_config.use_caching = Rails.env.production? if rp_config.use_caching.nil?
|
16
17
|
RocketPants.caching_enabled = rp_config.use_caching
|
18
|
+
RocketPants.header_metadata = rp_config.header_metadata unless rp_config.header_metadata.nil?
|
17
19
|
# Set the rocket pants cache if present.
|
18
20
|
RocketPants.cache = rp_config.cache if rp_config.cache
|
19
21
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rocket_pants
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-05-
|
12
|
+
date: 2012-05-06 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: actionpack
|
@@ -250,8 +250,10 @@ files:
|
|
250
250
|
- lib/rocket_pants/controller/caching.rb
|
251
251
|
- lib/rocket_pants/controller/error_handling.rb
|
252
252
|
- lib/rocket_pants/controller/format_verification.rb
|
253
|
+
- lib/rocket_pants/controller/header_metadata.rb
|
253
254
|
- lib/rocket_pants/controller/instrumentation.rb
|
254
255
|
- lib/rocket_pants/controller/jsonp.rb
|
256
|
+
- lib/rocket_pants/controller/linking.rb
|
255
257
|
- lib/rocket_pants/controller/rescuable.rb
|
256
258
|
- lib/rocket_pants/controller/respondable.rb
|
257
259
|
- lib/rocket_pants/controller/url_for.rb
|