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,42 @@
1
+ # Copyright:: (c) Autotelik Media Ltd 2011
2
+ # Author :: Tom Statter
3
+ # Date :: Aug 2010
4
+ # License:: MIT
5
+ #
6
+ # Details:: Module for loaders, providing a process hook which populates a model,
7
+ # based on a method map and supplied value from a file - i.e a single column/row's string value.
8
+ # Note that although a single column, the string can be formatted to contain multiple values.
9
+ #
10
+ # Tightly coupled with Binder classes (in lib/engine) which contains full details of
11
+ # a file's column and it's correlated AR associations.
12
+ #
13
+ module DataShift
14
+
15
+ module Loader
16
+
17
+ class Factory
18
+
19
+ # Based on file_name find appropriate Loader
20
+
21
+ # Currently supports :
22
+ # Excel/Open Office files saved as .xls
23
+ # CSV files
24
+ #
25
+ def self.get_loader(file_name)
26
+
27
+ raise DataShift::BadFile, "Cannot load #{file_name} file not found." unless File.exist?(file_name)
28
+
29
+ ext = File.extname(file_name)
30
+
31
+ if ext.casecmp('.xls') == 0 || ext.casecmp('.xlsx') == 0
32
+ return ExcelLoader.new
33
+ elsif ext.casecmp('.csv') == 0
34
+ return CsvLoader.new
35
+ else
36
+ raise DataShift::UnsupportedFileType, "#{ext} files not supported - Try .csv or OpenOffice/Excel .xls"
37
+ end
38
+ end
39
+
40
+ end
41
+ end
42
+ end
@@ -9,176 +9,193 @@ require 'loader_base'
9
9
  require 'datashift_paperclip'
10
10
 
11
11
  module DataShift
12
-
12
+
13
13
  module Paperclip
14
-
14
+
15
15
  class AttachmentLoader < LoaderBase
16
-
16
+
17
17
  include DataShift::Paperclip
18
-
19
- attr_accessor :attach_to_klass, :attach_to_find_by_field
20
-
21
- attr_writer :attach_to_field
22
- attr_reader :attachment_path, :loading_files_cache
23
-
24
-
25
- # Constructor
26
- #
27
- # Options
28
- #
29
- # => :attach_to_klass
30
- # A class that has a relationship with the attachment (has_many, has_one or belongs_to etc)
18
+
19
+ attr_accessor :attach_to_klass, :attach_to_find_by_field, :attach_to_field
20
+
21
+ # We try splitting up inbound file_names in various ways looking for the attachment Owner
22
+ attr_accessor :split_file_name_on
23
+
24
+ attr_reader :loading_files_cache, :missing_records
25
+
26
+ def initialize
27
+ super
28
+
29
+ @attach_to_klass = nil
30
+ @attach_to_find_by_field = nil
31
+ @attach_to_field = nil
32
+
33
+ @split_file_name_on = Regexp.new(/\s+/)
34
+
35
+ @missing_records = []
36
+ end
37
+
38
+ # => :attach_to_klass
39
+ # A class that has a relationship with the attachment (has_many, has_one or belongs_to etc)
31
40
  # The instance of :attach_to_klass can be searched for and the new attachment assigned.
32
- #
33
- # Examples
41
+ #
42
+ # Examples
34
43
  # Owner has_many pdfs and mp3 files as Digitals .... :attach_to_klass = Owner
35
44
  # User has a single image used as an avatar ... :attach_to_klass = User
36
45
  #
37
- # => :attach_to_find_by_field
38
- # For the :attach_to_klass, this is the field used to search for the parent
39
- # object to assign the new attachment to.
40
- #
41
- # Examples
46
+ # => :attach_to_find_by_field
47
+ # Field on the :attach_to_klass, this is the field used to search for the
48
+ # object (class == attach_to_klass) to assign the new attachment to.
49
+ #
50
+ # Examples
42
51
  # Owner has a unique 'name' field ... :attach_to_find_by_field = :name
43
52
  # User has a unique 'login' field ... :attach_to_klass = :login
44
53
  #
