ezframe 0.0.4 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -0
  3. data/README.md +1 -1
  4. data/asset/css/materialize.min.css +13 -0
  5. data/asset/css/style.css +3 -0
  6. data/asset/html/index.html +1 -0
  7. data/{app_template/asset/image/favicon.ico → asset/image/c_e.ico} +0 -0
  8. data/asset/js/ezframe.js +387 -0
  9. data/exe/check_column_yml +64 -0
  10. data/exe/console +2 -2
  11. data/exe/{create_table.rb → create_table} +7 -4
  12. data/exe/dbmigrate +174 -0
  13. data/exe/html2ruby +61 -0
  14. data/ezframe.gemspec +10 -8
  15. data/lib/ezframe.rb +9 -3
  16. data/lib/ezframe/auth.rb +50 -31
  17. data/lib/ezframe/column_set.rb +314 -103
  18. data/lib/ezframe/column_type.rb +456 -99
  19. data/lib/ezframe/config.rb +27 -6
  20. data/lib/ezframe/controller.rb +41 -38
  21. data/lib/ezframe/database.rb +171 -52
  22. data/lib/ezframe/editor_common.rb +74 -0
  23. data/lib/ezframe/email.rb +34 -0
  24. data/lib/ezframe/ezlog.rb +40 -0
  25. data/lib/ezframe/ht.rb +42 -17
  26. data/lib/ezframe/html.rb +47 -31
  27. data/lib/ezframe/japanese_utils.rb +15 -0
  28. data/lib/ezframe/jquery-ui.rb +29 -0
  29. data/lib/ezframe/loader.rb +4 -4
  30. data/lib/ezframe/main_editor.rb +19 -0
  31. data/lib/ezframe/main_page_kit.rb +226 -0
  32. data/lib/ezframe/materialize.rb +10 -14
  33. data/lib/ezframe/message.rb +46 -0
  34. data/lib/ezframe/page_base.rb +59 -71
  35. data/lib/ezframe/route.rb +126 -0
  36. data/lib/ezframe/server.rb +16 -5
  37. data/lib/ezframe/single_page_editor.rb +22 -0
  38. data/lib/ezframe/single_page_kit.rb +199 -0
  39. data/lib/ezframe/sub_editor.rb +25 -0
  40. data/lib/ezframe/sub_page_kit.rb +213 -0
  41. data/lib/ezframe/template.rb +5 -4
  42. data/lib/ezframe/util.rb +45 -23
  43. data/lib/ezframe/version.rb +1 -1
  44. metadata +74 -34
  45. data/.rubocop.yml +0 -44
  46. data/app_template/asset/js/ezframe.js +0 -288
  47. data/app_template/config.ru +0 -10
  48. data/app_template/config/generic.yml +0 -3
  49. data/app_template/config/materialize.yml +0 -5
  50. data/app_template/pages/basic.rb +0 -5
  51. data/exe/setup.rb +0 -15
  52. data/lib/ezframe/editor.rb +0 -188
  53. data/lib/ezframe/model.rb +0 -52
  54. data/lib/ezframe/page_kit.rb +0 -63
@@ -4,17 +4,16 @@ module Ezframe
4
4
  class Materialize
5
5
  class << self
6
6
  def into_html_header
7
-
8
- css_a = Config[:extra_css_list].map {|file| "<link href=\"#{file}\" rel=\"stylesheet\">\n" }
9
- js_a = Config[:extra_js_list].map {|file| "<script src=\"#{file}\"></script>\n" }
7
+ css_a = Config[:extra_css_list]&.map {|file| "<link href=\"#{file}\" rel=\"stylesheet\">\n" }
8
+ js_a = Config[:extra_js_list]&.map {|file| "<script src=\"#{file}\"></script>\n" }
10
9
 
11
10
  css_files = Dir["./asset/css/*.css"]||[]
12
- css_a += css_files.map do |file|
11
+ css_a += css_files.sort.map do |file|
13
12
  file.gsub!("./asset", "")
14
13
  "<link href=\"#{file}\" rel=\"stylesheet\">\n"
