datashift 0.16.0 → 0.40.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (422) hide show
  1. checksums.yaml +4 -4
  2. data/{LICENSE.txt → LICENSE} +0 -0
  3. data/Rakefile +1 -20
  4. data/datashift.thor +125 -0
  5. data/lib/applications/apache_poi_extensions.rb +21 -52
  6. data/lib/applications/excel.rb +64 -57
  7. data/lib/applications/hssf_row_extensions.rb +66 -0
  8. data/lib/applications/jexcel_file.rb +99 -95
  9. data/lib/applications/jexcel_file_extensions.rb +76 -83
  10. data/lib/applications/jruby/word.rb +36 -36
  11. data/lib/applications/ruby_poi_translations.rb +34 -32
  12. data/lib/applications/spreadsheet_extensions.rb +21 -19
  13. data/lib/datashift.rb +49 -59
  14. data/lib/datashift/binder.rb +217 -0
  15. data/lib/datashift/column_packer.rb +21 -72
  16. data/lib/datashift/configuration.rb +317 -0
  17. data/lib/datashift/context_factory.rb +88 -0
  18. data/lib/datashift/core_ext/array.rb +15 -0
  19. data/lib/datashift/core_ext/csv_ext.rb +46 -0
  20. data/lib/datashift/core_ext/string.rb +49 -0
  21. data/lib/datashift/core_ext/to_b.rb +11 -0
  22. data/lib/datashift/delimiters.rb +55 -61
  23. data/lib/datashift/doc_context.rb +137 -0
  24. data/lib/datashift/excel_base.rb +93 -81
  25. data/lib/datashift/exceptions.rb +30 -28
  26. data/lib/datashift/file_definitions.rb +44 -39
  27. data/lib/datashift/guards.rb +5 -5
  28. data/lib/datashift/header.rb +25 -0
  29. data/lib/datashift/headers.rb +94 -0
  30. data/lib/datashift/inbound_data/column.rb +44 -0
  31. data/lib/datashift/inbound_data/lookup_support.rb +33 -0
  32. data/lib/datashift/inbound_data/method_binding.rb +139 -0
  33. data/lib/datashift/load_object.rb +37 -12
  34. data/lib/datashift/logging.rb +54 -27
  35. data/lib/datashift/mandatory.rb +39 -0
  36. data/lib/datashift/mapping/data_flow_schema.rb +198 -0
  37. data/lib/datashift/{model_mapper.rb → mapping/mapper_utils.rb} +30 -10
  38. data/lib/datashift/model_methods/catalogue.rb +183 -0
  39. data/lib/datashift/model_methods/collection.rb +140 -0
  40. data/lib/datashift/model_methods/model_method.rb +162 -0
  41. data/lib/datashift/model_methods/model_methods_manager.rb +76 -0
  42. data/lib/datashift/model_methods/operator.rb +62 -0
  43. data/lib/datashift/node_collection.rb +26 -0
  44. data/lib/datashift/node_context.rb +68 -0
  45. data/lib/datashift/populator.rb +308 -282
  46. data/lib/datashift/progress_monitor.rb +91 -0
  47. data/lib/datashift/querying.rb +110 -52
  48. data/lib/datashift/templates/import_export_config.erb +55 -0
  49. data/lib/datashift/transformation/factory.rb +219 -0
  50. data/lib/datashift/transformation/remove.rb +44 -0
  51. data/lib/datashift/version.rb +3 -0
  52. data/lib/exporters/configuration.rb +84 -0
  53. data/lib/exporters/csv_exporter.rb +54 -52
  54. data/lib/exporters/excel_exporter.rb +80 -61
  55. data/lib/exporters/exporter_base.rb +8 -8
  56. data/lib/generators/config_generator.rb +218 -0
  57. data/lib/generators/csv_generator.rb +13 -70
  58. data/lib/generators/excel_generator.rb +23 -111
  59. data/lib/generators/generator_base.rb +15 -70
  60. data/lib/loaders/configuration.rb +90 -0
  61. data/lib/loaders/csv_loader.rb +63 -101
  62. data/lib/loaders/excel_loader.rb +71 -156
  63. data/lib/loaders/failure_data.rb +40 -0
  64. data/lib/loaders/file_loader.rb +16 -0
  65. data/lib/loaders/loader_base.rb +82 -410
  66. data/lib/loaders/loader_factory.rb +42 -0
  67. data/lib/loaders/paperclip/attachment_loader.rb +157 -140
  68. data/lib/loaders/paperclip/datashift_paperclip.rb +18 -35
  69. data/lib/loaders/paperclip/image_loading.rb +40 -35
  70. data/lib/loaders/reporters/basic_stdout_reporter.rb +40 -0
  71. data/lib/loaders/reporters/reporter.rb +26 -0
  72. data/lib/tasks/config.thor +65 -0
  73. data/{tasks → lib/tasks}/config/seed_fu_product_template.erb +0 -0
  74. data/{tasks → lib/tasks}/config/tidy_config.txt +0 -0
  75. data/lib/tasks/export.thor +192 -0
  76. data/lib/tasks/generate.thor +190 -0
  77. data/lib/tasks/import.thor +142 -0
  78. data/lib/{thor → tasks}/paperclip.thor +69 -69
  79. data/{tasks → lib/tasks/to_convert_to_thor}/db_tasks.rake +20 -20
  80. data/lib/tasks/tools.thor +109 -0
  81. data/spec/MissingAttachmentRecords/DEMO_001_ror_bag.jpeg +0 -0
  82. data/spec/MissingAttachmentRecords/DEMO_002_Powerstation.jpeg +0 -0
  83. data/spec/MissingAttachmentRecords/DEMO_003_ror_mug.jpeg +0 -0
  84. data/spec/MissingAttachmentRecords/DEMO_004_ror_ringer.jpeg +0 -0
  85. data/spec/datashift/binder_spec.rb +266 -0
  86. data/spec/datashift/config_generator_spec.rb +186 -0
  87. data/spec/datashift/configuration.rb +66 -0
  88. data/spec/datashift/context_factory_spec.rb +63 -0
  89. data/spec/datashift/data_flow_schema_spec.rb +150 -0
  90. data/spec/datashift/datashift_spec.rb +52 -0
  91. data/spec/datashift/excel_base_spec.rb +57 -0
  92. data/spec/datashift/excel_spec.rb +188 -0
  93. data/spec/datashift/failure_data_spec.rb +27 -0
  94. data/spec/{file_definitions.rb → datashift/file_definitions.rb} +9 -10
  95. data/spec/datashift/headers_spec.rb +56 -0
  96. data/spec/datashift/inbound_data_spec.rb +47 -0
  97. data/spec/datashift/mapper_utils_spec.rb +38 -0
  98. data/spec/datashift/method_binding_spec.rb +60 -0
  99. data/spec/datashift/model_method_spec.rb +109 -0
  100. data/spec/datashift/model_methods_catalogue.rb +111 -0
  101. data/spec/datashift/model_methods_collection_spec.rb +138 -0
  102. data/spec/datashift/model_methods_manager_spec.rb +329 -0
  103. data/spec/datashift/populator_spec.rb +117 -0
  104. data/spec/datashift/thor_spec.rb +314 -0
  105. data/spec/datashift/transformation/factory_spec.rb +195 -0
  106. data/spec/datashift/transformation/transformer_remove_spec.rb +43 -0
  107. data/spec/dummy/Gemfile +53 -0
  108. data/spec/dummy/Gemfile.lock +197 -0
  109. data/spec/dummy/README.rdoc +28 -0
  110. data/spec/dummy/Rakefile +6 -0
  111. data/spec/dummy/app/assets/javascripts/application.js +16 -0
  112. data/spec/dummy/app/assets/javascripts/categories.js +2 -0
  113. data/spec/dummy/app/assets/javascripts/digitals.js +2 -0
  114. data/spec/dummy/app/assets/javascripts/empties.js +2 -0
  115. data/spec/dummy/app/assets/javascripts/loader_releases.js +2 -0
  116. data/spec/dummy/app/assets/javascripts/long_and_complex_table_linked_to_versions.js +2 -0
  117. data/spec/dummy/app/assets/javascripts/milestones.js +2 -0
  118. data/spec/dummy/app/assets/javascripts/owners.js +2 -0
  119. data/spec/dummy/app/assets/javascripts/projects.js +2 -0
  120. data/spec/dummy/app/assets/javascripts/users.js +2 -0
  121. data/spec/dummy/app/assets/javascripts/versions.js +2 -0
  122. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  123. data/spec/dummy/app/assets/stylesheets/categories.css +4 -0
  124. data/spec/dummy/app/assets/stylesheets/digitals.css +4 -0
  125. data/spec/dummy/app/assets/stylesheets/empties.css +4 -0
  126. data/spec/dummy/app/assets/stylesheets/loader_releases.css +4 -0
  127. data/spec/dummy/app/assets/stylesheets/long_and_complex_table_linked_to_versions.css +4 -0
  128. data/spec/dummy/app/assets/stylesheets/milestones.css +4 -0
  129. data/spec/dummy/app/assets/stylesheets/owners.css +4 -0
  130. data/spec/dummy/app/assets/stylesheets/projects.css +4 -0
  131. data/spec/dummy/app/assets/stylesheets/scaffold.css +56 -0
  132. data/spec/dummy/app/assets/stylesheets/users.css +4 -0
  133. data/spec/dummy/app/assets/stylesheets/versions.css +4 -0
  134. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  135. data/spec/dummy/app/controllers/categories_controller.rb +58 -0
  136. data/spec/dummy/app/controllers/digitals_controller.rb +58 -0
  137. data/spec/dummy/app/controllers/empties_controller.rb +58 -0
  138. data/spec/dummy/app/controllers/loader_releases_controller.rb +58 -0
  139. data/spec/dummy/app/controllers/long_and_complex_table_linked_to_versions_controller.rb +58 -0
  140. data/spec/dummy/app/controllers/milestones_controller.rb +58 -0
  141. data/spec/dummy/app/controllers/owners_controller.rb +58 -0
  142. data/spec/dummy/app/controllers/projects_controller.rb +58 -0
  143. data/spec/dummy/app/controllers/users_controller.rb +58 -0
  144. data/spec/dummy/app/controllers/versions_controller.rb +58 -0
  145. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  146. data/spec/dummy/app/helpers/categories_helper.rb +2 -0
  147. data/spec/dummy/app/helpers/digitals_helper.rb +2 -0
  148. data/spec/dummy/app/helpers/empties_helper.rb +2 -0
  149. data/spec/dummy/app/helpers/loader_releases_helper.rb +2 -0
  150. data/spec/dummy/app/helpers/long_and_complex_table_linked_to_versions_helper.rb +2 -0
  151. data/spec/dummy/app/helpers/milestones_helper.rb +2 -0
  152. data/spec/dummy/app/helpers/owners_helper.rb +2 -0
  153. data/spec/dummy/app/helpers/projects_helper.rb +2 -0
  154. data/spec/dummy/app/helpers/users_helper.rb +2 -0
  155. data/spec/dummy/app/helpers/versions_helper.rb +2 -0
  156. data/spec/dummy/app/models/category.rb +6 -0
  157. data/spec/dummy/app/models/digital.rb +22 -0
  158. data/spec/dummy/app/models/empty.rb +2 -0
  159. data/spec/dummy/app/models/loader_release.rb +10 -0
  160. data/spec/dummy/app/models/long_and_complex_table_linked_to_version.rb +6 -0
  161. data/spec/dummy/app/models/milestone.rb +15 -0
  162. data/spec/dummy/app/models/owner.rb +13 -0
  163. data/spec/dummy/app/models/project.rb +53 -0
  164. data/spec/dummy/app/models/user.rb +5 -0
  165. data/spec/dummy/app/models/version.rb +7 -0
  166. data/spec/dummy/app/views/categories/_form.html.erb +17 -0
  167. data/spec/dummy/app/views/categories/edit.html.erb +6 -0
  168. data/spec/dummy/app/views/categories/index.html.erb +25 -0
  169. data/spec/dummy/app/views/categories/new.html.erb +5 -0
  170. data/spec/dummy/app/views/categories/show.html.erb +4 -0
  171. data/spec/dummy/app/views/digitals/_form.html.erb +17 -0
  172. data/spec/dummy/app/views/digitals/edit.html.erb +6 -0
  173. data/spec/dummy/app/views/digitals/index.html.erb +25 -0
  174. data/spec/dummy/app/views/digitals/new.html.erb +5 -0
  175. data/spec/dummy/app/views/digitals/show.html.erb +4 -0
  176. data/spec/dummy/app/views/empties/_form.html.erb +17 -0
  177. data/spec/dummy/app/views/empties/edit.html.erb +6 -0
  178. data/spec/dummy/app/views/empties/index.html.erb +25 -0
  179. data/spec/dummy/app/views/empties/new.html.erb +5 -0
  180. data/spec/dummy/app/views/empties/show.html.erb +4 -0
  181. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  182. data/spec/dummy/app/views/loader_releases/_form.html.erb +17 -0
  183. data/spec/dummy/app/views/loader_releases/edit.html.erb +6 -0
  184. data/spec/dummy/app/views/loader_releases/index.html.erb +25 -0
  185. data/spec/dummy/app/views/loader_releases/new.html.erb +5 -0
  186. data/spec/dummy/app/views/loader_releases/show.html.erb +4 -0
  187. data/spec/dummy/app/views/long_and_complex_table_linked_to_versions/_form.html.erb +17 -0
  188. data/spec/dummy/app/views/long_and_complex_table_linked_to_versions/edit.html.erb +6 -0
  189. data/spec/dummy/app/views/long_and_complex_table_linked_to_versions/index.html.erb +25 -0
  190. data/spec/dummy/app/views/long_and_complex_table_linked_to_versions/new.html.erb +5 -0
  191. data/spec/dummy/app/views/long_and_complex_table_linked_to_versions/show.html.erb +4 -0
  192. data/spec/dummy/app/views/milestones/_form.html.erb +17 -0
  193. data/spec/dummy/app/views/milestones/edit.html.erb +6 -0
  194. data/spec/dummy/app/views/milestones/index.html.erb +25 -0
  195. data/spec/dummy/app/views/milestones/new.html.erb +5 -0
  196. data/spec/dummy/app/views/milestones/show.html.erb +4 -0
  197. data/spec/dummy/app/views/owners/_form.html.erb +17 -0
  198. data/spec/dummy/app/views/owners/edit.html.erb +6 -0
  199. data/spec/dummy/app/views/owners/index.html.erb +25 -0
  200. data/spec/dummy/app/views/owners/new.html.erb +5 -0
  201. data/spec/dummy/app/views/owners/show.html.erb +4 -0
  202. data/spec/dummy/app/views/projects/_form.html.erb +17 -0
  203. data/spec/dummy/app/views/projects/edit.html.erb +6 -0
  204. data/spec/dummy/app/views/projects/index.html.erb +25 -0
  205. data/spec/dummy/app/views/projects/new.html.erb +5 -0
  206. data/spec/dummy/app/views/projects/show.html.erb +4 -0
  207. data/spec/dummy/app/views/users/_form.html.erb +17 -0
  208. data/spec/dummy/app/views/users/edit.html.erb +6 -0
  209. data/spec/dummy/app/views/users/index.html.erb +25 -0
  210. data/spec/dummy/app/views/users/new.html.erb +5 -0
  211. data/spec/dummy/app/views/users/show.html.erb +4 -0
  212. data/spec/dummy/app/views/versions/_form.html.erb +17 -0
  213. data/spec/dummy/app/views/versions/edit.html.erb +6 -0
  214. data/spec/dummy/app/views/versions/index.html.erb +25 -0
  215. data/spec/dummy/app/views/versions/new.html.erb +5 -0
  216. data/spec/dummy/app/views/versions/show.html.erb +4 -0
  217. data/spec/dummy/bin/bundle +3 -0
  218. data/spec/dummy/bin/rails +9 -0
  219. data/spec/dummy/bin/rake +9 -0
  220. data/spec/dummy/bin/setup +29 -0
  221. data/spec/dummy/bin/spring +16 -0
  222. data/spec/dummy/config.ru +4 -0
  223. data/spec/dummy/config/application.rb +26 -0
  224. data/spec/dummy/config/boot.rb +3 -0
  225. data/spec/dummy/config/database.yml +25 -0
  226. data/spec/dummy/config/environment.rb +5 -0
  227. data/spec/dummy/config/environments/development.rb +41 -0
  228. data/spec/dummy/config/environments/production.rb +79 -0
  229. data/spec/dummy/config/environments/test.rb +42 -0
  230. data/spec/dummy/config/initializers/assets.rb +11 -0
  231. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  232. data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
  233. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  234. data/spec/dummy/config/initializers/inflections.rb +16 -0
  235. data/spec/dummy/config/initializers/mime_types.rb +4 -0
  236. data/spec/dummy/config/initializers/session_store.rb +3 -0
  237. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  238. data/spec/dummy/config/locales/en.yml +23 -0
  239. data/spec/dummy/config/routes.rb +76 -0
  240. data/spec/dummy/config/secrets.yml +22 -0
  241. data/spec/dummy/db/development.sqlite3 +0 -0
  242. data/spec/dummy/db/migrate/20110803201325_create_test_bed.rb +98 -0
  243. data/spec/dummy/db/migrate/20121009161700_add_digitals.rb +24 -0
  244. data/spec/dummy/db/migrate/20161005123106_create_digitals.rb +8 -0
  245. data/spec/dummy/db/migrate/20161005123106_create_long_and_complex_table_linked_to_versions.rb +8 -0
  246. data/spec/dummy/db/migrate/20161005123107_create_loader_releases.rb +8 -0
  247. data/spec/dummy/db/migrate/20161005123108_create_owners.rb +8 -0
  248. data/spec/dummy/db/migrate/20161005123109_create_empties.rb +8 -0
  249. data/spec/dummy/db/migrate/20161005123110_create_projects.rb +8 -0
  250. data/spec/dummy/db/migrate/20161005123111_create_users.rb +8 -0
  251. data/spec/dummy/db/migrate/20161005123111_create_versions.rb +8 -0
  252. data/spec/dummy/db/migrate/20161005123112_create_milestones.rb +8 -0
  253. data/spec/dummy/db/migrate/20161005123113_create_categories.rb +8 -0
  254. data/spec/dummy/db/schema.rb +93 -0
  255. data/spec/dummy/db/seeds.rb +9 -0
  256. data/spec/dummy/db/test.sqlite3 +0 -0
  257. data/spec/dummy/log/test.log +69 -0
  258. data/spec/dummy/public/404.html +67 -0
  259. data/spec/dummy/public/422.html +67 -0
  260. data/spec/dummy/public/500.html +66 -0
  261. data/spec/dummy/public/favicon.ico +0 -0
  262. data/spec/dummy/public/robots.txt +5 -0
  263. data/spec/dummy/sandbox_example.thor +4 -0
  264. data/spec/dummy/test/controllers/categories_controller_test.rb +49 -0
  265. data/spec/dummy/test/controllers/digitals_controller_test.rb +49 -0
  266. data/spec/dummy/test/controllers/empties_controller_test.rb +49 -0
  267. data/spec/dummy/test/controllers/loader_releases_controller_test.rb +49 -0
  268. data/spec/dummy/test/controllers/long_and_complex_table_linked_to_versions_controller_test.rb +49 -0
  269. data/spec/dummy/test/controllers/milestones_controller_test.rb +49 -0
  270. data/spec/dummy/test/controllers/owners_controller_test.rb +49 -0
  271. data/spec/dummy/test/controllers/projects_controller_test.rb +49 -0
  272. data/spec/dummy/test/controllers/users_controller_test.rb +49 -0
  273. data/spec/dummy/test/controllers/versions_controller_test.rb +49 -0
  274. data/spec/dummy/test/factories/categories.rb +5 -0
  275. data/spec/dummy/test/factories/digitals.rb +5 -0
  276. data/spec/dummy/test/factories/empties.rb +5 -0
  277. data/spec/dummy/test/factories/loader_releases.rb +5 -0
  278. data/spec/dummy/test/factories/long_and_complex_table_linked_to_versions.rb +5 -0
  279. data/spec/dummy/test/factories/milestones.rb +5 -0
  280. data/spec/dummy/test/factories/owners.rb +5 -0
  281. data/spec/dummy/test/factories/projects.rb +5 -0
  282. data/spec/dummy/test/factories/users.rb +5 -0
  283. data/spec/dummy/test/factories/versions.rb +5 -0
  284. data/spec/dummy/test/models/category_test.rb +7 -0
  285. data/spec/dummy/test/models/digital_test.rb +7 -0
  286. data/spec/dummy/test/models/empty_test.rb +7 -0
  287. data/spec/dummy/test/models/loader_release_test.rb +7 -0
  288. data/spec/dummy/test/models/long_and_complex_table_linked_to_version_test.rb +7 -0
  289. data/spec/dummy/test/models/milestone_test.rb +7 -0
  290. data/spec/dummy/test/models/owner_test.rb +7 -0
  291. data/spec/dummy/test/models/project_test.rb +7 -0
  292. data/spec/dummy/test/models/user_test.rb +7 -0
  293. data/spec/dummy/test/models/version_test.rb +7 -0
  294. data/spec/dummy/test/test_helper.rb +10 -0
  295. data/spec/exporters/csv_exporter_spec.rb +240 -0
  296. data/spec/exporters/csv_generator_spec.rb +139 -0
  297. data/spec/exporters/excel_exporter_spec.rb +193 -0
  298. data/spec/exporters/excel_generator_spec.rb +181 -0
  299. data/spec/exporters/generator_base_spec.rb +45 -0
  300. data/spec/factories/categories.rb +7 -0
  301. data/spec/factories/factories.rb +18 -0
  302. data/spec/factories/milestone.rb +16 -0
  303. data/spec/factories/projects.rb +41 -0
  304. data/spec/fixtures/BadAssociationName.xls +0 -0
  305. data/spec/fixtures/DemoNegativeTesting.xls +0 -0
  306. data/spec/fixtures/ProjectConfiguration.yml +18 -0
  307. data/spec/fixtures/ProjectsMultiCategories.xls +0 -0
  308. data/spec/fixtures/ProjectsMultiCategoriesHeaderLookup.xls +0 -0
  309. data/spec/fixtures/ProjectsSingleCategories.xls +0 -0
  310. data/spec/fixtures/ProjectsSingleCategories.xlsx +0 -0
  311. data/spec/fixtures/SimpleProjects.xls +0 -0
  312. data/spec/fixtures/config/database.yml +28 -0
  313. data/spec/fixtures/csv/BadAssociationName.csv +6 -0
  314. data/spec/fixtures/csv/DemoNegativeTesting.csv +6 -0
  315. data/spec/fixtures/csv/ProjectsMultiCategories.csv +5 -0
  316. data/spec/fixtures/csv/ProjectsMultiCategoriesHeaderLookup.csv +5 -0
  317. data/spec/fixtures/csv/ProjectsSingleCategories.csv +5 -0
  318. data/spec/fixtures/csv/SimpleProjects.csv +4 -0
  319. data/spec/fixtures/db/migrate/20110803201325_create_test_bed.rb +98 -0
  320. data/spec/fixtures/db/migrate/20121009161700_add_digitals.rb +24 -0
  321. data/spec/fixtures/db/seeds.rb +9 -0
  322. data/spec/fixtures/images/DEMO_001_ror_bag.jpeg +0 -0
  323. data/spec/fixtures/images/DEMO_002_Powerstation.jpeg +0 -0
  324. data/spec/fixtures/images/DEMO_003_ror_mug.jpeg +0 -0
  325. data/spec/fixtures/images/DEMO_004_ror_ringer.jpeg +0 -0
  326. data/spec/fixtures/load_datashift.thor +3 -0
  327. data/spec/fixtures/models/category.rb +6 -0
  328. data/spec/fixtures/models/digital.rb +22 -0
  329. data/spec/fixtures/models/empty.rb +2 -0
  330. data/spec/fixtures/models/loader_release.rb +10 -0
  331. data/spec/fixtures/models/long_and_complex_table_linked_to_version.rb +6 -0
  332. data/spec/fixtures/models/milestone.rb +15 -0
  333. data/spec/fixtures/models/owner.rb +13 -0
  334. data/spec/fixtures/models/project.rb +53 -0
  335. data/spec/fixtures/models/user.rb +5 -0
  336. data/spec/fixtures/models/version.rb +7 -0
  337. data/spec/fixtures/results/exp_project_assoc_headers.xls +0 -0
  338. data/spec/fixtures/results/exp_project_collection_spec.csv +2 -0
  339. data/spec/fixtures/results/exp_project_export.xls +0 -0
  340. data/spec/fixtures/results/exp_project_first_export.xls +0 -0
  341. data/spec/fixtures/results/exp_project_plus_assoc.xls +0 -0
  342. data/spec/fixtures/results/exp_project_plus_assoc_export_spec.csv +9 -0
  343. data/spec/fixtures/results/gen_project_plus_assoc_template.xls +0 -0
  344. data/spec/fixtures/results/gen_project_plus_some_assoc_template.xls +0 -0
  345. data/spec/fixtures/results/gen_project_template.xls +0 -0
  346. data/spec/fixtures/results/project_and_assoc_in_hash_export.xls +0 -0
  347. data/spec/fixtures/results/project_and_assoc_in_json_export.csv +9 -0
  348. data/spec/fixtures/results/project_and_assoc_in_json_export.xls +0 -0
  349. data/spec/fixtures/results/project_export_spec_with_custom_delim_,.csv +2 -0
  350. data/spec/fixtures/results/project_export_spec_with_custom_delim_/302/243.csv +2 -0
  351. data/spec/fixtures/results/project_export_spec_with_custom_delim_/302/247.csv +2 -0
  352. data/spec/fixtures/results/project_plus_assoc_template.csv +1 -0
  353. data/spec/fixtures/results/project_plus_some_assoc_template.csv +1 -0
  354. data/spec/fixtures/results/project_remove_export_spec.csv +2 -0
  355. data/spec/fixtures/results/project_template.csv +1 -0
  356. data/spec/fixtures/results/project_with_methods_export_spec.csv +2 -0
  357. data/spec/fixtures/results/thor_spec_gen_project.csv +1 -0
  358. data/spec/fixtures/sandbox_example.thor +4 -0
  359. data/spec/fixtures/simple_export_spec.xls +0 -0
  360. data/spec/fixtures/simple_template_spec.xls +0 -0
  361. data/spec/fixtures/test_model_defs.rb +7 -0
  362. data/spec/loaders/csv_loader_spec.rb +206 -0
  363. data/spec/loaders/data_flow_excel_loader_spec.rb +290 -0
  364. data/spec/loaders/excel_loader_failures_spec.rb +67 -0
  365. data/spec/loaders/excel_loader_spec.rb +294 -0
  366. data/spec/loaders/loader_base_spec.rb +29 -0
  367. data/spec/loaders/paperclip_loader_spec.rb +106 -0
  368. data/spec/log/datashift.log +14930 -0
  369. data/spec/private/digitals/1/DEMO_003_ror_mug.jpeg +0 -0
  370. data/spec/private/digitals/2/DEMO_002_Powerstation.jpeg +0 -0
  371. data/spec/private/digitals/3/DEMO_004_ror_ringer.jpeg +0 -0
  372. data/spec/private/digitals/4/DEMO_001_ror_bag.jpeg +0 -0
  373. data/spec/spec_helper.rb +26 -230
  374. data/spec/support/clear_and_manage_contexts.rb +25 -0
  375. data/spec/support/database_cleaner.rb +32 -0
  376. data/spec/support/datashift_test_helpers.rb +153 -0
  377. data/spec/support/files_paths_helper.rb +13 -0
  378. data/spec/support/fixtures/results/mapping_template.yaml +15 -0
  379. data/spec/support/sandbox.rb +136 -0
  380. metadata +804 -85
  381. data/README.markdown +0 -274
  382. data/README.rdoc +0 -19
  383. data/VERSION +0 -1
  384. data/datashift.gemspec +0 -48
  385. data/lib/applications/jruby/old_pre_proxy_jexcel_file.rb +0 -437
  386. data/lib/datashift/data_transforms.rb +0 -83
  387. data/lib/datashift/mapping_file_definitions.rb +0 -88
  388. data/lib/datashift/mapping_service.rb +0 -91
  389. data/lib/datashift/method_detail.rb +0 -165
  390. data/lib/datashift/method_details_manager.rb +0 -95
  391. data/lib/datashift/method_dictionary.rb +0 -281
  392. data/lib/datashift/method_mapper.rb +0 -174
  393. data/lib/datashift/thor_base.rb +0 -38
  394. data/lib/generators/mapping_generator.rb +0 -112
  395. data/lib/helpers/core_ext/csv_file.rb +0 -33
  396. data/lib/helpers/core_ext/to_b.rb +0 -24
  397. data/lib/loaders/reporter.rb +0 -58
  398. data/lib/thor/export.thor +0 -175
  399. data/lib/thor/generate.thor +0 -191
  400. data/lib/thor/import.thor +0 -110
  401. data/lib/thor/mapping.thor +0 -65
  402. data/lib/thor/tools.thor +0 -84
  403. data/spec/Gemfile +0 -31
  404. data/spec/Gemfile.lock +0 -134
  405. data/spec/csv_exporter_spec.rb +0 -144
  406. data/spec/csv_generator_spec.rb +0 -159
  407. data/spec/csv_loader_spec.rb +0 -212
  408. data/spec/datashift_spec.rb +0 -55
  409. data/spec/excel_exporter_spec.rb +0 -199
  410. data/spec/excel_generator_spec.rb +0 -203
  411. data/spec/excel_loader_spec.rb +0 -237
  412. data/spec/excel_spec.rb +0 -203
  413. data/spec/loader_base_spec.rb +0 -166
  414. data/spec/mapping_spec.rb +0 -117
  415. data/spec/method_dictionary_spec.rb +0 -300
  416. data/spec/method_mapper_spec.rb +0 -100
  417. data/spec/model_mapper_spec.rb +0 -41
  418. data/spec/paperclip_loader_spec.rb +0 -92
  419. data/spec/populator_spec.rb +0 -128
  420. data/spec/thor_spec.rb +0 -90
  421. data/tasks/file_tasks.rake +0 -37
  422. data/tasks/word_to_seedfu.rake +0 -167
