kiss 0.9

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.
@@ -0,0 +1,166 @@
1
+ require 'base64'
2
+
3
+ class Kiss
4
+ # Session store using Sequel.
5
+ class SequelSession
6
+
7
+ # set_schema do
8
+ # primary_key :id
9
+ # varchar :session_id
10
+ # text :data
11
+ # timestamp :created_at
12
+ # timestamp :updated_at
13
+ # end
14
+
15
+ attr_accessor :needs_new_cookie
16
+
17
+ class << self
18
+ def setup_storage(controller)
19
+ unless controller.db.table_exists?(:sessions)
20
+ controller.db.create_table :sessions do
21
+ primary_key :id, :null => false
22
+ column :session_id, :varchar, :null => false
23
+ column :data, :text
24
+ column :created_at, :timestamp, :null => false
25
+ column :updated_at, :timestamp, :null => false
26
+ index :session_id
27
+ end
28
+
29
+ # db << <<-EOT
30
+ # CREATE TABLE `sessions` (
31
+ # `id` int(11) NOT NULL auto_increment,
32
+ # `session_id` varchar(255) default NULL,
33
+ # `data` text,
34
+ # `created_at` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
35
+ # `updated_at` timestamp NOT NULL default '0000-00-00 00:00:00',
36
+ # PRIMARY KEY (`id`)
37
+ # );
38
+ # EOT
39
+ end
40
+ end
41
+
42
+ def rand_uuid
43
+ values = [
44
+ rand(0x0010000),
45
+ rand(0x0010000),
46
+ rand(0x0010000),
47
+ rand(0x0010000),
48
+ rand(0x0010000),
49
+ rand(0x1000000),
50
+ rand(0x1000000),
51
+ ]
52
+ "%04x%04x%04x%04x%04x%06x%06x" % values
53
+ end
54
+
55
+ # Generates a new session ID and creates a row for the new session in the database.
56
+ def generate
57
+ new(Sequel::Model(:sessions).create(
58
+ :session_id => rand_uuid,
59
+ :data => marshal({}),
60
+ :created_at => Time.now,
61
+ :updated_at => Time.now
62
+ ))
63
+ end
64
+
65
+ # Gets the existing session based on the <tt>session_id</tt> available in cookies.
66
+ # If none is found, generates a new session.
67
+ def persist(session_id)
68
+ if session_id
69
+ if object = Sequel::Model(:sessions).where(:session_id => session_id).first
70
+ session = new( object )
71
+ end
72
+ end
73
+ unless session
74
+ session = generate
75
+ end
76
+ session
77
+ end
78
+
79
+ # Don't try to reload ARStore::Session in dev mode.
80
+ def reloadable? #:nodoc:
81
+ false
82
+ end
83
+
84
+ # good
85
+ def marshal(data)
86
+ Base64.encode64(Marshal.dump(data)) if data
87
+ end
88
+
89
+ # good
90
+ def unmarshal(data)
91
+ Marshal.load(Base64.decode64(data)) if data
92
+ end
93
+ end
94
+
95
+ def initialize(object)
96
+ @object = object
97
+ @data = self.class.unmarshal(@object[:data]) || {}
98
+ end
99
+
100
+ def values(*args)
101
+ @object.values(*args)
102
+ end
103
+
104
+ # Regenerate the Session ID
105
+ def regenerate
106
+ @object.update_attributes(:session_id => Kiss::SessionMixin::rand_uuid)
107
+ @needs_new_cookie = true
108
+ end
109
+
110
+ # Recreates the cookie with the default expiration time
111
+ # Useful during log in for pushing back the expiration date
112
+ def refresh_expiration
113
+ @needs_new_cookie = true
114
+ end
115
+
116
+ # good
117
+ # Lazy-delete of session data
118
+ def delete(key = nil)
119
+ key ? self.data.delete(key) : self.data.clear
120
+ end
121
+
122
+ # good
123
+ def [](key)
124
+ data[key]
125
+ end
126
+
127
+ # good
128
+ def []=(key, val)
129
+ data[key] = val
130
+ end
131
+
132
+ # good
133
+ def empty?
134
+ data.empty?
135
+ end
136
+
137
+ # good
138
+ def each(&b)
139
+ data.each(&b)
140
+ end
141
+
142
+ # good
143
+ # Lazy-unmarshal session state.
144
+ def data
145
+ @data
146
+ end
147
+
148
+ # good
149
+ # Has the session been loaded yet?
150
+ def loaded?
151
+ !! @data
152
+ end
153
+
154
+ # good
155
+ def save
156
+ @object[:data] = self.class.marshal(self.data)
157
+ @object[:updated_at] = Time.now
158
+ @object.save
159
+ end
160
+
161
+ private
162
+
163
+ attr_writer :data
164
+
165
+ end
166
+ end
@@ -0,0 +1,125 @@
1
+ class Kiss
2
+ module TemplateMethods
3
+ include Kiss::ControllerAccessors
4
+
5
+ # Contains data set by action/mailer logic to be displayed in templates.
6
+ def data
7
+ @data
8
+ end
9
+ alias_method :vars, :data
10
+
11
+ # Merges specified data (key-value pairs) into template data hash.
12
+ def set(vars)
13
+ vars.each_pair do |key,value|
14
+ # convert symbols to strings
15
+ @data[key.to_s] = value
16
+ end
17
+ end
18
+
19
+ # Shorthand to access vars.title, here for backward compatibility.
20
+ # Note: @title is deprecated for use in templates and will not be
21
+ # supported in Kiss 1.0. Use title and title= instead.
22
+ def title
23
+ vars.title
24
+ end
25
+
26
+ # Shorthand to set vars.title, here for backward compatibility.
27
+ # Note: @title is deprecated for use in templates and will not be
28
+ # supported in Kiss 1.0. Use title and title= instead.
29
+ def title=(new_title)
30
+ vars.title = new_title
31
+ @title = new_title
32
+ end
33
+
34
+ # Returns value of next layout file, which will be used to wrap the
35
+ # results of current rendering template.
36
+ # Note: @layout is deprecated for use in templates and will not be
37
+ # supported in Kiss 1.0. Use layout and layout= instead.
38
+ def layout
39
+ # @layout deprecated; future will be action.layout
40
+ @layout
41
+ end
42
+
43
+ # Sets path to next layout file, which will be used to wrap the
44
+ # results of current rendering template.
45
+ # Note: @layout is deprecated for use in templates and will not be
46
+ # supported in Kiss 1.0. Use layout and layout= instead.
47
+ def layout=(new_layout)
48
+ # @layout deprecated; future will be action.layout
49
+ @layout = new_layout
50
+ end
51
+
52
+ # Reads file specified by options and return contents (without template
53
+ # processing).
54
+ def insert(options = {})
55
+ path = get_template_path(options)
56
+ content = File.read(path)
57
+ end
58
+
59
+ # Processes template specified by options and return results.
60
+ def process(options = {})
61
+ path = get_template_path(options)
62
+ content = erubis(path,binding)
63
+ end
64
+
65
+ # Gets path to insert/template file from specified options.
66
+ def get_template_path(options)
67
+ @current_template_dir ||= @template_dir
68
+
69
+ path = options.is_a?(String) ? options : "#{options[:template]}.#{options[:extension] || 'rhtml'}"
70
+ path = path =~ /\A\// ? "#{@template_dir}#{path}" : "#{@current_template_dir}/#{path}"
71
+
72
+ path
73
+ end
74
+
75
+ # Processes specified template file using specified binding.
76
+ # content is used to pass previously rendered results into
77
+ # wrapper templates such as layouts.
78
+ def erubis(path,template_binding = binding,content = nil)
79
+ # params note: content (if provided) is passed to erubis template via binding
80
+
81
+ # set template dir to dir that contains this template
82
+ @current_template_dir ||= @template_dir
83
+ old_template_dir = @current_template_dir
84
+ @current_template_dir = path.sub(/\/?[^\/]*\Z/,'')
85
+
86
+ eruby_src = file_cache(path,'template') do |template|
87
+ # macros
88
+ template.gsub!(/\<\%\s*macro\s+(\w+.*?)\s*\%\>/,'<% def \1; _buf = \'\' %>')
89
+ template.gsub!(/\<\%\s*end\s+macro\s*\%\>/,'<% _buf; end %>')
90
+
91
+ # for loop iterator
92
+ template.gsub!(/\<\%\s*for\s+(\w+)\s+in\s+(.*?)\s*\%\>/,'<% loop = Kiss::Iterator.new(\2); for \1 in loop.collection; loop.increment %>')
93
+ # while loop iterator
94
+ template.gsub!(/\<\%\s*while\s+(.*?)\s*\%\>/,'<% loop = Kiss::Iterator.new; while \1; loop.increment %>')
95
+
96
+ Erubis::Eruby.new(template).src
97
+ end
98
+ result = eval eruby_src, template_binding, path
99
+
100
+ # restore previous template dir
101
+ @template_dir = old_template_dir
102
+
103
+ result
104
+ end
105
+
106
+ # Escapes string for use in URLs.
107
+ def url_encode(string)
108
+ # don't encode to hex: letters, numbers, periods, spaces
109
+ # encode space to +
110
+ string.gsub(/([^A-Za-z0-9\.])/) { sprintf("%%%02X", $&.unpack("C")[0]) }
111
+ end
112
+ alias_method :escape, :url_encode
113
+ alias_method :h, :url_encode
114
+
115
+ # Encodes string for output to HTML.
116
+ def escape_html(str)
117
+ Rack::Utils.escape_html(str)
118
+ end
119
+
120
+ # Formats number to two decimal places.
121
+ def currency(num)
122
+ sprintf("%0.2f",num.to_f)
123
+ end
124
+ end
125
+ end