egalite 0.0.1 → 0.0.2

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.
Files changed (33) hide show
  1. data/Gemfile +4 -0
  2. data/LICENSE.txt +22 -0
  3. data/Rakefile +1 -0
  4. data/egalite.gemspec +24 -0
  5. data/lib/egalite/auth/basic.rb +32 -0
  6. data/lib/egalite/blank.rb +53 -0
  7. data/lib/egalite/errorconsole.rb +77 -0
  8. data/lib/egalite/helper.rb +251 -0
  9. data/lib/egalite/keitai/keitai.rb +107 -0
  10. data/lib/egalite/keitai/ketai.rb +11 -0
  11. data/lib/egalite/keitai/rack/ketai/carrier/abstract.rb +131 -0
  12. data/lib/egalite/keitai/rack/ketai/carrier/au.rb +78 -0
  13. data/lib/egalite/keitai/rack/ketai/carrier/docomo.rb +80 -0
  14. data/lib/egalite/keitai/rack/ketai/carrier/emoji/ausjisstrtoemojiid.rb +1391 -0
  15. data/lib/egalite/keitai/rack/ketai/carrier/emoji/docomosjisstrtoemojiid.rb +759 -0
  16. data/lib/egalite/keitai/rack/ketai/carrier/emoji/emojidata.rb +836 -0
  17. data/lib/egalite/keitai/rack/ketai/carrier/emoji/softbankutf8strtoemojiid.rb +1119 -0
  18. data/lib/egalite/keitai/rack/ketai/carrier/emoji/softbankwebcodetoutf8str.rb +499 -0
  19. data/lib/egalite/keitai/rack/ketai/carrier/iphone.rb +8 -0
  20. data/lib/egalite/keitai/rack/ketai/carrier/softbank.rb +82 -0
  21. data/lib/egalite/keitai/rack/ketai/carrier.rb +17 -0
  22. data/lib/egalite/keitai/rack/ketai/middleware.rb +24 -0
  23. data/lib/egalite/m17n.rb +193 -0
  24. data/lib/egalite/route.rb +231 -0
  25. data/lib/egalite/sendmail.rb +222 -0
  26. data/lib/egalite/sequel_helper.rb +20 -0
  27. data/lib/egalite/session.rb +132 -0
  28. data/lib/egalite/stringify_hash.rb +63 -0
  29. data/lib/egalite/support.rb +35 -0
  30. data/lib/egalite/template.rb +287 -0
  31. data/lib/egalite/version.rb +3 -0
  32. data/lib/egalite.rb +744 -0
  33. metadata +35 -3