@@ -0,0 +1,39 @@
1
+ # Copyright:: (c) Autotelik Media Ltd 2015
2
+ # Author :: Tom Statter
3
+ # Date :: Aug 2015
4
+ # License:: MIT
5
+ #
6
+ module DataShift
7
+
8
+ class Mandatory
9
+
10
+ include DataShift::Logging
11
+
12
+ attr_reader :mandatory_columns, :missing_columns
13
+
14
+ def initialize(columns)
15
+
16
+ @mandatory_columns = columns
17
+
18
+ logger.info("Mandatory columns set to #{@mandatory_columns.inspect}") unless @mandatory_columns.empty?
19
+
20
+ @comparable_mandatory_columns = @mandatory_columns.collect(&:downcase)
21
+ @missing_columns = []
22
+ end
23
+
24
+ def empty?
25
+ @comparable_mandatory_columns.empty?
26
+ end
27
+
28
+ # Sets mandatory_columns
29
+ # Returns true if bound methods contain every method listed in Mandatory
30
+ #
31
+ def contains_all?( binder )
32
+ return true if(empty?)
33
+ @missing_columns = @comparable_mandatory_columns - binder.operator_names.collect(&:downcase)
34
+ @missing_columns.empty?
35
+ end
36
+
37
+ end
38
+
39
+ end
@@ -0,0 +1,198 @@
1
+ # Copyright:: (c) Autotelik Media Ltd 2016
2
+ # Author :: Tom Statter
3
+ # Date :: Feb 2016
4
+ # License:: MIT
5
+ #
6
+ # Details:: You can build a FLow for import or export within a YAML config file
7
+ #
8
+ # It supports a simple DSL in below format.
9
+ #
10
+ # SYNTAX :
11
+ # Indentation, usually 2 spaces, or a 2 space TAB, is very important
12
+ # <> are used to illustrate the elements that accept free text
13
+ # Nodes :
14
+ #
15
+ # Since the order is important, i.e should be preserved so your columns come out in defined order a sequence
16
+ # should be used
17
+ #
18
+ # Node :
19
+ #
20
+ # Each Node can have these elements
21
+ #
22
+ # :heading:
23
+ # source: The column header
24
+ # destination: The column header
25
+ #
26
+ # :operator: How to get the data - for export would be the method call on the model
27
+ #
28
+ # EXAMPLE:
29
+ #
30
+ # data_flow_schema:
31
+ # Project:
32
+ # nodes:
33
+ # - project:
34
+ # heading:
35
+ # source: "title"
36
+ # destination: "Title"
37
+ # operator: title
38
+ #
39
+ # - project_owner_budget:
40
+ # heading:
41
+ # destination: "Budget"
42
+ # operator: owner.budget
43
+ #
44
+ require 'erubis'
45
+
46
+ module DataShift
47
+
48
+ class DataFlowSchema
49
+
50
+ include DataShift::Logging
51
+
52
+ attr_reader :nodes, :raw_data, :yaml_data
53
+
54
+ def initialize
55
+ @nodes = DataShift::NodeCollection.new
56
+ end
57
+
58
+ def sources
59
+ @nodes.collect(&:method_binding).collect(&:source)
60
+ end
61
+
62
+ # Build the node collection from a Class, that is for each operator in scope
63
+ # create a method binding and a node context, and add to collection.
64
+ #
65
+ def prepare_from_klass( klass, doc_context = nil )
66
+
67
+ context = doc_context || DocContext.new(klass)
68
+
69
+ @nodes = DataShift::NodeCollection.new
70
+
71
+ klass_to_model_methods( klass ).each_with_index do |mm, i|
72
+ binding = MethodBinding.new(mm.operator, i, mm)
73
+
74
+ @nodes << DataShift::NodeContext.new(context, binding, i, nil)
75
+ end
76
+
77
+ @nodes
78
+ end
79
+
80
+ # Helpers for dealing with Active Record models and collections
81
+ # Catalogs the supplied Klass and builds set of expected/valid Headers for Klass
82
+ #
83
+ def klass_to_model_methods(klass)
84
+
85
+ op_types_in_scope = DataShift::Configuration.call.op_types_in_scope
86
+
87
+ collection = ModelMethods::Manager.catalog_class(klass)
88
+
89
+ model_methods = []
90
+
91
+ if collection
92
+
93
+ collection.each { |mm| model_methods << mm if(op_types_in_scope.include? mm.operator_type) }
94
+
95
+ remove = DataShift::Transformation::Remove.new
96
+
97
+ remove.unwanted_model_methods model_methods
98
+ end
99
+
100
+ model_methods
101
+ end
102
+
103
+ def prepare_from_file(file_name, locale_key = 'data_flow_schema')
104
+ @raw_data = File.read(file_name)
105
+ yaml = YAML.load(raw_data)
106
+
107
+ prepare_from_yaml(yaml, locale_key)
108
+ end
109
+
110
+ def prepare_from_string(text, locale_key = 'data_flow_schema')
111
+ @raw_data = text
112
+ yaml = YAML.load(text)
113
+
114
+ prepare_from_yaml(yaml, locale_key)
115
+ end
116
+
117
+ def prepare_from_yaml(yaml, locale_key = 'data_flow_schema')
118
+
119
+ @yaml_data = yaml
120
+
121
+ @nodes = NodeCollection.new
122
+
123
+ raise RuntimeError.new("Bad YAML syntax - No key #{locale_key} found in #{yaml}") unless yaml[locale_key]
124
+
125
+ locale_section = yaml[locale_key]
126
+
127
+ class_name = locale_section.keys.first
128
+
129
+ klass = MapperUtils.class_from_string_or_raise(class_name)
130
+
131
+ # The over all doc context
132
+ doc = DocContext.new(klass)
133
+ nodes.doc_context = doc
134
+
135
+ klass_section = locale_section[class_name]
136
+
137
+ DataShift::Transformation.factory { |f| f.configure_from_yaml(class_name, klass_section) }
138
+
139
+ yaml_nodes = klass_section['nodes']
140
+
141
+ logger.info("Read Data Schema Nodes: #{yaml_nodes.inspect}")
142
+
143
+ unless(yaml_nodes.is_a?(Array))
144
+ Rails.logger.error('Bad syntax in flow schema YAML - Nodes should be a sequence')
145
+ raise 'Bad syntax in flow schema YAML - Nodes should be a sequence'
146
+ end
147
+
148
+ model_method_mgr = ModelMethods::Manager.catalog_class(klass)
149
+
150
+ yaml_nodes.each_with_index do |keyed_node, i|
151
+
152
+ unless(keyed_node.keys.size == 1)
153
+ Rails.logger.error('Bad syntax in flow schema YAML - Section should be keyed hash')
154
+ raise 'Bad syntax in flow schema YAML - Section should be keyed hash'
155
+ end
156
+
157
+ # data_flow_schema:
158
+ # Project:
159
+ # nodes:
160
+ # - project:
161
+ # heading:
162
+ # source: "title"
163
+ # presentation: "Title"
164
+ # operator: title
165
+ # operator_type: has_many
166
+ #
167
+ logger.info("Node Data: #{keyed_node.inspect}")
168
+
169
+ # type one of ModelMethod.supported_types_enum
170
+ section = keyed_node.values.first
171
+
172
+ if(section['operator'])
173
+ # Find the domain model method details
174
+ model_method = model_method_mgr.search(section['operator'])
175
+
176
+ unless model_method
177
+ operator_type = section['operator_type'] || :method
178
+
179
+ model_method = model_method_mgr.insert(section['operator'], operator_type)
180
+ end
181
+ end
182
+
183
+ source = section.fetch('heading', {}).fetch('source', nil)
184
+
185
+ doc.headers.add( source )
186
+
187
+ method_binding = MethodBinding.new(source, i, model_method)
188
+
189
+ node = DataShift::NodeContext.new(doc, method_binding, i, nil)
190
+
191
+ nodes << node
192
+ end
193
+
194
+ nodes
195
+ end
196
+
197
+ end
198
+ end
@@ -1,24 +1,33 @@
1
+ # Copyright:: (c) Autotelik Media Ltd 2015
2
+ # Author :: Tom Statter
3
+ # Date :: Feb 2015
4
+ # License:: MIT
5
+ #
6
+ # Details:: Helpers for dealing with Ccass <-> String, Table <-> String type mappings
7
+
1
8
  module DataShift
