keight 0.0.1

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 (46) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +263 -0
  4. data/Rakefile +92 -0
  5. data/bench/bench.rb +278 -0
  6. data/bench/benchmarker.rb +502 -0
  7. data/bin/k8rb +496 -0
  8. data/keight.gemspec +36 -0
  9. data/lib/keight/skeleton/.gitignore +10 -0
  10. data/lib/keight/skeleton/app/action.rb +98 -0
  11. data/lib/keight/skeleton/app/api/hello.rb +39 -0
  12. data/lib/keight/skeleton/app/form/.keep +0 -0
  13. data/lib/keight/skeleton/app/helper/.keep +0 -0
  14. data/lib/keight/skeleton/app/model/.keep +0 -0
  15. data/lib/keight/skeleton/app/model.rb +144 -0
  16. data/lib/keight/skeleton/app/page/welcome.rb +17 -0
  17. data/lib/keight/skeleton/app/template/_layout.html.eruby +56 -0
  18. data/lib/keight/skeleton/app/template/welcome.html.eruby +6 -0
  19. data/lib/keight/skeleton/app/usecase/.keep +0 -0
  20. data/lib/keight/skeleton/config/app.rb +29 -0
  21. data/lib/keight/skeleton/config/app_dev.private +11 -0
  22. data/lib/keight/skeleton/config/app_dev.rb +8 -0
  23. data/lib/keight/skeleton/config/app_prod.rb +7 -0
  24. data/lib/keight/skeleton/config/app_stg.rb +5 -0
  25. data/lib/keight/skeleton/config/app_test.private +11 -0
  26. data/lib/keight/skeleton/config/app_test.rb +8 -0
  27. data/lib/keight/skeleton/config/server_puma.rb +22 -0
  28. data/lib/keight/skeleton/config/server_unicorn.rb +21 -0
  29. data/lib/keight/skeleton/config/urlpath_mapping.rb +16 -0
  30. data/lib/keight/skeleton/config.rb +44 -0
  31. data/lib/keight/skeleton/config.ru +21 -0
  32. data/lib/keight/skeleton/index.txt +38 -0
  33. data/lib/keight/skeleton/static/lib/jquery/1.11.3/jquery.min.js +6 -0
  34. data/lib/keight/skeleton/static/lib/jquery/1.11.3/jquery.min.js.gz +0 -0
  35. data/lib/keight/skeleton/static/lib/modernizr/2.8.3/modernizr.min.js +4 -0
  36. data/lib/keight/skeleton/static/lib/modernizr/2.8.3/modernizr.min.js.gz +0 -0
  37. data/lib/keight/skeleton/tmp/upload/.keep +0 -0
  38. data/lib/keight.rb +2017 -0
  39. data/test/data/example1.jpg +0 -0
  40. data/test/data/example1.png +0 -0
  41. data/test/data/multipart.form +0 -0
  42. data/test/data/wabisabi.js +77 -0
  43. data/test/data/wabisabi.js.gz +0 -0
  44. data/test/keight_test.rb +3161 -0
  45. data/test/oktest.rb +1537 -0
  46. metadata +114 -0