@@ -0,0 +1,132 @@
1
+
2
+ require 'openssl'
3
+
4
+ module Egalite
5
+ class Session
6
+ attr_accessor :expire_after, :hash, :cookie_name
7
+
8
+ def initialize(env, cookies, opts = {})
9
+ @env = env
10
+ @cookies = cookies
11
+ @cookie_name = opts[:cookie_name] || 'egalite_session'
12
+ @expire_after = opts[:expire_after] || (86400 * 30)
13
+ @secure = opts[:secure] || false
14
+ @path = opts[:path] || '/'
15
+ @hash = {}
16
+ @loaded = false
17
+ end
18
+ def create
19
+ raise NotImplementedError
20
+ end
21
+ def load
22
+ raise NotImplementedError
23
+ end
24
+ def save
25
+ raise NotImplementedError
26
+ end
27
+ def delete
28
+ raise NotImplementedError
29
+ end
30
+ def [](k)
31
+ @hash[k]
32
+ end
33
+ def []=(k,v)
34
+ @hash[k] = v
35
+ end
36
+ end
37
+ class SessionSequel < Session
38
+ def self.create_table(db, opts = {})
39
+ table = opts[:table_name] || :sessions
40
+
41
+ db.create_table(table) {
42
+ primary_key :id, :integer, :auto_increment => true
43
+ column :mac, :varchar
44
+ column :updated_at, :timestamp
45
+ }
46
+ end
47
+
48
+ def initialize(env, cookies, opts = {})
49
+ @db = env.db
50
+ @table = opts[:tablename] || :sessions
51
+
52
+ super(env, cookies, opts)
53
+ end
54
+ def cookie
55
+ {
56
+ :value => @sstr,
57
+ :expires => Time.now + @expire_after,
58
+ :path => @path,
59
+ :secure => @secure
60
+ }
61
+ end
62
+ def sstr
63
+ @sstr
64
+ end
65
+ def _load(_sstr)
66
+ return false unless _sstr and _sstr.size > 0
67
+ (sid,mac) = _sstr.split(/_/)
68
+
69
+ sid = sid.to_i
70
+ return false if sid <= 0
71
+ return false unless mac and mac.size > 0
72
+
73
+ rec = @db[@table][:id => sid]
74
+ return false unless rec and rec[:mac] == mac
75
+
76
+ # timeout check
77
+ updated = rec[:updated_at]
78
+ return false if Time.now > (updated + @expire_after)
79
+
80
+ @sstr = _sstr
81
+ @hash = rec
82
+ @sid = sid
83
+ @mac = mac
84
+ @loaded = true
85
+ @cookies[@cookie_name] = cookie
86
+
87
+ @db[@table].filter(:id => sid).update(:updated_at => 'now')
88
+
89
+ true
90
+ end
91
+ def load_from_param(_sstr)
92
+ _load(_sstr)
93
+ end
94
+ def load
95
+ _sstr = @cookies[@cookie_name]
96
+ _sstr = _sstr[0] if _sstr.is_a?(Array)
97
+ _load(_sstr)
98
+ end
99
+ def create(hash = nil)
100
+ @sid = @db[@table].insert({})
101
+ @mac = OpenSSL::Random.random_bytes(8).unpack('h*')[0]
102
+ hash ||= {}
103
+ @db[@table].filter(:id => @sid).update(hash.merge(:mac => @mac,:updated_at => Time.now))
104
+ @hash = @db[@table][:id => @sid]
105
+
106
+ @sstr = "#@sid" + "_#@mac"
107
+ @cookies[@cookie_name] = cookie
108
+ @loaded = true
109
+
110
+ true
111
+ end
112
+ def delete
113
+ @cookies[@cookie_name] = {
114
+ :value => nil,
115
+ :expires => Time.now - 3600,
116
+ :path => @path,
117
+ :secure => @secure
118
+ }
119
+ @db[@table].filter(:id => @sid).delete
120
+ @loaded = false
121
+ true
122
+ end
123
+ def save
124
+ return false unless @loaded
125
+ [:updated_at, :mac, :id].each { |s| @hash.delete(s) }
126
+ @db[@table].filter(:id => @sid).update(
127
+ {:updated_at => Time.now}.merge(@hash)
128
+ )
129
+ true
130
+ end
131
+ end
132
+ end # module
@@ -0,0 +1,63 @@
1
+ # used with http parameters
2
+ # simpler version of HashWithIndifferentAccess of Ruby on Rails
3
+
4
+ module Egalite
5
+ class StringifyHash < Hash
6
+ def self.create(values)
7
+ hash = self.new
8
+ hash.update(values)
9
+ hash
10
+ end
11
+ def [](k)
12
+ super(stringify(k))
13
+ end
14
+ def []=(k,v)
15
+ super(stringify(k),v)
16
+ end
17
+ def update(hash)
18
+ newhash = {}
19
+ hash.each { |k,v|
20
+ newhash[stringify(k)] = v
21
+ }
22
+ super(newhash)
23
+ end
24
+ alias_method :merge!, :update
25
+
26
+ def key?(key)
27
+ super(stringify(key))
28
+ end
29
+
30
+ alias_method :include?, :key?
31
+ alias_method :has_key?, :key?
32
+ alias_method :member?, :key?
33
+
34
+ def fetch(key, *extras)
35
+ super(stringify(key), *extras)
36
+ end
37
+
38
+ def values_at(*indices)
39
+ indices.collect {|key| self[key]}
40
+ end
41
+
42
+ def dup
43
+ StringifyHash.create(self)
44
+ end
45
+
46
+ def merge(hash)
47
+ dup.update(hash)
48
+ end
49
+
50
+ def delete(key)
51
+ super(stringify(key))
52
+ end
53
+
54
+ # Convert to a Hash with String keys.
55
+ def to_hash
56
+ Hash.new(default).merge(self)
57
+ end
58
+ private
59
+ def stringify(key)
60
+ key.kind_of?(Symbol) ? key.to_s : key
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,35 @@
1
+ # Egalite support methods
2
+
3
+ class Hash
4
+ def <<(b)
5
+ merge(b.to_hash)
6
+ end
7
+ def >>(b)
8
+ b.to_hash.merge(self)
9
+ end
10
+ end
11
+
12
+ class NilClass #:nodoc:
13
+ def size
14
+ 0
15
+ end
16
+ end
17
+
18
+ # <<from ActiveSupport library of Ruby on Rails>>
19
+ # (MIT License)
20
+
21
+ # Tries to send the method only if object responds to it. Return +nil+ otherwise.
22
+ #
23
+ # ==== Example :
24
+ #
25
+ # # Without try
26
+ # @person ? @person.name : nil
27
+ #
28
+ # With try
29
+ # @person.try(:name)
30
+ class Object
31
+ def try(method)
32
+ send(method) if respond_to?(method, true)
33
+ end
34
+ end
35
+
@@ -0,0 +1,287 @@
1
+ require 'jcode'
2
+
3
+ module Egalite
4
+
5
+ class NonEscapeString < String
6
+ def +(b)
7
+ NonEscapeString.new(super(HTMLTagBuilder.escape_html(b)))
8
+ end
9
+ end
10
+
11
+ class HTMLTemplate
12
+ RE_NEST = /<(group|if|unless)\s+name=['"](.+?)['"]>/i
13
+ RE_ENDNEST = /<\/(group|if|unless)>/i
14
+ RE_PLACE = /&=([.-_0-9a-zA-Z]+?);/
15
+ RE_INPUT = /<input\s+(.+?)>/im
16
+ RE_SELECT = /<select\s+name\s*=\s*['"](.+?)['"](.*?)>\s*<\/select>/im
17
+
18
+ RE_A = /<a\s+(.+?)>/im
19
+ RE_FORM = /<form\s+(.+?)>/im
20
+
21
+ RE_INCLUDE = /<include\s+(.+?)\/>/i
22
+ RE_PARENT = /<parent\s+name=['"](.+?)['"]\s*\/>/i
23
+ RE_YIELD = /<yield\/>/i
24
+
25
+ attr_accessor :controller, :default_escape
26
+
27
+ def initialize
28
+ @default_escape = true
29
+ @controller = nil
30
+ end
31
+
32
+ private
33
+
34
+ def parse_tag_attributes(attrs)
35
+ a = attrs.split(/(\:?\w+(!:[^=])|\:?\w+=(?:'[^']+'|"[^"]+"|\S+))\s*/)
36
+ a = a.select { |s| s != "" }
37
+ hash = {}
38
+ a.each { |s|
39
+ b = s.split('=',2)
40
+ b[0].sub!(/\s$/,'')
41
+ b[1] = b[1][1..-2] if b[1] and (b[1][0,1] == '"' or b[1][0,1] == "'")
42
+ hash[b[0]] = b[1] || true
43
+ }
44
+ hash
45
+ end
46
+ def attr_colon(attrs)
47
+ colons = {}
48
+ attrs.each { |k,v| colons[k[1..-1]] = v if k =~ /^\:/ }
49
+ str = attrs.select { |k,v| k !~ /^\:/ }.map { |k,v| "#{k}='#{v}'" }.join(' ')
50
+ [colons, str]
51
+ end
52
+
53
+ def dotchain(values, name)
54
+ dots = name.split('.').select {|s| not s.empty? }
55
+
56
+ value = values
57
+ dots.each { |key|
58
+ value = if not value.is_a?(Hash) and value.respond_to?(key)
59
+ value.send(key)
60
+ elsif value.respond_to?(:[])
61
+ value[key] || value[key.to_sym]
62
+ end
63
+ break unless value
64
+ }
65
+ value
66
+ end
67
+
68
+ #
69
+ # tags
70
+ #
71
+ def placeholder(html, params)
72
+ html.gsub!(RE_PLACE) {
73
+ key = $1
74
+ if params[key].is_a?(NonEscapeString) or not @default_escape
75
+ params[key]
76
+ else
77
+ escapeHTML(params[key])
78
+ end
79
+ }
80
+ end
81
+ def input_tag(html, params)
82
+ html.gsub!(RE_INPUT) { |s|
83
+ attrs = parse_tag_attributes($1)
84
+ next s if attrs['checked'] or attrs['selected']
85
+ name = attrs['name']
86
+ next s unless name
87
+ case attrs['type']
88
+ when 'text'
89
+ next s if attrs['value']
90
+ s.sub!(/\/?>$/," value='"+escapeHTML(params[name])+"'/>") if params[name]
91
+ when 'hidden'
92
+ next s if attrs['value']
93
+ s.sub!(/\/?>$/," value='"+escapeHTML(params[name])+"'/>") if params[name]
94
+ when 'radio'
95
+ s.sub!(/\/?>$/," checked/>") if (params[name].to_s == attrs['value'])
96
+ when 'checkbox'
97
+ s.sub!(/\/?>$/," checked/>") if params[name]
98
+ end
99
+ s
100
+ }
101
+ end
102
+ def a_tag(html, params)
103
+ html.gsub!(RE_A) { |s|
104
+ attrs = parse_tag_attributes($1)
105
+ next s if attrs['href']
106
+ next s unless @controller
107
+
108
+ (colons, noncolons) = attr_colon(attrs)
109
+ next s if colons.empty?
110
+ # when :hoge=$foo, expand hash parameter ['foo']
111
+ colons.each { |k,v|
112
+ next if v[0,1] != '$'
113
+ val = params[v[1..-1]]
114
+ colons[k] = val
115
+ }
116
+ colons = StringifyHash.create(colons)
117
+ link = @controller.url_for(colons)
118
+ "<a href='#{link}' #{noncolons}>"
119
+ }
120
+ end
121
+ def form_tag(html,params)
122
+ html.gsub!(RE_FORM) { |s|
123
+ attrs = parse_tag_attributes($1)
124
+ next s if attrs['action']
125
+ next s unless @controller
126
+
127
+ (colons, noncolons) = attr_colon(attrs)
128
+ next s if colons.empty?
129
+ colons = StringifyHash.create(colons)
130
+ link = @controller.url_for(colons)
131
+ "<form action='#{link}' #{noncolons}>"
132
+ }
133
+ end
134
+ def select_tag(html,params)
135
+ html.gsub!(RE_SELECT) { sel = "<select name='#$1'#$2>"
136
+ if (params[$1] and params[$1].is_a?(Array))
137
+ params[$1].each_index() { |key|
138
+ next if (key == 0)
139
+ selected = " selected" if params[$1][0] == key
140
+ value = params[$1][key]
141
+ sel << "<option value='#{key}'#{selected}>"
142
+ sel << escapeHTML(value)
143
+ sel << "</option>" unless @keitai
144
+ }
145
+ end
146
+ sel << "</select>"
147
+ }
148
+ end
149
+
150
+ #
151
+ # main routines
152
+ #
153
+
154
+ def nonnestedtags(html, params)
155
+ placeholder(html,params)
156
+ input_tag(html,params)
157
+ a_tag(html,params)
158
+ form_tag(html,params)
159
+ select_tag(html,params)
160
+
161
+ # parse include tag
162
+ if block_given?
163
+ html.gsub!(RE_INCLUDE) {
164
+ attrs = parse_tag_attributes($1)
165
+ attrs.each { |k,v| attrs[k[1..-1]] = v if k =~ /^\:/ }
166
+ yield(attrs)
167
+ }
168
+ parent = nil
169
+ md = RE_PARENT.match(html)
170
+ parent = md[1] if md
171
+ html.gsub!(RE_PARENT,"")
172
+ if parent
173
+ txt = yield(parent)
174
+ txt.gsub!(RE_YIELD, html)
175
+ html = txt
176
+ end
177
+ end
178
+ html
179
+ end
180
+
181
+ def keyexpander(params, parent_params)
182
+ lambda { |k|
183
+ if k[0,1] == '.'
184
+ dotchain(params, k)
185
+ else
186
+ if params[k] == nil
187
+ if params[k.to_sym] == nil
188
+ parent_params[k]
189
+ else
190
+ params[k.to_sym]
191
+ end
192
+ else
193
+ params[k]
194
+ end
195
+ end
196
+ }
197
+ end
198
+
199
+ def string_after_outermost_closetag(html)
200
+ while md1 = RE_NEST.match(html)
201
+ break if (RE_ENDNEST.match(md1.pre_match))
202
+ html = string_after_outermost_closetag(md1.post_match)
203
+ end
204
+ RE_ENDNEST.match(html).post_match
205
+ end
206
+
207
+ public
208
+
209
+ def escapeHTML(s)
210
+ s.to_s.gsub(/&/n, '&amp;').gsub(/'/n,'&#039;').gsub(/\"/n, '&quot;').gsub(/>/n, '&gt;').gsub(/</n, '&lt;')
211
+ end
212
+
213
+ def handleTemplate(html, orig_values, parent_params={}, &block)
214
+ params = keyexpander(orig_values, parent_params)
215
+
216
+ # parse group tag and recurse inner loop
217
+ while md1 = RE_NEST.match(html) # beware: complicated....
218
+ # break if it is innermost loop.
219
+ break if (RE_ENDNEST.match(md1.pre_match))
220
+
221
+ # obtain a length of outermost group tag.
222
+ post = string_after_outermost_closetag(md1.post_match)
223
+
224
+ tag = md1[1]
225
+ key = md1[2]
226
+
227
+ # recursive-call for each element of array
228
+ innertext = ""
229
+ case tag.downcase
230
+ when 'group'
231
+ groupval = params[key]
232
+ groupval = [] if (groupval == nil)
233
+ groupval = [groupval] unless (groupval.is_a?(Array))
234
+ groupval.each { |v|
235
+ innertext << handleTemplate(md1.post_match, v, params)
236
+ }
237
+ when 'if'
238
+ unless params[key].blank?
239
+ innertext << handleTemplate(md1.post_match, orig_values, parent_params)
240
+ end
241
+ when 'unless'
242
+ if params[key].blank?
243
+ innertext << handleTemplate(md1.post_match, orig_values, parent_params)
244
+ end
245
+ else
246
+ raise
247
+ end
248
+ # replace this group tag
249
+ html[md1.begin(0)..-(post.size+1)] = innertext
250
+ end
251
+ # cutoff after end tag, in inner-most loop.
252
+ md1 = RE_ENDNEST.match(html)
253
+ html = md1.pre_match if (md1)
254
+
255
+ nonnestedtags(html, params, &block)
256
+ end
257
+ end
258
+
259
+ class CSRFTemplate < HTMLTemplate
260
+ RE_FORM = /<form\s+([^>]+?)>(?!\s*<input type='hidden' name='csrf')/im
261
+
262
+ def form_tag(html,params)
263
+ html.gsub!(RE_FORM) { |s|
264
+ formtag = s
265
+ attrs = parse_tag_attributes($1)
266
+ csrf = nil
267
+ if attrs[":nocsrf"]
268
+ attrs.delete(":nocsrf")
269
+ elsif attrs["method"] =~ /\APOST\Z/i
270
+ csrf = params["csrf"]
271
+ csrf = "<input type='hidden' name='csrf' value='#{escapeHTML(csrf)}'/>"
272
+ end
273
+
274
+ if (not attrs['action']) and @controller
275
+ (colons, noncolons) = attr_colon(attrs)
276
+ unless colons.empty?
277
+ colons = StringifyHash.create(colons)
278
+ link = @controller.url_for(colons)
279
+ formtag = "<form action='#{link}' #{noncolons}>"
280
+ end
281
+ end
282
+ "#{formtag}#{csrf}"
283
+ }
284
+ end
285
+ end
286
+
287
+ end # end module
@@ -0,0 +1,3 @@
1
+ module Egalite
2
+ VERSION = "0.0.2"
3
+ end