45
- # => :attach_to_field
54
+ # => :attach_to_field
46
55
  # Attribute/association to assign attachment to on :attach_to_klass.
47
56
  # Examples
48
- #
57
+ #
49
58
  # :attach_to_field => digitals : Owner.digitals = attachment
50
59
  # :attach_to_field => avatar : User.avatar = attachment
51
- #
52
- #
53
- def initialize(attachment_klazz, attachment = nil, options = {})
54
-
55
- init_from_options( options )
56
-
57
- super( attachment_klazz, attachment, options.dup )
58
-
59
- puts "Attachment Class is #{load_object_class}" if(@verbose)
60
-
61
- raise "Failed to create Attachment for loading" unless @load_object
62
- end
63
-
64
-
65
- # Options
66
- # :reload
67
- # :attach_to_klass, :attach_to_field, :attach_to_find_by_field
68
60
  #
69
- def init_from_options( options )
70
-
71
- @attach_to_klass = options[:attach_to_klass] || @attach_to_klass || nil
72
-
73
- unless(@attach_to_klass.nil? || (MethodDictionary::for?(@attach_to_klass) && options[:reload] == false))
74
- #puts "Building Method Dictionary for class #{object_class}"
75
- DataShift::MethodDictionary.find_operators( @attach_to_klass, :reload => options[:reload], :instance_methods => true )
76
-
77
- # Create dictionary of data on all possible 'setter' methods which can be used to
78
- # populate or integrate an object of type @load_object_class
79
- DataShift::MethodDictionary.build_method_details(@attach_to_klass)
80
- end
81
-
82
- @attach_to_find_by_field = options[:attach_to_find_by_field] || @attach_to_find_by_field || nil
83
- @attach_to_field = options[:attach_to_field] || @attach_to_field || nil
84
-
85
- unless(@attach_to_klass.nil? && @attach_to_field.nil? )
86
- @attach_to_method_detail = MethodDictionary.find_method_detail(@attach_to_klass, @attach_to_field)
61
+ def init(attach_to_klass, attach_to_find_by_field, attach_to_field, options = {})
62
+
63
+ @attach_to_klass = MapperUtils.ensure_class( attach_to_klass )
64
+
65
+ ModelMethods::Manager.catalog_class(@attach_to_klass, reload: options[:reload], instance_methods: true)
66
+
67
+ @attach_to_find_by_field = attach_to_find_by_field
68
+ @attach_to_field = attach_to_field
69
+ end
70
+
71
+ def init_from_options(options)
72
+ init(options[:attach_to_klass], options[:attach_to_find_by_field], options[:attach_to_field])
73
+
74
+ @split_file_name_on = options[:split_file_name_on] if(options[:split_file_name_on])
75
+ end
76
+
77
+ def find_bindings
78
+ # Map field to a suitable call on the Active Record Owner class e.g Owner.digitals
79
+ bindings = begin
80
+ logger.info("Finding matching field/association [#{attach_to_field}] on class [#{attach_to_klass}]")
81
+
82
+ binder.map_inbound_fields(attach_to_klass, attach_to_field)
83
+ rescue => e
84
+ logger.error("Failed to map #{attach_to_field} to database operator : #{e.inspect}")
85
+ logger.error( e.backtrace )
86
+ raise MappingDefinitionError, 'Failed to map #{attach_to_field} to database operator'
87
87
  end
88
+
89
+ bindings
88
90
  end
89
-
90
-
91
- # If we have instantiated a method detail based on the attach to class and fields
92
- # return that otherwise return the raw format of :attach_to_find_by_field
93
-
94
- def attach_to_field
95
- @attach_to_method_detail || @attach_to_field
91
+
92
+ def find_owner(in_file_name, options = {} )
93
+
94
+ search_term = File.basename(in_file_name, '.*')
95
+ search_term.strip!
96
+
97
+ logger.info("Attempting to find attachment owner (#{attach_to_klass} for [#{search_term}]")
98
+
99
+ owner_record = get_record_by(attach_to_klass, attach_to_find_by_field, search_term, split_file_name_on, options)
100
+
101
+ if owner_record
102
+ logger.info("#{owner_record.class} (id : #{owner_record.id}) found with matching :#{attach_to_find_by_field} ")
103
+ else
104
+
105
+ message = "No matching owner found for file name : #{search_term}"
106
+
107
+ failed = FailureData.new(nil, doc_context.node_context, message)
108
+
109
+ doc_context.progress_monitor.failure(failed)
110
+
111
+ missing_records << in_file_name
112
+ end
113
+
114
+ owner_record
96
115
  end
