marty 2.5.2 → 2.5.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +4 -0
- data/.rubocop.yml +7 -0
- data/.rubocop_todo.yml +11 -589
- data/Gemfile +9 -9
- data/Gemfile.lock +1 -1
- data/Rakefile +1 -3
- data/app/components/marty/api_auth_view.rb +3 -3
- data/app/components/marty/api_config_view.rb +8 -8
- data/app/components/marty/api_log_view.rb +16 -20
- data/app/components/marty/auth_app.rb +6 -6
- data/app/components/marty/base_rule_view.rb +27 -19
- data/app/components/marty/config_view.rb +12 -9
- data/app/components/marty/data_grid_view.rb +26 -26
- data/app/components/marty/delorean_rule_view.rb +0 -1
- data/app/components/marty/event_view.rb +27 -27
- data/app/components/marty/extras/layout.rb +26 -26
- data/app/components/marty/extras/misc.rb +2 -2
- data/app/components/marty/grid.rb +13 -13
- data/app/components/marty/grid_append_only.rb +0 -1
- data/app/components/marty/import_type_view.rb +13 -13
- data/app/components/marty/import_view.rb +17 -16
- data/app/components/marty/log_view.rb +16 -14
- data/app/components/marty/main_auth_app.rb +59 -59
- data/app/components/marty/main_auth_app/client/main_auth_app.js +3 -3
- data/app/components/marty/mcfly_grid_panel.rb +10 -10
- data/app/components/marty/new_posting_form.rb +11 -11
- data/app/components/marty/new_posting_window.rb +0 -1
- data/app/components/marty/posting_grid.rb +12 -13
- data/app/components/marty/promise_view.rb +6 -6
- data/app/components/marty/report_form.rb +50 -53
- data/app/components/marty/report_select.rb +27 -27
- data/app/components/marty/reporting.rb +4 -4
- data/app/components/marty/script_form.rb +40 -42
- data/app/components/marty/script_grid.rb +24 -24
- data/app/components/marty/script_tester.rb +40 -42
- data/app/components/marty/scripting.rb +25 -27
- data/app/components/marty/simple_app.rb +24 -9
- data/app/components/marty/tag_grid.rb +12 -13
- data/app/components/marty/user_view.rb +35 -35
- data/app/controllers/marty/application_controller.rb +3 -4
- data/app/controllers/marty/components_controller.rb +1 -1
- data/app/controllers/marty/delayed_job_controller.rb +1 -0
- data/app/controllers/marty/diagnostic/controller.rb +4 -6
- data/app/controllers/marty/job_controller.rb +6 -6
- data/app/controllers/marty/report_controller.rb +11 -11
- data/app/controllers/marty/rpc_controller.rb +15 -16
- data/app/helpers/marty/script_set.rb +4 -4
- data/app/models/marty/api_auth.rb +4 -5
- data/app/models/marty/api_config.rb +1 -1
- data/app/models/marty/base.rb +9 -8
- data/app/models/marty/base_rule.rb +18 -13
- data/app/models/marty/config.rb +4 -5
- data/app/models/marty/data_grid.rb +157 -181
- data/app/models/marty/delorean_rule.rb +63 -62
- data/app/models/marty/enum.rb +1 -1
- data/app/models/marty/event.rb +56 -59
- data/app/models/marty/helper.rb +38 -6
- data/app/models/marty/import_type.rb +6 -6
- data/app/models/marty/log.rb +3 -2
- data/app/models/marty/name_validator.rb +3 -2
- data/app/models/marty/pg_enum.rb +3 -4
- data/app/models/marty/posting.rb +20 -24
- data/app/models/marty/promise.rb +28 -30
- data/app/models/marty/script.rb +30 -28
- data/app/models/marty/tag.rb +8 -8
- data/app/models/marty/token.rb +2 -2
- data/app/models/marty/user.rb +24 -23
- data/app/models/marty/vw_promise.rb +10 -11
- data/config/routes.rb +2 -2
- data/delorean/blame_report.dl +268 -0
- data/{spec/dummy/delorean/fields.dl → delorean/marty_fields.dl} +8 -0
- data/delorean/table_report.dl +34 -0
- data/docker-compose.dummy.yml +2 -3
- data/lib/marty/aws/base.rb +8 -8
- data/lib/marty/aws/request.rb +4 -4
- data/lib/marty/cache_adapters/mcfly_ruby_cache.rb +1 -0
- data/lib/marty/content_handler.rb +25 -25
- data/lib/marty/data_change.rb +49 -71
- data/lib/marty/data_conversion.rb +20 -28
- data/lib/marty/data_exporter.rb +25 -28
- data/lib/marty/data_importer.rb +25 -27
- data/lib/marty/engine.rb +1 -2
- data/lib/marty/json_schema.rb +22 -24
- data/lib/marty/logger.rb +6 -9
- data/lib/marty/mcfly_model.rb +20 -24
- data/lib/marty/migrations.rb +37 -35
- data/lib/marty/monkey.rb +33 -33
- data/lib/marty/permissions.rb +18 -18
- data/lib/marty/promise_job.rb +17 -17
- data/lib/marty/promise_proxy.rb +6 -6
- data/lib/marty/relation.rb +6 -7
- data/lib/marty/rpc_call.rb +13 -12
- data/lib/marty/rule_script_set.rb +32 -28
- data/lib/marty/schema_helper.rb +37 -51
- data/lib/marty/util.rb +25 -24
- data/lib/marty/version.rb +1 -1
- data/lib/marty/xl.rb +121 -115
- data/make-dummy.mk +3 -0
- data/marty.gemspec +21 -21
- data/other/marty/api/base.rb +34 -35
- data/other/marty/diagnostic/aws/ec2_instance.rb +8 -8
- data/other/marty/diagnostic/base.rb +13 -14
- data/other/marty/diagnostic/collection.rb +2 -1
- data/other/marty/diagnostic/connections.rb +8 -6
- data/other/marty/diagnostic/database.rb +1 -0
- data/other/marty/diagnostic/delayed_job_version.rb +7 -9
- data/other/marty/diagnostic/delayed_job_worker_total_count.rb +1 -1
- data/other/marty/diagnostic/delayed_job_workers.rb +1 -1
- data/other/marty/diagnostic/environment_variables.rb +17 -15
- data/other/marty/diagnostic/fatal.rb +1 -1
- data/other/marty/diagnostic/node.rb +5 -9
- data/other/marty/diagnostic/nodes.rb +7 -5
- data/other/marty/diagnostic/packer.rb +7 -7
- data/other/marty/diagnostic/reporter.rb +24 -27
- data/other/marty/diagnostic/version.rb +3 -5
- data/script/rails +2 -1
- data/spec/controllers/application_controller_spec.rb +6 -6
- data/spec/controllers/delayed_job_controller_spec.rb +4 -4
- data/spec/controllers/diagnostic/controller_spec.rb +59 -60
- data/spec/controllers/job_controller_spec.rb +68 -69
- data/spec/controllers/rpc_controller_spec.rb +353 -359
- data/spec/controllers/rpc_import_spec.rb +15 -16
- data/spec/dummy/delorean/blame_report.dl +110 -15
- data/spec/dummy/delorean/data_report.dl +4 -4
- data/spec/dummy/delorean/marty_fields.dl +63 -0
- data/spec/dummy/delorean/table_report.dl +34 -0
- data/spec/features/auth_app_spec.rb +1 -2
- data/spec/features/data_import_spec.rb +2 -3
- data/spec/features/enum_spec.rb +42 -46
- data/spec/features/jobs_dashboard_spec.rb +14 -8
- data/spec/features/log_view_spec.rb +40 -43
- data/spec/features/reporting_spec.rb +15 -15
- data/spec/features/rule_spec.rb +195 -190
- data/spec/features/scripting_spec.rb +17 -20
- data/spec/features/scripting_test_spec.rb +32 -33
- data/spec/features/user_view_spec.rb +15 -17
- data/spec/job_helper.rb +11 -11
- data/spec/lib/data_blame_spec.rb +82 -0
- data/spec/lib/data_exporter_spec.rb +31 -32
- data/spec/lib/data_importer_spec.rb +382 -395
- data/spec/lib/delorean_query_spec.rb +117 -119
- data/spec/lib/json_schema_spec.rb +382 -392
- data/spec/lib/logger_spec.rb +23 -24
- data/spec/lib/mcfly_model_spec.rb +112 -109
- data/spec/lib/migrations_spec.rb +10 -10
- data/spec/lib/struct_compare_spec.rb +6 -6
- data/spec/lib/table_report_spec.rb +90 -0
- data/spec/lib/xl_spec.rb +63 -65
- data/spec/lib/xl_styles_spec.rb +16 -19
- data/spec/models/api_auth_spec.rb +30 -30
- data/spec/models/config_spec.rb +32 -32
- data/spec/models/data_grid_spec.rb +642 -655
- data/spec/models/event_spec.rb +96 -88
- data/spec/models/import_type_spec.rb +20 -20
- data/spec/models/posting_spec.rb +35 -35
- data/spec/models/promise_spec.rb +5 -5
- data/spec/models/rule_spec.rb +280 -269
- data/spec/models/script_spec.rb +27 -18
- data/spec/models/user_spec.rb +9 -9
- data/spec/other/diagnostic/base_spec.rb +20 -19
- data/spec/other/diagnostic/collection_spec.rb +6 -5
- data/spec/other/diagnostic/delayed_job_version_spec.rb +1 -1
- data/spec/other/diagnostic/delayed_job_workers_spec.rb +8 -8
- data/spec/other/diagnostic/reporter_spec.rb +31 -33
- data/spec/spec_helper.rb +5 -5
- data/spec/support/chromedriver.rb +3 -5
- data/spec/support/components/netzke_combobox.rb +1 -1
- data/spec/support/components/netzke_grid.rb +17 -17
- data/spec/support/custom_matchers.rb +2 -2
- data/spec/support/download_helper.rb +1 -1
- data/spec/support/helper.rb +1 -2
- data/spec/support/netzke.rb +31 -31
- data/spec/support/performance_helper.rb +8 -8
- data/spec/support/post_run_logger.rb +1 -2
- data/spec/support/setup.rb +1 -4
- data/spec/support/shared_connection.rb +2 -2
- data/spec/support/structure_compare.rb +21 -22
- data/spec/support/suite.rb +1 -2
- data/spec/support/users.rb +5 -6
- metadata +32 -26
data/Gemfile
CHANGED
@@ -1,28 +1,28 @@
|
|
1
|
-
source
|
1
|
+
source 'http://rubygems.org'
|
2
2
|
|
3
3
|
# Declare your gem's dependencies in marty.gemspec.
|
4
4
|
# Bundler will treat runtime dependencies like base dependencies, and
|
5
5
|
# development dependencies will be added by default to the :development group.
|
6
6
|
gemspec
|
7
7
|
|
8
|
-
gem 'delayed_job_active_record'
|
9
8
|
gem 'daemons'
|
10
|
-
gem '
|
9
|
+
gem 'delayed_job_active_record'
|
11
10
|
gem 'pg'
|
11
|
+
gem 'rails', '~> 5.1.4'
|
12
12
|
gem 'sqlite3'
|
13
13
|
|
14
14
|
group :development, :test do
|
15
|
+
gem 'capybara'
|
16
|
+
gem 'chromedriver-helper'
|
17
|
+
gem 'connection_pool'
|
18
|
+
gem 'database_cleaner'
|
15
19
|
gem 'pry-rails'
|
16
|
-
gem '
|
20
|
+
gem 'rails-controller-testing'
|
17
21
|
gem 'rspec-instafail', require: false
|
22
|
+
gem 'rspec-rails'
|
18
23
|
gem 'rubocop', require: false
|
19
|
-
gem 'capybara'
|
20
24
|
gem 'selenium-webdriver'
|
21
|
-
gem 'chromedriver-helper'
|
22
25
|
gem 'timecop'
|
23
|
-
gem 'database_cleaner'
|
24
|
-
gem 'rails-controller-testing'
|
25
|
-
gem 'connection_pool'
|
26
26
|
|
27
27
|
# gem 'mcfly', path: File.expand_path('../../mcfly', __FILE__)
|
28
28
|
gem 'mcfly'
|
data/Gemfile.lock
CHANGED
data/Rakefile
CHANGED
@@ -20,11 +20,9 @@ RDoc::Task.new(:rdoc) do |rdoc|
|
|
20
20
|
rdoc.rdoc_files.include('lib/**/*.rb')
|
21
21
|
end
|
22
22
|
|
23
|
-
APP_RAKEFILE = File.expand_path(
|
23
|
+
APP_RAKEFILE = File.expand_path('../spec/dummy/Rakefile', __FILE__)
|
24
24
|
load 'rails/tasks/engine.rake'
|
25
25
|
|
26
|
-
|
27
|
-
|
28
26
|
Bundler::GemHelper.install_tasks
|
29
27
|
|
30
28
|
task default: 'app:spec'
|
@@ -7,10 +7,10 @@ class Marty::ApiAuthView < Marty::McflyGridPanel
|
|
7
7
|
def configure(c)
|
8
8
|
super
|
9
9
|
|
10
|
-
c.title = I18n.t('api_auth', default:
|
11
|
-
c.model =
|
10
|
+
c.title = I18n.t('api_auth', default: 'API Authorization')
|
11
|
+
c.model = 'Marty::ApiAuth'
|
12
12
|
c.attributes = [:app_name, :api_key, :script_name]
|
13
|
-
c.store_config.merge!(
|
13
|
+
c.store_config.merge!(sorters: [{ property: :app_name, direction: 'ASC' }])
|
14
14
|
end
|
15
15
|
|
16
16
|
attribute :app_name do |c|
|
@@ -23,11 +23,12 @@ class Marty::ApiConfigView < Marty::Grid
|
|
23
23
|
c.paging = :pagination
|
24
24
|
c.editing = :in_form
|
25
25
|
c.store_config.merge!(
|
26
|
-
sorters: [
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
26
|
+
sorters: [
|
27
|
+
{ property: :script, direction: :ASC },
|
28
|
+
{ property: :node, direction: :ASC },
|
29
|
+
{ property: :attr, direction: :ASC },
|
30
|
+
{ property: :api_class, direction: :ASC },
|
31
|
+
])
|
31
32
|
@model = c.model
|
32
33
|
end
|
33
34
|
|
@@ -44,7 +45,7 @@ class Marty::ApiConfigView < Marty::Grid
|
|
44
45
|
type: :string,
|
45
46
|
)
|
46
47
|
c.width = 200
|
47
|
-
c.label =
|
48
|
+
c.label = 'API Class'
|
48
49
|
end
|
49
50
|
|
50
51
|
attribute :script do |c|
|
@@ -70,8 +71,7 @@ class Marty::ApiConfigView < Marty::Grid
|
|
70
71
|
end
|
71
72
|
end
|
72
73
|
|
73
|
-
[:logged, :input_validated, :output_validated, :strict_validate].each do
|
74
|
-
|a|
|
74
|
+
[:logged, :input_validated, :output_validated, :strict_validate].each do |a|
|
75
75
|
attribute a do |c|
|
76
76
|
c.width = 110
|
77
77
|
end
|
@@ -30,8 +30,8 @@ class Marty::ApiLogView < Marty::Grid
|
|
30
30
|
c.title = 'Api Log View'
|
31
31
|
c.model = Marty::Log
|
32
32
|
c.attributes = @@attrs
|
33
|
-
c.scope = {message_type: 'api'}
|
34
|
-
c.store_config.merge!(sorters: [{property: :timestamp, direction: 'DESC'}])
|
33
|
+
c.scope = { message_type: 'api' }
|
34
|
+
c.store_config.merge!(sorters: [{ property: :timestamp, direction: 'DESC' }])
|
35
35
|
end
|
36
36
|
|
37
37
|
component :edit_window do |c|
|
@@ -46,8 +46,8 @@ class Marty::ApiLogView < Marty::Grid
|
|
46
46
|
:attrs,
|
47
47
|
:start_time,
|
48
48
|
:end_time,
|
49
|
-
textarea_field(:input).merge!(
|
50
|
-
textarea_field(:output).merge!(
|
49
|
+
textarea_field(:input).merge!(height: 300),
|
50
|
+
textarea_field(:output).merge!(height: 300),
|
51
51
|
:error,
|
52
52
|
:remote_ip,
|
53
53
|
:auth_name,
|
@@ -58,13 +58,11 @@ class Marty::ApiLogView < Marty::Grid
|
|
58
58
|
attribute a do |c|
|
59
59
|
c.filterable = true
|
60
60
|
c.read_only = true
|
61
|
-
c.getter = lambda {|r| r.details[a.to_s] }
|
62
|
-
c.sorting_scope = lambda {
|
63
|
-
|r, dir|
|
61
|
+
c.getter = lambda { |r| r.details[a.to_s] }
|
62
|
+
c.sorting_scope = lambda { |r, dir|
|
64
63
|
r.order("details->>'#{a.to_s}'" + dir.to_s)
|
65
64
|
}
|
66
|
-
c.filter_with = lambda {
|
67
|
-
|r, v, op|
|
65
|
+
c.filter_with = lambda { |r, v, op|
|
68
66
|
r.where("details->>'#{a.to_s}' #{op} '#{v}%'")
|
69
67
|
} unless [:start_time, :endtime].include?(a)
|
70
68
|
|
@@ -72,17 +70,15 @@ class Marty::ApiLogView < Marty::Grid
|
|
72
70
|
when :start_time, :end_time
|
73
71
|
c.type = :datetime
|
74
72
|
c.format = 'Y-m-d h:i:s'
|
75
|
-
c.getter = lambda {|r| Time.zone.parse(r.details[a.to_s])}
|
76
|
-
c.filter_with = lambda {
|
77
|
-
|r, v, op|
|
73
|
+
c.getter = lambda { |r| Time.zone.parse(r.details[a.to_s]) }
|
74
|
+
c.filter_with = lambda { |r, v, op|
|
78
75
|
r.where("(details->>'#{a.to_s}')::date #{DATE_OP_MAP[op]} '#{v}%'")
|
79
76
|
}
|
80
77
|
when :input, :output
|
81
78
|
c.getter = lambda { |r| r.details[a.to_s].pretty_inspect }
|
82
79
|
c.width = 900
|
83
80
|
c.read_only = true
|
84
|
-
c.filter_with = lambda {
|
85
|
-
|r, v, op|
|
81
|
+
c.filter_with = lambda { |r, v, op|
|
86
82
|
r.where("(details->>'#{a.to_s}')::text #{op} '%#{v}%'")
|
87
83
|
}
|
88
84
|
end
|
@@ -96,9 +92,9 @@ class Marty::ApiLogView < Marty::Grid
|
|
96
92
|
end
|
97
93
|
end
|
98
94
|
|
99
|
-
#copied from log_view.rb
|
95
|
+
# copied from log_view.rb
|
100
96
|
attribute :timestamp_custom do |c|
|
101
|
-
c.text = I18n.t(
|
97
|
+
c.text = I18n.t('log_grid.timestamp')
|
102
98
|
c.width = 200
|
103
99
|
c.read_only = true
|
104
100
|
c.filterable = true
|
@@ -108,14 +104,14 @@ class Marty::ApiLogView < Marty::Grid
|
|
108
104
|
xtype: :displayfield,
|
109
105
|
}
|
110
106
|
c.getter = lambda { |r| Time.at(r.timestamp) }
|
111
|
-
c.sorting_scope = lambda {|r, dir| r.order(
|
107
|
+
c.sorting_scope = lambda { |r, dir| r.order('timestamp ' + dir.to_s) }
|
112
108
|
|
113
109
|
# FIXME?: The UI AR/PG DateTime workaround requires the timestamp to be cast
|
114
110
|
# to text in order to compare filter input using the LIKE operator.
|
115
111
|
# Otherwise it will fail. '<' and '>' functionality is missing.
|
116
|
-
c.filter_with = lambda {|r, v, op|
|
117
|
-
r.where("timestamp::text #{op} '#{v}%'")
|
112
|
+
c.filter_with = lambda { |r, v, op|
|
113
|
+
r.where("timestamp::text #{op} '#{v}%'")
|
114
|
+
}
|
118
115
|
end
|
119
|
-
|
120
116
|
end
|
121
117
|
ApiLogView = Marty::ApiLogView
|
@@ -12,14 +12,14 @@ class Marty::AuthApp < Marty::SimpleApp
|
|
12
12
|
[].tap do |menu|
|
13
13
|
user = Mcfly.whodunnit
|
14
14
|
if !user.nil?
|
15
|
-
menu <<
|
15
|
+
menu << '->' << {
|
16
16
|
text: user.name,
|
17
17
|
tooltip: 'Current user',
|
18
18
|
menu: user_menu,
|
19
|
-
name:
|
19
|
+
name: 'sign_out',
|
20
20
|
}
|
21
21
|
else
|
22
|
-
menu <<
|
22
|
+
menu << '->' << :sign_in
|
23
23
|
end
|
24
24
|
end
|
25
25
|
end
|
@@ -29,18 +29,18 @@ class Marty::AuthApp < Marty::SimpleApp
|
|
29
29
|
end
|
30
30
|
|
31
31
|
action :sign_in do |c|
|
32
|
-
c.icon_cls =
|
32
|
+
c.icon_cls = 'fa fa-sign-in-alt gylph'
|
33
33
|
end
|
34
34
|
|
35
35
|
action :sign_out do |c|
|
36
|
-
c.icon_cls =
|
36
|
+
c.icon_cls = 'fa fa-sign-out-alt gylph'
|
37
37
|
c.text = "Sign out #{Mcfly.whodunnit.name}" if Mcfly.whodunnit
|
38
38
|
end
|
39
39
|
|
40
40
|
endpoint :sign_in do |params|
|
41
41
|
user = Marty::User.try_to_login(params[:login], params[:password])
|
42
42
|
user ? Netzke::Base.controller.set_user(user) :
|
43
|
-
client.netzke_notify(
|
43
|
+
client.netzke_notify('Wrong credentials')
|
44
44
|
|
45
45
|
!!user
|
46
46
|
end
|
@@ -4,6 +4,7 @@ class Marty::BaseRuleView < Marty::McflyGridPanel
|
|
4
4
|
def self.klass
|
5
5
|
Marty::BaseRule
|
6
6
|
end
|
7
|
+
|
7
8
|
def klass
|
8
9
|
self.class.klass
|
9
10
|
end
|
@@ -11,19 +12,21 @@ class Marty::BaseRuleView < Marty::McflyGridPanel
|
|
11
12
|
def self.base_fields
|
12
13
|
[:name]
|
13
14
|
end
|
15
|
+
|
14
16
|
def self.computed_fields
|
15
17
|
[:computed_guards, :grids, :results]
|
16
18
|
end
|
19
|
+
|
17
20
|
def configure(c)
|
18
21
|
super
|
19
22
|
c.model = self.class.klass
|
20
23
|
c.title = I18n.t('rule')
|
21
24
|
c.attributes = self.class.base_fields +
|
22
25
|
klass.guard_info.
|
23
|
-
sort_by{|_, h| h[:order] || 0}.
|
24
|
-
reject{|_, h| h[:hidden]}.
|
26
|
+
sort_by { |_, h| h[:order] || 0 }.
|
27
|
+
reject { |_, h| h[:hidden] }.
|
25
28
|
map { |name, _| name.to_sym } + self.class.computed_fields
|
26
|
-
c.store_config.merge!(sorters: [{property: :name, direction: 'ASC'}])
|
29
|
+
c.store_config.merge!(sorters: [{ property: :name, direction: 'ASC' }])
|
27
30
|
c.editing = :in_form
|
28
31
|
c.paging = :pagination
|
29
32
|
c.multi_select = false
|
@@ -42,6 +45,7 @@ class Marty::BaseRuleView < Marty::McflyGridPanel
|
|
42
45
|
@key = key
|
43
46
|
@lineno = lineno
|
44
47
|
end
|
48
|
+
|
45
49
|
def message
|
46
50
|
"keyword '#{@key}' specified more than once (line #{@lineno})"
|
47
51
|
end
|
@@ -53,22 +57,25 @@ class Marty::BaseRuleView < Marty::McflyGridPanel
|
|
53
57
|
last_key = nil
|
54
58
|
s.lines.each.with_index(1) do |line, idx|
|
55
59
|
next if /\A\s*\z/.match(line)
|
60
|
+
|
56
61
|
line.chomp!
|
57
62
|
begin
|
58
63
|
m = /\A\s*([a-z][a-z0-9_]*)\s*=\s*(.*)\s*\z/.match(line)
|
59
64
|
if m
|
60
65
|
k, v = m[1], m[2]
|
61
66
|
raise DupKeyError.new(k, idx) if result.keys.include?(k)
|
67
|
+
|
62
68
|
save_linenos[k] = idx
|
63
69
|
result[k] = v
|
64
70
|
last_key = k
|
65
71
|
else
|
66
72
|
raise unless last_key
|
73
|
+
|
67
74
|
result[last_key] += "\n" + line.strip
|
68
75
|
end
|
69
76
|
rescue DupKeyError => e
|
70
77
|
raise
|
71
|
-
rescue => e
|
78
|
+
rescue StandardError => e
|
72
79
|
raise "syntax error on line #{idx}"
|
73
80
|
end
|
74
81
|
end
|
@@ -77,6 +84,7 @@ class Marty::BaseRuleView < Marty::McflyGridPanel
|
|
77
84
|
|
78
85
|
def self.hash_to_simple(h)
|
79
86
|
return unless h && h.present?
|
87
|
+
|
80
88
|
lhs_wid = h.keys.map(&:length).max
|
81
89
|
fmt = "%-#{lhs_wid}s = %s"
|
82
90
|
result = []
|
@@ -84,7 +92,7 @@ class Marty::BaseRuleView < Marty::McflyGridPanel
|
|
84
92
|
vlines = vstr.lines.map(&:chomp)
|
85
93
|
fst = vlines.shift
|
86
94
|
result << fmt % [k, fst]
|
87
|
-
vlines.each {|l| result <<
|
95
|
+
vlines.each { |l| result << ' ' * (lhs_wid + 3) + l }
|
88
96
|
end
|
89
97
|
result.join("\n")
|
90
98
|
end
|
@@ -94,7 +102,7 @@ class Marty::BaseRuleView < Marty::McflyGridPanel
|
|
94
102
|
end
|
95
103
|
|
96
104
|
def jsonb_simple_getter(c)
|
97
|
-
lambda {|r| Marty::BaseRuleView.hash_to_simple(r.send(c)) }
|
105
|
+
lambda { |r| Marty::BaseRuleView.hash_to_simple(r.send(c)) }
|
98
106
|
end
|
99
107
|
|
100
108
|
def jsonb_simple_setter(c)
|
@@ -104,7 +112,7 @@ class Marty::BaseRuleView < Marty::McflyGridPanel
|
|
104
112
|
|
105
113
|
begin
|
106
114
|
final = Marty::BaseRuleView.simple_to_hash(v)
|
107
|
-
rescue => e
|
115
|
+
rescue StandardError => e
|
108
116
|
final = { "~~ERROR~~": e.message }
|
109
117
|
end
|
110
118
|
|
@@ -115,16 +123,16 @@ class Marty::BaseRuleView < Marty::McflyGridPanel
|
|
115
123
|
}
|
116
124
|
end
|
117
125
|
|
118
|
-
def self.jsonb_field_getter(j, c, nullbool=nil)
|
126
|
+
def self.jsonb_field_getter(j, c, nullbool = nil)
|
119
127
|
lambda do |r|
|
120
128
|
rv = r.send(j)[c]
|
121
129
|
v = nullbool ? (rv == true ? 'True' :
|
122
130
|
rv == false ? 'False' : rv) : rv
|
123
|
-
v ||
|
131
|
+
v || ''
|
124
132
|
end
|
125
133
|
end
|
126
134
|
|
127
|
-
def self.jsonb_field_setter(j, c, bool=nil)
|
135
|
+
def self.jsonb_field_setter(j, c, bool = nil)
|
128
136
|
lambda do |r, rv|
|
129
137
|
v = bool ? rv.to_s.downcase == 'true' : rv
|
130
138
|
rv == '' || rv == '---' ? r.send(j).delete(c) : r.send(j)[c] = v
|
@@ -157,7 +165,7 @@ class Marty::BaseRuleView < Marty::McflyGridPanel
|
|
157
165
|
c.width = 150
|
158
166
|
end
|
159
167
|
|
160
|
-
def self.grid_column(c, label=nil)
|
168
|
+
def self.grid_column(c, label = nil)
|
161
169
|
editor_config = {
|
162
170
|
trigger_action: :all,
|
163
171
|
xtype: :combo,
|
@@ -173,8 +181,8 @@ class Marty::BaseRuleView < Marty::McflyGridPanel
|
|
173
181
|
type: :string,
|
174
182
|
getter: jsonb_field_getter(:grids, c.to_s),
|
175
183
|
setter: jsonb_field_setter(:grids, c.to_s),
|
176
|
-
# getter: lambda { |r| r.grids[c.to_s] },
|
177
|
-
# setter: lambda { |r, v| r.grids[c.to_s] = v },
|
184
|
+
# getter: lambda { |r| r.grids[c.to_s] },
|
185
|
+
# setter: lambda { |r, v| r.grids[c.to_s] = v },
|
178
186
|
}
|
179
187
|
end
|
180
188
|
|
@@ -183,7 +191,7 @@ class Marty::BaseRuleView < Marty::McflyGridPanel
|
|
183
191
|
end
|
184
192
|
|
185
193
|
def form_items_guards
|
186
|
-
klass.guard_info.reject{|_, h| h[:hidden]}.keys.map
|
194
|
+
klass.guard_info.reject { |_, h| h[:hidden] }.keys.map(&:to_sym)
|
187
195
|
end
|
188
196
|
|
189
197
|
def form_items_grids
|
@@ -213,11 +221,11 @@ class Marty::BaseRuleView < Marty::McflyGridPanel
|
|
213
221
|
vbox(*form_items_attrs +
|
214
222
|
form_items_guards,
|
215
223
|
border: false,
|
216
|
-
width:
|
217
|
-
|
224
|
+
width: '40%',
|
225
|
+
),
|
218
226
|
vbox(width: '2%', border: false),
|
219
227
|
vbox(
|
220
|
-
|
228
|
+
width: '55%', border: false),
|
221
229
|
height: '40%',
|
222
230
|
border: false,
|
223
231
|
),
|
@@ -227,7 +235,7 @@ class Marty::BaseRuleView < Marty::McflyGridPanel
|
|
227
235
|
form_items_results,
|
228
236
|
width: '99%',
|
229
237
|
border: false
|
230
|
-
|
238
|
+
),
|
231
239
|
height: '40%',
|
232
240
|
border: false
|
233
241
|
)
|
@@ -264,7 +272,7 @@ class Marty::BaseRuleView < Marty::McflyGridPanel
|
|
264
272
|
if h[:type] != :range
|
265
273
|
c.getter = Marty::BaseRuleView.jsonb_field_getter(meth, namestr, nullbool)
|
266
274
|
c.setter = Marty::BaseRuleView.jsonb_field_setter(meth, namestr,
|
267
|
-
h[:type]
|
275
|
+
h[:type] == :boolean)
|
268
276
|
c.filter_with = lambda do |rel, value, op|
|
269
277
|
v = ActiveRecord::Base.connection.quote(value)[1..-2]
|
270
278
|
rel.where("#{meth}->>'#{namestr}' like '%#{v}%'")
|
@@ -9,11 +9,11 @@ class Marty::ConfigView < Marty::Grid
|
|
9
9
|
def configure(c)
|
10
10
|
super
|
11
11
|
|
12
|
-
c.title = I18n.t('config', default:
|
13
|
-
c.model =
|
12
|
+
c.title = I18n.t('config', default: 'Config')
|
13
|
+
c.model = 'Marty::Config'
|
14
14
|
c.attributes = [:key, :value, :description]
|
15
15
|
c.editing = :both
|
16
|
-
c.store_config.merge!(sorters: [{property: :key, direction: 'ASC'}])
|
16
|
+
c.store_config.merge!(sorters: [{ property: :key, direction: 'ASC' }])
|
17
17
|
end
|
18
18
|
|
19
19
|
def my_jsonb_getter
|
@@ -21,13 +21,16 @@ class Marty::ConfigView < Marty::Grid
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def my_jsonb_pretty_getter
|
24
|
-
lambda { |r|
|
25
|
-
|
24
|
+
lambda { |r|
|
25
|
+
v = Marty::Config[r.key]
|
26
|
+
!v.nil? && (JSON.pretty_generate(v) rescue v.to_json) || ''
|
27
|
+
}
|
26
28
|
end
|
27
29
|
|
28
30
|
def my_jsonb_setter
|
29
31
|
lambda { |r, v|
|
30
32
|
return r.set_value(nil) if v.blank?
|
33
|
+
|
31
34
|
decoded = ActiveSupport::JSON.decode(v) rescue nil
|
32
35
|
r.set_value(decoded)
|
33
36
|
}
|
@@ -36,10 +39,10 @@ class Marty::ConfigView < Marty::Grid
|
|
36
39
|
def default_form_items
|
37
40
|
[
|
38
41
|
:key,
|
39
|
-
jsonb_field(:value,
|
40
|
-
|
41
|
-
|
42
|
-
|
42
|
+
jsonb_field(:value,
|
43
|
+
getter: my_jsonb_pretty_getter,
|
44
|
+
setter: my_jsonb_setter,
|
45
|
+
),
|
43
46
|
textarea_field(:description),
|
44
47
|
]
|
45
48
|
end
|