2
9
 
3
- class ModelMapper
10
+ class MapperUtils
4
11
 
12
+ def self.ensure_class( klass )
13
+ klass.is_a?(String) ? MapperUtils.class_from_string_or_raise( klass ) : klass
14
+ end
5
15
 
6
16
  def self.class_from_string_or_raise( klass )
7
17
 
8
18
  ruby_klass = begin
9
- # support modules e.g "Spree::Property")
10
- ModelMapper::class_from_string(klass) #Kernel.const_get(model)
19
+ # support modules e.g "Spree::Property")
20
+ MapperUtils.class_from_string(klass) # Kernel.const_get(model)
11
21
  rescue NameError => e
12
- puts e
22
+ logger.error( e.message )
13
23
  raise Thor::Error.new("ERROR: No such Class [#{klass}] found - check valid model supplied")
14
24
  end
15
25
 
16
- raise NoSuchClassError.new("ERROR: No such Model [#{klass}] found - check valid model supplied") unless(ruby_klass)
26
+ raise NoSuchClassError.new("ERROR: No such Model [#{klass}] found - check valid model supplied") unless ruby_klass
17
27
 
18
28
  ruby_klass
19
29
  end
20
30
 
21
-
22
31
  # Helper to deal with string versions of modules/namespaced classes
