-
Notifications
You must be signed in to change notification settings - Fork 2k
/
event.rb
140 lines (108 loc) · 2.71 KB
/
event.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
module Sinatra
module EventManager
extend self
def reset!
@events.clear if @events
end
def events
@events || []
end
def register_event(event)
(@events ||= []) << event
end
def determine_event(verb, path, if_nil = :present_error)
events.detect(method(if_nil)) do |e|
e.path == path && e.verb == verb
end
end
def present_error
determine_event(:get, 404, :not_found)
end
def not_found
Event.new(:get, nil, false) do
status 404
views_dir SINATRA_ROOT + '/files'
if request.path_info == '/' && request.request_method == 'GET'
erb :default_index
else
erb :not_found
end
end
end
end
class EventContext
cattr_accessor :logger
attr_reader :request
def initialize(request)
@request = request
@headers = {}
end
def status(value = nil)
@status = value if value
@status || 200
end
def body(value = nil, &block)
@body = value if value
@body = block.call if block
@body || ''
end
def error(value = nil)
if value
@error = value
status 500
end
@error
end
# This allows for:
# header 'Content-Type' => 'text/html'
# header 'Foo' => 'Bar'
# or
# headers 'Content-Type' => 'text/html',
# 'Foo' => 'Bar'
#
# Whatever blows your hair back
def headers(value = nil)
@headers.merge!(value) if value
@headers
end
alias :header :headers
def params
@params ||= @request.params.symbolize_keys
end
def log_event
logger.info "#{request.request_method} #{request.path_info} | Status: #{status} | Params: #{params.inspect}"
logger.exception(error) if error
end
end
class Event
cattr_accessor :logger
cattr_accessor :after_filters
self.after_filters = []
def self.after_attend(filter)
after_filters << filter
end
after_attend :log_event
attr_reader :path, :verb
def initialize(verb, path, register = true, &block)
@verb = verb
@path = path
@block = block
EventManager.register_event(self) if register
end
def attend(request)
context = EventContext.new(request)
begin
context.instance_eval(&@block) if @block
rescue => e
context.error e
end
run_through_after_filters(context)
context
end
alias :call :attend
private
def run_through_after_filters(context)
after_filters.each { |filter| context.send(filter) }
end
end
end