marty 0.5.15 → 0.5.16
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +27 -0
- data/.rspec +3 -0
- data/.travis.yml +23 -0
- data/Gemfile +23 -0
- data/INDEPENDENCE_ISSUES.md +23 -0
- data/app/assets/images/marty/.gitkeep +0 -0
- data/app/components/marty/report_form.rb +9 -4
- data/gemini_deprecations.md +6 -0
- data/lib/marty/data_change.rb +99 -0
- data/lib/marty/data_conversion.rb +11 -3
- data/lib/marty/data_exporter.rb +9 -0
- data/lib/marty/version.rb +1 -1
- data/marty.gemspec +35 -0
- data/script/rails +8 -0
- data/spec/controllers/application_controller_spec.rb +52 -0
- data/spec/controllers/job_controller_spec.rb +226 -0
- data/spec/controllers/rpc_controller_spec.rb +379 -0
- data/spec/controllers/rpc_import_spec.rb +45 -0
- data/spec/dummy/README.rdoc +261 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/assets/javascripts/application.js +15 -0
- data/spec/dummy/app/assets/stylesheets/application.css +13 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/controllers/components_controller.rb +7 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/mailers/.gitkeep +0 -0
- data/spec/dummy/app/models/.gitkeep +0 -0
- data/spec/dummy/app/models/gemini/amortization_type.rb +5 -0
- data/spec/dummy/app/models/gemini/bud_category.rb +7 -0
- data/spec/dummy/app/models/gemini/entity.rb +2 -0
- data/spec/dummy/app/models/gemini/extras/data_import.rb +5 -0
- data/spec/dummy/app/models/gemini/extras/settlement_import.rb +28 -0
- data/spec/dummy/app/models/gemini/fannie_bup.rb +29 -0
- data/spec/dummy/app/models/gemini/grouping.rb +8 -0
- data/spec/dummy/app/models/gemini/grouping_head_version.rb +14 -0
- data/spec/dummy/app/models/gemini/head.rb +7 -0
- data/spec/dummy/app/models/gemini/head_version.rb +14 -0
- data/spec/dummy/app/models/gemini/helper.rb +44 -0
- data/spec/dummy/app/models/gemini/loan_program.rb +11 -0
- data/spec/dummy/app/models/gemini/mortgage_type.rb +5 -0
- data/spec/dummy/app/models/gemini/simple.rb +6 -0
- data/spec/dummy/app/models/gemini/streamline_type.rb +16 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +82 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml.example +10 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +35 -0
- data/spec/dummy/config/environments/production.rb +69 -0
- data/spec/dummy/config/environments/test.rb +39 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/delayed_job.rb +5 -0
- data/spec/dummy/config/initializers/inflections.rb +15 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +12 -0
- data/spec/dummy/db/migrate/20140801000000_create_groupings.rb +11 -0
- data/spec/dummy/db/migrate/20150406171536_create_categories.rb +27 -0
- data/spec/dummy/db/migrate/20150408200916_create_loan_programs.rb +26 -0
- data/spec/dummy/db/migrate/20150408201429_create_types.rb +21 -0
- data/spec/dummy/db/migrate/20150420000001_create_heads.rb +14 -0
- data/spec/dummy/db/migrate/20150420000002_create_head_versions.rb +15 -0
- data/spec/dummy/db/migrate/20150420000003_create_grouping_head_versions.rb +12 -0
- data/spec/dummy/db/migrate/20151023000001_create_simple.rb +12 -0
- data/spec/dummy/db/seeds.rb +8 -0
- data/spec/dummy/delorean/blame_report.dl +171 -0
- data/spec/dummy/delorean/data_report.dl +105 -0
- data/spec/dummy/delorean/fields.dl +52 -0
- data/spec/dummy/delorean/styles.dl +134 -0
- data/spec/dummy/lib/assets/.gitkeep +0 -0
- data/spec/dummy/lib/class_list.rb +3 -0
- data/spec/dummy/log/.gitkeep +0 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +25 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/public/icons/READ.txt +3 -0
- data/spec/dummy/public/icons/application_cascade.png +0 -0
- data/spec/dummy/public/icons/application_delete.png +0 -0
- data/spec/dummy/public/icons/application_put.png +0 -0
- data/spec/dummy/public/icons/application_view_detail.png +0 -0
- data/spec/dummy/public/icons/arrow_in.png +0 -0
- data/spec/dummy/public/icons/arrow_refresh.png +0 -0
- data/spec/dummy/public/icons/database_save.png +0 -0
- data/spec/dummy/public/icons/door_in.png +0 -0
- data/spec/dummy/public/icons/door_out.png +0 -0
- data/spec/dummy/public/icons/group.png +0 -0
- data/spec/dummy/public/icons/page_lightning.png +0 -0
- data/spec/dummy/public/icons/printer.png +0 -0
- data/spec/dummy/public/icons/report_disk.png +0 -0
- data/spec/dummy/public/icons/report_go.png +0 -0
- data/spec/dummy/public/icons/report_magnify.png +0 -0
- data/spec/dummy/public/icons/script.png +0 -0
- data/spec/dummy/public/icons/script_add.png +0 -0
- data/spec/dummy/public/icons/script_go.png +0 -0
- data/spec/dummy/public/icons/script_key.png +0 -0
- data/spec/dummy/public/icons/table_go.png +0 -0
- data/spec/dummy/public/icons/time.png +0 -0
- data/spec/dummy/public/icons/time_add.png +0 -0
- data/spec/dummy/public/icons/time_go.png +0 -0
- data/spec/dummy/public/icons/timeline_marker.png +0 -0
- data/spec/dummy/public/icons/user_add.png +0 -0
- data/spec/dummy/public/icons/user_delete.png +0 -0
- data/spec/dummy/public/icons/user_edit.png +0 -0
- data/spec/dummy/public/icons/wrench.png +0 -0
- data/spec/dummy/script/delayed_job +6 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/features/javascripts/job_dashboard_live_search.js.coffee +8 -0
- data/spec/features/javascripts/login.js.coffee +8 -0
- data/spec/features/jobs_dashboard_netzke_spec.rb +24 -0
- data/spec/features/jobs_dashboard_spec.rb +49 -0
- data/spec/fixtures/scripts/load_tests/script1.dl +2 -0
- data/spec/fixtures/scripts/load_tests/script2.dl +2 -0
- data/spec/job_helper.rb +102 -0
- data/spec/lib/data_exporter_spec.rb +71 -0
- data/spec/lib/data_importer_spec.rb +461 -0
- data/spec/lib/xl_spec.rb +198 -0
- data/spec/lib/xl_styles_spec.rb +115 -0
- data/spec/models/api_auth_spec.rb +187 -0
- data/spec/models/posting_spec.rb +107 -0
- data/spec/models/promise_spec.rb +65 -0
- data/spec/models/script_spec.rb +187 -0
- data/spec/models/user_spec.rb +68 -0
- data/spec/requests/routes_spec.rb +12 -0
- data/spec/spec_helper.rb +61 -0
- data/spec/support/clean_db_helpers.rb +18 -0
- data/spec/support/delayed_job_helpers.rb +12 -0
- data/spec/support/user_helpers.rb +12 -0
- metadata +139 -89
- data/app/components/marty/auth_app.rb~ +0 -51
- data/app/components/marty/auth_app/javascripts/auth_app.js~ +0 -91
- data/app/components/marty/cm_form_panel.rb~ +0 -5
- data/app/components/marty/cm_grid_panel.rb~ +0 -35
- data/app/components/marty/data_import_view.rb~ +0 -142
- data/app/components/marty/extras/layout.rb~ +0 -46
- data/app/components/marty/live_search_grid_panel.rb~ +0 -49
- data/app/components/marty/main_auth_app.rb~ +0 -238
- data/app/components/marty/mcfly_grid_panel.rb~ +0 -80
- data/app/components/marty/new_posting_form.rb~ +0 -46
- data/app/components/marty/new_posting_window.rb~ +0 -21
- data/app/components/marty/pivot_grid.rb +0 -52
- data/app/components/marty/pivot_grid/endpoints.rb +0 -45
- data/app/components/marty/pivot_grid/javascripts/extensions.js +0 -150
- data/app/components/marty/pivot_grid/javascripts/pivot_grid.js +0 -86
- data/app/components/marty/pivot_grid/services.rb +0 -44
- data/app/components/marty/posting_grid.rb~ +0 -140
- data/app/components/marty/promise_view.rb~ +0 -157
- data/app/components/marty/promise_view/stylesheets/promise_view.css~ +0 -15
- data/app/components/marty/report_form.rb~ +0 -217
- data/app/components/marty/report_select.rb~ +0 -133
- data/app/components/marty/reporting.rb~ +0 -39
- data/app/components/marty/script_detail.rb~ +0 -430
- data/app/components/marty/script_form.rb~ +0 -233
- data/app/components/marty/script_form/javascripts/Ext.ux.form.field.CodeMirror.js~ +0 -909
- data/app/components/marty/script_grid.rb~ +0 -99
- data/app/components/marty/script_tester.rb~ +0 -213
- data/app/components/marty/scripting.rb~ +0 -124
- data/app/components/marty/select_report.rb~ +0 -143
- data/app/components/marty/simple_app.rb~ +0 -101
- data/app/components/marty/tag_grid.rb~ +0 -89
- data/app/components/marty/tree_panel.rb~ +0 -256
- data/app/components/marty/tree_panel/javascripts/tree_panel.js~ +0 -317
- data/app/components/marty/user_pivot.rb +0 -128
- data/app/components/marty/user_view.rb~ +0 -188
- data/app/controllers/marty/application_controller.rb~ +0 -133
- data/app/controllers/marty/components_controller.rb~ +0 -37
- data/app/controllers/marty/job_controller.rb~ +0 -28
- data/app/controllers/marty/rpc_controller.rb~ +0 -61
- data/app/helpers/marty/script_set.rb~ +0 -59
- data/app/models/marty/api_auth.rb~ +0 -48
- data/app/models/marty/data_change.rb~ +0 -141
- data/app/models/marty/enum.rb~ +0 -16
- data/app/models/marty/import_type.rb~ +0 -48
- data/app/models/marty/poop.rb~ +0 -169
- data/app/models/marty/posting.rb~ +0 -86
- data/app/models/marty/posting_type.rb~ +0 -21
- data/app/models/marty/promise.rb~ +0 -196
- data/app/models/marty/role.rb~ +0 -10
- data/app/models/marty/script.rb~ +0 -62
- data/app/models/marty/tag.rb~ +0 -91
- data/app/models/marty/user.rb~ +0 -148
- data/app/models/marty/user_role.rb~ +0 -13
- data/app/views/layouts/marty/application.html.erb~ +0 -11
- data/config/routes.rb~ +0 -10
- data/db/migrate/019_create_marty_postings.rb~ +0 -19
- data/db/migrate/095_create_marty_tags.rb~ +0 -19
- data/lib/marty.rb~ +0 -13
- data/lib/marty/content_handler.rb~ +0 -93
- data/lib/marty/data_exporter.rb~ +0 -137
- data/lib/marty/data_importer.rb~ +0 -114
- data/lib/marty/data_row_processor.rb~ +0 -206
- data/lib/marty/drop_folder_hook.rb~ +0 -17
- data/lib/marty/folder_hook.rb~ +0 -9
- data/lib/marty/lazy_column_loader.rb~ +0 -47
- data/lib/marty/mcfly_query.rb~ +0 -188
- data/lib/marty/migrations.rb~ +0 -65
- data/lib/marty/monkey.rb~ +0 -160
- data/lib/marty/permissions.rb~ +0 -69
- data/lib/marty/promise.rb~ +0 -41
- data/lib/marty/promise_job.rb~ +0 -121
- data/lib/marty/promise_proxy.rb~ +0 -69
- data/lib/marty/util.rb~ +0 -80
- data/lib/marty/version.rb~ +0 -3
- data/lib/marty/xl.rb~ +0 -526
- data/lib/pyxll/README.txt~ +0 -16
- data/lib/pyxll/gemini.py~ +0 -110
- data/lib/pyxll/pyxll.cfg~ +0 -12
@@ -1,37 +0,0 @@
|
|
1
|
-
class Marty::ComponentsController < Marty::ApplicationController
|
2
|
-
# This is useful for individual component testing. Note that the
|
3
|
-
# appropriate route needs to be defined.
|
4
|
-
# <base_url>/components/<ComponentCamelCaseName>
|
5
|
-
def index
|
6
|
-
component = params[:component]
|
7
|
-
|
8
|
-
return redirect_to root_path unless component
|
9
|
-
|
10
|
-
format, req_disposition, title =
|
11
|
-
params[:format], params[:disposition], params[:reptitle]
|
12
|
-
|
13
|
-
if format && Marty::ContentHandler::GEN_FORMATS.member?(format)
|
14
|
-
klass = component.constantize
|
15
|
-
|
16
|
-
raise "bad component" unless klass < Netzke::Base
|
17
|
-
|
18
|
-
inst = klass.new
|
19
|
-
return unless inst.respond_to?(:export_content)
|
20
|
-
|
21
|
-
title ||= component
|
22
|
-
|
23
|
-
res, type, disposition, filename =
|
24
|
-
inst.export_content(format, title, params)
|
25
|
-
|
26
|
-
return send_data(res,
|
27
|
-
type: type,
|
28
|
-
filename: filename,
|
29
|
-
disposition: req_disposition || disposition,
|
30
|
-
)
|
31
|
-
end
|
32
|
-
|
33
|
-
cname = component.gsub("::", "_").underscore
|
34
|
-
render layout: true,
|
35
|
-
inline: "<%= netzke :#{cname}, class_name: '#{component}', height: 650 %>"
|
36
|
-
end
|
37
|
-
end
|
@@ -1,28 +0,0 @@
|
|
1
|
-
class Marty::JobController < ActionController::Base
|
2
|
-
def download
|
3
|
-
job_id = params["job_id"]
|
4
|
-
|
5
|
-
promise = Marty::Promise.find_by_id(job_id)
|
6
|
-
|
7
|
-
if promise
|
8
|
-
format = promise.cformat
|
9
|
-
# somewhat hacky: if result has "result" key, it's used as the
|
10
|
-
# content.
|
11
|
-
data = promise.result["result"] || promise.result
|
12
|
-
title = promise.title
|
13
|
-
else
|
14
|
-
format = "json"
|
15
|
-
data = {error: "Job not found: #{job_id}"}
|
16
|
-
title = "error"
|
17
|
-
end
|
18
|
-
|
19
|
-
res, type, disposition, filename =
|
20
|
-
Marty::ContentHandler.export(data, format, title)
|
21
|
-
|
22
|
-
send_data(res,
|
23
|
-
type: type,
|
24
|
-
filename: filename,
|
25
|
-
disposition: disposition,
|
26
|
-
)
|
27
|
-
end
|
28
|
-
end
|
@@ -1,61 +0,0 @@
|
|
1
|
-
class Marty::RpcController < ActionController::Base
|
2
|
-
respond_to :json, :csv
|
3
|
-
|
4
|
-
def evaluate
|
5
|
-
res = do_eval(params["script"],
|
6
|
-
params["version"],
|
7
|
-
params["node"],
|
8
|
-
params["attrs"] || "[]",
|
9
|
-
params["params"] || "{}",
|
10
|
-
)
|
11
|
-
|
12
|
-
respond_to do |format|
|
13
|
-
format.json { send_data res.to_json }
|
14
|
-
format.csv {
|
15
|
-
# SEMI-HACKY: strip outer list if there's only one element.
|
16
|
-
res = res[0] if res.is_a?(Array) && res.length==1
|
17
|
-
send_data Marty::DataExporter.to_csv(res)
|
18
|
-
}
|
19
|
-
end
|
20
|
-
|
21
|
-
end
|
22
|
-
|
23
|
-
private
|
24
|
-
|
25
|
-
def do_eval(sname, version, node, attrs, params)
|
26
|
-
return {error: "Bad attrs"} if !attrs.is_a?(String)
|
27
|
-
|
28
|
-
begin
|
29
|
-
attrs = ActiveSupport::JSON.decode(attrs)
|
30
|
-
rescue MultiJson::DecodeError
|
31
|
-
return {error: "Malformed attrs"}
|
32
|
-
end
|
33
|
-
|
34
|
-
return {error: "Malformed attrs"} unless
|
35
|
-
attrs.is_a?(Array) && attrs.all? {|x| x.is_a? String}
|
36
|
-
|
37
|
-
return {error: "Bad params"} if !params.is_a?(String)
|
38
|
-
|
39
|
-
begin
|
40
|
-
params = ActiveSupport::JSON.decode(params)
|
41
|
-
rescue MultiJson::DecodeError
|
42
|
-
return {error: "Malformed params"}
|
43
|
-
end
|
44
|
-
|
45
|
-
return {error: "Malformed params"} unless
|
46
|
-
params.is_a?(Hash)
|
47
|
-
|
48
|
-
script = Marty::Script.find_script(sname, version)
|
49
|
-
|
50
|
-
return {error: "Can't find #{sname} version #{version}"} unless script
|
51
|
-
|
52
|
-
engine = Marty::ScriptSet.get_engine(script)
|
53
|
-
|
54
|
-
begin
|
55
|
-
engine.evaluate_attrs(node, attrs, params)
|
56
|
-
rescue => exc
|
57
|
-
Delorean::Engine.grok_runtime_exception(exc)
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
end
|
@@ -1,59 +0,0 @@
|
|
1
|
-
class Marty::ScriptSet < Delorean::AbstractContainer
|
2
|
-
# ScriptSet acts as a process-wide cache for Delorean
|
3
|
-
# engines. FIXME: rewrite as Singleton.
|
4
|
-
|
5
|
-
@@engines, @@dengines, @@dengines_dt = {}, {}, nil
|
6
|
-
|
7
|
-
attr_reader :tag
|
8
|
-
|
9
|
-
def self.clear_cache
|
10
|
-
@@engines, @@dengines, @@dengines_dt = {}, {}, nil
|
11
|
-
end
|
12
|
-
|
13
|
-
def initialize(tag=nil)
|
14
|
-
@tag = Marty::Tag.map_to_tag(tag)
|
15
|
-
super()
|
16
|
-
end
|
17
|
-
|
18
|
-
def parse_check(sname, body)
|
19
|
-
engine = Delorean::Engine.new(sname, self)
|
20
|
-
engine.parse(body)
|
21
|
-
engine
|
22
|
-
end
|
23
|
-
|
24
|
-
def get_engine(sname)
|
25
|
-
raise "bad sname #{sname}" unless sname.is_a?(String)
|
26
|
-
|
27
|
-
script = Marty::Script.find_script(sname, tag)
|
28
|
-
|
29
|
-
raise "No such script" unless script
|
30
|
-
|
31
|
-
if tag.isdev?
|
32
|
-
# FIXME: there are race conditions here if a script changes in
|
33
|
-
# the middle of a DEV import sequence. But, DEV imports are
|
34
|
-
# hacky/rare anyway. So, don't bother for now.
|
35
|
-
|
36
|
-
max_dt = Marty::Script.
|
37
|
-
where("created_dt <> 'infinity'").
|
38
|
-
order("created_dt DESC").limit(1).pluck(:created_dt).first
|
39
|
-
|
40
|
-
@@dengines_dt ||= max_dt
|
41
|
-
|
42
|
-
# reset dengine cache if a script has changed
|
43
|
-
@@dengines = {} if max_dt > @@dengines_dt
|
44
|
-
|
45
|
-
engine = @@dengines[sname]
|
46
|
-
|
47
|
-
return engine if engine
|
48
|
-
|
49
|
-
@@dengines[sname] = engine = parse_check(sname, script.body)
|
50
|
-
else
|
51
|
-
engine = @@engines[[tag.id, sname]]
|
52
|
-
|
53
|
-
return engine if engine
|
54
|
-
|
55
|
-
@@engines[[tag.id, sname]] = engine = parse_check(sname, script.body)
|
56
|
-
end
|
57
|
-
engine
|
58
|
-
end
|
59
|
-
end
|
@@ -1,48 +0,0 @@
|
|
1
|
-
require 'mcfly'
|
2
|
-
|
3
|
-
class Marty::ApiAuth < Marty::Base
|
4
|
-
has_mcfly
|
5
|
-
|
6
|
-
KEY_SIZE = 19
|
7
|
-
|
8
|
-
def self.generate_key
|
9
|
-
SecureRandom.hex(KEY_SIZE)
|
10
|
-
end
|
11
|
-
|
12
|
-
class ApiAuthValidator < ActiveModel::Validator
|
13
|
-
def validate(api)
|
14
|
-
api.errors[:base] =
|
15
|
-
"API Key length must be #{KEY_SIZE*2}" if
|
16
|
-
api.api_key && api.api_key.length != KEY_SIZE*2
|
17
|
-
|
18
|
-
api.errors[:base] =
|
19
|
-
"Script Name must reference a valid script" if
|
20
|
-
Marty::Script.find_script(api.script_name, nil).nil?
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
before_validation do
|
25
|
-
self.api_key = Marty::ApiAuth.generate_key if
|
26
|
-
self.api_key.nil? || self.api_key.length == 0
|
27
|
-
end
|
28
|
-
|
29
|
-
<<<<<<< HEAD
|
30
|
-
# attr_accessible :app_name, :api_key, :script_name
|
31
|
-
=======
|
32
|
-
>>>>>>> master
|
33
|
-
validates_presence_of :app_name, :api_key, :script_name
|
34
|
-
|
35
|
-
validates_with ApiAuthValidator
|
36
|
-
|
37
|
-
mcfly_validates_uniqueness_of :api_key, scope: [:script_name]
|
38
|
-
validates_uniqueness_of :app_name, scope: [:script_name,
|
39
|
-
:obsoleted_dt]
|
40
|
-
|
41
|
-
def self.authorized?(script_name, api_key)
|
42
|
-
is_secured = where(script_name: script_name,
|
43
|
-
obsoleted_dt: 'infinity').exists?
|
44
|
-
!is_secured || where(api_key: api_key,
|
45
|
-
script_name: script_name,
|
46
|
-
obsoleted_dt: 'infinity').exists?
|
47
|
-
end
|
48
|
-
end
|
@@ -1,141 +0,0 @@
|
|
1
|
-
require 'delorean_lang'
|
2
|
-
|
3
|
-
class Marty::DataChange
|
4
|
-
include Delorean::Model
|
5
|
-
|
6
|
-
# Some arbitrary limit so we don't allow enormous queries
|
7
|
-
MAX_COUNT = 64000
|
8
|
-
|
9
|
-
delorean_fn :changes, sig: 3 do
|
10
|
-
|t0, t1, class_name|
|
11
|
-
|
12
|
-
klass = class_name.constantize
|
13
|
-
|
14
|
-
t0 = 'infinity' if t0 == Float::INFINITY
|
15
|
-
t1 = 'infinity' if t1 == Float::INFINITY
|
16
|
-
|
17
|
-
info = Marty::DataExporter.class_info(klass)
|
18
|
-
changes = get_changed_data(t0, t1, klass)
|
19
|
-
|
20
|
-
changes.inject({}) { |h, (group_id, ol)|
|
21
|
-
h[group_id] = ol.each_with_index.map { |o, i|
|
22
|
-
profile = {
|
23
|
-
"obj" => o,
|
24
|
-
}
|
25
|
-
|
26
|
-
# Create a profile hash for each object in the group.
|
27
|
-
# "status" tells us if the object is old/new/mod. If
|
28
|
-
# status=="mod" then "changes" will provide the list of
|
29
|
-
# columns which changed. If the object was deleted during
|
30
|
-
# t0-t1 then we set the deleted flag in the profile.
|
31
|
-
profile["deleted"] = (group_id == o.id &&
|
32
|
-
o.obsoleted_dt != Float::INFINITY &&
|
33
|
-
(t1 == 'infinity' || o.obsoleted_dt < t1)
|
34
|
-
)
|
35
|
-
if i == 0
|
36
|
-
profile["status"] = o.created_dt < t0 ? "old" : "new"
|
37
|
-
prev = nil
|
38
|
-
else
|
39
|
-
profile["status"], prev = "mod", prev = ol[i-1]
|
40
|
-
end
|
41
|
-
|
42
|
-
profile["attrs"] = info[:cols].map { |c|
|
43
|
-
{
|
44
|
-
# FIXME: using .first on export_attr -- this will not work
|
45
|
-
# if the attr is an association which will requires
|
46
|
-
# multiple keys to identify (e.g. Rule: name & version)
|
47
|
-
"value" => Marty::DataExporter.export_attr(o, c, info).first,
|
48
|
-
"changed" => prev && (o.send(c.to_sym) != prev.send(c.to_sym)),
|
49
|
-
}
|
50
|
-
}
|
51
|
-
|
52
|
-
profile
|
53
|
-
}
|
54
|
-
h
|
55
|
-
}
|
56
|
-
end
|
57
|
-
|
58
|
-
delorean_fn :change_summary, sig: 3 do
|
59
|
-
|t0, t1, class_name|
|
60
|
-
|
61
|
-
klass = class_name.constantize
|
62
|
-
|
63
|
-
t0 = 'infinity' if t0 == Float::INFINITY
|
64
|
-
t1 = 'infinity' if t1 == Float::INFINITY
|
65
|
-
|
66
|
-
info = Marty::DataExporter.class_info(klass)
|
67
|
-
changes = get_changed_data(t0, t1, klass)
|
68
|
-
|
69
|
-
created = updated = deleted = 0
|
70
|
-
|
71
|
-
changes.each { |group_id, ol|
|
72
|
-
ol.each_with_index.map { |o, i|
|
73
|
-
deleted +=1 if (group_id == o.id &&
|
74
|
-
o.obsoleted_dt != Float::INFINITY &&
|
75
|
-
(t1 == 'infinity' || o.obsoleted_dt < t1)
|
76
|
-
)
|
77
|
-
if i == 0
|
78
|
-
created +=1 unless o.created_dt < t0
|
79
|
-
else
|
80
|
-
updated += 1
|
81
|
-
end
|
82
|
-
}
|
83
|
-
}
|
84
|
-
|
85
|
-
{'created' => created, 'updated' => updated, 'deleted' => deleted}
|
86
|
-
end
|
87
|
-
|
88
|
-
delorean_fn :class_list, sig: 0 do
|
89
|
-
Rails.configuration.marty.class_list.sort.uniq || []
|
90
|
-
end
|
91
|
-
|
92
|
-
delorean_fn :class_headers, sig: 1 do
|
93
|
-
|class_name|
|
94
|
-
|
95
|
-
klass = class_name.constantize
|
96
|
-
info = Marty::DataExporter.class_info(klass)
|
97
|
-
info[:cols].map { |c|
|
98
|
-
# strip _id if it's an assoc
|
99
|
-
c = c[0..-4] if info[:assoc][c]
|
100
|
-
I18n.t(c, scope: 'attributes')
|
101
|
-
}
|
102
|
-
end
|
103
|
-
|
104
|
-
delorean_fn :user_name, sig: 1 do
|
105
|
-
|user_id|
|
106
|
-
|
107
|
-
Marty::User.find_by_id(user_id).try(:name)
|
108
|
-
end
|
109
|
-
|
110
|
-
delorean_fn :sanitize_classes, sig: 1 do
|
111
|
-
|classes|
|
112
|
-
classes = classes.split(/,\s*/) if classes.is_a? String
|
113
|
-
|
114
|
-
classes.to_set & class_list.to_set
|
115
|
-
end
|
116
|
-
|
117
|
-
delorean_fn :do_export, sig: [2, 3] do
|
118
|
-
|pt, klass, sort_field=nil|
|
119
|
-
|
120
|
-
# allow classes on class_list or any Enum to be exported
|
121
|
-
raise "'#{klass}' not on class_list" unless
|
122
|
-
class_list.member?(klass) || klass.constantize.is_a?(Marty::Enum)
|
123
|
-
|
124
|
-
Marty::DataExporter.do_export(pt, klass.constantize, sort_field)
|
125
|
-
end
|
126
|
-
|
127
|
-
def self.get_changed_data(t0, t1, klass)
|
128
|
-
# The following test fails when t0/t1 are infinity. ActiveSupport
|
129
|
-
# doesn't know about infinity.
|
130
|
-
# return unless t0 < t1
|
131
|
-
|
132
|
-
change_q = '(obsoleted_dt >= ? AND obsoleted_dt < ?)' +
|
133
|
-
' OR (created_dt >= ? AND created_dt < ?)'
|
134
|
-
|
135
|
-
raise "Change count exceeds limit #{MAX_COUNT}" if
|
136
|
-
klass.where(change_q, t0, t1, t0, t1).count > MAX_COUNT
|
137
|
-
|
138
|
-
klass.where(change_q, t0, t1, t0, t1).
|
139
|
-
order("group_id, created_dt").group_by(&:group_id)
|
140
|
-
end
|
141
|
-
end
|
data/app/models/marty/enum.rb~
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
module Marty::Enum
|
2
|
-
def method_missing(meth, *args, &block)
|
3
|
-
if meth.to_s =~ /^[A-Z_]+$/ && args.empty?
|
4
|
-
items = self.all
|
5
|
-
items.each { |item|
|
6
|
-
name = item.name.upcase.gsub(/[\/\s-]/, '_')
|
7
|
-
self.define_singleton_method(name) do
|
8
|
-
item
|
9
|
-
end unless self.methods.member?(name.to_sym)
|
10
|
-
}
|
11
|
-
|
12
|
-
return self.send(meth) if self.methods.member?(meth)
|
13
|
-
end
|
14
|
-
super
|
15
|
-
end
|
16
|
-
end
|
@@ -1,48 +0,0 @@
|
|
1
|
-
class Marty::ImportType < Marty::Base
|
2
|
-
class ImportTypeValidator < ActiveModel::Validator
|
3
|
-
def validate(entry)
|
4
|
-
klass = entry.get_model_class
|
5
|
-
|
6
|
-
unless klass.is_a?(Class) && klass < ActiveRecord::Base
|
7
|
-
entry.errors[:base] = "bad model name"
|
8
|
-
return
|
9
|
-
end
|
10
|
-
|
11
|
-
[entry.cleaner_function, entry.validation_function].each { |func|
|
12
|
-
entry.errors[:base] = "unknown class method #{func}" if
|
13
|
-
func && !klass.respond_to?(func.to_sym)
|
14
|
-
}
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
<<<<<<< HEAD
|
19
|
-
# attr_accessible :name,
|
20
|
-
# :model_name,
|
21
|
-
# :cleaner_function,
|
22
|
-
# :validation_function
|
23
|
-
=======
|
24
|
-
belongs_to :role
|
25
|
-
>>>>>>> master
|
26
|
-
|
27
|
-
validates_presence_of :name, :model_name, :role_id
|
28
|
-
validates_uniqueness_of :name
|
29
|
-
validates_with ImportTypeValidator
|
30
|
-
|
31
|
-
def get_model_class
|
32
|
-
model_name.constantize
|
33
|
-
end
|
34
|
-
|
35
|
-
def allow_import?()
|
36
|
-
Mcfly.whodunnit.roles.pluck(:id).
|
37
|
-
include?(role_id) if Mcfly.whodunnit
|
38
|
-
end
|
39
|
-
|
40
|
-
delorean_fn :lookup, sig: 1 do
|
41
|
-
|name|
|
42
|
-
self.find_by_name(name)
|
43
|
-
end
|
44
|
-
|
45
|
-
delorean_fn :get_all, sig: 0 do
|
46
|
-
self.all
|
47
|
-
end
|
48
|
-
end
|