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,193 @@
1
+
2
+ module Egalite
3
+ module M17N
4
+
5
+
6
+ module Filters
7
+ def before_filter
8
+ # check hostname first to determine which language to serve.
9
+ first = req.host.split(/\./).first
10
+ @lang = Translation.lang(first)
11
+ if not @lang and req.accept_language and Translation.allow_content_negotiation
12
+ # fallback to Accept-Language HTTP header for language to serve.
13
+ langs = req.accept_language.split(/,/)
14
+ @lang = langs.map { |s| Translation.lang(s.split(/;/).first) }.compact.first
15
+ end
16
+ @lang ||= Translation.lang(Translation.user_default_lang)
17
+ @lang ||= Translation.lang('ja')
18
+
19
+ super
20
+ end
21
+ def filter_on_html_load(html,path)
22
+ html = @lang.translate_html(path, html) if @lang
23
+ super(html,path)
24
+ end
25
+ def after_filter_return_value(response)
26
+ if @lang
27
+ response = @lang.translate_msg(req.controller_class, req.action_method, response)
28
+ end
29
+ super(response)
30
+ end
31
+ def _(str, values = [])
32
+ if @lang
33
+ str = @lang.translate_string(req.controller_class, req.action_method, str, values)
34
+ else
35
+ str = str.dup
36
+ values.each_with_index { |s2,i| str.gsub!(/\{#{i}\}/, s2) }
37
+ end
38
+ str
39
+ end
40
+ end
41
+ class Controller < Egalite::Controller
42
+ include Filters
43
+ end
44
+
45
+
46
+ class Translation
47
+ class <<self
48
+ attr_accessor :langs, :user_default_lang, :allow_content_negotiation
49
+ end
50
+ def self.load(path)
51
+ @@langs = {}
52
+
53
+ s = open(path) { |f| f.read }
54
+
55
+ langs = nil
56
+ system_default = nil
57
+
58
+ [:languages, :system_default, :english_name, :native_name, :aliases].each { |optname|
59
+ s.gsub!(/\{\{#{optname}\s*(.+?)\s*\}\}\s*\n+/i) {
60
+ values = $1.split(/\s*,\s*/)
61
+ case optname
62
+ when :languages
63
+ langs = values
64
+ values.each { |lang|
65
+ @@langs[lang] = Translation.new(lang)
66
+ @@langs[lang].data = {}
67
+ }
68
+ when :system_default
69
+ lang = values.shift
70
+ @@langs[lang] = Translation.new(lang)
71
+ @@langs[lang].data = nil
72
+ system_default = lang
73
+ when :aliases
74
+ lang = values.shift
75
+ @@langs[lang].send("#{optname}=", values)
76
+ else
77
+ lang = values.shift
78
+ @@langs[lang].send("#{optname}=", values.first)
79
+ end
80
+ ''
81
+ }
82
+ }
83
+
84
+ s.split(/###+\s*\n+/).each { |part|
85
+ next if part =~ /\A\s*\Z/
86
+ lines = part.split(/\n+/)
87
+ key = lines.shift
88
+ (type, path) = key.split(/\s+/,2)
89
+ raise "Egalite::M17N::Translation.load: type should be 'html', 'msg' or 'img' but it was '#{type}'" unless %w[msg html img].include?(type)
90
+ lines.each { |line|
91
+ if type == 'img'
92
+ langs.each { |lang|
93
+ next unless @@langs[lang].data
94
+ img = line.sub(/\.(jpg|jpeg|gif|png)/i,"_#{lang}.\\1")
95
+ @@langs[lang].data[:img] ||= {}
96
+ @@langs[lang].data[:img][path] ||= {}
97
+ @@langs[lang].data[:img][path][line] = img
98
+ }
99
+ else
100
+ a = line.split(/\s*\t+\s*/)
101
+ k = nil
102
+ a.each_with_index { |s,i|
103
+ unless @@langs[langs[i]].data
104
+ k = s
105
+ else
106
+ @@langs[langs[i]].data[type.to_sym] ||= {}
107
+ @@langs[langs[i]].data[type.to_sym][path] ||= {}
108
+ @@langs[langs[i]].data[type.to_sym][path][k] = s
109
+ end
110
+ }
111
+ end
112
+ }
113
+ }
114
+ @@langs
115
+ end
116
+ def self.lang(s)
117
+ return nil unless s
118
+ a = @@langs.find { |k,v| v.fullmatch?(s) }
119
+ a ||= @@langs.find { |k,v| v.partialmatch?(s) }
120
+ a ? a.last : nil
121
+ end
122
+ private
123
+ def method_path(c,a)
124
+ c.class.name.to_s + '#' + a.to_s
125
+ end
126
+ def t_string(list, s)
127
+ list[s] ? list[s] : s
128
+ end
129
+ def t_hash(list, h)
130
+ if h.is_a?(EgaliteResponse)
131
+ h.param = t_hash(list, h.param)
132
+ return h
133
+ end
134
+ return h unless h.is_a?(Hash)
135
+ h2 = {}
136
+ h.each { |k,v|
137
+ h2[k] = case v
138
+ when String: t_string(list,v)
139
+ when Array: v.map { |x| t_hash(list,x) }
140
+ when Hash: t_hash(list, v)
141
+ else v
142
+ end
143
+ }
144
+ h2
145
+ end
146
+
147
+ public
148
+
149
+ attr_accessor :english_name, :native_name, :aliases, :data
150
+ attr_reader :langcode
151
+
152
+ def initialize(langcode)
153
+ @langcode = langcode
154
+ @aliases = []
155
+ end
156
+ def fullmatch?(lang)
157
+ lang = lang.to_s.downcase
158
+ @langcode == lang or @aliases.include?(lang)
159
+ end
160
+ def partialmatch?(lang)
161
+ fullmatch?(lang.to_s.split(/-/).first)
162
+ end
163
+ def translate_html(path, html)
164
+ return html unless @data
165
+ list = @data[:html][path]
166
+ return html unless list
167
+ s = html.dup
168
+ list.sort { |a,b| b[0].length <=> a[0].length }.each { |k,v| s.gsub!(k, v)}
169
+ if @data[:img] and @data[:img][path]
170
+ @data[:img][path].each { |k,v| s.gsub!(k, v) }
171
+ end
172
+ s
173
+ end
174
+ def translate_msg(controller, action, msg)
175
+ return msg unless @data
176
+ list = @data[:msg][method_path(controller,action)]
177
+ return msg unless list
178
+ t_hash(list, msg)
179
+ end
180
+ def translate_string(controller, action, string, placeholders = [])
181
+ if @data
182
+ list = @data[:msg][method_path(controller,action)]
183
+ if list
184
+ string = t_string(list, string)
185
+ end
186
+ end
187
+ string = string.dup
188
+ placeholders.each_with_index { |s2,i| string.gsub!(/\{#{i}\}/, s2) }
189
+ string
190
+ end
191
+ end
192
+ end
193
+ end
@@ -0,0 +1,231 @@
1
+ module Egalite
2
+ class Route
3
+ def initialize(route_def)
4
+ @route = route_def
5
+ @controller = nil
6
+ @prefix = nil
7
+ @action = nil
8
+ end
9
+ def self.default_routes
10
+ routes = []
11
+ routes << Route.new([
12
+ [:controller],
13
+ [:controller],
14
+ [:action],
15
+ [:param_arg, :id],
16
+ [:params]
17
+ ])
18
+ routes << Route.new([
19
+ [:controller],
20
+ [:controller],
21
+ [:param_arg, :id],
22
+ [:params]
23
+ ])
24
+ routes << Route.new([
25
+ [:controller],
26
+ [:action],
27
+ [:param_arg, :id],
28
+ [:params]
29
+ ])
30
+ routes << Route.new([
31
+ [:controller],
32
+ [:param_arg, :id],
33
+ [:params]
34
+ ])
35
+ routes << Route.new([
36
+ [:action],
37
+ [:param_arg, :id],
38
+ [:params]
39
+ ])
40
+ routes << Route.new([
41
+ [:param_arg, :id],
42
+ [:params]
43
+ ])
44
+ routes
45
+ end
46
+
47
+
48
+ def match(path)
49
+ path = path.sub(/^\/+/,'')
50
+ pathary = path.to_s.split('/')
51
+ controller = nil
52
+ action = nil
53
+ path_params = []
54
+ params = {}
55
+ prefix = []
56
+ @route.each { |fragment|
57
+ command = fragment[0]
58
+
59
+ case command
60
+ when :controller
61
+ if pathary.empty? and controller
62
+ controller += '/index'
63
+ elsif pathary.empty?
64
+ return nil
65
+ else
66
+ controller += '/' if controller
67
+ controller ||= ''
68
+ controller += pathary.shift
69
+ end
70
+ when :action
71
+ return nil if pathary.empty?
72
+ action = pathary.shift
73
+ when :param
74
+ next if pathary.empty?
75
+ val = pathary.shift
76
+ params[fragment[1]] = val
77
+ prefix << val unless controller
78
+ when :param_arg
79
+ next if pathary.empty?
80
+ val = pathary.shift
81
+ params[fragment[1]] = val if fragment[1]
82
+ path_params << val
83
+ prefix << val unless controller
84
+ when :param_fix
85
+ return nil if pathary[0] != fragment[2]
86
+ params[fragment[1]] = pathary.shift
87
+ prefix << val unless controller
88
+ when :controller_fix
89
+ return nil if pathary[0] != fragment[1]
90
+ controller += '/' if controller
91
+ controller ||= ''
92
+ controller += pathary.shift
93
+ when :params
94
+ path_params += pathary
95
+ pathary = []
96
+ end
97
+ }
98
+ return nil if pathary.size > 0
99
+ @controller = controller
100
+ @action = action
101
+ @path_params = path_params
102
+ @params = params
103
+ @prefix = prefix.join('/')
104
+ [controller, action, path_params, params]
105
+ end
106
+
107
+ def escape(s)
108
+ Rack::Utils.escape(s)
109
+ end
110
+
111
+ def get_path_and_params_from_params(params, current_host = nil, current_port = nil, current_scheme = nil)
112
+ route = @route || []
113
+ pathary = []
114
+ controller_exist = false
115
+ action_exist = false
116
+ contfrags = (@controller || "").to_s.split('/')
117
+
118
+ scheme = nil
119
+ host = nil
120
+ port = nil
121
+ if params[:scheme]
122
+ scheme = params[:scheme].to_s
123
+ params.delete(:scheme)
124
+ end
125
+ if params[:host]
126
+ host = params[:host]
127
+ params.delete(:host)
128
+ end
129
+ if params[:port]
130
+ port = params[:port].to_i
131
+ params.delete(:port)
132
+ end
133
+ if (scheme or port or host)
134
+ raise "get_path_and_params_from_params: current_host is not supplied." unless host or current_host
135
+ scheme = scheme || current_scheme || 'http'
136
+ prefix = "#{scheme}://#{host || current_host}"
137
+ unless (current_scheme == 'http' and current_port == 80) or (current_scheme == 'https' and current_port == 443)
138
+ port ||= current_port
139
+ end
140
+ if port
141
+ unless (scheme == 'http' and port == 80) or (scheme == 'https' and port == 443)
142
+ prefix << ":#{port}"
143
+ end
144
+ end
145
+ end
146
+
147
+ route.each { |fragment|
148
+ command = fragment[0]
149
+
150
+ case command
151
+ when :controller
152
+ next if controller_exist
153
+ if params[:controller] == nil
154
+ pathary += contfrags
155
+ elsif params[:controller] =~ /^\//
156
+ pathary += params[:controller].to_s.split('/')
157
+ else
158
+ pathary += contfrags[0..-2]
159
+ pathary += params[:controller].to_s.split('/')
160
+ end
161
+ controller_exist = pathary.size
162
+ params.delete(:controller)
163
+ when :action
164
+ pathary << (params[:action] || (controller_exist ? nil : @action))
165
+ action_exist = true
166
+ params.delete(:action)
167
+ when :param
168
+ pathary << params[fragment[1]]
169
+ params.delete(fragment[1])
170
+ when :param_arg
171
+ pathary << params[fragment[1]]
172
+ params.delete(fragment[1])
173
+ when :param_fix
174
+ value = params[fragment[1]]
175
+ value = fragment[2] unless value
176
+ pathary << params[fragment[1]]
177
+ params.delete(fragment[1])
178
+ when :controller_fix
179
+ next
180
+ when :params
181
+ ary = (params[:params] || [])
182
+ if ary.respond_to?(:map)
183
+ pathary += ary.map { |s| s.to_s }
184
+ else
185
+ pathary += [ary.to_s]
186
+ end
187
+ params.delete(:params)
188
+ end
189
+ }
190
+ if not action_exist and params[:action]
191
+ if controller_exist
192
+ pathary.insert(controller_exist,params[:action])
193
+ else
194
+ pathary.unshift(params[:action])
195
+ end
196
+ params.delete(:action)
197
+ end
198
+ if not controller_exist and params[:controller]
199
+ pathary.unshift(params[:controller].to_s.split('/')).flatten!
200
+ params.delete(:controller)
201
+ end
202
+ pathary = pathary.compact.map { |frag| escape(frag) }
203
+ path = "/" + pathary.join('/').sub(/\/+$/,'').sub(/^\//,'')
204
+
205
+ [path, params, pathary, prefix]
206
+ end
207
+
208
+ def url_for(params, host = nil, port = nil, scheme = nil)
209
+ (path, params, z, prefix) = get_path_and_params_from_params(params, host, port, scheme)
210
+ if params and params.size > 0
211
+ q = []
212
+ params.each { |k,v|
213
+ if v.is_a?(Hash)
214
+ v.each { |k2,v2|
215
+ next if v2 == nil
216
+ q << "#{escape(k)}[#{escape(k2)}]=#{escape(v2)}"
217
+ }
218
+ else
219
+ q << "#{escape(k)}=#{escape(v)}" if v
220
+ end
221
+ }
222
+ path += "?" + q.join('&') unless q.empty?
223
+ end
224
+ "#{prefix}#{path}"
225
+ end
226
+
227
+ def link_to(title, params, host = nil, port = nil, scheme = nil)
228
+ "<a href='#{url_for(params, host, port, scheme)}'>#{title}</a>"
229
+ end
230
+ end
231
+ end
@@ -0,0 +1,222 @@
1
+
2
+ require 'template'
3
+ require 'nkf'
4
+ require 'time'
5
+
6
+ # mailheaders
7
+ # {
8
+ # :date => Time.new,
9
+ # :from => 'ARAI Shunichi <arai@example.com>', # encoded by Sendmail.address
10
+ # :reply_to => ,
11
+ # :to => 'tanaka@example.com', # encoded by Sendmail.address
12
+ # :cc => '', # encoded by Sendmail.address
13
+ # :bcc => '',
14
+ # :message_id => '',
15
+ # :in_reply_to => '',
16
+ # :references => '',
17
+ # :subject => '',
18
+ # }
19
+
20
+ module Sendmail
21
+ class QualifiedMailbox < String
22
+ end
23
+ class <<self
24
+ @@mock = false
25
+ def mock=(bool)
26
+ @@mock=bool
27
+ end
28
+ def folding(h, s) # folding white space. see RFC5322, section 2.3.3 and 3.2.2.
29
+ len = 78 - h.size - ": ".size
30
+ len2nd = 78 - " ".size
31
+ lines = []
32
+ line = ""
33
+ s.strip.split(/\s+/).each { |c| # each word (according to gmail's behavior)
34
+ if (line+c).size > len
35
+ len = len2nd
36
+ lines << line.strip
37
+ line = c + " "
38
+ else
39
+ line << c + " "
40
+ end
41
+ }
42
+ lines << line.strip if line.size > 0
43
+ lines.join("\n ")
44
+ end
45
+ def multibyte_folding(h, s, encoding = 'UTF-8') # RFC2047
46
+ bracketsize = "=?#{encoding}?B??=".size
47
+ len = 76 - h.size - ": ".size - bracketsize
48
+ len2nd = 76 - bracketsize
49
+ lines = []
50
+ line = ""
51
+ s = s.gsub(/\s+/, ' ').strip
52
+ s.split(//).each { |c| # each character (including multi-byte ones)
53
+ teststr = line+c
54
+ teststr = NKF.nkf('-Wj',teststr) if encoding =~ /iso-2022-jp/i
55
+ if [teststr].pack('m').chomp.size > len
56
+ len = len2nd
57
+ lines << line
58
+ line = c
59
+ else
60
+ line << c
61
+ end
62
+ }
63
+ lines << line if line.size > 0
64
+ lines = lines.map { |s| "=?#{encoding}?B?#{[s].pack('m').gsub(/\n/,'')}?=" }
65
+ lines.join("\n ")
66
+ end
67
+ def vchar(s)
68
+ s.gsub(/[\x00-\x1f\x7f]/,'')
69
+ end
70
+ def wsp(s)
71
+ s.gsub(/\s+/,' ')
72
+ end
73
+ def quote_string(s)
74
+ '"' + vchar(wsp(s)).gsub(/\\/,"\\\\\\").gsub(/\"/,'\\\"') + '"'
75
+ end
76
+ def multibyte?(s)
77
+ s.each_byte.any? { |c| c > 0x7f }
78
+ end
79
+ def encode_phrase(header, s)
80
+ if multibyte?(s)
81
+ multibyte_folding(header, s)
82
+ else
83
+ folding(header, quote_string(s))
84
+ end
85
+ end
86
+ def encode_unstructured(header, s)
87
+ if multibyte?(s)
88
+ multibyte_folding(header, s)
89
+ else
90
+ folding(header, vchar(wsp(s)))
91
+ end
92
+ end
93
+ def atext; '[0-9a-zA-Z!#$%&\'*+\-/=?\^_`{|}~]'; end
94
+ def atext_loose; '[0-9a-zA-Z!#$%&\'*+\-/=?\^_`{|}~.]'; end
95
+
96
+ def check_domain(s)
97
+ s =~ /\A#{atext}+?(\.#{atext}+?)+\Z/
98
+ end
99
+ def check_local_loose(s)
100
+ s =~ /\A#{atext_loose}+\Z/
101
+ end
102
+ def parse_addrspec(addrspec)
103
+ # no support for CFWS, FWS, and domain-literal.
104
+ if addrspec[0,1] == '"' # quoted-string
105
+ addrspec =~ /\A(\".*?[^\\]\")\@(.+)\Z/
106
+ (local, domain) = [$1, $2]
107
+ return nil if local =~ /[\x00-\x1f\x7f]/
108
+ return nil unless check_domain(domain)
109
+ [local, domain]
110
+ else
111
+ (local, domain) = addrspec.split(/@/,2)
112
+ return nil unless check_local_loose(local)
113
+ return nil unless check_domain(domain)
114
+ [local, domain]
115
+ end
116
+ end
117
+ def address(addrspec, name = nil, header='Reply-to')
118
+ # mailbox in RFC5322 section 3.4. not 'address' as in RFC.
119
+ raise 'invalid mail address.' unless parse_addrspec(addrspec)
120
+ if name and name.size > 0
121
+ QualifiedMailbox.new(folding(header, "#{encode_phrase(header, name)} <#{addrspec}>"))
122
+ else
123
+ addrspec
124
+ end
125
+ end
126
+ def mailboxlist(value, header = 'Reply-to')
127
+ case value
128
+ when QualifiedMailbox: value
129
+ when String: parse_addrspec(value) ? value : nil
130
+ when Hash: address(value[:address],value[:name],header)
131
+ when Array
132
+ folding(header, value.map { |v|
133
+ v.is_a?(Array) ? address(v[0],v[1]) : mailboxlist(v,header)
134
+ }.join(', '))
135
+ else
136
+ nil
137
+ end
138
+ end
139
+ def message(body, params)
140
+ headers = {}
141
+
142
+ raise "From must be exist." unless params[:from]
143
+ raise "The number of sender must be zero or one." if params[:sender].is_a?(Array) and params[:sender].size > 1
144
+ raise "When the number of 'from' is more than one, sender must be exist" if params[:from].is_a?(Array) and params[:from].size > 1 and not params[:sender]
145
+
146
+ %w[From To Sender Reply-To Cc].each { |s|
147
+ v = params[s.gsub(/-/,'_').downcase.to_sym]
148
+ headers[s] = mailboxlist(v,s) if v and v.size >= 1
149
+ }
150
+
151
+ headers["Subject"] = encode_unstructured("Subject",params[:subject].to_s) if params[:subject]
152
+ headers["MIME-Version"] = "1.0"
153
+ date = params[:date] || Time.now
154
+ headers["Date"] = date.is_a?(Time) ? date.rfc822 : date
155
+ headers["Content-Type"] = "text/plain; charset=UTF-8"
156
+
157
+ if multibyte?(body)
158
+ headers["Content-Transfer-Encoding"] = "base64"
159
+ body = [body].pack('m')
160
+ else
161
+ headers["Content-Transfer-Encoding"] = "7bit"
162
+ end
163
+
164
+ text = [headers.map{|k,v| "#{k}: #{v}"}.join("\n"),body].join("\n\n")
165
+ end
166
+ private
167
+ def _extract_addrspec(value)
168
+ case value
169
+ when QualifiedMailbox
170
+ value =~ /<(#{atext_loose}+?@#{atext_loose}+?)>\Z/
171
+ $1
172
+ when String: parse_addrspec(value) ? value : nil
173
+ when Hash: parse_addrspec(value[:address]) ? value[:address] : nil
174
+ when Array
175
+ value.map { |v|
176
+ if v.is_a?(Array)
177
+ parse_addrspec(v[0]) ? v[0] : nil
178
+ else
179
+ _extract_addrspec(v)
180
+ end
181
+ }
182
+ else nil
183
+ end
184
+ end
185
+ public
186
+ def to_addresses(params)
187
+ addresses = [:to, :cc, :bcc].map { |s|
188
+ _extract_addrspec(params[s])
189
+ }
190
+ addresses.flatten.compact.uniq
191
+ end
192
+ def _send(text, envelope_from, to, host = 'localhost')
193
+ if @@mock
194
+ @@lastmail = [text, envelope_from, to, host]
195
+ else
196
+ Net::SMTP.start(host) { |smtp|
197
+ smtp.send_message(text, envelope_from, to)
198
+ }
199
+ end
200
+ end
201
+ def lastmail
202
+ @@lastmail if @@lastmail
203
+ end
204
+ def send(body, params, host = 'localhost')
205
+ _send(
206
+ message(body, params),
207
+ _extract_addrspec(params[:envelope_from] || params[:sender] || params[:from]),
208
+ to_addresses(params),
209
+ host
210
+ )
211
+ end
212
+ def send_with_template(filename, params, host = 'localhost')
213
+ File.open("mail/"+ filename ,"r") { |f|
214
+ text = f.read
215
+ tengine = Egalite::HTMLTemplate.new
216
+ tengine.default_escape = false
217
+ text = tengine.handleTemplate(text,params)
218
+ send(text, params, host)
219
+ }
220
+ end
221
+ end
222
+ end
@@ -0,0 +1,20 @@
1
+
2
+ class Sequel::Model
3
+ def update_with(hash, *selection)
4
+ data = {}
5
+ selection.flatten.each { |k| data[k] = hash[k] || hash[k.to_sym] }
6
+ update(data)
7
+ end
8
+ def update_without(hash, *selection)
9
+ hash = hash.clone
10
+ selection.flatten.each { |k| hash.delete(k.to_s) if hash.key?(k.to_s) }
11
+ selection.flatten.each { |k| hash.delete(k.to_sym) if hash.key?(k.to_sym) }
12
+ update(hash)
13
+ end
14
+ def to_hash
15
+ hash = {}
16
+ self.each { |k,v| hash[k] = v }
17
+ hash
18
+ end
19
+ end
20
+