97
-
98
-
116
+
99
117
  # This version creates attachments and also attaches them to instances of :attach_to_klazz
100
- #
101
- # Each file found in PATH will be processed - it's filename being used to scan for
118
+ #
119
+ # Each file found in PATH will be processed - it's file_name being used to scan for
102
120
  # a matching record to attach the file to.
103
- #
121
+ #
104
122
  # Options
105
- # :split_file_name_on Used in scan process to progresivly split filename to find
106
- # :attach_to_klass with matching :attach_to_find_by_field
123
+ # :split_file_name_on Used in scan process to progressively split file_name to find
107
124
  #
108
125
  # :add_prefix
109
126
  #
110
- def process_from_filesystem(path, options = {} )
111
-
112
- init_from_options( options )
113
-
114
- raise "The class that attachments belongs to has not been set (:attach_to_klass)" unless(@attach_to_klass)
115
-
116
- raise "The field to search for attachment's owner has not been set (:attach_to_find_by_field)" unless(@attach_to_find_by_field)
117
-
118
- @load_object = options[:attachment] if(options[:attachment])
119
-
120
- @attachment_path = path
121
-
122
- missing_records = []
123
-
124
- # try splitting up filename in various ways looking for the attachment owqner
125
- split_on = @config['split_file_name_on'] || options[:split_file_name_on]
126
-
127
- @loading_files_cache = DataShift::Paperclip::get_files(path, options)
128
-
129
- puts "Found #{loading_files_cache.size} files - splitting names on delimiter [#{split_on}]"
130
-
131
- loading_files_cache.each do |file_name|
132
-
133
- attachment_name = File.basename(file_name)
127
+ def perform_load(options = {} )
128
+
129
+ raise 'The class that attachments belongs to has not been set (:attach_to_klass)' unless @attach_to_klass
130
+
131
+ raise "The field to search for attachment's owner has not been set (:attach_to_find_by_field)" unless @attach_to_find_by_field
132
+
133
+ @missing_records = []
134
+
135
+ @load_object = options[:attachment] if options[:attachment]
136
+
137
+ # Support both directory and file
138
+ @loading_files_cache = DataShift::Paperclip.get_files(file_name, options)
139
+
140
+ logger.info("Found #{loading_files_cache.size} files - splitting names on delimiter [#{split_file_name_on}]")
141
+
142
+ # Map field to a suitable call on the Active Record Owner class e.g Owner.digitals
143
+ bindings = find_bindings
144
+
145
+ attach_to_method_binding = if bindings.size != 1
146
+ logger.warn("Failed to map #{attach_to_field} to database operator")
147
+ nil
148
+ else
149
+ bindings[0]
150
+ end
151
+
152
+ # Iterate through all the files creating an attachment per file
153
+
154
+ loading_files_cache.each do |in_file_name|
155
+ attachment_name = File.basename(in_file_name)
134
156
 
135
157
  logger.info "Processing attachment file #{attachment_name} "
136
-
137
- base_name = File.basename(file_name, '.*')
138
- base_name.strip!
139
-
140
- record = nil
141
-
142
- puts "Attempting fo find Record for file name : #{base_name}"
143
- record = get_record_by(attach_to_klass, attach_to_find_by_field, base_name, split_on, options)
144
-
145
- if(record)
146
- puts "Found #{record.class} where : #{attach_to_find_by_field} = #{record.send(attach_to_find_by_field)}(id : #{record.id})"
147
- else
148
- missing_records << file_name
149
- end
150
-
151
- next if(options[:dummy]) # Don't actually create/upload to DB if we are doing dummy run
152
-
153
- # Check if attachment must have an associated record
154
- if(record)
155
- reset()
156
-
157
- create_paperclip_attachment(@load_object_class, file_name, record, attach_to_field, options)
158
-
159
- puts "Added Attachment #{File.basename(file_name)} to #{record.send(attach_to_find_by_field)}(id : #{record.id})" if(@verbose)
160
- end
161
158
 
