orange-core 0.5.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +145 -0
- data/lib/orange-core.rb +8 -0
- data/lib/orange-core/application.rb +132 -0
- data/lib/orange-core/assets/css/exceptions.css +50 -0
- data/lib/orange-core/assets/js/exceptions.js +44 -0
- data/lib/orange-core/carton.rb +178 -0
- data/lib/orange-core/core.rb +266 -0
- data/lib/orange-core/magick.rb +270 -0
- data/lib/orange-core/middleware/base.rb +96 -0
- data/lib/orange-core/middleware/database.rb +45 -0
- data/lib/orange-core/middleware/four_oh_four.rb +45 -0
- data/lib/orange-core/middleware/globals.rb +17 -0
- data/lib/orange-core/middleware/loader.rb +13 -0
- data/lib/orange-core/middleware/rerouter.rb +53 -0
- data/lib/orange-core/middleware/restful_router.rb +99 -0
- data/lib/orange-core/middleware/route_context.rb +39 -0
- data/lib/orange-core/middleware/route_site.rb +51 -0
- data/lib/orange-core/middleware/show_exceptions.rb +80 -0
- data/lib/orange-core/middleware/static.rb +67 -0
- data/lib/orange-core/middleware/static_file.rb +32 -0
- data/lib/orange-core/middleware/template.rb +60 -0
- data/lib/orange-core/packet.rb +232 -0
- data/lib/orange-core/plugin.rb +172 -0
- data/lib/orange-core/resource.rb +96 -0
- data/lib/orange-core/resources/mapper.rb +36 -0
- data/lib/orange-core/resources/model_resource.rb +228 -0
- data/lib/orange-core/resources/not_found.rb +10 -0
- data/lib/orange-core/resources/page_parts.rb +68 -0
- data/lib/orange-core/resources/parser.rb +113 -0
- data/lib/orange-core/resources/routable_resource.rb +16 -0
- data/lib/orange-core/resources/scaffold.rb +106 -0
- data/lib/orange-core/stack.rb +226 -0
- data/lib/orange-core/templates/exceptions.haml +111 -0
- data/lib/orange-core/views/default_resource/create.haml +4 -0
- data/lib/orange-core/views/default_resource/edit.haml +9 -0
- data/lib/orange-core/views/default_resource/list.haml +10 -0
- data/lib/orange-core/views/default_resource/show.haml +4 -0
- data/lib/orange-core/views/default_resource/table_row.haml +7 -0
- data/lib/orange-core/views/not_found/404.haml +2 -0
- data/spec/orange-core/application_spec.rb +183 -0
- data/spec/orange-core/carton_spec.rb +136 -0
- data/spec/orange-core/core_spec.rb +248 -0
- data/spec/orange-core/magick_spec.rb +96 -0
- data/spec/orange-core/middleware/base_spec.rb +38 -0
- data/spec/orange-core/middleware/globals_spec.rb +3 -0
- data/spec/orange-core/middleware/rerouter_spec.rb +3 -0
- data/spec/orange-core/middleware/restful_router_spec.rb +3 -0
- data/spec/orange-core/middleware/route_context_spec.rb +3 -0
- data/spec/orange-core/middleware/route_site_spec.rb +3 -0
- data/spec/orange-core/middleware/show_exceptions_spec.rb +3 -0
- data/spec/orange-core/middleware/static_file_spec.rb +3 -0
- data/spec/orange-core/middleware/static_spec.rb +3 -0
- data/spec/orange-core/mock/mock_app.rb +16 -0
- data/spec/orange-core/mock/mock_carton.rb +43 -0
- data/spec/orange-core/mock/mock_core.rb +2 -0
- data/spec/orange-core/mock/mock_middleware.rb +25 -0
- data/spec/orange-core/mock/mock_mixins.rb +19 -0
- data/spec/orange-core/mock/mock_model_resource.rb +47 -0
- data/spec/orange-core/mock/mock_pulp.rb +24 -0
- data/spec/orange-core/mock/mock_resource.rb +26 -0
- data/spec/orange-core/mock/mock_router.rb +10 -0
- data/spec/orange-core/orange_spec.rb +19 -0
- data/spec/orange-core/packet_spec.rb +203 -0
- data/spec/orange-core/resource_spec.rb +96 -0
- data/spec/orange-core/resources/mapper_spec.rb +5 -0
- data/spec/orange-core/resources/model_resource_spec.rb +246 -0
- data/spec/orange-core/resources/parser_spec.rb +5 -0
- data/spec/orange-core/resources/routable_resource_spec.rb +5 -0
- data/spec/orange-core/spec_helper.rb +53 -0
- data/spec/orange-core/stack_spec.rb +232 -0
- data/spec/stats.rb +182 -0
- metadata +227 -0
@@ -0,0 +1,96 @@
|
|
1
|
+
require 'orange-core/packet'
|
2
|
+
|
3
|
+
# Orange Middleware is a bit more complex than Rack middleware.
|
4
|
+
# Initializing it requires both a link to the downstream app and
|
5
|
+
# the core, and calling the app often requires an Orange::Packet
|
6
|
+
#
|
7
|
+
# Orange::Middleware::Base takes care of these basic tasks.
|
8
|
+
# Subclasses override the init method for extra initialization
|
9
|
+
# and the packet_call for a call with a packet, rather than
|
10
|
+
# a basic call
|
11
|
+
module Orange::Middleware
|
12
|
+
class Base
|
13
|
+
# Initialize will set the core and downstream app, then call init
|
14
|
+
# subclasses should override init instead of initialize.
|
15
|
+
# If the subclass defines a stack_init, then it will be registered
|
16
|
+
# as a stack_loaded event.
|
17
|
+
# @param [Object] app a downstream app
|
18
|
+
# @param [Orange::Core] core the orange core
|
19
|
+
# @param [optional, Array] args any arguments
|
20
|
+
def initialize(app, core, *args)
|
21
|
+
@app = app
|
22
|
+
@core = core
|
23
|
+
init(*args)
|
24
|
+
core.middleware(self)
|
25
|
+
end
|
26
|
+
|
27
|
+
# A stub method that subclasses can override to handle initialization
|
28
|
+
# For initialization
|
29
|
+
# @return [void]
|
30
|
+
def init(*args)
|
31
|
+
end
|
32
|
+
|
33
|
+
# The standard Rack "call". By default, Orange Middleware wraps the env into
|
34
|
+
# an Orange::Packet and passes it on to #packet_call. Subclasses will typically
|
35
|
+
# override packet_call rather than overriding call directly.
|
36
|
+
#
|
37
|
+
# Orange Middleware
|
38
|
+
# should expect to have this method ignored by upstream Orange-aware apps in
|
39
|
+
# favor of calling packet_call directly.
|
40
|
+
# @param [Hash] env the hash of environment variables given by the rack interface.
|
41
|
+
# @return [Array] the standard Rack striplet of status, headers and content
|
42
|
+
def call(env)
|
43
|
+
packet = Orange::Packet.new(@core, env)
|
44
|
+
packet_call(packet)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Like the standard call, but with the env hash already wrapped into a Packet
|
48
|
+
# This is called automatically as part of #call, so subclasses can have a packet
|
49
|
+
# without having to initialize it. It will be called directly by Orange-aware
|
50
|
+
# upstream middleware, skipping the step of initializing the packet during #call.
|
51
|
+
#
|
52
|
+
# Passing the packet downstream should be done with #pass rather than the Rack
|
53
|
+
# standard @app.call, since #pass will take the packet and do a #packet_call
|
54
|
+
# if possible.
|
55
|
+
# @param [Orange::Packet] packet the packet corresponding to this env
|
56
|
+
# @return [Array] the standard Rack striplet of status, headers and content
|
57
|
+
def packet_call(packet)
|
58
|
+
pass packet
|
59
|
+
end
|
60
|
+
|
61
|
+
# Pass will sent the packet to the downstream app by calling call or packet call.
|
62
|
+
# Calling pass on a packet is the preferred way to call downstream apps, as it
|
63
|
+
# will call packet_call directly if possible (to avoid reinitializing the packet)
|
64
|
+
# @param [Orange::Packet] packet the packet to pass to downstream apps
|
65
|
+
# @return [Array] the standard Rack striplet of status, headers and content
|
66
|
+
def pass(packet)
|
67
|
+
if @app.respond_to?(:packet_call)
|
68
|
+
@app.packet_call(packet)
|
69
|
+
else
|
70
|
+
recapture(@app.call(packet.env), packet)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# After the pass has been completed, we should recapture the contents and make
|
75
|
+
# sure they are placed in the packet, in case the downstream app is not Orange aware.
|
76
|
+
# @param [Array] the standard Rack striplet of status, headers and content
|
77
|
+
# @param [Orange::Packet] packet the packet to pass to downstream apps
|
78
|
+
# @return [Array] the standard Rack striplet of status, headers and content
|
79
|
+
def recapture(response, packet)
|
80
|
+
packet[:status] = response[0]
|
81
|
+
packet[:headers] = response[1]
|
82
|
+
packet[:content] = response[2].first
|
83
|
+
response
|
84
|
+
end
|
85
|
+
|
86
|
+
# Accessor for @core, which is the stack's instance of Orange::Core
|
87
|
+
# @return [Orange::Core] the stack's instance of Orange::Core
|
88
|
+
def orange; @core; end
|
89
|
+
|
90
|
+
# Help stack traces
|
91
|
+
# @return [String] string representing this middleware (#to_s)
|
92
|
+
def inspect
|
93
|
+
self.to_s
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'orange-core/middleware/base'
|
2
|
+
module Orange::Middleware
|
3
|
+
|
4
|
+
class Database < Base
|
5
|
+
def init(opts = {})
|
6
|
+
opts = opts.with_defaults(:migration_url => (orange.options[:development_mode] ? '/__ORANGE_DB__/migrate' : false), :no_auto_upgrade => false)
|
7
|
+
orange.mixin Orange::Mixins::DBLoader
|
8
|
+
@options = opts
|
9
|
+
end
|
10
|
+
|
11
|
+
def stack_init
|
12
|
+
unless orange.options.has_key?('database') && orange.options['database'] == false
|
13
|
+
db = orange.options['database'] || 'sqlite3::memory:'
|
14
|
+
orange.load_db!(db)
|
15
|
+
orange.upgrade_db! unless @options[:no_auto_upgrade] || orange.options['db_no_auto_upgrade']
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def packet_call(packet)
|
20
|
+
path = packet['route.path'] || packet.request.path_info
|
21
|
+
if @options[:migration_url] && @options[:migration_url] == path
|
22
|
+
orange.migrate_db!
|
23
|
+
after = packet.flash('redirect_to') || '/'
|
24
|
+
packet.reroute(after)
|
25
|
+
end
|
26
|
+
pass packet
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
module Orange::Mixins::DBLoader
|
33
|
+
def load_db!(url)
|
34
|
+
DataMapper.setup(:default, url)
|
35
|
+
end
|
36
|
+
|
37
|
+
def migrate_db!
|
38
|
+
DataMapper.auto_migrate!
|
39
|
+
end
|
40
|
+
|
41
|
+
def upgrade_db!
|
42
|
+
DataMapper.auto_upgrade!
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'orange-core/middleware/base'
|
2
|
+
|
3
|
+
module Orange::Middleware
|
4
|
+
# The FlexRouter middleware takes a resource that can route paths and
|
5
|
+
# then intercepts routes for that resource. By default,
|
6
|
+
# it uses the Orange::SitemapResource.
|
7
|
+
#
|
8
|
+
# The resource is automatically loaded into the core as
|
9
|
+
# :sitemap. The resource must respond to "route?(path)"
|
10
|
+
# and "route(packet)".
|
11
|
+
#
|
12
|
+
# Pass a different routing resource using the :resource arg
|
13
|
+
class FourOhFour < Base
|
14
|
+
def init(opts = {})
|
15
|
+
@resource = opts[:resource] || Orange::NotFound
|
16
|
+
orange.load @resource.new, :not_found
|
17
|
+
orange.add_pulp Orange::Pulp::NotFoundHelper
|
18
|
+
end
|
19
|
+
|
20
|
+
# Sets the sitemap resource as the router if the resource can accept
|
21
|
+
# the path.
|
22
|
+
def packet_call(packet)
|
23
|
+
packet['route.router'] = orange[:not_found] unless packet['route.router']
|
24
|
+
begin
|
25
|
+
pass packet
|
26
|
+
rescue Orange::NotFoundException
|
27
|
+
orange[:not_found].route(packet)
|
28
|
+
packet.finish
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
module Orange
|
36
|
+
class NotFoundException < Exception
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
module Pulp::NotFoundHelper
|
41
|
+
def not_found
|
42
|
+
raise Orange::NotFoundException.new
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'orange-core/middleware/base'
|
2
|
+
module Orange::Middleware
|
3
|
+
|
4
|
+
class Globals < Base
|
5
|
+
def init(opts = {})
|
6
|
+
opts = opts.with_defaults(:file => "__ORANGE__/config.yml")
|
7
|
+
@file = opts[:file].gsub('__ORANGE__', orange.app_dir)
|
8
|
+
@globals = orange[:parser].yaml(@file) || {}
|
9
|
+
@globals.each{|k,v| orange.options[k] = v}
|
10
|
+
end
|
11
|
+
def packet_call(packet)
|
12
|
+
packet['orange.globals'] ||= orange.options
|
13
|
+
pass packet
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'orange-core/middleware/base'
|
2
|
+
module Orange::Middleware
|
3
|
+
class Loader < Base
|
4
|
+
def init(*args)
|
5
|
+
Dir.glob(File.join(orange.app_dir, 'resources', '*.rb')).each do |f|
|
6
|
+
require f
|
7
|
+
orange.load Orange::Inflector.constantize(Orange::Inflector.camelize(File.basename(f, '.rb'))).new
|
8
|
+
end
|
9
|
+
Dir.glob(File.join(orange.app_dir, 'cartons', '*.rb')).each { |f| require f }
|
10
|
+
Dir.glob(File.join(orange.app_dir, 'middleware', '*.rb')).each { |f| require f }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'orange-core/middleware/base'
|
2
|
+
module Orange::Middleware
|
3
|
+
|
4
|
+
class Rerouter < Base
|
5
|
+
def init(*args)
|
6
|
+
orange.add_pulp Orange::Pulp::Packet_Reroute
|
7
|
+
end
|
8
|
+
|
9
|
+
def packet_call(packet)
|
10
|
+
begin
|
11
|
+
pass packet
|
12
|
+
rescue Orange::Reroute
|
13
|
+
packet.finish
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
module Orange
|
20
|
+
|
21
|
+
module Pulp::Packet_Reroute
|
22
|
+
def reroute(url, type = :real, *args)
|
23
|
+
packet['reroute.to'] = url
|
24
|
+
packet['reroute.type'] = type
|
25
|
+
packet['reroute.args'] = *args if args
|
26
|
+
raise Reroute.new(self), 'Unhandled reroute'
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class Reroute < Exception
|
31
|
+
def initialize(packet)
|
32
|
+
@packet = packet
|
33
|
+
@packet[:headers] = {"Content-Type" => 'text/html', "Location" => self.url}
|
34
|
+
@packet[:status] = 302
|
35
|
+
end
|
36
|
+
|
37
|
+
def url
|
38
|
+
case packet['reroute.type']
|
39
|
+
when :real
|
40
|
+
packet['reroute.to']
|
41
|
+
# Parsing for orange urls or something
|
42
|
+
when :orange
|
43
|
+
packet.route_to(packet['reroute.to'], *packet['reroute.args', []])
|
44
|
+
else
|
45
|
+
packet['reroute.to']
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def packet
|
50
|
+
@packet
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'orange-core/middleware/base'
|
2
|
+
|
3
|
+
module Orange::Middleware
|
4
|
+
class RestfulRouter < Base
|
5
|
+
def init(*args)
|
6
|
+
opts = args.extract_options!.with_defaults(:restful_contexts => [:admin, :orange], :not_found => false, :exposed_actions => {:admin => :all, :orange => :all})
|
7
|
+
@exposed = opts[:exposed_actions]
|
8
|
+
@contexts = opts[:restful_contexts]
|
9
|
+
@not_found = opts[:not_found]
|
10
|
+
end
|
11
|
+
|
12
|
+
# sets resource, resource_id, resource_action and resource_path
|
13
|
+
# /resource/id/action/[resource/path/if/any]
|
14
|
+
# /resource/action/[resource/path/if/any]
|
15
|
+
#
|
16
|
+
# In future - support for nested resources
|
17
|
+
def packet_call(packet)
|
18
|
+
return (pass packet) if packet['route.router'] # Don't route if other middleware
|
19
|
+
# already has
|
20
|
+
parts = route_parts(packet)
|
21
|
+
if(should_route?(packet, parts))
|
22
|
+
# Take parts of route and set packet info
|
23
|
+
packet['route.resource'] = parts[:resource] if parts[:resource]
|
24
|
+
packet['route.resource_id'] = parts[:resource_id] if parts[:resource_id]
|
25
|
+
packet['route.resource_action'] = parts[:resource_action] if parts[:resource_action]
|
26
|
+
|
27
|
+
# Take remainder and set to resource_path
|
28
|
+
packet['route.resource_path'] = parts[:remainder]
|
29
|
+
|
30
|
+
# Set self as router if resource was found
|
31
|
+
if(packet['route.resource', false])
|
32
|
+
packet['route.router'] = self
|
33
|
+
elsif(@not_found)
|
34
|
+
packet['route.resource'] = @not_found
|
35
|
+
packet['route.router'] = self
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
pass packet
|
40
|
+
end
|
41
|
+
|
42
|
+
def route_parts(packet)
|
43
|
+
return_parts = {}
|
44
|
+
path = packet['route.path'] || packet.request.path_info
|
45
|
+
parts = path.split('/')
|
46
|
+
pad = parts.shift
|
47
|
+
if !parts.empty?
|
48
|
+
resource = parts.shift
|
49
|
+
if orange.loaded?(resource.to_sym)
|
50
|
+
return_parts[:resource] = resource.to_sym
|
51
|
+
if !parts.empty?
|
52
|
+
second = parts.shift
|
53
|
+
if second =~ /^\d+$/
|
54
|
+
return_parts[:resource_id] = second
|
55
|
+
if !parts.empty?
|
56
|
+
return_parts[:resource_action] = parts.shift.to_sym
|
57
|
+
else
|
58
|
+
return_parts[:resource_action] = :show
|
59
|
+
end
|
60
|
+
else
|
61
|
+
return_parts[:resource_action] = second.to_sym
|
62
|
+
end
|
63
|
+
else
|
64
|
+
return_parts[:resource_action] = :list
|
65
|
+
end # end check for second part
|
66
|
+
else
|
67
|
+
parts.unshift(resource)
|
68
|
+
end # end check for loaded resource
|
69
|
+
end # end check for nonempty route
|
70
|
+
return_parts[:remainder] = parts.unshift(pad).join('/')
|
71
|
+
return_parts
|
72
|
+
end
|
73
|
+
|
74
|
+
def should_route?(packet, parts)
|
75
|
+
return false unless @exposed.has_key?(packet['route.context'])
|
76
|
+
action_exposed?(@exposed[packet['route.context']], parts)
|
77
|
+
end
|
78
|
+
|
79
|
+
def action_exposed?(list, route_parts)
|
80
|
+
return true if list == :all
|
81
|
+
return true if list == route_parts[:resource_action]
|
82
|
+
return true if list.is_a?(Array) && list.include?(route_parts[:resource_action])
|
83
|
+
if list.is_a?(Hash)
|
84
|
+
all = list.has_key?(:all) ? action_exposed?(list[:all], route_parts) : false
|
85
|
+
one = list.has_key?(route_parts[:resource]) ? action_exposed?(list[route_parts[:resource]], route_parts) : false
|
86
|
+
return all || one
|
87
|
+
end
|
88
|
+
false
|
89
|
+
end
|
90
|
+
|
91
|
+
def route(packet)
|
92
|
+
resource = packet['route.resource']
|
93
|
+
raise 'resource not found' unless orange.loaded? resource
|
94
|
+
mode = packet['route.resource_action'] ||
|
95
|
+
(packet['route.resource_id'] ? :show : :list)
|
96
|
+
packet[:content] = orange[resource].view packet
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'orange-core/middleware/base'
|
2
|
+
|
3
|
+
module Orange::Middleware
|
4
|
+
# This middleware handles setting orange.env['route.context']
|
5
|
+
# to a value based on the route, if any. The route is then
|
6
|
+
# trimmed before continuing on.
|
7
|
+
class RouteContext < Base
|
8
|
+
def initialize(app, core, *args)
|
9
|
+
opts = args.extract_options!
|
10
|
+
opts.with_defaults!(:contexts => [:preview, :live, :admin, :orange],
|
11
|
+
:default => :live,
|
12
|
+
:urls => {})
|
13
|
+
@app = app
|
14
|
+
@core = core
|
15
|
+
@contexts = opts[:contexts]
|
16
|
+
@default = opts[:default]
|
17
|
+
@urls = opts[:urls]
|
18
|
+
end
|
19
|
+
def packet_call(packet)
|
20
|
+
path_info = packet['route.path'] || packet.env['PATH_INFO']
|
21
|
+
path = path_info.split('/')
|
22
|
+
pad = path.shift # Shift off empty first part
|
23
|
+
if @urls[packet.request.host]
|
24
|
+
packet['route.context'] = urls[packet.request.host]
|
25
|
+
elsif path.empty?
|
26
|
+
packet['route.context'] = @default
|
27
|
+
else
|
28
|
+
if(@contexts.include?(path.first.to_sym))
|
29
|
+
packet['route.context'] = path.shift.to_sym
|
30
|
+
path.unshift(pad)
|
31
|
+
packet['route.path'] = path.join('/')
|
32
|
+
else
|
33
|
+
packet['route.context'] = @default
|
34
|
+
end
|
35
|
+
end
|
36
|
+
pass packet
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'orange-core/middleware/base'
|
2
|
+
|
3
|
+
module Orange::Middleware
|
4
|
+
# This middleware handles setting orange.env['route.site_url']
|
5
|
+
# to a value based on the route, if any. The route is then
|
6
|
+
# trimmed before continuing on.
|
7
|
+
#
|
8
|
+
# Options -
|
9
|
+
# :multi - does Orange need to handle multiple urls
|
10
|
+
# :fake_it - host url(s) that Orange will fake requests on
|
11
|
+
# ex: :multi => true, :fake_it => 'localhost'
|
12
|
+
# will fake hostnames as first component of url
|
13
|
+
# only on localhost
|
14
|
+
class RouteSite < Base
|
15
|
+
def initialize(app, core, *args)
|
16
|
+
opts = args.extract_options!
|
17
|
+
opts.with_defaults!(:multi => false, :fake_it => ['localhost'])
|
18
|
+
@app = app
|
19
|
+
@core = core
|
20
|
+
@multi = opts[:multi]
|
21
|
+
# Put fake_it into an array, if necessary
|
22
|
+
@fake_it = opts[:fake_it].respond_to?(:include?) ?
|
23
|
+
opts[:fake_it] : [opts[:fake_it]]
|
24
|
+
end
|
25
|
+
|
26
|
+
def packet_call(packet)
|
27
|
+
request = packet.request
|
28
|
+
path_info = packet['route.path'] || packet.env['PATH_INFO']
|
29
|
+
path = path_info.split('/')
|
30
|
+
pad = path.shift # Shift off empty first part
|
31
|
+
packet['route.faked_site'] = false
|
32
|
+
if @multi
|
33
|
+
if path.empty?
|
34
|
+
packet['route.site_url'] = request.host
|
35
|
+
else
|
36
|
+
if @fake_it.include?(request.host)
|
37
|
+
packet['route.site_url'] = path.shift
|
38
|
+
packet['route.faked_site'] = true
|
39
|
+
else
|
40
|
+
packet['route.site_url'] = request.host
|
41
|
+
end
|
42
|
+
path.unshift(pad)
|
43
|
+
packet['route.path'] = path.join('/')
|
44
|
+
end
|
45
|
+
else
|
46
|
+
packet['route.site_url'] = request.host
|
47
|
+
end
|
48
|
+
pass packet
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|