engine2 1.0.0

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 (145) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +2 -0
  3. data/Rakefile +138 -0
  4. data/conf/message.yaml +93 -0
  5. data/conf/message_pl.yaml +93 -0
  6. data/engine2.gemspec +34 -0
  7. data/lib/engine2.rb +34 -0
  8. data/lib/engine2/action.rb +217 -0
  9. data/lib/engine2/core.rb +572 -0
  10. data/lib/engine2/handler.rb +134 -0
  11. data/lib/engine2/meta.rb +969 -0
  12. data/lib/engine2/meta/decode_meta.rb +110 -0
  13. data/lib/engine2/meta/delete_meta.rb +73 -0
  14. data/lib/engine2/meta/form_meta.rb +144 -0
  15. data/lib/engine2/meta/infra_meta.rb +292 -0
  16. data/lib/engine2/meta/link_meta.rb +133 -0
  17. data/lib/engine2/meta/list_meta.rb +284 -0
  18. data/lib/engine2/meta/save_meta.rb +63 -0
  19. data/lib/engine2/meta/view_meta.rb +22 -0
  20. data/lib/engine2/model.rb +390 -0
  21. data/lib/engine2/models/Files.rb +38 -0
  22. data/lib/engine2/models/UserInfo.rb +24 -0
  23. data/lib/engine2/post_bootstrap.rb +83 -0
  24. data/lib/engine2/pre_bootstrap.rb +27 -0
  25. data/lib/engine2/scheme.rb +202 -0
  26. data/lib/engine2/templates.rb +229 -0
  27. data/lib/engine2/type_info.rb +342 -0
  28. data/lib/engine2/version.rb +9 -0
  29. data/public/assets/javascripts.js +13 -0
  30. data/public/assets/styles.css +4 -0
  31. data/public/css/angular-motion.css +1022 -0
  32. data/public/css/angular-ui-tree.min.css +1 -0
  33. data/public/css/app.css +196 -0
  34. data/public/css/bootstrap-additions.css +1560 -0
  35. data/public/css/bootstrap.min.css +11 -0
  36. data/public/css/font-awesome.min.css +4 -0
  37. data/public/favicon.ico +0 -0
  38. data/public/fonts/FontAwesome.otf +0 -0
  39. data/public/fonts/fontawesome-webfont.eot +0 -0
  40. data/public/fonts/fontawesome-webfont.svg +655 -0
  41. data/public/fonts/fontawesome-webfont.ttf +0 -0
  42. data/public/fonts/fontawesome-webfont.woff +0 -0
  43. data/public/fonts/fontawesome-webfont.woff2 +0 -0
  44. data/public/fonts/glyphicons-halflings-regular.eot +0 -0
  45. data/public/fonts/glyphicons-halflings-regular.svg +288 -0
  46. data/public/fonts/glyphicons-halflings-regular.ttf +0 -0
  47. data/public/fonts/glyphicons-halflings-regular.woff +0 -0
  48. data/public/fonts/glyphicons-halflings-regular.woff2 +0 -0
  49. data/public/images/file.png +0 -0
  50. data/public/images/folder-closed.png +0 -0
  51. data/public/images/folder.png +0 -0
  52. data/public/images/node-closed-2.png +0 -0
  53. data/public/images/node-closed-light.png +0 -0
  54. data/public/images/node-closed.png +0 -0
  55. data/public/images/node-opened-2.png +0 -0
  56. data/public/images/node-opened-light.png +0 -0
  57. data/public/images/node-opened.png +0 -0
  58. data/public/img/ajax-loader-dark.gif +0 -0
  59. data/public/img/ajax-loader-light.gif +0 -0
  60. data/public/img/ajax-loader.gif +0 -0
  61. data/public/js/angular-animate.js +4115 -0
  62. data/public/js/angular-cookies.js +322 -0
  63. data/public/js/angular-local-storage.js +455 -0
  64. data/public/js/angular-route.js +1022 -0
  65. data/public/js/angular-sanitize.js +717 -0
  66. data/public/js/angular-strap.js +4339 -0
  67. data/public/js/angular-strap.tpl.js +43 -0
  68. data/public/js/angular-ui-tree.js +1569 -0
  69. data/public/js/angular.js +30714 -0
  70. data/public/js/i18n/angular-locale_pl.js +115 -0
  71. data/public/js/lodash.custom.min.js +97 -0
  72. data/public/js/ng-file-upload-shim.min.js +2 -0
  73. data/public/js/ng-file-upload.min.js +3 -0
  74. data/views/app.coffee +3 -0
  75. data/views/engine2.coffee +557 -0
  76. data/views/engine2actions.coffee +849 -0
  77. data/views/engine2templates.coffee +0 -0
  78. data/views/fields/blob.slim +22 -0
  79. data/views/fields/bs_select.slim +10 -0
  80. data/views/fields/bsselect_picker.slim +18 -0
  81. data/views/fields/bsselect_picker_opt.slim +22 -0
  82. data/views/fields/checkbox.slim +11 -0
  83. data/views/fields/checkbox_buttons.slim +6 -0
  84. data/views/fields/checkbox_buttons_opt.slim +8 -0
  85. data/views/fields/currency.slim +10 -0
  86. data/views/fields/date.slim +21 -0
  87. data/views/fields/date_range.slim +44 -0
  88. data/views/fields/date_time.slim +42 -0
  89. data/views/fields/datetime.slim +42 -0
  90. data/views/fields/decimal.slim +11 -0
  91. data/views/fields/decimal_date.slim +22 -0
  92. data/views/fields/decimal_time.slim +26 -0
  93. data/views/fields/email.slim +13 -0
  94. data/views/fields/file_store.slim +61 -0
  95. data/views/fields/input_text.slim +14 -0
  96. data/views/fields/integer.slim +11 -0
  97. data/views/fields/list_bsselect.slim +18 -0
  98. data/views/fields/list_bsselect_opt.slim +21 -0
  99. data/views/fields/list_buttons.slim +3 -0
  100. data/views/fields/list_buttons_opt.slim +5 -0
  101. data/views/fields/list_select.slim +11 -0
  102. data/views/fields/list_select_opt.slim +15 -0
  103. data/views/fields/password.slim +14 -0
  104. data/views/fields/radio_checkbox.slim +10 -0
  105. data/views/fields/scaffold.slim +2 -0
  106. data/views/fields/scaffold_picker.slim +20 -0
  107. data/views/fields/select_picker.slim +12 -0
  108. data/views/fields/select_picker_opt.slim +16 -0
  109. data/views/fields/text_area.slim +10 -0
  110. data/views/fields/time.slim +22 -0
  111. data/views/fields/typeahead_picker.slim +25 -0
  112. data/views/index.slim +44 -0
  113. data/views/infra/index.slim +5 -0
  114. data/views/infra/inspect.slim +81 -0
  115. data/views/modals/close_m.slim +15 -0
  116. data/views/modals/confirm_m.slim +19 -0
  117. data/views/modals/empty_m.slim +12 -0
  118. data/views/modals/menu_m.slim +13 -0
  119. data/views/modals/yes_no_m.slim +19 -0
  120. data/views/panels/menu_m.slim +9 -0
  121. data/views/scaffold/confirm.slim +3 -0
  122. data/views/scaffold/fields.slim +10 -0
  123. data/views/scaffold/form.slim +11 -0
  124. data/views/scaffold/list.slim +42 -0
  125. data/views/scaffold/message.slim +3 -0
  126. data/views/scaffold/search.slim +20 -0
  127. data/views/scaffold/view.slim +18 -0
  128. data/views/search_fields/bsmselect_picker.slim +25 -0
  129. data/views/search_fields/bsselect_picker.slim +24 -0
  130. data/views/search_fields/checkbox.slim +11 -0
  131. data/views/search_fields/checkbox2.slim +14 -0
  132. data/views/search_fields/checkbox_buttons.slim +10 -0
  133. data/views/search_fields/date_range.slim +46 -0
  134. data/views/search_fields/decimal_date_range.slim +47 -0
  135. data/views/search_fields/input_text.slim +18 -0
  136. data/views/search_fields/integer.slim +18 -0
  137. data/views/search_fields/integer_range.slim +27 -0
  138. data/views/search_fields/list_bsmselect.slim +24 -0
  139. data/views/search_fields/list_bsselect.slim +22 -0
  140. data/views/search_fields/list_buttons.slim +8 -0
  141. data/views/search_fields/list_select.slim +17 -0
  142. data/views/search_fields/scaffold_picker.slim +19 -0
  143. data/views/search_fields/select_picker.slim +17 -0
  144. data/views/search_fields/typeahead_picker.slim +25 -0
  145. metadata +327 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: bc80e81843c9720bf34223f646d6f2bb747e33d0