162
- end
159
+ owner_record = find_owner(in_file_name, options)
160
+
161
+ next if(configuration.dummy_run) # Don't actually create/upload to DB if we are doing dummy run
162
+
163
+ attachment = create_paperclip_attachment(load_object_class, in_file_name, options)
164
+
165
+ # Check if attachment must have an associated owner_record
166
+ next unless attachment && owner_record && attach_to_method_binding
167
+ reset
163
168
 
164
- unless missing_records.empty?
165
- FileUtils.mkdir_p('MissingAttachmentRecords') unless File.directory?('MissingAttachmentRecords')
166
-
167
- puts "WARNING : #{missing_records.size} of #{loading_files_cache.size} files could not be attached to a #{@load_object_class}"
168
- puts "For your convenience copying files with MISSING #{attach_to_klass} to : MissingAttachmentRecords"
169
- missing_records.each do |i|
170
- FileUtils.cp( i, 'MissingAttachmentRecords') unless(options[:dummy] == 'true')
171
- puts "Copyied #{i} to MissingAttachmentRecords folder" if(options[:verbose])
172
- end
169
+ # TOFIX - what about has_one etc ? - indicates that Context etc are still too complex and Excel/CSV focused
170
+ owner_record.send(attach_to_method_binding.operator) << attachment
171
+
172
+ logger.info "Added Attachment to #{owner_record.class} (id : #{owner_record.id})"
173
173
  end
174
174
 
175
- puts "Created #{loading_files_cache.size - missing_records.size} of #{loading_files_cache.size} #{@load_object_class} attachments and succesfully attached to a #{@attach_to_klass}"
176
-
177
- puts "Dummy Run Complete- if happy run without -d" if(options[:dummy])
178
-
175
+ process_missing_records( missing_records )
176
+
177
+ created = loading_files_cache.size - missing_records.size
178
+
179
+ puts "Created #{created} / #{loading_files_cache.size} attachments of type #{load_object_class} attached to #{@attach_to_klass}"
180
+
181
+ puts 'Dummy Run Complete - if happy run with full commit' if(configuration.dummy_run)
182
+
183
+ end
184
+
185
+ end
186
+
187
+ def process_missing_records( missing_records )
188
+ unless missing_records.empty?
189
+ FileUtils.mkdir_p('MissingAttachmentRecords') unless File.directory?('MissingAttachmentRecords')
190
+
191
+ puts "WARNING : #{missing_records.size} of #{loading_files_cache.size} files could not be attached to a #{load_object_class}"
192
+ puts "For your convenience copying files with MISSING #{attach_to_klass} to : MissingAttachmentRecords"
193
+ missing_records.each do |i|
194
+ logger.info("Copying #{i} to MissingAttachmentRecords folder")
195
+ FileUtils.cp( i, 'MissingAttachmentRecords') unless(configuration.dummy_run)
196
+ end
179
197
  end
180
-
181
198
  end
182
-
199
+
183
200
  end
184
- end
201
+ end
@@ -24,24 +24,24 @@ module DataShift
24
24
  # => :recursive : Descend tree looking for files rather than just supplied path
25
25
 
26
26
  def self.get_files(path, options = {})
27
- return [path] if(File.file?(path))
27
+ return [path] if File.file?(path)
28
28
  glob = options[:glob] ? options[:glob] : '*.*'
29
- glob = (options['recursive'] || options[:recursive]) ? "**/#{glob}" : glob
29
+ glob = (options['recursive'] || options[:recursive]) ? "**/#{glob}" : glob
30
30
 
31
31
  Dir.glob("#{path}/#{glob}", File::FNM_CASEFOLD)
32
32
  end
33
33
 
34
34
  def get_file( attachment_path )
