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
data/app/models/marty/role.rb~
DELETED
data/app/models/marty/script.rb~
DELETED
@@ -1,62 +0,0 @@
|
|
1
|
-
require 'mcfly'
|
2
|
-
|
3
|
-
class Marty::Script < Marty::Base
|
4
|
-
has_mcfly
|
5
|
-
|
6
|
-
<<<<<<< HEAD
|
7
|
-
# attr_accessible :name, :body
|
8
|
-
=======
|
9
|
-
>>>>>>> master
|
10
|
-
validates_presence_of :name, :body
|
11
|
-
mcfly_validates_uniqueness_of :name
|
12
|
-
validates_format_of :name, {
|
13
|
-
with: /\A[A-Z][a-zA-Z0-9]*\z/,
|
14
|
-
message: I18n.t('script.save_error'),
|
15
|
-
}
|
16
|
-
|
17
|
-
belongs_to :user, class_name: "Marty::User"
|
18
|
-
|
19
|
-
gen_mcfly_lookup :lookup, {
|
20
|
-
name: false,
|
21
|
-
}
|
22
|
-
|
23
|
-
gen_mcfly_lookup :get_all, {}, mode: :all
|
24
|
-
|
25
|
-
# find script by name/tag
|
26
|
-
def self.find_script(sname, tag=nil)
|
27
|
-
tag = Marty::Tag.map_to_tag(tag)
|
28
|
-
Marty::Script.lookup(tag.created_dt, sname)
|
29
|
-
end
|
30
|
-
|
31
|
-
def find_tag
|
32
|
-
# find the first tag created after this script.
|
33
|
-
Marty::Tag.where("created_dt >= ?", created_dt).order(:created_dt).first
|
34
|
-
end
|
35
|
-
|
36
|
-
def self.create_script(name, body)
|
37
|
-
script = new
|
38
|
-
script.name = name
|
39
|
-
script.body = body
|
40
|
-
script.save
|
41
|
-
script
|
42
|
-
end
|
43
|
-
|
44
|
-
delorean_fn :eval_to_hash, sig: 5 do
|
45
|
-
|dt, script, node, attrs, params|
|
46
|
-
tag = Marty::Tag.find_match(dt)
|
47
|
-
|
48
|
-
# IMPORTANT: engine evals (e.g. eval_to_hash) modify the
|
49
|
-
# params. So, need to clone it.
|
50
|
-
params = params.clone
|
51
|
-
|
52
|
-
raise "no tag found for #{dt}" unless tag
|
53
|
-
|
54
|
-
engine = Marty::ScriptSet.new(tag).get_engine(script)
|
55
|
-
res = engine.eval_to_hash(node, attrs, params)
|
56
|
-
|
57
|
-
# FIXME: should sanitize res to make sure that no nodes are being
|
58
|
-
# passed back. It's likely that nodes which are not from the
|
59
|
-
# current tag can caused problems.
|
60
|
-
res
|
61
|
-
end
|
62
|
-
end
|
data/app/models/marty/tag.rb~
DELETED
@@ -1,91 +0,0 @@
|
|
1
|
-
class Marty::Tag < Marty::Base
|
2
|
-
has_mcfly append_only: true
|
3
|
-
|
4
|
-
<<<<<<< HEAD
|
5
|
-
# attr_accessible :created_dt, :name, :comment
|
6
|
-
=======
|
7
|
-
>>>>>>> master
|
8
|
-
mcfly_validates_uniqueness_of :name
|
9
|
-
validates_presence_of :name, :comment
|
10
|
-
|
11
|
-
belongs_to :user, class_name: "Marty::User"
|
12
|
-
|
13
|
-
def self.make_name(dt)
|
14
|
-
return 'DEV' if Mcfly.is_infinity(dt)
|
15
|
-
|
16
|
-
# If no dt is provided (which is the usual non-testing case), we
|
17
|
-
# use Time.now.strftime to name the posting. This has the effect
|
18
|
-
# of using the host's timezone. i.e. since we're in PST8PDT, names
|
19
|
-
# will be based off of the Pacific TZ.
|
20
|
-
dt ||= Time.now
|
21
|
-
dt.strftime('%Y%m%d-%H%M')
|
22
|
-
end
|
23
|
-
|
24
|
-
before_validation :set_tag_name
|
25
|
-
def set_tag_name
|
26
|
-
self.name = self.class.make_name(self.created_dt)
|
27
|
-
true
|
28
|
-
end
|
29
|
-
|
30
|
-
def self.do_create(dt, comment)
|
31
|
-
o = new
|
32
|
-
o.comment = comment
|
33
|
-
o.created_dt = dt
|
34
|
-
o.save!
|
35
|
-
o
|
36
|
-
end
|
37
|
-
|
38
|
-
def isdev?
|
39
|
-
Mcfly.is_infinity(created_dt)
|
40
|
-
end
|
41
|
-
|
42
|
-
def self.map_to_tag(tag_id)
|
43
|
-
case tag_id
|
44
|
-
when String
|
45
|
-
tag = find_by_name(tag_id)
|
46
|
-
# if tag name wasn't found, look for a matching
|
47
|
-
# posting, then find the tag whose created_dt <= posting dt.
|
48
|
-
if !tag
|
49
|
-
posting = Marty::Posting.lookup(tag_id)
|
50
|
-
tag = find_match(Mcfly.normalize_infinity(posting.created_dt)) if
|
51
|
-
posting
|
52
|
-
end
|
53
|
-
when Fixnum
|
54
|
-
tag = find_by_id(tag_id)
|
55
|
-
when nil
|
56
|
-
tag = get_latest1
|
57
|
-
else
|
58
|
-
tag = tag_id
|
59
|
-
end
|
60
|
-
|
61
|
-
raise "bad tag identifier #{tag_id}" unless tag.is_a? Marty::Tag
|
62
|
-
tag
|
63
|
-
end
|
64
|
-
|
65
|
-
cached_delorean_fn :lookup, sig: 1 do
|
66
|
-
|name|
|
67
|
-
self.find_by_name(name)
|
68
|
-
end
|
69
|
-
|
70
|
-
# Performance hack to cache Rule AR object
|
71
|
-
cached_delorean_fn :lookup_id, sig: 1 do
|
72
|
-
|id|
|
73
|
-
find_by_id(id)
|
74
|
-
end
|
75
|
-
|
76
|
-
delorean_fn :lookup_dt, sig: 1 do
|
77
|
-
|name|
|
78
|
-
lookup(name).try(:created_dt)
|
79
|
-
end
|
80
|
-
|
81
|
-
delorean_fn :get_latest1, sig: 0 do
|
82
|
-
where("created_dt <> 'infinity'").order("created_dt DESC").first
|
83
|
-
end
|
84
|
-
|
85
|
-
delorean_fn :find_match, sig: 1 do
|
86
|
-
|dt|
|
87
|
-
id = where("created_dt <= ?", dt).order("created_dt DESC").pluck(:id).first
|
88
|
-
# performance hack
|
89
|
-
id && lookup_id(id)
|
90
|
-
end
|
91
|
-
end
|
data/app/models/marty/user.rb~
DELETED
@@ -1,148 +0,0 @@
|
|
1
|
-
require 'mcfly'
|
2
|
-
require 'net/ldap'
|
3
|
-
|
4
|
-
class Marty::User < Marty::Base
|
5
|
-
has_paper_trail
|
6
|
-
|
7
|
-
validates_presence_of :login, :firstname, :lastname
|
8
|
-
validates_uniqueness_of :login
|
9
|
-
|
10
|
-
validates_format_of :login, :with => /\A[a-z0-9_\-@\.]*\z/i
|
11
|
-
validates_length_of :login, :firstname, :lastname, maximum: 100
|
12
|
-
|
13
|
-
has_many :user_roles, dependent: :destroy
|
14
|
-
has_many :roles, through: :user_roles
|
15
|
-
|
16
|
-
scope :active, -> { where("#{self.table_name}.active = ?", true) }
|
17
|
-
|
18
|
-
validate :verify_changes
|
19
|
-
before_destroy :destroy_user
|
20
|
-
|
21
|
-
def name
|
22
|
-
"#{firstname} #{lastname}"
|
23
|
-
end
|
24
|
-
|
25
|
-
def to_s
|
26
|
-
name
|
27
|
-
end
|
28
|
-
|
29
|
-
# Returns the user who matches the given autologin +key+ or nil
|
30
|
-
def self.try_to_autologin(key)
|
31
|
-
tokens = Marty::Token.find_all_by_action_and_value('autologin', key.to_s)
|
32
|
-
# Make sure there's only 1 token that matches the key
|
33
|
-
if tokens.size == 1
|
34
|
-
token = tokens.first
|
35
|
-
autologin = Rails.configuration.marty.autologin || 0
|
36
|
-
|
37
|
-
if (token.created_on > autologin.to_i.day.ago) &&
|
38
|
-
token.user && token.user.active?
|
39
|
-
token.user
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
# Returns the user that matches provided login and password, or nil
|
45
|
-
def self.try_to_login(login, password)
|
46
|
-
login = login.to_s
|
47
|
-
password = password.to_s
|
48
|
-
|
49
|
-
# Make sure no one can sign in with an empty password
|
50
|
-
return nil if password.empty?
|
51
|
-
|
52
|
-
user = find_by_login(login)
|
53
|
-
|
54
|
-
return nil if !user || !user.active?
|
55
|
-
|
56
|
-
authenticate_with?(login, password) || nil
|
57
|
-
end
|
58
|
-
|
59
|
-
def self.authenticate_with?(login, password)
|
60
|
-
cf = Rails.configuration.marty
|
61
|
-
|
62
|
-
auth_source = cf.auth_source.to_s
|
63
|
-
|
64
|
-
if auth_source == "local"
|
65
|
-
ok = password == cf.local_password
|
66
|
-
elsif auth_source == "ldap"
|
67
|
-
# IMPORTANT NOTE: if server allows anonymous LDAP access, empty
|
68
|
-
# passwords will succeed! i.e. if a valid user with empty
|
69
|
-
# password is sent in, ldap.bind will return OK.
|
70
|
-
cf = Rails.configuration.marty.ldap
|
71
|
-
ldap = Net::LDAP.new(host: cf.host,
|
72
|
-
port: cf.port,
|
73
|
-
base: cf.base_dn,
|
74
|
-
auth: {
|
75
|
-
method: :simple,
|
76
|
-
username: cf.domain + "\\" + login,
|
77
|
-
password: password,
|
78
|
-
})
|
79
|
-
ok = ldap.bind
|
80
|
-
else
|
81
|
-
raise "bad auth_source: #{auth_source.inspect}"
|
82
|
-
end
|
83
|
-
|
84
|
-
find_by_login(login) if ok
|
85
|
-
end
|
86
|
-
|
87
|
-
def self.current=(user)
|
88
|
-
Mcfly.whodunnit = user
|
89
|
-
end
|
90
|
-
|
91
|
-
def self.current
|
92
|
-
Mcfly.whodunnit
|
93
|
-
end
|
94
|
-
|
95
|
-
def self.has_role(role)
|
96
|
-
mr = Mcfly.whodunnit.roles rescue []
|
97
|
-
mr.any? {|attr| attr.name == role}
|
98
|
-
end
|
99
|
-
|
100
|
-
private
|
101
|
-
def verify_changes
|
102
|
-
# If current users role is only user_manager, restrict following
|
103
|
-
# 1 - Do not allow user to edit own record
|
104
|
-
# 2 - Do not allow user to edit the Gemini system record
|
105
|
-
if user_manager_only
|
106
|
-
gemini_user = Marty::User.find_by_login(
|
107
|
-
Rails.configuration.marty.system_account.to_s)
|
108
|
-
gemini_id = gemini_user.id if gemini_user
|
109
|
-
|
110
|
-
if self.id == Mcfly.whodunnit.id
|
111
|
-
roles.each {|r| roles.delete r unless r.name == "user_manager"}
|
112
|
-
errors.add :base, "User Managers cannot edit "\
|
113
|
-
"or add additional roles to their own accounts"
|
114
|
-
elsif self.id == gemini_id
|
115
|
-
errors.add :base,
|
116
|
-
"User Managers cannot edit the Gemini system account"
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
errors.add :base, "The Gemini system account cannot be deactivated" if
|
121
|
-
self.login == Rails.configuration.marty.system_account.to_s &&
|
122
|
-
!self.active
|
123
|
-
|
124
|
-
errors.blank?
|
125
|
-
end
|
126
|
-
|
127
|
-
delorean_fn :get_roles, sig: 0 do
|
128
|
-
Mcfly.whodunnit.roles
|
129
|
-
end
|
130
|
-
|
131
|
-
def user_manager_only
|
132
|
-
Marty::User.has_role("user_manager") && !Marty::User.has_role("admin")
|
133
|
-
end
|
134
|
-
|
135
|
-
def destroy_user
|
136
|
-
errors.add :base, "You cannot delete your own account" if
|
137
|
-
self.login == Mcfly.whodunnit.login
|
138
|
-
|
139
|
-
errors.add :base, "You cannot delete the system account" if
|
140
|
-
self.login == Rails.configuration.marty.system_account.to_s
|
141
|
-
# Default to disallowing any deletions for now
|
142
|
-
|
143
|
-
errors.add :base,
|
144
|
-
"Users cannot be deleted - set 'Active' to false to disable the account"
|
145
|
-
|
146
|
-
errors.blank?
|
147
|
-
end
|
148
|
-
end
|
@@ -1,13 +0,0 @@
|
|
1
|
-
class Marty::UserRole < Marty::Base
|
2
|
-
has_paper_trail
|
3
|
-
|
4
|
-
<<<<<<< HEAD
|
5
|
-
# attr_accessible :user_id, :role_id
|
6
|
-
=======
|
7
|
-
>>>>>>> master
|
8
|
-
validates_uniqueness_of :user_id, scope: [:role_id]
|
9
|
-
validates_presence_of :user_id, :role_id
|
10
|
-
|
11
|
-
belongs_to :user
|
12
|
-
belongs_to :role
|
13
|
-
end
|
data/config/routes.rb~
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
require 'marty/migrations'
|
2
|
-
|
3
|
-
class CreateMartyPostings < McflyAppendOnlyMigration
|
4
|
-
include Marty::Migrations
|
5
|
-
|
6
|
-
def change
|
7
|
-
create_table :marty_postings do |t|
|
8
|
-
t.string :name, null: false
|
9
|
-
t.references :posting_type, null: false
|
10
|
-
t.boolean :is_test, null: false
|
11
|
-
t.string :comment, null: false
|
12
|
-
end
|
13
|
-
|
14
|
-
add_mcfly_index :marty_postings,
|
15
|
-
:name, :posting_type_id, :is_test
|
16
|
-
|
17
|
-
add_fk :postings, :posting_types
|
18
|
-
end
|
19
|
-
end
|
@@ -1,19 +0,0 @@
|
|
1
|
-
require 'marty/migrations'
|
2
|
-
|
3
|
-
class CreateMartyPostings < McflyAppendOnlyMigration
|
4
|
-
include Marty::Migrations
|
5
|
-
|
6
|
-
def change
|
7
|
-
create_table :marty_postings do |t|
|
8
|
-
t.string :name, null: false
|
9
|
-
t.references :posting_type, null: false
|
10
|
-
t.boolean :is_test, null: false
|
11
|
-
t.string :comment, null: false
|
12
|
-
end
|
13
|
-
|
14
|
-
add_mcfly_index :marty_postings,
|
15
|
-
:name, :posting_type_id, :is_test
|
16
|
-
|
17
|
-
add_fk :postings, :posting_types
|
18
|
-
end
|
19
|
-
end
|
data/lib/marty.rb~
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
require 'marty/engine'
|
2
|
-
require 'marty/monkey'
|
3
|
-
require 'marty/mcfly_query'
|
4
|
-
require 'marty/util'
|
5
|
-
require 'marty/migrations'
|
6
|
-
require 'marty/data_exporter'
|
7
|
-
require 'marty/xl.rb'
|
8
|
-
require 'marty/data_importer'
|
9
|
-
require 'marty/promise_job'
|
10
|
-
require 'marty/promise_proxy'
|
11
|
-
require 'marty/content_handler'
|
12
|
-
require 'marty/lazy_column_loader'
|
13
|
-
require 'marty/version'
|
@@ -1,93 +0,0 @@
|
|
1
|
-
module Marty::ContentHandler
|
2
|
-
GEN_FORMATS = {
|
3
|
-
"csv" => ['text/csv', 'download'],
|
4
|
-
"zip" => ['application/zip', 'download'],
|
5
|
-
"xlsx" => ['application/vnd.ms-excel', 'download'],
|
6
|
-
"html" => ['text/html', 'inline'],
|
7
|
-
"txt" => ['text/plain', 'inline'],
|
8
|
-
"json" => ['application/json', 'download'],
|
9
|
-
|
10
|
-
# hacky: default format is JSON
|
11
|
-
nil => ['application/json', 'download'],
|
12
|
-
}
|
13
|
-
|
14
|
-
def self.log_and_raise(err)
|
15
|
-
Marty::Util.logger.error err
|
16
|
-
raise err
|
17
|
-
end
|
18
|
-
|
19
|
-
def self.export(data, format, name)
|
20
|
-
begin
|
21
|
-
case format
|
22
|
-
when "csv"
|
23
|
-
res = Marty::DataExporter.to_csv(data)
|
24
|
-
when "xlsx"
|
25
|
-
res = Marty::Xl.spreadsheet(data).to_stream.read
|
26
|
-
when "zip"
|
27
|
-
res = to_zip(data)
|
28
|
-
when nil, "json"
|
29
|
-
res, format = data.to_json, "json"
|
30
|
-
else
|
31
|
-
res, format = {error: "Unknown format: #{format}"}.to_json, "json"
|
32
|
-
end
|
33
|
-
rescue => exc
|
34
|
-
res, format =
|
35
|
-
{error: "Failed conversion #{format}: #{exc}"}.to_json, "json"
|
36
|
-
end
|
37
|
-
|
38
|
-
type, disposition = GEN_FORMATS[format]
|
39
|
-
|
40
|
-
return [res, type, disposition, "#{name}.#{format}"]
|
41
|
-
end
|
42
|
-
|
43
|
-
private
|
44
|
-
|
45
|
-
def self.sanitize_filename(filename)
|
46
|
-
filename.strip.
|
47
|
-
gsub(/[\\\/]/, '_').
|
48
|
-
gsub(/[^[:print:]]/, '_')
|
49
|
-
end
|
50
|
-
|
51
|
-
def self.uniq_filename(filename, fset)
|
52
|
-
(0..1000).each { |i|
|
53
|
-
post = i==0 ? "" : " (#{i})"
|
54
|
-
fn = filename + post
|
55
|
-
return fn unless fset.member? fn
|
56
|
-
}
|
57
|
-
filename
|
58
|
-
end
|
59
|
-
|
60
|
-
def self.to_zip_stream(stream, path, data)
|
61
|
-
fset = Set.new
|
62
|
-
|
63
|
-
data.each { |r|
|
64
|
-
title, format, result = r["title"], r["format"], r["result"]
|
65
|
-
|
66
|
-
log_and_raise "Result has no title" unless title
|
67
|
-
log_and_raise "Result has no result" unless result
|
68
|
-
|
69
|
-
if format == "zip"
|
70
|
-
to_zip_stream(stream, path + [title], result)
|
71
|
-
next
|
72
|
-
end
|
73
|
-
|
74
|
-
res_data, _type, _disposition, res_name = export(result, format, title)
|
75
|
-
|
76
|
-
filename = uniq_filename(sanitize_filename(res_name), fset)
|
77
|
-
fset.add filename
|
78
|
-
|
79
|
-
stream.put_next_entry((path + [filename]).join('/'))
|
80
|
-
stream.write res_data
|
81
|
-
}
|
82
|
-
end
|
83
|
-
|
84
|
-
def self.to_zip(data)
|
85
|
-
raise "Can't convert non-array data to zip format: #{data.class}" unless
|
86
|
-
data.is_a?(Array)
|
87
|
-
|
88
|
-
res = Zip::OutputStream.write_buffer do |stream|
|
89
|
-
to_zip_stream(stream, [], data)
|
90
|
-
end
|
91
|
-
res.string
|
92
|
-
end
|
93
|
-
end
|