4
+ data.tar.gz: d4e47ca39797d61936f7322d3e181db9ba27486b
5
+ SHA512:
6
+ metadata.gz: 6f2c82ff8b62c2a45745afb59e8095ac27b370d64a2f4ada1c294e403fb456573f719a7de636bc281ec8405190c63029e7afcd48df3f86db287ffcc5848852ee
7
+ data.tar.gz: f64cf30cacc5c8de8a8f3370b62bc50f9b30b94284da7354bfdf5a29135e188acef864ad71f50782c49723cf5f5b781ebd3cbcb06ab3b32fa4438d9f670c5d97
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
@@ -0,0 +1,138 @@
1
+ DIR = Dir.pwd
2
+ VIEWS = DIR + "/views"
3
+ PUBLIC = DIR + "/public"
4
+ COFFEE_FILES = ["app", "engine2", "engine2actions"]
5
+
6
+ desc "Compile JS"
7
+ task :compile_js do
8
+ require 'coffee-script'
9
+ require 'uglifier'
10
+ COFFEE_FILES.each do |cf|
11
+ out = CoffeeScript.compile(open("#{VIEWS}/#{cf}.coffee", "r:UTF-8"))
12
+ out = Uglifier.new(
13
+ # mangle: false
14
+ mangle: {except: %w|
15
+ $injector
16
+ $window
17
+ $rootScope
18
+ $scope
19
+ $compile
20
+ $routeProvider
21
+ $compileProvider
22
+ $locationProvider
23
+ $location
24
+ $route
25
+ $parse
26
+ $templateCache
27
+ $resource
28
+ $attrs
29
+ $element
30
+ $http
31
+ $cookies
32
+ $sanitize
33
+ $timeout
34
+ $httpProvider
35
+ $logProvider
36
+ $q
37
+ $upload
38
+ $dropdown
39
+ $modal
40
+ E2
41
+ E2Snippets
42
+ E2Actions
43
+ E2ActionsX
44
+ $e2Scaffold
45
+ $e2Modal
46
+ localStorageServiceProvider
47
+ localStorageService
48
+ $dateParser
49
+ $dateFormatter
50
+ $filter
51
+ e2HttpInterceptor
52
+ |}
53
+ ).compile(out)
54
+ open("#{PUBLIC}/js/#{cf}.js", "w") << out
55
+ end
56
+ end
57
+
58
+ desc "Compile SLIM"
59
+ task :compile_slim do
60
+ require 'slim'
61
+ view_dirs = ["fields", "scaffold", "search_fields", "modals"]
62
+ slims = view_dirs.each.map do |view_dir|
63
+ Dir["views/#{view_dir}/*.slim"].map do |slim_file|
64
+ slim = Slim::Template.new(slim_file).render.gsub('"', '\"')
65
+ tpl_name = slim_file.sub("views/", "").sub(".slim", "")
66
+ "$templateCache.put('#{tpl_name}', \"#{slim}\");"
67
+ end
68
+ end
69
+
70
+ open("#{PUBLIC}/js/engine2templates.js", "wb") << <<-EOF
71
+ angular.module('Engine2').run(['$templateCache', function($templateCache) {
72
+ #{slims.join("\n")}
73
+ }]);
74
+ EOF
75
+ end
76
+
77
+ desc "Compile"
78
+ task :compile => [:compile_js, :compile_slim] do
79
+ end
80
+
81
+ desc "Clean"
82
+ task :clean do
83
+ (COFFEE_FILES + ["engine2templates"]).each do |js|
84
+ File.delete "#{PUBLIC}/js/#{js}.js"
85
+ end
86
+ end
87
+
88
+ desc "Assets Js"
89
+ task :assets_js do
90
+ require 'uglifier'
91
+ # jquery-builder.cmd -m -v 2.0.3 -e ajax,deprecated,effects,offset > jquery-custom.min.js
92
+ # lodash category=array,collection,object,seq,lang plus=template
93
+
94
+ js_files = %w[
95
+ ng-file-upload-shim.min.js
96
+ angular.js
97
+ i18n/angular-locale_pl.js
98
+ angular-route.js
99
+ angular-sanitize.js
100
+ angular-animate.js
101
+ angular-cookies.js
102
+ angular-strap.js
103
+ angular-strap.tpl.js
104
+ ng-file-upload.min.js
105
+ angular-ui-tree.js
106
+ angular-local-storage.js
107
+ lodash.custom.min.js
108
+ ]
109
+
110
+ out = js_files.map{|js| open("#{PUBLIC}/js/#{js}", "r:UTF-8").read}.join("")
111
+
112
+ out = Uglifier.new(output: {comments: :none}, mangle: true).compile(out)
113
+
114
+ open("#{PUBLIC}/assets/javascripts.js", "wb") << out
115
+ end
116
+
117
+ desc "Assets Css"
118
+ task :assets_css do
119
+ require 'yui/compressor'
120
+
121
+ css_files = %w[
122
+ bootstrap-additions.css
123
+ angular-motion.css
124
+ angular-ui-tree.min.css
125
+ font-awesome.min.css
126
+ ]
127
+
128
+ out = css_files.map{|css|open("#{PUBLIC}/css/#{css}", "r:UTF-8").read}.join("")
129
+
130
+ out = YUI::CssCompressor.new(java: "#{ENV['JAVA_HOME']}/bin/java").compress(out)
131
+ open("#{PUBLIC}/assets/styles.css", "wb") << out
132
+
133
+ end
134
+
135
+ desc "Assets"
136
+ task :assets => [:assets_js, :assets_css] do
137
+ # File.delete *Dir["#{Dir.pwd}/public/assets/*"]
138
+ end
@@ -0,0 +1,93 @@
1
+ :engine2_resource_loaded: true
2
+ :default_date_format: yyyy-MM-dd
3
+ :default_date_short_format: yy-MM-dd
4
+ :default_date_model_format: yyyy-MM-dd
5
+ :default_date_model_short_format: yy-MM-dd
6
+ :default_time_format: HH:mm:ss
7
+ :default_time_model_format: HH:mm:ss
8
+
9
+ :no_entry: Entry doesnt exist
10
+ :decode_selected: selected
11
+
12
+ :name: Name
13
+ :mime: Mime
14
+ :owner: Owner
15
+ :model: Model
16
+ :field: Field
17
+ :updated: Updated
18
+
19
+ :ok: Ok
20
+ :link: Attach
21
+ :choose: Choose
22
+ :view: Details
23
+ :search_toggle: Search
24
+ :link_list: Attach
25
+ :create: Create
26
+ :modify: Modify
27
+ :search: Search
28
+ :refresh: Refresh
29
+ :default_order: Default order
30
+ :select_toggle: Select
31
+ :confirm_delete: Delete
32
+ :confirm_delete_title: <span class='glyphicon glyphicon-trash'></span> Confirmation
33
+ :confirm_bulk_delete: Delete selected
34
+ :delete_restricted: Restricted relations
35
+ :confirm_bulk_delete_title: <span class='glyphicon glyphicon-trash'></span> Confirmation
36
+ :confirm_unlink: Detach
37
+ :confirm_unlink_title: <span class='glyphicon glyphicon-minus'></span> Confirmation
38
+ :confirm_bulk_unlink: Detach selected
39
+ :confirm_bulk_unlink_title: <span class='glyphicon glyphicon-minus'></span> Confirmation
40
+ :debug_info: Debug info
41
+ :show_meta: Show metainfo
42
+ # :meta: Meta
43
+ :view_title: <span class='glyphicon glyphicon-book'></span> Details
44
+ :create_title: <span class='glyphicon glyphicon-pencil'></span> Create
45
+ :modify_title: <span class='glyphicon glyphicon-pencil'></span> Modify
46
+ :delete_title: <span class='glyphicon glyphicon-trash'></span> Delete
47
+ :link_title: <span class='glyphicon glyphicon-paperclip'></span> Attach
48
+ :delete_question: Delete entry ?
49
+ :unlink_question: Detach entry ?
50
+ :confirmation: Confirmation
51
+ :save: Save
52
+ :approve: Approve
53
+ :cancel: Cancel
54
+
55
+ :inspect_modal: Inspect
56
+
57
+ :login_form: Login
58
+ :user_name: User
59
+ :password: Password
60
+ :login: Login
61
+ :login_title: <span class='glyphicon glyphicon-log-in'></span> Login
62
+
63
+ :logout_form: Logout
64
+ :logout_title: <span class='glyphicon glyphicon-log-out'></span> Logout
65
+ :logout_message: Logout ?
66
+
67
+ :user_required: user name required
68
+ :password_required: password required
69
+ :password_invalid: Password doesnt match
70
+
71
+ :welcome: Welcome
72
+
73
+ :non_nullable: Non nullable
74
+ :field_required: Field required
75
+ :wrong_boolean_value: Bad boolean value
76
+ :value_exceeds_maximum_length: Length exceeded
77
+ :invalid_date_format: Incorrect date format
78
+ :invalid_time_format: Incorrect time format
79
+ :invalid_datetime_format: Incorrect date/time format
80
+ :value_from_gt_to: Value from > to
81
+ :invalid_number_value: Incorrect number value
82
+ :number_negative: Negative value
83
+ :invalid_list_value: Incorrect value for list
84
+ :invalid_decimal_value: Incorrect decimal value
85
+ :invalid_currency_value: Incorrect currency value
86
+ :required_unique_value: Require unique value
87
+ :invalid_email_format: Incorrect email format
88
+ :invalid_format: Incorrect format
89
+
90
+ :access_forbidden: Access forbidden
91
+ :access_unauthorized: Access unauthorized
92
+ :access_not_found: Not found
93
+ :access_method_not_allowed: Metod not allowed
@@ -0,0 +1,93 @@
1
+ :engine2_resource_loaded: true
2
+ :default_date_format: yyyy-MM-dd
3
+ :default_date_short_format: yy-MM-dd
4
+ :default_date_model_format: yyyy-MM-dd
5
+ :default_date_model_short_format: yy-MM-dd
6
+ :default_time_format: HH:mm:ss
7
+ :default_time_model_format: HH:mm:ss
8
+
9
+ :no_entry: Wpis nie istnieje
10
+ :decode_selected: wybranych
11
+
12
+ :name: Nazwa
13
+ :mime: Mime
14
+ :owner: Właściciel
15
+ :model: Model
16
+ :field: Pole
17
+ :updated: Aktualizowany
18
+
19
+ :ok: Ok
20
+ :link: Dołącz
21
+ :choose: Wybierz
22
+ :view: Szczegóły
23
+ :search_toggle: Szukaj
24
+ :link_list: Dołącz
25
+ :create: Utwórz
26
+ :modify: Modyfikuj
27
+ :search: Szukaj
28
+ :refresh: Odśwież
29
+ :default_order: Sortowanie domyślne
30
+ :select_toggle: Zaznacz
31
+ :confirm_delete: Usuń
32
+ :confirm_delete_title: <span class='glyphicon glyphicon-trash'></span> Potwierdzenie
33
+ :confirm_bulk_delete: Usuń zaznacznone
34
+ :delete_restricted: Blokujące relacje
35
+ :confirm_bulk_delete_title: <span class='glyphicon glyphicon-trash'></span> Potwierdzenie
36
+ :confirm_unlink: Odłącz
37
+ :confirm_unlink_title: <span class='glyphicon glyphicon-minus'></span> Potwierdzenie
38
+ :confirm_bulk_unlink: Odłącz zaznacznone
39
+ :confirm_bulk_unlink_title: <span class='glyphicon glyphicon-minus'></span> Potwierdzenie
40
+ :debug_info: Debug info
41
+ :show_meta: Pokaż metainformacje
42
+ # :meta: Meta
43
+ :view_title: <span class='glyphicon glyphicon-book'></span> Szczegóły
44
+ :create_title: <span class='glyphicon glyphicon-pencil'></span> Utwórz
45
+ :modify_title: <span class='glyphicon glyphicon-pencil'></span> Modyfikuj
46
+ :delete_title: <span class='glyphicon glyphicon-trash'></span> Usuń
47
+ :link_title: <span class='glyphicon glyphicon-paperclip'></span> Dołącz
48
+ :delete_question: Usunąć wpis ?
49
+ :unlink_question: Odłączyć wpis ?
50
+ :confirmation: Potwierdzenie
51
+ :save: Zapisz
52
+ :approve: Zatwierdź
53
+ :cancel: Anuluj
54
+
55
+ :inspect_modal: Inspekcja
56
+
57
+ :login_form: Zaloguj
58
+ :user_name: Użytkownik
59
+ :password: Hasło
60
+ :login: Zaloguj
61
+ :login_title: <span class='glyphicon glyphicon-log-in'></span> Logowanie
62
+
63
+ :logout_form: Wyloguj
64
+ :logout_title: <span class='glyphicon glyphicon-log-out'></span> Wyloguj
65
+ :logout_message: Wylogować ?
66
+
67
+ :user_required: Podaj nazwę użytkownika
68
+ :password_required: Podaj hasło
69
+ :password_invalid: Błędne hasło
70
+
71
+ :welcome: Witaj
72
+
73
+ :non_nullable: Niemożliwe ustawienie wartości pustej
74
+ :field_required: Pole wymagane
75
+ :wrong_boolean_value: Zła wartość dla boolean
76
+ :value_exceeds_maximum_length: Wartość przekracza dopuszczalną długość
77
+ :invalid_date_format: Niepoprawny format daty
78
+ :invalid_time_format: Niepoprawny format czasu
79
+ :invalid_datetime_format: Niepoprawny format daty/czasu
80
+ :value_from_gt_to: Wartość od > do
81
+ :invalid_number_value: Niepoprawna wartość liczbowa
82
+ :number_negative: Wartość ujemna
83
+ :invalid_list_value: Niepoprawna wartość dla listy
84
+ :invalid_decimal_value: Niepoprawna wartość decymalna
85
+ :invalid_currency_value: Niepoprawna wartość kwoty
86
+ :required_unique_value: Wymagana unikatowa wartość
87
+ :invalid_email_format: Niepoprawny format email
88
+ :invalid_format: Niepoprawny format
89
+
90
+ :access_forbidden: Dostęp zabroniony
91
+ :access_unauthorized: Dostęp nieautoryzowany
92
+ :access_not_found: Nie znaleziono
93
+ :access_method_not_allowed: Metoda niedozwolona
@@ -0,0 +1,34 @@
1
+ # coding: utf-8
2
+
3
+ require File.expand_path("../lib/engine2/version", __FILE__)
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "engine2"
7
+ spec.version = Engine2::VERSION
8
+ spec.authors = ["lopex"]
9
+ spec.email = ["lopx@gazeta.pl"]
10
+
11
+ spec.summary = "Tree based routing framework with scaffolding support"
12
+ spec.description = spec.summary
13
+ spec.homepage = "http://none.for.now"
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
17
+ spec.require_paths = ["lib"]
18
+
19
+ spec.add_dependency "sequel", '~> 4'
20
+ if defined? JRUBY_VERSION
21
+ spec.add_dependency 'jdbc-sqlite3', '~> 3.8'
22
+ else
23
+ spec.add_dependency 'sqlite3', '~> 1.3'
24
+ end
25
+ spec.add_dependency "sinatra", '~> 1.4'
26
+ spec.add_dependency 'slim', '~> 3.0'
27
+ spec.add_dependency "execjs", '~> 2.6'
28
+ spec.add_dependency 'coffee-script', '~> 2.4'
29
+
30
+ spec.add_development_dependency "bundler", "~> 1.11"
31
+ spec.add_development_dependency "rake", "~> 10.0"
32
+ spec.add_development_dependency 'uglifier', '~> 3.0'
33
+ spec.add_development_dependency 'yui-compressor', '~> 0.12'
34
+ end
@@ -0,0 +1,34 @@
1
+ # coding: utf-8
2
+
3
+ require 'yaml'
4
+ require 'logger'
5
+ require 'sequel'
6
+ require 'sinatra'
7
+ require 'json'
8
+ require 'slim'
9
+ require 'tilt/coffee'
10
+ require 'engine2/version'
11
+
12
+ %w[
13
+ core.rb
14
+ handler.rb
15
+ type_info.rb
16
+ model.rb
17
+ templates.rb
18
+ meta.rb
19
+ action.rb
20
+ scheme.rb
21
+
22
+ meta/list_meta.rb
23
+ meta/view_meta.rb
24
+ meta/form_meta.rb
25
+ meta/save_meta.rb
26
+ meta/delete_meta.rb
27
+ meta/decode_meta.rb
28
+ meta/link_meta.rb
29
+ meta/infra_meta.rb
30
+ ].each do |f|
31
+ load "engine2/#{f}"
32
+ end
33
+
34
+ Engine2.bootstrap
@@ -0,0 +1,217 @@
1
+ # coding: utf-8
2
+
3
+ module Engine2
4
+ class Action < BasicObject
5
+ ACCESS_FORBIDDEN ||= ->h{false}
6
+ attr_reader :parent, :name, :number, :actions, :recheck_access
7
+ attr_reader :meta_proc
8
+
9
+ class << self
10
+ attr_accessor :count
11
+ end
12
+
13
+ def initialize parent, name, meta_class, assets
14
+ Action.count += 1
15
+ @number = Action.count
16
+ @parent = parent
17
+ @name = name
18
+ @meta = meta_class.new(self, assets)
19
+ @actions = {}
20
+ end
21
+
22
+ def * &blk
23
+ if blk
24
+ ::Kernel.raise E2Error.new("Meta #{name} with proc already defined for action #{self.inspect}") if @meta_proc
25
+ @meta_proc = blk
26
+ end
27
+ @meta
28
+ end
29
+
30
+ def access! &blk
31
+ ::Kernel.raise E2Error.new("Access for action #{name} already defined") if @access_block
32
+ @access_block = blk
33
+ end
34
+
35
+ def access_forbidden!
36
+ access! &ACCESS_FORBIDDEN
37
+ end
38
+
39
+ def check_access! handler
40
+ !@access_block || @access_block.(handler)
41
+ end
42
+
43
+ def run_scheme name, *args, &blk
44
+ result = instance_exec(*args, &SCHEMES[name])
45
+ result.instance_eval(&blk) if blk
46
+ result
47
+ end
48
+
49
+ def define_action name, meta_class = DummyMeta, assets = {}, &blk
50
+ ::Kernel.raise E2Error.new("Action #{name} already defined") if @actions[name]
51
+ action = @actions[name] = Action.new(self, name, meta_class, assets)
52
+ action.*.pre_run
53
+ define_singleton_method! name do |&ablk| # forbidden list
54
+ action.instance_eval(&ablk) if ablk
55
+ action
56
+ end
57
+ action.instance_eval(&blk) if blk
58
+ action.*.action_defined
59
+ action
60
+ end
61
+
62
+ def undefine_action name
63
+ ::Kernel.raise E2Error.new("No action #{name} defined") unless @actions[name]
64
+ @actions.delete(name)
65
+ end
66
+
67
+ def define_action_bundle name, *actions
68
+ define_singleton_method!(name) do |&blk|
69
+ if blk
70
+ actions.each{|a|__send__(a, &blk)} # if @actions[action] ?
71
+ else
72
+ ActionBundle.new(self, actions)
73
+ end
74
+ end
75
+ end
76
+
77
+ def define_singleton_method! name, &blk
78
+ class << self;self;end.instance_eval do # __realclass__
79
+ define_method name, &blk
80
+ end
81
+ end
82
+
83
+ def [] name
84
+ @actions[name]
85
+ end
86
+
87
+ def actions_info handler
88
+ info = actions.inject({}) do |h, (name, a)|
89
+ meta = a.*
90
+ h[name] = {
91
+ meta_type: meta.meta_type,
92
+ method: meta.http_method,
93
+ number: a.number,
94
+ access: recheck_access ? nil : a.check_access!(handler),
95
+ recheck_access: a.recheck_access,
96
+ terminal: a.actions.empty?,
97
+ meta: !meta.get.empty?,
98
+ invokable: meta.invokable
99
+ }
100
+ h
101
+ end
102
+
103
+ info.first[1][:default] = true unless actions.empty?
104
+ info
105
+ end
106
+
107
+ def access_info handler
108
+ @actions.inject({}) do |h, (name, a)|
109
+ h[name] = a.check_access!(handler)
110
+ h
111
+ end
112
+ end
113
+
114
+ def recheck_access!
115
+ @recheck_access = true
116
+ end
117
+
118
+ def each_action &blk
119
+ # no self
120
+ @actions.each_pair do |n, a|
121
+ a.each_action(&blk) if yield a
122
+ end
123
+ end
124
+
125
+ def to_a_rec root = true, result = [], &blk # optimize
126
+ if root && (yield self)
127
+ result << self
128
+ @actions.each_pair do |n, a|
129
+ if yield a
130
+ result << a
131
+ a.to_a_rec(false, result, &blk)
132
+ end
133
+ end
134
+ end
135
+ result
136
+ end
137
+
138
+ def inspect
139
+ "Action: #{@name}, meta: #{@meta.class}, meta_type: #{@meta.meta_type}"
140
+ end
141
+
142
+ def setup_action_tree
143
+ time = ::Time.now
144
+
145
+ model_actions = {}
146
+ each_action do |action|
147
+ if model = action.*.assets[:model]
148
+ model_name = model.name.to_sym
149
+ model.synchronize_type_info
150
+ model_actions[model_name] = action.to_a_rec{|a| !a.*.assets[:assoc]}
151
+ action.run_scheme(model_name) if SCHEMES.schemes[model_name]
152
+ false
153
+ else
154
+ true
155
+ end
156
+ end
157
+
158
+ each_action do |action|
159
+ meta = action.*
160
+ model = meta.assets[:model]
161
+ assoc = meta.assets[:assoc]
162
+ if model && assoc
163
+ if source_actions = model_actions[model.name.to_sym]
164
+ source_action = source_actions.select{|sa| sa.meta_proc && sa.*.class >= meta.class}
165
+ # source_action = source_actions.select{|sa| sa.meta_proc && meta.class <= sa.*.class}
166
+ unless source_action.empty?
167
+ # raise E2Error.new("Multiple meta candidates for #{action.inspect} found in '#{source_action.inspect}'") if source_action.size > 1
168
+ # puts "#{action.inspect} => #{source_action.inspect}\n"
169
+ meta.instance_eval(&source_action.first.meta_proc)
170
+ end
171
+ end
172
+ end
173
+
174
+ meta.instance_eval(&action.meta_proc) if action.meta_proc
175
+ true
176
+ end
177
+
178
+ each_action do |action|
179
+ action.*.post_run
180
+ action.*.freeze_meta
181
+ true
182
+ end
183
+
184
+ ::Kernel::puts "ACTIONS: #{Action.count}, Time: #{::Time.now - time}"
185
+ # verify_action_usage
186
+ end
187
+
188
+ def verify_action_usage
189
+ t = ::Time.now
190
+ each_action do |action|
191
+ meta = action.*
192
+ model = meta.assets[:model]
193
+ if model
194
+ model.one_to_many_associations.each do |a|
195
+ end
196
+ true
197
+ else
198
+ true
199
+ end
200
+
201
+ end
202
+ ::Kernel::puts "VERIFY #{::Time.now - t}"
203
+ end
204
+ end
205
+
206
+
207
+ class ActionBundle
208
+ def initialize action, action_names
209
+ @action = action
210
+ @action_names = action_names
211
+ end
212
+
213
+ def method_missing name, *args, &blk
214
+ @action_names.each{|an| @action[an].__send__(name, *args, &blk)}
215
+ end
216
+ end
217
+ end