35
35
 
36
- unless File.exists?(attachment_path) && File.readable?(attachment_path)
36
+ unless File.exist?(attachment_path) && File.readable?(attachment_path)
37
37
  logger.error("Cannot process Image from #{Dir.pwd}: Invalid Path #{attachment_path}")
38
38
  raise PathError.new("Cannot process Image : Invalid Path #{attachment_path}")
39
39
  end
40
40
 
41
41
  file = begin
42
- File.new(attachment_path, "rb")
42
+ File.new(attachment_path, 'rb')
43
43
  rescue => e
44
- puts e.inspect
44
+ logger.error(e.inspect)
45
45
  raise PathError.new("ERROR : Failed to read image from #{attachment_path}")
46
46
  end
47
47
 
@@ -72,55 +72,38 @@ module DataShift
72
72
  #
73
73
  # Give : { :has_attached_file_attribute => :icon }
74
74
  #
75
- def create_paperclip_attachment(klass, attachment_path, record = nil, attach_to_record_field = nil, options = {})
75
+ def create_paperclip_attachment(klass, attachment_path, options = {})
76
76
 
77
77
  logger.info("Paperclip::create_paperclip_attachment on Class #{klass}")
78
78
 
79
79
  has_attached_file_attribute = options[:has_attached_file_name] ? options[:has_attached_file_name].to_sym : :attachment
80
80
 
81
- # e.g (:attachment => File.read)
82
-
83
81
  attachment_file = get_file(attachment_path)
84
- paperclip_attributes = { has_attached_file_attribute => attachment_file }
85
82
 
86
- paperclip_attributes.merge!(options[:attributes]) if(options[:attributes])
83
+ paperclip_attributes = { "#{has_attached_file_attribute}": attachment_file}
84
+
85
+ paperclip_attributes.merge!(options[:attributes]) if options[:attributes]
87
86
 
88
87
  begin
89
- @attachment = klass.new(paperclip_attributes, :without_protection => true)
88
+ @attachment = klass.new(paperclip_attributes)
90
89
  rescue => e
91
90
  logger.error( e.backtrace)
92
- logger.error("Failed to create PaperClip Attachment for cl;ass #{klass} : #{e.inspect}")
93
- raise CreateAttachmentFailed.new("Failed to create PaperClip Attachment from : #{attachment_path}")
91
+ raise CreateAttachmentFailed.new("Failed [#{e.message}] creating PaperClip Attachment on #{klass} for [#{attachment_path}]")
94
92
  ensure
95
93
  attachment_file.close unless attachment_file.closed?
96
94
  end
97
95
 
98
- begin
99
-
100
- if(@attachment.save)
101
- puts "Success: Created Attachment #{@attachment.id} : #{@attachment.attachment_file_name}"
102
-
103
- if(attach_to_record_field.is_a? MethodDetail)
104
- DataShift::Populator.new().prepare_and_assign(attach_to_record_field, record, @attachment)
105
- else
106
- # assume its not a has_many and try basic send
107
- record.send("#{attach_to_record_field}=", @attachment)
108
- end if(record && attach_to_record_field)
109
-
110
- else
111
- puts "ERROR : Problem saving to DB : #{@attachment.inspect}"
112
- puts @attachment.errors.messages.inspect
113
- end
96
+ if @attachment.save
97
+ logger.info("Success: Created Attachment #{@attachment.id} : #{@attachment.attachment_file_name}")
114
98
 
115
99
  @attachment
116
- rescue => e
117
- logger.error("Problem saving Paperclip Attachment: #{e.inspect}")
118
- puts e.inspect
119
- raise CreateAttachmentFailed.new("PaperClip error - Problem saving Attachment")
120
- ensure
121
- attachment_file.close unless attachment_file.closed?
100
+ else
101
+ logger.error('Problem creating and saving Paperclip Attachment')
102
+ logger.error(@attachment.errors.messages.inspect)
103
+ raise CreateAttachmentFailed.new('PaperClip error - Problem saving Attachment')
122
104
  end
123
105
  end
106
+
124
107
  end
125
108
 
126
109
  end