15
14
  end
16
15
  js_files = Dir["./asset/js/*.js"]||[]
17
- js_a += js_files.map do |file|
16
+ js_a += js_files.sort.map do |file|
18
17
  file.gsub!("./asset", "")
19
18
  "<script src=\"#{file}\"></script>\n"
20
19
  end
@@ -27,19 +26,16 @@ module Ezframe
27
26
 
28
27
  def convert(ht_h)
29
28
  return nil unless ht_h
30
- return ht_h if (ht_h.kind_of?(Hash) && ht_h[:final])
29
+ return ht_h if (ht_h.is_a?(Hash) && ht_h[:final])
31
30
  new_h = ht_h.clone
32
- if ht_h.kind_of?(Array)
31
+ if ht_h.is_a?(Array)
33
32
  new_h = ht_h.map { |v| convert(v) }
34
- elsif ht_h.kind_of?(Hash)
33
+ elsif ht_h.is_a?(Hash)
35
34
  unless ht_h[:tag]
36
- mylog("convert: no tag: #{ht_h.inspect}")
35
+ EzLog.info("convert: no tag: #{ht_h.inspect}")
37
36
  return nil
38
37
  end
39
38
  case ht_h[:tag].to_sym
40
- # when :input, :select
41
- # new_h = input(ht_h) if "hidden" != ht_h[:type]
42
- # return new_h
43
39
  when :checkbox
44
40
  return checkbox(ht_h)
45
41
  when :radio
@@ -58,8 +54,8 @@ module Ezframe
58
54
 
59
55
  def icon(ht_h)
60
56
  new_h = ht_h.clone
61
- mylog "[warn] no name attribute for icon ht_h: #{ht_h.inspect}" unless new_h[:name]
62
- new_h.add_class("material-icons")
57
+ EzLog.info "[warn] no name attribute for icon ht_h: #{ht_h.inspect}" unless new_h[:name]
58
+ new_h.add_class(%w[material-icons align-icon])
63
59
  new_h.update({ tag: "i", child: ht_h[:name] })
64
60
  new_h.delete(:name)
65
61
  return new_h
@@ -0,0 +1,46 @@
1
+ module Ezframe
2
+ class Message
3
+ class << self
4
+ def init
5
+ load_yaml_files
6
+ end
7
+
8
+ def load_yaml_files(dir = "./message")
9
+ unless @catalog
10
+ @catalog = {}
11
+ Dir["#{dir}/*.yml"].each do |file|
12
+ load_one_file(file)
13
+ end
14
+ end
15
+ end
16
+
17
+ def load_one_file(file)
18
+ begin
19
+ yaml = YAML.load(File.open(file), symbolize_names: true)
20
+ rescue
21
+ EzLog.info("YAML load error: #{file}")
22
+ return
23
+ end
24
+ if /([a-z]{2})\.yml$/ =~ file
25
+ lang = $1
26
+ @catalog[lang.to_sym] = yaml # .recursively_symbolize_keys
27
+ end
28
+ end
29
+
30
+ def languages
31
+ return @catalog.keys
32
+ end
33
+
34
+ def get(key, lang = nil)
35
+ lang = languages[0] unless lang
36
+ messages = @catalog[lang]
37
+ return messages[key.to_sym] if messages
38
+ return nil
39
+ end
40
+
41
+ def [](key)
42
+ return get(key)
43
+ end
44
+ end
45
+ end
46
+ end
@@ -2,106 +2,94 @@
2
2
 
3
3
  require "json"
4
4
  require "uri"
5
-
6
5
  require_relative "util"
7
6
 
8
7
  module Ezframe
9
8
  class PageBase
