rack-flash 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/lib/rack-flash.rb ADDED
@@ -0,0 +1 @@
1
+ require File.join(File.dirname(__FILE__), *%w[rack flash])
data/lib/rack/flash.rb ADDED
@@ -0,0 +1,166 @@
1
+ module Rack
2
+ class Builder
3
+ attr :ins
4
+ def use(middleware, *args, &block)
5
+ middleware.instance_variable_set "@rack_builder", self
6
+ def middleware.rack_builder
7
+ @rack_builder
8
+ end
9
+ @ins << lambda { |app|
10
+ middleware.new(app, *args, &block)
11
+ }
12
+ end
13
+
14
+ def run(app)
15
+ klass = app.class
16
+ klass.instance_variable_set "@rack_builder", self
17
+ def klass.rack_builder
18
+ @rack_builder
19
+ end
20
+ @ins << app #lambda { |nothing| app }
21
+ end
22
+
23
+ def leaf_app
24
+ ins.last
25
+ end
26
+ end
27
+ end
28
+
29
+ module Rack
30
+ class Flash
31
+ # Raised when the session passed to FlashHash initialize is nil. This
32
+ # is usually an indicator that session middleware is not in use.
33
+ class SessionUnavailable < StandardError; end
34
+
35
+ # Implements bracket accessors for storing and retrieving flash entries.
36
+ class FlashHash
37
+ attr_reader :flagged
38
+
39
+ def initialize(store, opts={})
40
+ raise Rack::Flash::SessionUnavailable \
41
+ .new('Rack::Flash depends on session middleware.') unless store
42
+
43
+ @opts = opts
44
+ @store = store
45
+ @store[:__FLASH__] ||= {}
46
+
47
+ if accessors = @opts[:accessorize]
48
+ accessors.each { |opt| def_accessor(opt) }
49
+ end
50
+ end
51
+
52
+ # Remove an entry from the session and return its value. Cache result in
53
+ # the instance cache.
54
+ def [](key)
55
+ key = key.to_sym
56
+ cache[key] ||= values.delete(key)
57
+ end
58
+
59
+ # Store the entry in the session, updating the instance cache as well.
60
+ def []=(key,val)
61
+ key = key.to_sym
62
+ cache[key] = values[key] = val
63
+ end
64
+
65
+ # Store a flash entry for only the current request, swept regardless of
66
+ # whether or not it was actually accessed. Useful for AJAX requests, where
67
+ # you want a flash message, even though you're response isn't redirecting.
68
+ def now
69
+ cache
70
+ end
71
+
72
+ # Checks for the presence of a flash entry without retrieving or removing
73
+ # it from the cache or store.
74
+ def has?(key)
75
+ [cache, values].any? { |store| store.keys.include?(key.to_sym) }
76
+ end
77
+ alias_method :include?, :has?
78
+
79
+ # Mark existing entries to allow for sweeping.
80
+ def flag!
81
+ @flagged = values.keys
82
+ end
83
+
84
+ # Remove flagged entries from flash session, clear flagged list.
85
+ def sweep!
86
+ Array(flagged).each { |key| values.delete(key) }
87
+ flagged.clear
88
+ end
89
+
90
+ # Hide the underlying :__FLASH__ session key and only expose values stored
91
+ # in the flash.
92
+ def inspect
93
+ '#<FlashHash @values=%s @cache=%s>' % [values.inspect, cache.inspect]
94
+ end
95
+
96
+ # Human readable for logging.
97
+ def to_s
98
+ values.inspect
99
+ end
100
+
101
+ private
102
+
103
+ # Maintain an instance-level cache of retrieved flash entries. These
104
+ # entries will have been removed from the session, but are still available
105
+ # through the cache.
106
+ def cache
107
+ @cache ||= {}
108
+ end
109
+
110
+ # Helper to access flash entries from :__FLASH__ session value. This key
111
+ # is used to prevent collisions with other user-defined session values.
112
+ def values
113
+ @store[:__FLASH__]
114
+ end
115
+
116
+ # Generate accessor methods for the given entry key if :accessorize is true.
117
+ def def_accessor(key)
118
+ raise ArgumentError.new('Invalid entry type: %s' % key) if respond_to?(key)
119
+
120
+ class << self; self end.class_eval do
121
+ define_method(key) { |*args| val = args.first; val ? (self[key]=val) : self[key] }
122
+ define_method("#{key}=") { |val| self[key] = val }
123
+ define_method("#{key}!") { |val| cache[key] = val }
124
+ end
125
+ end
126
+ end
127
+
128
+ # -------------------------------------------------------------------------
129
+ # - Rack Middleware implementation
130
+
131
+ def initialize(app, opts={})
132
+ if klass = app_class(app, opts)
133
+ klass.class_eval do
134
+ def flash; env['x-rack.flash'] end
135
+ end
136
+ end
137
+
138
+ @app, @opts = app, opts
139
+ end
140
+
141
+ def call(env)
142
+ env['x-rack.flash'] ||= Rack::Flash::FlashHash.new(env['rack.session'], @opts)
143
+
144
+ if @opts[:sweep]
145
+ env['x-rack.flash'].flag!
146
+ end
147
+
148
+ res = @app.call(env)
149
+
150
+ if @opts[:sweep]
151
+ env['x-rack.flash'].sweep!
152
+ end
153
+
154
+ res
155
+ end
156
+
157
+ private
158
+
159
+ def app_class(app, opts)
160
+ return nil if opts.has_key?(:helper) and not opts[:helper]
161
+ opts[:flash_app_class] ||
162
+ defined?(Sinatra::Base) && Sinatra::Base ||
163
+ self.class.rack_builder.leaf_app.class
164
+ end
165
+ end
166
+ end
@@ -0,0 +1,14 @@
1
+ module Rack
2
+ class Flash
3
+ def self.fake_session
4
+ @fake_session ||= {}
5
+ end
6
+
7
+ alias_method :old_call, :call
8
+ def new_call(env)
9
+ env['rack.session'] ||= Rack::Flash.fake_session
10
+ old_call(env)
11
+ end
12
+ alias_method :call, :new_call
13
+ end
14
+ end
metadata ADDED
@@ -0,0 +1,66 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rack-flash
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Pat Nakajima
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-02-26 00:00:00 -05:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rack
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ description:
26
+ email: patnakajima@gmail.com
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files: []
32
+
33
+ files:
34
+ - lib/rack-flash.rb
35
+ - lib/rack/flash.rb
36
+ - lib/rack/flash/test.rb
37
+ has_rdoc: true
38
+ homepage:
39
+ licenses: []
40
+
41
+ post_install_message:
42
+ rdoc_options: []
43
+
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: "0"
51
+ version:
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ version:
58
+ requirements: []
59
+
60
+ rubyforge_project:
61
+ rubygems_version: 1.3.5
62
+ signing_key:
63
+ specification_version: 2
64
+ summary: Flash hash implementation for Rack apps.
65
+ test_files: []
66
+