data/bin/k8rb ADDED
@@ -0,0 +1,496 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- coding: utf-8 -*-
3
+
4
+ ###
5
+ ### $Release: 0.0.1 $
6
+ ### $Copyright: copyright(c) 2014-2015 kuwata-lab.com all rights reserved $
7
+ ### $License: MIT License $
8
+ ###
9
+
10
+
11
+ require 'digest/sha1'
12
+
13
+ require 'keight'
14
+ require 'baby_erubis'
15
+
16
+
17
+ module K8
18
+
19
+
20
+ class Main
21
+
22
+ @__current = nil
23
+ @__actions = []
24
+
25
+ @action = proc do |action_name, desc|
26
+ options = []
27
+ method_name = nil
28
+ tuple = [action_name, desc, options, method_name]
29
+ @__current = tuple
30
+ @__actions << tuple
31
+ end
32
+
33
+ @option = proc do |optdef_str, desc|
34
+ tuple = @__current or
35
+ raise "@option.() is called without @action.()"
36
+ tuple[2] << [optdef_str, desc]
37
+ end
38
+
39
+ def self.method_added(method_name)
40
+ tuple = @__current or return
41
+ tuple[3] = method_name
42
+ @__current = nil
43
+ end
44
+
45
+ def self.find_action(name)
46
+ name = name.to_s
47
+ return @__actions.find {|tuple| tuple[0].to_s == name }
48
+ end
49
+
50
+ def self.each_action(&block)
51
+ @__actions.each(&block)
52
+ end
53
+
54
+
55
+ ###
56
+
57
+ def initialize(script_name=nil)
58
+ @script_name = script_name || File.basename($0) # ex: 'k8rb'
59
+ end
60
+
61
+ attr_reader :script_name
62
+
63
+
64
+ ### actions
65
+
66
+ @action.(:help, "show help")
67
+ def do_help(action_name=nil)
68
+ script = self.script_name
69
+ sb = []
70
+ if action_name.nil?
71
+ sb << "Usage:"
72
+ sb << " #{script} ACTION [..OPTIONS..]"
73
+ sb << ""
74
+ sb << "Actions:"
75
+ self.class.each_action do |action_name, desc, options, _|
76
+ next unless desc
77
+ help = desc.lines.first.chomp()
78
+ sb << " #{script} %-15s # #{help}" % [action_name, help]
79
+ end
80
+ sb << ""
81
+ sb << "(Tips: try '#{script} help ACTION' for details of each action.)"
82
+ else
83
+ tuple = self.class.find_action(action_name) or
84
+ raise K8::OptionError.new("help #{action_name}: no such action.")
85
+ action_name, desc, options, method_name = tuple
86
+ pnames = self.method(method_name).parameters.collect {|kind, pname|
87
+ case kind
88
+ when :req ; pname
89
+ when :opt ; "[#{pname}]"
90
+ when :rest ; "[#{pname}...]"
91
+ when :key ; nil
92
+ else
93
+ raise "** kind=#{kind.inspect}, pname=#{pname.inspect}"
94
+ end
95
+ }.compact()
96
+ pnames.unshift('') unless pnames.empty?
97
+ argstr = pnames.join(' ')
98
+ sb << "#{script} #{action_name} - #{desc}"
99
+ sb << ""
100
+ sb << "Usage:"
101
+ if options.empty?
102
+ sb << " #{script} #{action_name}#{argstr}"
103
+ else
104
+ sb << " #{script} #{action_name} [options]#{argstr}"
105
+ sb << ""
106
+ sb << "Options:"
107
+ options.each do |optdef_str, optdesc|
108
+ optstr = optdef_str.sub(/\A\s*--/, ' --').sub(/\s+\#\w+\s*\z/, '')
109
+ sb << " %-20s # %s" % [optstr, optdesc] if optdesc
110
+ end
111
+ end
112
+ end
113
+ sb << ""
114
+ sb << ""
115
+ return sb.join("\n")
116
+ end
117
+
118
+ @action.(:init, "create project files")
119
+ @option.("-s, --skeleton=DIR", "directory of skeleton files")
120
+ def do_init(project_name, dir: nil)
121
+ dir ||= K8::FILEPATH.sub(/\.rb\z/, '') + "/skeleton"
122
+ if dir
123
+ File.directory?(dir) or
124
+ raise "#{dir}: directory not exist."
125
+ o = K8::FileTool.new
126
+ descs = o.parse_index_file("#{dir}/index.txt")
127
+ o.mkdir(project_name, "project root directory")
128
+ files = Dir.glob("#{dir}/**/*")
129
+ files.concat(["#{dir}/.gitignore"])
130
+ files.each do |path|
131
+ base = path[(dir.length+1)..-1]
132
+ if base == "index.txt"
133
+ next
134
+ elsif base =~ /\/\.keep\z/
135
+ next
136
+ elsif File.directory?(path)
137
+ o.mkdir("#{project_name}/#{base}", descs[base+"/"])
138
+ elsif File.file?(path)
139
+ content = path =~ /\Astatic\/lib|\.gz\z/ \
140
+ ? File.read(path, encoding: 'ascii-8bit') \
141
+ : K8::SkeletonTemplate.new.from_file(path, 'ascii-8bit').render()
142
+ o.mkfile("#{project_name}/#{base}", content, descs[base])
143
+ else
144
+ next
145
+ end
146
+ end
147
+ return
148
+ end
149
+ 0
150
+ end
151
+
152
+ @action.(:mapping, "show action mappings")
153
+ def do_mapping()
154
+ ENV['APP_MODE'] ||= 'dev'
155
+ load_config()
156
+ require './config/urlpath_mapping'
157
+ app = K8::RackApplication.new
158
+ $urlpath_mapping.each do |urlpath, children|
159
+ app.mount(urlpath, children)
160
+ end
161
+ return app.show_mappings()
162
+ end
163
+
164
+ @action.(:configs, "list config keys and values")
165
+ @option.("--getenv", "show actual ENV value")
166
+ def do_configs(getenv: false)
167
+ ENV['APP_MODE'] ||= 'dev'
168
+ load_config()
169
+ s = ""
170
+ ::Config.each do |key, val, desc, secret|
171
+ kv = "%-20s = %s" % [key, __var_dump(val, secret, getenv)]
172
+ s << ("%-43s # %s\n" % [kv, desc]) if desc
173
+ end
174
+ return s
175
+ end
176
+
177
+ @action.(:config, "show config value")
178
+ @option.("--getenv", "show actual ENV value")
179
+ def do_config(key, getenv: false)
180
+ key_name = key
181
+ ENV['APP_MODE'] ||= 'dev'
182
+ load_config()
183
+ ::Config.each do |key, val, desc, secret|
184
+ if key.to_s == key_name
185
+ return __var_dump(val, secret, getenv)
186
+ end
187
+ end
188
+ $stderr.puts "#{key_name}: no such config key."
189
+ return 1
190
+ end
191
+
192
+ @action.(:'config:check', "check config values")
193
+ def do_config_check()
194
+ ENV['APP_MODE'] ||= 'dev'
195
+ load_config()
196
+ not_set = []
197
+ not_env = []
198
+ ::Config.each do |key, val, desc, secret|
199
+ if val.is_a?(K8::SecretValue)
200
+ if ! val.name
201
+ not_set << [key, val, desc]
202
+ elsif ! ENV[val.name]
203
+ not_env << [key, val, desc]
204
+ end
205
+ end
206
+ end
207
+ if not_set.empty? && not_env.empty?
208
+ puts "ok."
209
+ return 0
210
+ else
211
+ sb = []
212
+ sb << "**"
213
+ sb << "** NG!"
214
+ unless not_set.empty?
215
+ sb << "**"
216
+ sb << "** The following configs should be set, but not."
217
+ sb << "**"
218
+ not_set.each do |key, val, desc|
219
+ sb << "** %-20s = %s" % [key, val.inspect]
220
+ end
221
+ end
222
+ unless not_env.empty?
223
+ sb << "**"
224
+ sb << "** The following configs expect environment variable, but not set."
225
+ sb << "**"
226
+ not_env.each do |key, val, desc|
227
+ sb << "** %-20s = %s" % [key, val.inspect]
228
+ end
229
+ end
230
+ sb << "**"
231
+ puts sb.join("\n")
232
+ return 1
233
+ end
234
+ end
235
+
236
+ def __var_dump(val, secret, getenv)
237
+ if ! val.is_a?(K8::SecretValue)
238
+ #secret ? '<secret>' : val.inspect
239
+ val.inspect
240
+ elsif val.name
241
+ getenv ? ENV[val.name].inspect : "ENV['#{val.name}']"
242
+ else
243
+ '<SECRET>'
244
+ end
245
+ end
246
+ private :__var_dump
247
+
248
+
249
+ if ENV['DEBUG']
250
+ @action.(:debug, "debug")
251
+ @option.("-h, --help" , "show help message")
252
+ @option.("--version" , "print version")
253
+ #@option.("-f, --file=FILE" , "filename")
254
+ @option.("-f FILE #file" , "filename")
255
+ @option.("-i, --indent[=N]" , "indent depth (default 2)")
256
+ @option.("-s" , "be silent")
257
+ @option.("-S #silent" , "be silent")
258
+ @option.("-d[N] #dbg1" , "debug level #1")
259
+ @option.(" --dbg2[=N]" , "debug level #2")
260
+ def do_debug(argmnt=nil, help: nil, version: nil, file: nil, indent: nil, s: nil, silent: false, dbg1: nil, dbg2: nil)
261
+ sb = []
262
+ sb << "** argmnt = #{argmnt.inspect}"
263
+ sb << "** help: #{help.inspect}"
264
+ sb << "** version: #{version.inspect}"
265
+ sb << "** file: #{file.inspect}"
266
+ sb << "** indent: #{indent.inspect}"
267
+ sb << "** s: #{s.inspect}"
268
+ sb << "** silent: #{silent.inspect}"
269
+ sb << "** dbg1: #{dbg1.inspect}"
270
+ sb << "** dbg2: #{dbg2.inspect}"
271
+ return sb.join("\n")
272
+ end
273
+ end
274
+
275
+
276
+ ###
277
+
278
+ def load_config
279
+ require './config' rescue K8::ConfigError
280
+ end
281
+
282
+ def run(*cmd_args)
283
+ action_name = cmd_args.shift() || 'help'
284
+ tuple = self.class.find_action(action_name) or
285
+ raise K8::OptionError.new("#{action_name}: unknown action.")
286
+ action_name, desc, options, method_name = tuple
287
+ optdefs = options.collect {|arr| K8::OptionDefinition.new(*arr) }
288
+ optparser = K8::OptionParser.new(optdefs)
289
+ cmd_opts = optparser.parse(cmd_args)
290
+ func_args = []
291
+ func_kwds = {}
292
+ method_params = self.method(method_name).parameters
293
+ method_params.each do |param_info|
294
+ kind, pname = param_info
295
+ case kind
296
+ when :req
297
+ ! cmd_args.empty? or
298
+ raise K8::OptionError.new("#{action_name}: argument '#{pname}' required.")
299
+ func_args << cmd_args.shift()
300
+ when :opt
301
+ func_args << cmd_args.shift() # may be nil
302
+ when :rest
303
+ func_args.concat(cmd_args)
304
+ cmd_args.clear()
305
+ when :key
306
+ k = pname.to_s
307
+ func_kwds[pname] = cmd_opts.delete(k) if cmd_opts.key?(k)
308
+ if cmd_opts.key?(pname.to_s)
309
+ func_kwds[pname] = cmd_opts.delete(pname.to_s)
310
+ end
311
+ else
312
+ $stderr.puts "*** internal error: kind=#{kind.inspect}, pname=#{pname.inspect}"
313
+ end
314
+ end
315
+ cmd_args.empty? or
316
+ raise K8::OptionError.new("#{action_name}: too many argument.")
317
+ cmd_opts.empty? or
318
+ raise K8::OptionError.new("#{action_name}: keyword arg not defined (#{cmd_opts.inspect}).")
319
+ if func_kwds.empty?
320
+ output = __send__(method_name, *func_args)
321
+ else
322
+ output = __send__(method_name, *func_args, func_kwds)
323
+ end
324
+ return output
325
+ end
326
+
327
+ def self.main
328
+ status = 0
329
+ obj = self.new()
330
+ begin
331
+ output = obj.run(*ARGV)
332
+ case output
333
+ when nil ;
334
+ when String ; puts output
335
+ when Integer ; status = output
336
+ else ; raise "** output=#{output.inspect}"
337
+ end
338
+ rescue K8::OptionError => ex
339
+ $stderr.puts "ERROR (#{obj.script_name}): #{ex}"
340
+ output = nil
341
+ status = 1
342
+ end
343
+ exit status
344
+ end
345
+
346
+ end
347
+
348
+
349
+ class OptionDefinition
350
+
351
+ def initialize(defstr, desc)
352
+ @defstr = defstr
353
+ @desc = desc
354
+ parse(defstr)
355
+ end
356
+
357
+ attr_reader :defstr, :name, :desc, :short, :long, :argstr, :arg_required
358
+
359
+ def parse(defstr)
360
+ case defstr
361
+ when /\A\s*-(\w),\s+--(\w[-\w]*)(?:=(\S*)|\[=(\S+)\])?(?:\s+\#(\w+))?\z/
362
+ short, long, arg1, arg2, optname = $1, $2, $3, $4, $5
363
+ when /\A\s*--(\w[-\w]*)(?:=(\S*)|\[=(\S+)\])?(?:\s+\#(\w+))?\z/
364
+ short, long, arg1, arg2, optname = nil, $1, $2, $3, $4
365
+ when /\A\s*-(\w)(?:\s+(\S+)|\[(\S+)\])?(?:\s+\#(\w+))?\z/
366
+ short, long, arg1, arg2, optname = $1, nil, $2, $3, $4
367
+ else
368
+ raise "#{defstr.inspect}: invalid option definition."
369
+ end
370
+ @short = short
371
+ @long = long
372
+ @argstr = arg1 || arg2
373
+ @arg_required = !! arg1 # true when option argument is required
374
+ @name = optname || long || short
375
+ end
376
+
377
+ end
378
+
379
+
380
+ class OptionParser
381
+
382
+ def initialize(optdefs)
383
+ @optdefs = optdefs
384
+ end
385
+
386
+ def parse(cmd_args)
387
+ options = {}
388
+ while cmd_args.length > 0 && cmd_args.first.start_with?('-')
389
+ optstr = cmd_args.shift()
390
+ if optstr == '--'
391
+ break
392
+ elsif optstr.start_with?('--')
393
+ optstr =~ /\A--(\w+)(?:=(.*))?\z/ or
394
+ raise OptionError.new("#{optstr}: invalid option.")
395
+ long, optarg = $1, $2
396
+ optdef = @optdefs.find {|x| x.long == long } or
397
+ raise OptionError.new("#{optstr}: unknown option.")
398
+ if ! optdef.argstr && optarg
399
+ raise OptionError.new("#{optstr}: unexpected argument.")
400
+ elsif optdef.arg_required && ! optarg
401
+ raise OptionError.new("#{optstr}: argument required.")
402
+ end
403
+ options[optdef.name] = optarg || true
404
+ else
405
+ i = 0; len = optstr.length
406
+ while (i += 1) < len
407
+ ch = optstr[i]
408
+ optdef = @optdefs.find {|x| x.short == ch } or
409
+ raise OptionError.new("-#{ch}: unknown option.")
410
+ if ! optdef.argstr # no arg
411
+ optarg = true
412
+ elsif ! optdef.arg_required # optional arg
413
+ optarg = i + 1 < len ? optstr[(i+1)..-1] : true
414
+ i = len - 1
415
+ else # required arg
416
+ optarg = optstr[(i+1)..-1]
417
+ if optarg.empty?
418
+ optarg = cmd_args.shift() or
419
+ raise OptionError.new("-#{ch}: argument required.")
420
+ end
421
+ i = len - 1
422
+ end
423
+ options[optdef.name] = optarg
424
+ end
425
+ end
426
+ end
427
+ return options
428
+ end
429
+
430
+ end
431
+
432
+
433
+ class OptionError < StandardError
434
+ end
435
+
436
+
437
+ class SkeletonTemplate < BabyErubis::Text
438
+
439
+ rexp = BabyErubis::Text::PATTERN
440
+ PATTERN = Regexp.compile(rexp.to_s.sub(/<%/, '\{%').sub(/%>/, '%\}'))
441
+
442
+ def pattern
443
+ PATTERN
444
+ end
445
+
446
+ end
447
+
448
+
449
+ class FileTool
450
+
451
+ def initialize(width: 30)
452
+ @width = width
453
+ @depth = 0
454
+ end
455
+
456
+ def parse_index_file(index_file)
457
+ dict = File.open(index_file) {|f|
458
+ f.grep(/^[^#]/).each_with_object({}) {|line, d|
459
+ path, desc = line.chomp.split(/\s+/, 2)
460
+ d[path] = desc
461
+ }
462
+ }
463
+ return dict
464
+ end
465
+
466
+ def report(s, desc)
467
+ indent = ' ' * @depth
468
+ puts "%s%-#{@width - indent.length}s # %s" % [indent, s, desc]
469
+ end
470
+
471
+ def mkrootdir(dirpath)
472
+ @root = dirpath
473
+ mkdir(dirpath)
474
+ end
475
+
476
+ def mkdir(dirpath, desc)
477
+ Dir.mkdir dirpath
478
+ s = dirpath.gsub(/.*?[\/\\]/, ' ') + "/"
479
+ report(s, desc)
480
+ end
481
+
482
+ def mkfile(filepath, content, desc)
483
+ File.open(filepath, 'wb') {|dst| dst.write(content) }
484
+ s = filepath.gsub(/.*?[\/\\]/, ' ')
485
+ report(s, desc)
486
+ end
487
+
488
+ end
489
+
490
+
491
+ end
492
+
493
+
494
+ #if __FILE__ == $0
495
+ K8::Main.main() unless defined? NOEXEC_SCRIPT
496
+ #end
data/keight.gemspec ADDED
@@ -0,0 +1,36 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+
4
+ Gem::Specification.new do |o|
5
+ o.name = "keight"
6
+ o.version = "$Release: 0.0.1 $".split[1]
7
+ o.author = "makoto kuwata"
8
+ o.email = "kwa(at)kuwata-lab.com"
9
+ o.platform = Gem::Platform::RUBY
10
+ o.homepage = "https://github.com/kwatch/keight/tree/ruby"
11
+ o.license = "MIT Lisense"
12
+ o.summary = "Jet-speed webapp framework for Ruby"
13
+ o.description = <<'END'
14
+ Keight.rb is the crazy-fast webapp framework for Ruby.
15
+ It is about 100 times faster than Rails and 20 times faster than Sinatra.
16
+
17
+ See https://github.com/kwatch/keight/tree/ruby for details.
18
+ END
19
+
20
+ o.files = Dir[*%w[
21
+ README.md MIT-LICENSE keight.gemspec setup.rb Rakefile
22
+ bin/k8rb
23
+ lib/keight.rb lib/keight/**/*.{[a-z]*} lib/keight/**/.{[a-z]*}
24
+ test/*_test.rb test/data/* test/oktest.rb
25
+ bench/bench.rb bench/benchmarker.rb
26
+ ]]
27
+ #lib/keight.rb lib/keight/**/*
28
+ o.executables = ["k8rb"]
29
+ o.bindir = ["bin"]
30
+ #o.test_files = o.files.grep(/^test\//)
31
+ o.test_file = "test/keight_test.rb"
32
+
33
+ o.required_ruby_version = '>= 2.0'
34
+ o.add_runtime_dependency 'baby_erubis', '~> 2.1', '>= 2.1.1'
35
+ #o.add_development_dependency "oktest", "~> 0"
36
+ end
@@ -0,0 +1,10 @@
1
+ config/*.private
2
+ *.cache
3
+ *.gem
4
+ *.rbc
5
+ tmp/
6
+ .bundle
7
+ .rvmrc
8
+ .repl_history
9
+ .yardoc
10
+ _yardoc
@@ -0,0 +1,98 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'keight'
4
+ require 'baby_erubis'
5
+ require 'baby_erubis/renderer'
6
+
7
+ require './config'
8
+
9
+
10
+ module My
11
+ end
12
+
13
+
14
+ class My::Action < K8::Action
15
+
16
+
17
+ ##
18
+ ## template
19
+ ##
20
+
21
+ include BabyErubis::HtmlEscaper
22
+ include BabyErubis::Renderer
23
+
24
+ ERUBY_PATH = ['app/template']
25
+ ERUBY_LAYOUT = :_layout
26
+ ERUBY_HTML = BabyErubis::Html
27
+ ERUBY_HTML_EXT = '.html.eruby'
28
+ ERUBY_TEXT = BabyErubis::Text
29
+ ERUBY_TEXT_EXT = '.eruby'
30
+ ERUBY_CACHE = {}
31
+
32
+ protected
33
+
34
+ alias render_html eruby_render_html
35
+ alias render_text eruby_render_text
36
+
37
+
38
+ ##
39
+ ## event handler (= exception handler)
40
+ ##
41
+
42
+ protected
43
+
44
+ ##
45
+ ## Define event handlers here.
46
+ ##
47
+ ## ex:
48
+ ## class Event < Exception; end
49
+ ## class NotExist < Event; end
50
+ ## class NotPermitted < Event; end
51
+ ##
52
+ ## def on_NotExist(ev) # or: define_method "on_Foo::Bar" do |ev|
53
+ ## @resp.status_code = 404 # 404 Not Found
54
+ ## {"error"=>"Not exist"}
55
+ ## end
56
+ ## def on_NotPermitted(ev)
57
+ ## @resp.status_code = 403 # 403 Forbidden
58
+ ## {"error"=>"Not permitted"}
59
+ ## end
60
+ ##
61
+ ## def do_show(id)
62
+ ## item = Item.find(id) or raise NotExist
63
+ ## return {"item"=>{"id"=>id, "name"=>item.name}}
64
+ ## end
65
+ ##
66
+
67
+
68
+ end
69
+
70
+
71
+ class My::AdminAction < My::Action
72
+
73
+ ## override template configs
74
+ ERUBY_PATH = ['admin/template']
75
+ ERUBY_LAYOUT = :_admin_layout
76
+
77
+ end
78
+
79
+
80
+ class My::StaticPage < My::Action
81
+
82
+ mapping '/{urlpath:.+}', :GET=>:do_send_file
83
+ STATIC_DIR = "static"
84
+
85
+ def do_send_file(urlpath)
86
+ filepath = "#{STATIC_DIR}/#{urlpath}"
87
+ File.file?(filepath) or raise K8::HttpException.new(404)
88
+ #env = @req.env
89
+ #header_name = env['sendfile.type'] || env['HTTP_X_SENDFILE_TYPE']
90
+ #if header_name && ! header_name.empty?
91
+ # @resp.headers[header_name] = filepath
92
+ # return nil
93
+ #else
94
+ return send_file(filepath)
95
+ #end
96
+ end
97
+
98
+ end
@@ -0,0 +1,39 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'keight'
4
+
5
+ #require_relative '../action'
6
+
7
+
8
+ class HelloAPI < K8::Action # or My::Action
9
+
10
+ mapping '' , :GET=>:do_index, :POST=>:do_create
11
+ mapping '/{id}' , :GET=>:do_show, :PUT=>:do_update, :DELETE=>:do_delete
12
+ ## or if you want support '/hello.json' and '/hello/123.json':
13
+ #mapping '{ext}' , :GET=>:do_index, :POST=>:do_create
14
+ #mapping '/{id}{ext}' , :GET=>:do_show, :PUT=>:do_update, :DELETE=>:do_delete
15
+
16
+ def do_index()
17
+ query = @req.params_query # QUERY_STRING
18
+ {"action"=>"index", "query"=>query}
19
+ end
20
+
21
+ def do_create()
22
+ form = @req.params_form # or @req.params_json
23
+ {"action"=>"create", "form"=>form}
24
+ end
25
+
26
+ def do_show(id)
27
+ {"action"=>"show", "id"=>id}
28
+ end
29
+
30
+ def do_update(id)
31
+ form = @req.params_form # or @req.params_json
32
+ {"action"=>"update", "id"=>id, "form"=>form}
33
+ end
34
+
35
+ def do_delete(id)
36
+ {"action"=>"delete", "id"=>id}
37
+ end
38
+
39
+ end
File without changes
File without changes
File without changes