10
- class << self
11
- def decide_route(path_info)
12
- default_class = Config[:default_page_class]||"App"
13
- default_method = Config[:default_page_method]||"default"
14
- path_parts = path_info.split('/').drop(1)
15
- case path_parts.length
16
- when 0
17
- [get_class(default_class), default_method]
18
- when 1
19
- filename = path_parts[0]
20
- if filename.index(".")
21
- return nil
22
- end
23
- klass = get_class(path_parts)
24
- if klass
25
- return [klass, default_method]
26
- else
27
- return [get_class(default_class), path_parts[0]]
28
- end
29
- else
30
- klass = get_class(path_parts)
31
- if klass
32
- [klass, default_method]
33
- else
34
- method = path_parts.pop
35
- klass = get_class(path_parts)
36
- [klass, method]
37
- end
38
- end
39
- end
9
+ attr_accessor :request
40
10
 
41
- def get_class(keys)
42
- keys = [keys] if keys.is_a?(String)
43
- klass = (%w[Ezframe] + keys.map { |k| k.to_camel }).join("::")
44
- mylog "get_class: #{klass}"
45
- if Object.const_defined?(klass)
46
- return Object.const_get(klass)
47
- end
48
- return nil
49
- end
11
+ def initialize(request = nil)
12
+ @class_snake = class_to_snake(self.class)
13
+ # puts "class_snake = #{@class_snake}"
14
+ set_request(request) if request
15
+ init_vars
50
16
  end
51
17
 
52
- attr_accessor :auth
18
+ def init_vars
19
+ end
20
+
21
+ # Rackのrequestを代入し、関連するインスタンス変数を定義
22
+ def set_request(request)
23
+ @request = request
24
+ @column_set = ColumnSets.get(@class_snake)
25
+ @dataset = DB.dataset(@class_snake)
26
+ EzLog.debug "column_set is not defined: #{@class_snake}" unless @column_set
27
+ @params = parse_query_string(request.env["QUERY_STRING"])
28
+ @params.update(request.params)
29
+ # EzLog.info "set_request: params=#{@params.inspect}" if @params.length > 0
30
+ # @id, @key = @params[:id], @params[:key]
31
+ @env = @request.env
32
+ @session = @env["rack.session"]
53
33
 
54
- def initialize(request = nil, model = nil)
55
- @model = model if model
56
- if request
57
- @request = request
58
- @params = parse_query_string(request.env["QUERY_STRING"])
59
- @params.update(request.params)
60
- mylog "params=#{@params.inspect}" if @params.length > 0
61
- @id, @key = @params[:id], @params[:key]
62
- @env = @request.env
63
- @session = @env["rack.session"]
64
- mylog "session = #{@session.inspect}"
65
- if request.post?
66
- parse_json_body
67
- mylog "json=#{@json.inspect}"
34
+ if %w[POST PUT].include?(request.request_method)
35
+ body = @request.body.read
36
+ if request.content_type.index("json")
37
+ @parsed_body = parse_json_body(body)
38
+ else
39
+ @parsed_body = parse_query_string(body)
68
40
  end
41
+ # EzLog.info "parsed_body=#{@parsed_body.inspect}"
42
+ @event = @parsed_body[:ezevent] || {}
43
+ @form = @event[:form]
69
44
  end
70
- @auth = nil
71
45
  end
72
46
 
73
- def parse_query_string(str)
74
- query_a = URI::decode_www_form(str)
75
- res_h = {}
76
- query_a.map { |a| res_h[a[0].to_sym] = a[1] }
77
- res_h
47
+ # routeから基本URLを生成
48
+ def make_base_url(id = nil)
49
+ path = Route::get_path(@class_snake)
50
+ params = @request.env["url_params"] || {}
51
+ # EzLog.info "make_base_url: params=#{params}"
52
+ # params[@class_snake.to_sym] = id
53
+ path_s = path.map do |pa|
54
+ if pa == @class_snake.to_sym && id
55
+ "#{pa}/#{id}"
56
+ elsif params[pa.to_sym]
57
+ "#{pa}/#{params[pa.to_sym]}"
58
+ else
59
+ pa
60
+ end
61
+ end.join("/")
62
+ # EzLog.info "path_s=#{path_s}"
63
+ return "/#{path_s}"
78
64
  end
79
65
 
