marty 0.5.15 → 0.5.16

Sign up to get free protection for your applications and to get access to all the features.
Files changed (212) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +27 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +23 -0
  5. data/Gemfile +23 -0
  6. data/INDEPENDENCE_ISSUES.md +23 -0
  7. data/app/assets/images/marty/.gitkeep +0 -0
  8. data/app/components/marty/report_form.rb +9 -4
  9. data/gemini_deprecations.md +6 -0
  10. data/lib/marty/data_change.rb +99 -0
  11. data/lib/marty/data_conversion.rb +11 -3
  12. data/lib/marty/data_exporter.rb +9 -0
  13. data/lib/marty/version.rb +1 -1
  14. data/marty.gemspec +35 -0
  15. data/script/rails +8 -0
  16. data/spec/controllers/application_controller_spec.rb +52 -0
  17. data/spec/controllers/job_controller_spec.rb +226 -0
  18. data/spec/controllers/rpc_controller_spec.rb +379 -0
  19. data/spec/controllers/rpc_import_spec.rb +45 -0
  20. data/spec/dummy/README.rdoc +261 -0
  21. data/spec/dummy/Rakefile +7 -0
  22. data/spec/dummy/app/assets/javascripts/application.js +15 -0
  23. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  24. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  25. data/spec/dummy/app/controllers/components_controller.rb +7 -0
  26. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  27. data/spec/dummy/app/mailers/.gitkeep +0 -0
  28. data/spec/dummy/app/models/.gitkeep +0 -0
  29. data/spec/dummy/app/models/gemini/amortization_type.rb +5 -0
  30. data/spec/dummy/app/models/gemini/bud_category.rb +7 -0
  31. data/spec/dummy/app/models/gemini/entity.rb +2 -0
  32. data/spec/dummy/app/models/gemini/extras/data_import.rb +5 -0
  33. data/spec/dummy/app/models/gemini/extras/settlement_import.rb +28 -0
  34. data/spec/dummy/app/models/gemini/fannie_bup.rb +29 -0
  35. data/spec/dummy/app/models/gemini/grouping.rb +8 -0
  36. data/spec/dummy/app/models/gemini/grouping_head_version.rb +14 -0
  37. data/spec/dummy/app/models/gemini/head.rb +7 -0
  38. data/spec/dummy/app/models/gemini/head_version.rb +14 -0
  39. data/spec/dummy/app/models/gemini/helper.rb +44 -0
  40. data/spec/dummy/app/models/gemini/loan_program.rb +11 -0
  41. data/spec/dummy/app/models/gemini/mortgage_type.rb +5 -0
  42. data/spec/dummy/app/models/gemini/simple.rb +6 -0
  43. data/spec/dummy/app/models/gemini/streamline_type.rb +16 -0
  44. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  45. data/spec/dummy/config.ru +4 -0
  46. data/spec/dummy/config/application.rb +82 -0
  47. data/spec/dummy/config/boot.rb +10 -0
  48. data/spec/dummy/config/database.yml.example +10 -0
  49. data/spec/dummy/config/environment.rb +5 -0
  50. data/spec/dummy/config/environments/development.rb +35 -0
  51. data/spec/dummy/config/environments/production.rb +69 -0
  52. data/spec/dummy/config/environments/test.rb +39 -0
  53. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  54. data/spec/dummy/config/initializers/delayed_job.rb +5 -0
  55. data/spec/dummy/config/initializers/inflections.rb +15 -0
  56. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  57. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  58. data/spec/dummy/config/initializers/session_store.rb +8 -0
  59. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  60. data/spec/dummy/config/locales/en.yml +5 -0
  61. data/spec/dummy/config/routes.rb +12 -0
  62. data/spec/dummy/db/migrate/20140801000000_create_groupings.rb +11 -0
  63. data/spec/dummy/db/migrate/20150406171536_create_categories.rb +27 -0
  64. data/spec/dummy/db/migrate/20150408200916_create_loan_programs.rb +26 -0
  65. data/spec/dummy/db/migrate/20150408201429_create_types.rb +21 -0
  66. data/spec/dummy/db/migrate/20150420000001_create_heads.rb +14 -0
  67. data/spec/dummy/db/migrate/20150420000002_create_head_versions.rb +15 -0
  68. data/spec/dummy/db/migrate/20150420000003_create_grouping_head_versions.rb +12 -0
  69. data/spec/dummy/db/migrate/20151023000001_create_simple.rb +12 -0
  70. data/spec/dummy/db/seeds.rb +8 -0
  71. data/spec/dummy/delorean/blame_report.dl +171 -0
  72. data/spec/dummy/delorean/data_report.dl +105 -0
  73. data/spec/dummy/delorean/fields.dl +52 -0
  74. data/spec/dummy/delorean/styles.dl +134 -0
  75. data/spec/dummy/lib/assets/.gitkeep +0 -0
  76. data/spec/dummy/lib/class_list.rb +3 -0
  77. data/spec/dummy/log/.gitkeep +0 -0
  78. data/spec/dummy/public/404.html +26 -0
  79. data/spec/dummy/public/422.html +26 -0
  80. data/spec/dummy/public/500.html +25 -0
  81. data/spec/dummy/public/favicon.ico +0 -0
  82. data/spec/dummy/public/icons/READ.txt +3 -0
  83. data/spec/dummy/public/icons/application_cascade.png +0 -0
  84. data/spec/dummy/public/icons/application_delete.png +0 -0
  85. data/spec/dummy/public/icons/application_put.png +0 -0
  86. data/spec/dummy/public/icons/application_view_detail.png +0 -0
  87. data/spec/dummy/public/icons/arrow_in.png +0 -0
  88. data/spec/dummy/public/icons/arrow_refresh.png +0 -0
  89. data/spec/dummy/public/icons/database_save.png +0 -0
  90. data/spec/dummy/public/icons/door_in.png +0 -0
  91. data/spec/dummy/public/icons/door_out.png +0 -0
  92. data/spec/dummy/public/icons/group.png +0 -0
  93. data/spec/dummy/public/icons/page_lightning.png +0 -0
  94. data/spec/dummy/public/icons/printer.png +0 -0
  95. data/spec/dummy/public/icons/report_disk.png +0 -0
  96. data/spec/dummy/public/icons/report_go.png +0 -0
  97. data/spec/dummy/public/icons/report_magnify.png +0 -0
  98. data/spec/dummy/public/icons/script.png +0 -0
  99. data/spec/dummy/public/icons/script_add.png +0 -0
  100. data/spec/dummy/public/icons/script_go.png +0 -0
  101. data/spec/dummy/public/icons/script_key.png +0 -0
  102. data/spec/dummy/public/icons/table_go.png +0 -0
  103. data/spec/dummy/public/icons/time.png +0 -0
  104. data/spec/dummy/public/icons/time_add.png +0 -0
  105. data/spec/dummy/public/icons/time_go.png +0 -0
  106. data/spec/dummy/public/icons/timeline_marker.png +0 -0
  107. data/spec/dummy/public/icons/user_add.png +0 -0
  108. data/spec/dummy/public/icons/user_delete.png +0 -0
  109. data/spec/dummy/public/icons/user_edit.png +0 -0
  110. data/spec/dummy/public/icons/wrench.png +0 -0
  111. data/spec/dummy/script/delayed_job +6 -0
  112. data/spec/dummy/script/rails +6 -0
  113. data/spec/features/javascripts/job_dashboard_live_search.js.coffee +8 -0
  114. data/spec/features/javascripts/login.js.coffee +8 -0
  115. data/spec/features/jobs_dashboard_netzke_spec.rb +24 -0
  116. data/spec/features/jobs_dashboard_spec.rb +49 -0
  117. data/spec/fixtures/scripts/load_tests/script1.dl +2 -0
  118. data/spec/fixtures/scripts/load_tests/script2.dl +2 -0
  119. data/spec/job_helper.rb +102 -0
  120. data/spec/lib/data_exporter_spec.rb +71 -0
  121. data/spec/lib/data_importer_spec.rb +461 -0
  122. data/spec/lib/xl_spec.rb +198 -0
  123. data/spec/lib/xl_styles_spec.rb +115 -0
  124. data/spec/models/api_auth_spec.rb +187 -0
  125. data/spec/models/posting_spec.rb +107 -0
  126. data/spec/models/promise_spec.rb +65 -0
  127. data/spec/models/script_spec.rb +187 -0
  128. data/spec/models/user_spec.rb +68 -0
  129. data/spec/requests/routes_spec.rb +12 -0
  130. data/spec/spec_helper.rb +61 -0
  131. data/spec/support/clean_db_helpers.rb +18 -0
  132. data/spec/support/delayed_job_helpers.rb +12 -0
  133. data/spec/support/user_helpers.rb +12 -0
  134. metadata +139 -89
  135. data/app/components/marty/auth_app.rb~ +0 -51
  136. data/app/components/marty/auth_app/javascripts/auth_app.js~ +0 -91
  137. data/app/components/marty/cm_form_panel.rb~ +0 -5
  138. data/app/components/marty/cm_grid_panel.rb~ +0 -35
  139. data/app/components/marty/data_import_view.rb~ +0 -142
  140. data/app/components/marty/extras/layout.rb~ +0 -46
  141. data/app/components/marty/live_search_grid_panel.rb~ +0 -49
  142. data/app/components/marty/main_auth_app.rb~ +0 -238
  143. data/app/components/marty/mcfly_grid_panel.rb~ +0 -80
  144. data/app/components/marty/new_posting_form.rb~ +0 -46
  145. data/app/components/marty/new_posting_window.rb~ +0 -21
  146. data/app/components/marty/pivot_grid.rb +0 -52
  147. data/app/components/marty/pivot_grid/endpoints.rb +0 -45
  148. data/app/components/marty/pivot_grid/javascripts/extensions.js +0 -150
  149. data/app/components/marty/pivot_grid/javascripts/pivot_grid.js +0 -86
  150. data/app/components/marty/pivot_grid/services.rb +0 -44
  151. data/app/components/marty/posting_grid.rb~ +0 -140
  152. data/app/components/marty/promise_view.rb~ +0 -157
  153. data/app/components/marty/promise_view/stylesheets/promise_view.css~ +0 -15
  154. data/app/components/marty/report_form.rb~ +0 -217
  155. data/app/components/marty/report_select.rb~ +0 -133
  156. data/app/components/marty/reporting.rb~ +0 -39
  157. data/app/components/marty/script_detail.rb~ +0 -430
  158. data/app/components/marty/script_form.rb~ +0 -233
  159. data/app/components/marty/script_form/javascripts/Ext.ux.form.field.CodeMirror.js~ +0 -909
  160. data/app/components/marty/script_grid.rb~ +0 -99
  161. data/app/components/marty/script_tester.rb~ +0 -213
  162. data/app/components/marty/scripting.rb~ +0 -124
  163. data/app/components/marty/select_report.rb~ +0 -143
  164. data/app/components/marty/simple_app.rb~ +0 -101
  165. data/app/components/marty/tag_grid.rb~ +0 -89
  166. data/app/components/marty/tree_panel.rb~ +0 -256
  167. data/app/components/marty/tree_panel/javascripts/tree_panel.js~ +0 -317
  168. data/app/components/marty/user_pivot.rb +0 -128
  169. data/app/components/marty/user_view.rb~ +0 -188
  170. data/app/controllers/marty/application_controller.rb~ +0 -133
  171. data/app/controllers/marty/components_controller.rb~ +0 -37
  172. data/app/controllers/marty/job_controller.rb~ +0 -28
  173. data/app/controllers/marty/rpc_controller.rb~ +0 -61
  174. data/app/helpers/marty/script_set.rb~ +0 -59
  175. data/app/models/marty/api_auth.rb~ +0 -48
  176. data/app/models/marty/data_change.rb~ +0 -141
  177. data/app/models/marty/enum.rb~ +0 -16
  178. data/app/models/marty/import_type.rb~ +0 -48
  179. data/app/models/marty/poop.rb~ +0 -169
  180. data/app/models/marty/posting.rb~ +0 -86
  181. data/app/models/marty/posting_type.rb~ +0 -21
  182. data/app/models/marty/promise.rb~ +0 -196
  183. data/app/models/marty/role.rb~ +0 -10
  184. data/app/models/marty/script.rb~ +0 -62
  185. data/app/models/marty/tag.rb~ +0 -91
  186. data/app/models/marty/user.rb~ +0 -148
  187. data/app/models/marty/user_role.rb~ +0 -13
  188. data/app/views/layouts/marty/application.html.erb~ +0 -11
  189. data/config/routes.rb~ +0 -10
  190. data/db/migrate/019_create_marty_postings.rb~ +0 -19
  191. data/db/migrate/095_create_marty_tags.rb~ +0 -19
  192. data/lib/marty.rb~ +0 -13
  193. data/lib/marty/content_handler.rb~ +0 -93
  194. data/lib/marty/data_exporter.rb~ +0 -137
  195. data/lib/marty/data_importer.rb~ +0 -114
  196. data/lib/marty/data_row_processor.rb~ +0 -206
  197. data/lib/marty/drop_folder_hook.rb~ +0 -17
  198. data/lib/marty/folder_hook.rb~ +0 -9
  199. data/lib/marty/lazy_column_loader.rb~ +0 -47
  200. data/lib/marty/mcfly_query.rb~ +0 -188
  201. data/lib/marty/migrations.rb~ +0 -65
  202. data/lib/marty/monkey.rb~ +0 -160
  203. data/lib/marty/permissions.rb~ +0 -69
  204. data/lib/marty/promise.rb~ +0 -41
  205. data/lib/marty/promise_job.rb~ +0 -121
  206. data/lib/marty/promise_proxy.rb~ +0 -69
  207. data/lib/marty/util.rb~ +0 -80
  208. data/lib/marty/version.rb~ +0 -3
  209. data/lib/marty/xl.rb~ +0 -526
  210. data/lib/pyxll/README.txt~ +0 -16
  211. data/lib/pyxll/gemini.py~ +0 -110
  212. data/lib/pyxll/pyxll.cfg~ +0 -12
@@ -1,10 +0,0 @@
1
- class Marty::Role < Marty::Base
2
- extend Marty::Enum
3
-
4
- <<<<<<< HEAD
5
- # attr_accessible :name
6
- =======
7
- >>>>>>> master
8
- validates_uniqueness_of :name
9
- # FIXME: should have before_destroy
10
- end
@@ -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
@@ -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
@@ -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
@@ -1,11 +0,0 @@
1
- <!DOCTYPE html>
2
- <html>
3
- <head>
4
- <title><%= Rails.application.class.parent %></title>
5
- <%= load_netzke theme: "classic" %>
6
- <%= csrf_meta_tag %>
7
- </head>
8
- <body>
9
- <%= yield %>
10
- </body>
11
- </html>
data/config/routes.rb~ DELETED
@@ -1,10 +0,0 @@
1
- require 'netzke-core'
2
-
3
- Marty::Engine.routes.draw do
4
- <<<<<<< HEAD
5
- match via: [:get, :post], "rpc/:action(.:format)" => "rpc"
6
- =======
7
- match "rpc/:action(.:format)" => "rpc"
8
- get "job/:action" => "job"
9
- >>>>>>> master
10
- 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
@@ -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