engine2 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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