80
- def common_page(opts = {})
66
+ def show_base_template(opts = {})
81
67
  args = {
82
68
  title: opts[:title],
83
69
  body: opts[:body],
84
70
  into_html_header: Materialize.into_html_header,
85
71
  into_bottom_of_body: Materialize.into_bottom_of_body,
86
72
  }
87
- Template.fill("template/base.html", args)
73
+ Template.fill_from_file("template/base.html", args)
88
74
  end
89
75
 
90
- def parse_json_body
91
- body = @request.body.read
76
+ def parse_json_body(body)
92
77
  return {} if !body || body.length==0
93
78
  begin
94
- @json = JSON.parse(body)
79
+ json = JSON.parse(body, symbolize_names: true)
95
80
  rescue => e
96
- mylog "ERROR: #{e.class}:#{e.message}\n#{e.backtrace}"
81
+ EzLog.info "ERROR: #{e.class}:#{e.message}\n#{e.backtrace}"
97
82
  return nil
98
83
  end
99
- @json = @json.recursively_symbolize_keys if @json.is_a?(Hash) || @json.is_a?(Array)
100
- return @json
84
+ return json
85
+ end
86
+
87
+ def session
88
+ return @request.env['rack.session']
101
89
  end
102
90
 
103
91
  def warden
104
- @request.env["warden"]
92
+ return @request.env["warden"]
105
93
  end
106
94
 
107
95
  def login?
@@ -109,7 +97,7 @@ module Ezframe
109
97
  end
110
98
 
111
99
  def user
112
- warden.user
100
+ return warden.user
113
101
  end
114
102
  end
115
103
  end
@@ -0,0 +1,126 @@
1
+ module Ezframe
2
+ class Route
3
+ class << self
4
+ def choose(request, route_h = nil)
5
+ path_parts = request.path_info.split("/").drop(1)
6
+ route_h ||= Config[:route].deep_dup
7
+ unless route_h
8
+ raise "Config[:route] is not defined. It should be defined in config/route.yml"
9
+ end
10
+ # puts "config=#{Config[:route]}, route_h=#{route_h}"
11
+ args = {}
12
+ opts = {}
13
+ class_a = []
14
+ # p path_parts
15
+ if path_parts.empty?
16
+ root_conf = route_h[:/]
17
+ # p root_conf
18
+ if root_conf
19
+ klass = get_class(root_conf[:class])
20
+ return [ klass.new, make_method_name("default", request.request_method) ]
21
+ end
22
+ return [ 404 ]
23
+ end
24
+ # URLを解析して、クラスの決定とIDの取得を行う
25
+ while path_parts.length > 0
26
+ part = path_parts.shift
27
+ # break if part.empty?
28
+ # EzLog.info "part=#{part}, route_h=#{route_h.inspect}"
29
+ if route_h.has_key?(part.to_sym)
30
+ # EzLog.info "has_route: #{part}"
31
+ class_a.push(part)
32
+ if path_parts[0].to_i > 0
33
+ args[part.to_sym] = val = path_parts.shift
34
+ # EzLog.info "value: part=#{part}, val=#{val}"
35
+ end
36
+ route_h = route_h[part.to_sym]
37
+ break if route_h.nil?
38
+ opts = {}
39
+ route_h.keys.compact.each do |rkey|
40
+ if rkey =~ /option_(\w+)/
41
+ opt_key = $1
42
+ opts[opt_key.to_sym] = route_h[rkey]
43
+ end
44
+ end
45
+ else
46
+ # routeに無ければ、メソッドを探す
47
+ # EzLog.info "no_route: #{part}"
48
+ klass = get_class(class_a[-1])
49
+ return [ 404 ] unless klass
50
+ instance = klass.new
51
+ method_name = make_method_name(part, request.request_method)
52
+ if instance.respond_to?(method_name)
53
+ return [instance, method_name, args, opts]
54
+ else
55
+ EzLog.info "undefined method: #{klass}.#{method_name}: full path=#{request.path_info}"
56
+ end
57
+ end
58
+ end
59
+ # 最後にメソッド名が無い場合はpublic_default_#{method}を実行。
60
+ #puts "class_a=#{class_a}"
61
+ klass = get_class(class_a[-1])
62
+ return [404] unless klass
63
+ if path_parts.length > 0
64
+ part = path_parts.shift
65
+ else
66
+ part = "default"
67
+ end
68
+ method_name = make_method_name(part, request.request_method)
69
+ #EzLog.info "method_name=#{method_name}"
70
+ instance = klass.new
71
+ if instance.respond_to?(method_name)
72
+ return [instance, method_name, args, opts]
73
+ end
74
+ return [ 404 ]
75
+ end
76
+
77
+ # ページクラスの階層を辿る
78
+ def get_path(class_snake, route_h = nil)
79
+ route_h = Config[:route] unless route_h
80
+ # EzLog.info "get_path: route_h=#{route_h}"
81
+ @get_path_found_it = nil
82
+ route =_scan_route(class_snake, route_h.deep_dup)
83
+ return route.reverse if route
84
+ return nil
85
+ end
86
+
87
+ # targetに対応する名称のクラスまでの経路を返す
88
+ def _scan_route(target, route_h)
89
+ if route_h.keys.include?(target.to_sym)
90
+ @get_path_found_it = true
91
+ return [ target ]
92
+ else
93
+ route_h.each do |k, v|
94
+ next if k.to_s =~ /^option_/
95
+ if v.is_a?(Hash)
96
+ a = _scan_route(target, v)
97
+ if @get_path_found_it
98
+ a.push(k)
99
+ return a
100
+ end
101
+ end
102
+ end
103
+ end
104
+ return nil
105
+ end
106
+
107
+ def make_method_name(base_name, method = "get")
108
+ return ["public", base_name, method.downcase].join("_")
109
+ end
110
+
111
+ def get_class(keys)
112
+ # EzLog.info "get_class: #{keys.inspect}"
113
+ return nil unless keys
114
+ keys = [ keys ] if keys.is_a?(String)
115
+ klass = (%w[Ezframe] + keys.map { |k| k.to_s.to_camel }).join("::")
116
+ # EzLog.info "get_class: #{klass}"
117
+ if Object.const_defined?(klass)
118
+ return Object.const_get(klass)
119
+ else
120
+ raise "get_class: undefined class: #{klass}"
121
+ end
122
+ return nil
123
+ end
124
+ end
125
+ end
126
+ end
@@ -2,14 +2,25 @@
2
2
 