23
32
  # Find and return the base class from a string.
24
33
  #
@@ -30,18 +39,29 @@ module DataShift
30
39
  end
31
40
  end
32
41
 
33
-
34
42
  # Similar to const_get_from_string except this version
35
43
  # returns nil if no such class found
36
44
  # Support modules e.g "Spree::Property"
37
45
  #
38
46
  def self.class_from_string( str )
47
+
48
+ MapperUtils.const_get_from_string(str.to_s) # Kernel.const_get(model)
49
+ rescue
50
+ return nil
51
+
52
+ end
53
+
54
+ def self.table_to_arclass(table, mod)
55
+
56
+ find_table = mod.nil? ? table.classify : "#{mod}::#{table.classify}"
57
+
39
58
  begin
40
- ModelMapper::const_get_from_string(str.to_s) #Kernel.const_get(model)
59
+ DataShift::MapperUtils.class_from_string(find_table)
60
+ rescue LoadError
41
61
  rescue
42
- return nil
62
+ nil
43
63
  end
44
64
  end
45
65
 
46
66
  end
47
- end
67
+ end
@@ -0,0 +1,183 @@
1
+ # Copyright:: (c) Autotelik Media Ltd 2015
2
+ # Author :: Tom Statter
3
+ # Date :: Feb 2015
4
+ # License:: MIT
5
+ #
6
+ # Details:: Catalogues all possible methods for populating data on a class
7
+ #
8
+ # Provides high level find facilities to perform cataloguing on a class
9
+ # and retrieving operators per type (has_one, has_many, belongs_to, instance_method etc)
10
+ #
11
+ module DataShift
12
+
13
+ module ModelMethods
14
+
15
+ # HIGH LEVEL COLLECTION METHODS
16
+
17
+ class Catalogue
18
+
19
+ include DataShift::Logging
20
+ extend DataShift::Logging
21
+
22
+ def self.catalogued?(klass)
23
+ catalogued.include?(klass)
24
+ end
25
+
26
+ def self.size
27
+ catalogued.size
28
+ end
29
+
30
+ # Create simple picture of all the operator names for assignment available on a domain model,
31
+ # grouped by type of association (includes belongs_to and has_many which provides both << and = )
32
+ # Options:
33
+ # :reload => clear caches and re-perform lookup
34
+ # :instance_methods => if true include instance method type 'setters' as well as model's pure columns
35
+ #
36
+ def self.populate(klass, options = {} )
37
+
38
+ raise "Cannot find operators supplied klass nil #{klass}" if klass.nil?
39
+
40
+ register(klass)
41
+
42
+ logger.debug("Catalogue - building operators information for #{klass}")
43
+
44
+ # Find the has_many associations which can be populated via <<
45
+ if options[:reload] || has_many[klass].nil?
46
+ has_many[klass] = klass.reflect_on_all_associations(:has_many).map { |i| i.name.to_s }
47
+
48
+ klass.reflect_on_all_associations(:has_and_belongs_to_many).inject(has_many[klass]) do |x, i|
49
+ x << i.name.to_s
50
+ end
51
+ end
52
+
53
+ # Find the belongs_to associations which can be populated via Model.belongs_to_name = OtherArModelObject
54
+ if options[:reload] || belongs_to[klass].nil?
55
+ belongs_to[klass] = klass.reflect_on_all_associations(:belongs_to).map { |i| i.name.to_s }
56
+ end
57
+
58
+ # Find the has_one associations which can be populated via Model.has_one_name = OtherArModelObject
59
+ if options[:reload] || has_one[klass].nil?
60
+ has_one[klass] = klass.reflect_on_all_associations(:has_one).map { |i| i.name.to_s }
61
+ end
62
+
63
+ # Find the model's column associations which can be populated via xxxxxx= value
64
+ # Note, not all reflections return method names in same style so we convert all to
65
+ # the raw form i.e without the '=' for consistency
66
+ if options[:reload] || assignments[klass].nil?
67
+ build_assignments( klass, options[:instance_methods] )
68
+ end
69
+ end
70
+
71
+ def self.clear
72
+ belongs_to.clear
73
+ has_many.clear
74
+ assignments.clear
75
+ column_types.clear
76
+ has_one.clear
77
+ catalogued.clear
78
+ end
79
+
80
+ # rubocop:disable Style/PredicateName
81
+
82
+ def self.belongs_to
83
+ @belongs_to ||= {}
84
+ @belongs_to
85
+ end
86
+
87
+ def self.has_many
88
+ @has_many ||= {}
89
+ @has_many
90
+ end
91
+
92
+ def self.has_one
93
+ @has_one ||= {}
94
+ @has_one
95
+ end
96
+
97
+ def self.assignments
98
+ @assignments ||= {}
99
+ @assignments
100
+ end
101
+
102
+ # N.B this return strings for consistency with other collections
103
+ # Removes methods that start with '_'
104
+
105
+ def self.setters( klass )
106
+
107
+ @keep_only_pure_setters ||= Regexp.new(/^[a-zA-Z]\w+=/)
108
+
109
+ setters = klass.instance_methods.grep(@keep_only_pure_setters).sort.collect( &:to_s )
110
+ setters.uniq # TOFIX is this really required ?
111
+ end
112
+
113
+ def self.column_types
114
+ @column_types ||= {}
115
+ @column_types
116
+ end
117
+
118
+ def self.belongs_to_for(klass)
119
+ belongs_to[klass] || []
120
+ end
121
+
122
+ def self.has_many_for(klass)
123
+ has_many[klass] || []
124
+ end
125
+
126
+ def self.has_one_for(klass)
127
+ has_one[klass] || []
128
+ end
129
+
130
+ def self.assignments_for(klass)
131
+ assignments[klass] || []
132
+ end
133
+
134
+ def self.column_type_for(klass, column)
135
+ column_types[klass] ? column_types[klass][column] : []
136
+ end
137
+
138
+ # rubocop:enable Style/PredicateName
139
+
140
+ class << self
141
+ private
142
+
143
+ def build_assignments(klass, include_instance_methods)
144
+ begin
145
+ assignments[klass] = klass.column_names
146
+ rescue => x
147
+ raise DataShiftException, "Failed to process column_names for class #{klass} - #{x.message}"
148
+ end
149
+
150
+ # get into consistent format with other assignments names i.e remove the = for now
151
+ assignments[klass] += setters(klass).map { |i| i.delete('=') } if include_instance_methods
152
+
153
+ # Now remove all the associations
154
+ assignments[klass] -= has_many[klass] if has_many[klass]
155
+ assignments[klass] -= belongs_to[klass] if belongs_to[klass]
156
+ assignments[klass] -= has_one[klass] if has_one[klass]
157
+
158
+ # TODO: remove assignments with id
159
+ # assignments => tax_id but already in belongs_to => tax
160
+
161
+ assignments[klass].uniq!
162
+
163
+ assignments[klass].each do |assign|
164
+ column_types[klass] ||= {}
165
+ column_def = klass.columns.find { |col| col.name == assign }
166
+ column_types[klass].merge!( assign => column_def) if column_def
167
+ end
168
+ end
169
+
170
+ def catalogued
171
+ @catalogued ||= []
172
+ end
173
+
174
+ def register(klass)
175
+ catalogued << klass
176
+ catalogued.uniq!
177
+ end
178
+ end
179
+
180
+ end
181
+
182
+ end
183
+ end