3
3
  module Ezframe
4
4
  class Server
5
- def self.call(env)
5
+ def initialize
6
+ Controller.init
7
+ end
8
+
9
+ def call(env)
6
10
  req = Rack::Request.new(env)
7
11
  res = Rack::Response.new
8
- Boot.exec(req, res)
9
- if res.body.empty?
10
- raise "no body in response"
12
+ begin
13
+ Controller.exec(req, res)
14
+ rescue => e
15
+ EzLog.error("Controller.exec: exception: #{e.message}:\n#{e.backtrace}")
16
+ res.status = 500
17
+ res.headers["Content-Type"] = "text/plain"
18
+ res.body = [ "Internal server error" ]
11
19
  end
12
- res.finish
20
+ # if res.body.empty?
21
+ # raise "no body in response"
22
+ # end
23
+ return res.finish
13
24
  end
14
25
  end
15
26
  end
@@ -0,0 +1,22 @@
1
+ require_relative "editor_common"
2
+ require_relative "single_page_kit"
3
+
4
+ module Ezframe
5
+ # ページ遷移無しでデータを編集する仕組み
6
+ class SinglePageEditor < PageBase
7
+ include EditorCommon
8
+ include PageKit::Default
9
+ include PageKit::Index
10
+ include PageKit::Edit
11
+ include PageKit::Detail
12
+ include PageKit::Delete
13
+
14
+ def init_vars
15
+ super
16
+ @sort_key = :id
17
+ @event = @parsed_body[:ezevent] if @parsed_body
18
+ @dom_id = { create: "create-area", edit: "edit-area", index: "index-area", detail: "detail-area"}
19
+ # @show_delete_button = nil
20
+ end
21
+ end
22
+ end