geoblacklight_admin 0.0.1

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 (346) hide show
  1. checksums.yaml +7 -0
  2. data/.editorconfig +18 -0
  3. data/.gitignore +75 -0
  4. data/.standard.yml +4 -0
  5. data/Gemfile +59 -0
  6. data/LICENSE +21 -0
  7. data/README.md +84 -0
  8. data/Rakefile +72 -0
  9. data/app/assets/images/.keep +0 -0
  10. data/app/assets/images/aerial_photo.jpg +0 -0
  11. data/app/assets/images/archive-solid.svg +1 -0
  12. data/app/assets/images/bookmark-regular.svg +1 -0
  13. data/app/assets/images/bookmark-solid.svg +1 -0
  14. data/app/assets/images/btaa-logo.jpg +0 -0
  15. data/app/assets/images/cloud-download-alt-solid.svg +1 -0
  16. data/app/assets/images/file-import-solid.svg +1 -0
  17. data/app/assets/images/trash-alt-solid.svg +1 -0
  18. data/app/assets/javascripts/geoblacklight_admin/chosen.js +4 -0
  19. data/app/assets/javascripts/geoblacklight_admin/date_range_picker.js +173 -0
  20. data/app/assets/javascripts/geoblacklight_admin/datepicker.js +22 -0
  21. data/app/assets/javascripts/geoblacklight_admin/elements.js +38 -0
  22. data/app/assets/javascripts/geoblacklight_admin/exports.js +3 -0
  23. data/app/assets/javascripts/geoblacklight_admin/fields.js +11 -0
  24. data/app/assets/javascripts/geoblacklight_admin/geoblacklight_admin.js +2 -0
  25. data/app/assets/javascripts/geoblacklight_admin/inputmask.js +4 -0
  26. data/app/assets/javascripts/geoblacklight_admin/locale.js +5 -0
  27. data/app/assets/javascripts/geoblacklight_admin/sortable.js +2544 -0
  28. data/app/assets/javascripts/geoblacklight_admin/tooltips.js +3 -0
  29. data/app/assets/javascripts/geoblacklight_admin/truncate.js +4 -0
  30. data/app/assets/javascripts/geoblacklight_admin.js +40 -0
  31. data/app/assets/stylesheets/geoblacklight_admin/_core.scss +47 -0
  32. data/app/assets/stylesheets/geoblacklight_admin/modules/_autocomplete.scss +32 -0
  33. data/app/assets/stylesheets/geoblacklight_admin/modules/_blazer.scss +3 -0
  34. data/app/assets/stylesheets/geoblacklight_admin/modules/_code.scss +3 -0
  35. data/app/assets/stylesheets/geoblacklight_admin/modules/_datepicker.scss +477 -0
  36. data/app/assets/stylesheets/geoblacklight_admin/modules/_elements.scss +3 -0
  37. data/app/assets/stylesheets/geoblacklight_admin/modules/_forms.scss +28 -0
  38. data/app/assets/stylesheets/geoblacklight_admin/modules/_icons.scss +15 -0
  39. data/app/assets/stylesheets/geoblacklight_admin/modules/_nav.scss +9 -0
  40. data/app/assets/stylesheets/geoblacklight_admin/modules/_tables.scss +4 -0
  41. data/app/assets/stylesheets/geoblacklight_admin/modules/_toasts.scss +7 -0
  42. data/app/assets/stylesheets/geoblacklight_admin/modules/_visibility.scss +3 -0
  43. data/app/assets/stylesheets/geoblacklight_admin/settings/_variables.scss +1 -0
  44. data/app/channels/export_channel.rb +12 -0
  45. data/app/controllers/admin/admin_controller.rb +16 -0
  46. data/app/controllers/admin/advanced_search_controller.rb +365 -0
  47. data/app/controllers/admin/api_controller.rb +386 -0
  48. data/app/controllers/admin/bookmarks_controller.rb +68 -0
  49. data/app/controllers/admin/bulk_actions_controller.rb +94 -0
  50. data/app/controllers/admin/concerns/.keep +0 -0
  51. data/app/controllers/admin/concerns/upload_util.rb +8 -0
  52. data/app/controllers/admin/document_accesses_controller.rb +125 -0
  53. data/app/controllers/admin/document_assets_controller.rb +198 -0
  54. data/app/controllers/admin/document_downloads_controller.rb +127 -0
  55. data/app/controllers/admin/documents_controller.rb +219 -0
  56. data/app/controllers/admin/elements_controller.rb +81 -0
  57. data/app/controllers/admin/form_elements_controller.rb +81 -0
  58. data/app/controllers/admin/ids_controller.rb +379 -0
  59. data/app/controllers/admin/import_documents_controller.rb +18 -0
  60. data/app/controllers/admin/imports_controller.rb +105 -0
  61. data/app/controllers/admin/mappings_controller.rb +95 -0
  62. data/app/controllers/admin/notifications_controller.rb +51 -0
  63. data/app/controllers/admin/search_controller.rb +10 -0
  64. data/app/controllers/admin/users_controller.rb +10 -0
  65. data/app/helpers/bulk_actions_helper.rb +9 -0
  66. data/app/helpers/document_helper.rb +60 -0
  67. data/app/helpers/form_input_helper.rb +73 -0
  68. data/app/helpers/geoblacklight_admin_helper.rb +118 -0
  69. data/app/helpers/import_documents_helper.rb +5 -0
  70. data/app/helpers/mappings_helper.rb +27 -0
  71. data/app/indexers/document_indexer.rb +34 -0
  72. data/app/jobs/bulk_action_revert_document_job.rb +49 -0
  73. data/app/jobs/bulk_action_revert_job.rb +25 -0
  74. data/app/jobs/bulk_action_run_document_job.rb +42 -0
  75. data/app/jobs/bulk_action_run_job.rb +27 -0
  76. data/app/jobs/export_job.rb +72 -0
  77. data/app/jobs/export_json_job.rb +120 -0
  78. data/app/jobs/import_document_job.rb +25 -0
  79. data/app/jobs/import_run_job.rb +33 -0
  80. data/app/models/active_storage_attachment.rb +5 -0
  81. data/app/models/active_storage_blob.rb +5 -0
  82. data/app/models/api_search_builder.rb +12 -0
  83. data/app/models/application_record.rb +6 -0
  84. data/app/models/blacklight_api.rb +93 -0
  85. data/app/models/blacklight_api_facets.rb +15 -0
  86. data/app/models/blacklight_api_ids.rb +103 -0
  87. data/app/models/bookmark.rb +17 -0
  88. data/app/models/bulk_action.rb +88 -0
  89. data/app/models/bulk_action_document.rb +22 -0
  90. data/app/models/bulk_action_document_state_machine.rb +16 -0
  91. data/app/models/bulk_action_document_transition.rb +19 -0
  92. data/app/models/bulk_action_state_machine.rb +16 -0
  93. data/app/models/bulk_action_transition.rb +26 -0
  94. data/app/models/concerns/.keep +0 -0
  95. data/app/models/document/bbox_validator.rb +70 -0
  96. data/app/models/document/controlled_lists.rb +104 -0
  97. data/app/models/document/date_range_validator.rb +63 -0
  98. data/app/models/document/geom_validator.rb +117 -0
  99. data/app/models/document/reference.rb +107 -0
  100. data/app/models/document.rb +264 -0
  101. data/app/models/document_access.rb +35 -0
  102. data/app/models/document_download.rb +35 -0
  103. data/app/models/document_state_machine.rb +14 -0
  104. data/app/models/document_transition.rb +26 -0
  105. data/app/models/element.rb +90 -0
  106. data/app/models/form_control.rb +2 -0
  107. data/app/models/form_element.rb +19 -0
  108. data/app/models/form_feature.rb +2 -0
  109. data/app/models/form_group.rb +2 -0
  110. data/app/models/form_header.rb +2 -0
  111. data/app/models/geoblacklight_admin/field_mappings_btaa_aardvark.rb +379 -0
  112. data/app/models/geoblacklight_admin/field_mappings_gblv1.rb +344 -0
  113. data/app/models/geoblacklight_admin/iso_language_codes.rb +515 -0
  114. data/app/models/geoblacklight_admin/schema.rb +194 -0
  115. data/app/models/geoblacklight_admin.rb +3 -0
  116. data/app/models/import/csv_duplicates_validator.rb +36 -0
  117. data/app/models/import/csv_header_validator.rb +24 -0
  118. data/app/models/import.rb +186 -0
  119. data/app/models/import_btaa.rb +91 -0
  120. data/app/models/import_btaa_aardvark.rb +109 -0
  121. data/app/models/import_document.rb +34 -0
  122. data/app/models/import_document_state_machine.rb +12 -0
  123. data/app/models/import_document_transition.rb +19 -0
  124. data/app/models/import_gblv1.rb +92 -0
  125. data/app/models/import_state_machine.rb +16 -0
  126. data/app/models/import_transition.rb +26 -0
  127. data/app/models/mapping.rb +10 -0
  128. data/app/models/notification.rb +9 -0
  129. data/app/models/user.rb +26 -0
  130. data/app/notifications/export_notification.rb +30 -0
  131. data/app/services/export_csv_document_access_links_service.rb +47 -0
  132. data/app/services/export_csv_document_downloads_service.rb +47 -0
  133. data/app/services/export_csv_service.rb +44 -0
  134. data/app/services/export_json_service.rb +35 -0
  135. data/app/services/zip_file_generator.rb +56 -0
  136. data/app/views/admin/advanced_search/facets.json.jbuilder +80 -0
  137. data/app/views/admin/advanced_search/index.json.jbuilder +90 -0
  138. data/app/views/admin/api/_field.json.jbuilder +10 -0
  139. data/app/views/admin/api/fetch.json.jbuilder +86 -0
  140. data/app/views/admin/api/index.json.jbuilder +90 -0
  141. data/app/views/admin/bookmarks/_bookmark.json.jbuilder +4 -0
  142. data/app/views/admin/bookmarks/create.js.erb +7 -0
  143. data/app/views/admin/bookmarks/destroy.js.erb +7 -0
  144. data/app/views/admin/bookmarks/index.html.erb +21 -0
  145. data/app/views/admin/bookmarks/index.json.jbuilder +3 -0
  146. data/app/views/admin/bulk_actions/_bulk_action.json.jbuilder +4 -0
  147. data/app/views/admin/bulk_actions/_form.html.erb +17 -0
  148. data/app/views/admin/bulk_actions/edit.html.erb +6 -0
  149. data/app/views/admin/bulk_actions/index.html.erb +54 -0
  150. data/app/views/admin/bulk_actions/index.json.jbuilder +3 -0
  151. data/app/views/admin/bulk_actions/new.html.erb +5 -0
  152. data/app/views/admin/bulk_actions/show.html.erb +100 -0
  153. data/app/views/admin/bulk_actions/show.json.jbuilder +3 -0
  154. data/app/views/admin/devise/confirmations/new.html.erb +16 -0
  155. data/app/views/admin/devise/invitations/edit.html.erb +15 -0
  156. data/app/views/admin/devise/invitations/new.html.erb +15 -0
  157. data/app/views/admin/devise/mailer/invitation_instructions.html.erb +11 -0
  158. data/app/views/admin/devise/mailer/invitation_instructions.text.erb +11 -0
  159. data/app/views/admin/devise/passwords/edit.html.erb +26 -0
  160. data/app/views/admin/devise/passwords/new.html.erb +16 -0
  161. data/app/views/admin/devise/registrations/edit.html.erb +35 -0
  162. data/app/views/admin/devise/registrations/new.html.erb +30 -0
  163. data/app/views/admin/devise/sessions/new.html.erb +28 -0
  164. data/app/views/admin/devise/shared/_links.html.erb +27 -0
  165. data/app/views/admin/devise/unlocks/new.html.erb +16 -0
  166. data/app/views/admin/document_accesses/_document_access.json.jbuilder +4 -0
  167. data/app/views/admin/document_accesses/_form.html.erb +17 -0
  168. data/app/views/admin/document_accesses/destroy_all.html.erb +70 -0
  169. data/app/views/admin/document_accesses/edit.html.erb +5 -0
  170. data/app/views/admin/document_accesses/import.html.erb +70 -0
  171. data/app/views/admin/document_accesses/index.html.erb +74 -0
  172. data/app/views/admin/document_accesses/index.json.jbuilder +3 -0
  173. data/app/views/admin/document_accesses/new.html.erb +6 -0
  174. data/app/views/admin/document_accesses/show.html.erb +19 -0
  175. data/app/views/admin/document_accesses/show.json.jbuilder +3 -0
  176. data/app/views/admin/document_assets/display_attach_form.html.erb +44 -0
  177. data/app/views/admin/document_assets/index.html.erb +65 -0
  178. data/app/views/admin/document_downloads/_document_download.json.jbuilder +4 -0
  179. data/app/views/admin/document_downloads/_form.html.erb +15 -0
  180. data/app/views/admin/document_downloads/destroy_all.html.erb +70 -0
  181. data/app/views/admin/document_downloads/edit.html.erb +6 -0
  182. data/app/views/admin/document_downloads/import.html.erb +74 -0
  183. data/app/views/admin/document_downloads/index.html.erb +70 -0
  184. data/app/views/admin/document_downloads/index.json.jbuilder +3 -0
  185. data/app/views/admin/document_downloads/new.html.erb +5 -0
  186. data/app/views/admin/document_downloads/show.html.erb +24 -0
  187. data/app/views/admin/document_downloads/show.json.jbuilder +3 -0
  188. data/app/views/admin/documents/_document.html.erb +29 -0
  189. data/app/views/admin/documents/_document_bookmark.html.erb +17 -0
  190. data/app/views/admin/documents/_document_fields.html.erb +24 -0
  191. data/app/views/admin/documents/_form.html.erb +49 -0
  192. data/app/views/admin/documents/_form_control.html.erb +86 -0
  193. data/app/views/admin/documents/_form_group.html.erb +1 -0
  194. data/app/views/admin/documents/_form_header.html.erb +1 -0
  195. data/app/views/admin/documents/_form_nav.html.erb +21 -0
  196. data/app/views/admin/documents/_json_aardvark.jbuilder +47 -0
  197. data/app/views/admin/documents/_json_btaa_aardvark.jbuilder +16 -0
  198. data/app/views/admin/documents/_json_gbl_v1.jbuilder +32 -0
  199. data/app/views/admin/documents/_result_facets.html.erb +35 -0
  200. data/app/views/admin/documents/_result_pagination.html.erb +21 -0
  201. data/app/views/admin/documents/_result_selected_options.html.erb +54 -0
  202. data/app/views/admin/documents/_result_selection_options.html.erb +10 -0
  203. data/app/views/admin/documents/_result_toggle.html.erb +13 -0
  204. data/app/views/admin/documents/edit.html.erb +7 -0
  205. data/app/views/admin/documents/features/_assets.html.erb +3 -0
  206. data/app/views/admin/documents/features/_institutional_access_links.html.erb +3 -0
  207. data/app/views/admin/documents/features/_multiple_download_links.html.erb +27 -0
  208. data/app/views/admin/documents/fetch.json_aardvark.jbuilder +9 -0
  209. data/app/views/admin/documents/fetch.json_btaa_aardvark.jbuilder +9 -0
  210. data/app/views/admin/documents/fetch.json_gbl_v1.jbuilder +9 -0
  211. data/app/views/admin/documents/index.html.erb +49 -0
  212. data/app/views/admin/documents/index.json_aardvark.jbuilder +9 -0
  213. data/app/views/admin/documents/index.json_btaa_aardvark.jbuilder +9 -0
  214. data/app/views/admin/documents/index.json_gbl_v1.jbuilder +9 -0
  215. data/app/views/admin/documents/show.json_aardvark.jbuilder +3 -0
  216. data/app/views/admin/documents/show.json_btaa_aardvark.jbuilder +3 -0
  217. data/app/views/admin/documents/show.json_gbl_v1.jbuilder +3 -0
  218. data/app/views/admin/documents/versions.html.erb +110 -0
  219. data/app/views/admin/elements/_element.json.jbuilder +2 -0
  220. data/app/views/admin/elements/_form.html.erb +45 -0
  221. data/app/views/admin/elements/edit.html.erb +6 -0
  222. data/app/views/admin/elements/index.html.erb +68 -0
  223. data/app/views/admin/elements/index.json.jbuilder +1 -0
  224. data/app/views/admin/elements/new.html.erb +5 -0
  225. data/app/views/admin/elements/show.html.erb +121 -0
  226. data/app/views/admin/elements/show.json.jbuilder +1 -0
  227. data/app/views/admin/form_elements/_form.html.erb +46 -0
  228. data/app/views/admin/form_elements/_form_element.json.jbuilder +2 -0
  229. data/app/views/admin/form_elements/edit.html.erb +6 -0
  230. data/app/views/admin/form_elements/index.html.erb +49 -0
  231. data/app/views/admin/form_elements/index.json.jbuilder +1 -0
  232. data/app/views/admin/form_elements/new.html.erb +5 -0
  233. data/app/views/admin/form_elements/show.html.erb +19 -0
  234. data/app/views/admin/form_elements/show.json.jbuilder +1 -0
  235. data/app/views/admin/ids/fetch.json.jbuilder +86 -0
  236. data/app/views/admin/ids/index.json.jbuilder +41 -0
  237. data/app/views/admin/import_documents/show.html.haml +20 -0
  238. data/app/views/admin/imports/_form.html.erb +27 -0
  239. data/app/views/admin/imports/_import.json.jbuilder +4 -0
  240. data/app/views/admin/imports/_show_failed_tab.html.erb +37 -0
  241. data/app/views/admin/imports/_show_success_tab.html.erb +31 -0
  242. data/app/views/admin/imports/edit.html.erb +8 -0
  243. data/app/views/admin/imports/index.html.erb +56 -0
  244. data/app/views/admin/imports/index.json.jbuilder +3 -0
  245. data/app/views/admin/imports/new.html.erb +7 -0
  246. data/app/views/admin/imports/show.html.erb +123 -0
  247. data/app/views/admin/imports/show.json.jbuilder +3 -0
  248. data/app/views/admin/layouts/application.html.erb +30 -0
  249. data/app/views/admin/layouts/blazer/application.html.erb +23 -0
  250. data/app/views/admin/layouts/mailer.html.erb +13 -0
  251. data/app/views/admin/layouts/mailer.text.erb +1 -0
  252. data/app/views/admin/mappings/_form.html.erb +17 -0
  253. data/app/views/admin/mappings/_mapping.json.jbuilder +4 -0
  254. data/app/views/admin/mappings/edit.html.erb +6 -0
  255. data/app/views/admin/mappings/index.html.erb +37 -0
  256. data/app/views/admin/mappings/index.json.jbuilder +3 -0
  257. data/app/views/admin/mappings/new.html.erb +5 -0
  258. data/app/views/admin/mappings/show.html.erb +27 -0
  259. data/app/views/admin/mappings/show.json.jbuilder +3 -0
  260. data/app/views/admin/notifications/_notification.html.haml +31 -0
  261. data/app/views/admin/notifications/index.html.erb +54 -0
  262. data/app/views/admin/notifications/update.js.erb +7 -0
  263. data/app/views/admin/search/index.html.erb +38 -0
  264. data/app/views/admin/shared/_flash_messages.html.erb +5 -0
  265. data/app/views/admin/shared/_footer.html.erb +56 -0
  266. data/app/views/admin/shared/_js_behaviors.html.erb +147 -0
  267. data/app/views/admin/shared/_navbar.html.erb +78 -0
  268. data/app/views/admin/shared/_navbar_blazer.html.erb +42 -0
  269. data/app/views/admin/shared/_schema_timestamp.html.erb +16 -0
  270. data/app/views/admin/shared/_toast.html.erb +13 -0
  271. data/app/views/admin/users/index.html.erb +21 -0
  272. data/config/authorities/formats.yml +25 -0
  273. data/config/authorities/languages.yml +50 -0
  274. data/config/authorities/resource_type.yml +82 -0
  275. data/config/blazer.yml +79 -0
  276. data/config/gbl_v1_schema.json +118 -0
  277. data/config/geomg_aardvark_schema.json +211 -0
  278. data/config/geomg_schema.json +123 -0
  279. data/config/locales/devise.en.yml +65 -0
  280. data/config/locales/devise_invitable.en.yml +31 -0
  281. data/config/locales/documents.en.yml +189 -0
  282. data/config/locales/en.yml +51 -0
  283. data/config/locales/geoblacklight.en.yml +178 -0
  284. data/config/locales/simple_form.en.yml +31 -0
  285. data/config/routes.rb +162 -0
  286. data/db/migrate/20230316183001_add_geoblacklight_admin.rb +399 -0
  287. data/db/seeds.rb +26 -0
  288. data/db/seeds_elements.csv +56 -0
  289. data/db/seeds_elements.numbers +0 -0
  290. data/db/seeds_form_elements.csv +71 -0
  291. data/db/seeds_form_elements.numbers +0 -0
  292. data/db/structure.sql +816 -0
  293. data/geoblacklight_admin.gemspec +67 -0
  294. data/lib/generators/geoblacklight_admin/config_generator.rb +336 -0
  295. data/lib/generators/geoblacklight_admin/example_docs_generator.rb +18 -0
  296. data/lib/generators/geoblacklight_admin/helpers_generator.rb +18 -0
  297. data/lib/generators/geoblacklight_admin/install_generator.rb +60 -0
  298. data/lib/generators/geoblacklight_admin/jobs_generator.rb +21 -0
  299. data/lib/generators/geoblacklight_admin/models_generator.rb +23 -0
  300. data/lib/generators/geoblacklight_admin/templates/.env.development.example +28 -0
  301. data/lib/generators/geoblacklight_admin/templates/.solr_wrapper.yml +7 -0
  302. data/lib/generators/geoblacklight_admin/templates/_user_util_links.html.erb +30 -0
  303. data/lib/generators/geoblacklight_admin/templates/config/database.yml +18 -0
  304. data/lib/generators/geoblacklight_admin/templates/config/geomg_aardvark_schema.json +211 -0
  305. data/lib/generators/geoblacklight_admin/templates/config/initializers/geoblacklight_admin.rb +25 -0
  306. data/lib/generators/geoblacklight_admin/templates/config/initializers/kithe.rb +31 -0
  307. data/lib/generators/geoblacklight_admin/templates/config/initializers/pagy.rb +158 -0
  308. data/lib/generators/geoblacklight_admin/templates/config/initializers/statesman.rb +7 -0
  309. data/lib/generators/geoblacklight_admin/templates/javascript/channels/consumer.js +6 -0
  310. data/lib/generators/geoblacklight_admin/templates/javascript/channels/export_channel.js +30 -0
  311. data/lib/generators/geoblacklight_admin/templates/javascript/channels/index.js +5 -0
  312. data/lib/generators/geoblacklight_admin/templates/javascript/controllers/application_controller.js +17 -0
  313. data/lib/generators/geoblacklight_admin/templates/javascript/controllers/document_controller.js +26 -0
  314. data/lib/generators/geoblacklight_admin/templates/javascript/controllers/index.js +10 -0
  315. data/lib/generators/geoblacklight_admin/templates/javascript/controllers/results_controller.js +310 -0
  316. data/lib/generators/geoblacklight_admin/templates/javascript/packs/application.js +23 -0
  317. data/lib/generators/geoblacklight_admin/templates/javascript/src/js/admin/qa_autocomplete.js +1134 -0
  318. data/lib/generators/geoblacklight_admin/templates/package.json +32 -0
  319. data/lib/generators/geoblacklight_admin/templates/solr/README-geoblacklight-solr-development.txt +3 -0
  320. data/lib/generators/geoblacklight_admin/templates/solr/conf/_rest_managed.json +3 -0
  321. data/lib/generators/geoblacklight_admin/templates/solr/conf/admin-extra.html +31 -0
  322. data/lib/generators/geoblacklight_admin/templates/solr/conf/core.properties +5 -0
  323. data/lib/generators/geoblacklight_admin/templates/solr/conf/elevate.xml +36 -0
  324. data/lib/generators/geoblacklight_admin/templates/solr/conf/mapping-ISOLatin1Accent.txt +246 -0
  325. data/lib/generators/geoblacklight_admin/templates/solr/conf/protwords.txt +21 -0
  326. data/lib/generators/geoblacklight_admin/templates/solr/conf/schema.xml +229 -0
  327. data/lib/generators/geoblacklight_admin/templates/solr/conf/scripts.conf +24 -0
  328. data/lib/generators/geoblacklight_admin/templates/solr/conf/solrconfig.xml +266 -0
  329. data/lib/generators/geoblacklight_admin/templates/solr/conf/spellings.txt +2 -0
  330. data/lib/generators/geoblacklight_admin/templates/solr/conf/stopwords.txt +58 -0
  331. data/lib/generators/geoblacklight_admin/templates/solr/conf/stopwords_en.txt +58 -0
  332. data/lib/generators/geoblacklight_admin/templates/solr/conf/synonyms.txt +43 -0
  333. data/lib/generators/geoblacklight_admin/templates/solr/conf/xslt/example.xsl +132 -0
  334. data/lib/generators/geoblacklight_admin/templates/solr/conf/xslt/example_atom.xsl +67 -0
  335. data/lib/generators/geoblacklight_admin/templates/solr/conf/xslt/example_rss.xsl +66 -0
  336. data/lib/generators/geoblacklight_admin/templates/solr/conf/xslt/luke.xsl +337 -0
  337. data/lib/generators/geoblacklight_admin/templates/solr/snapshots/.keep +0 -0
  338. data/lib/generators/geoblacklight_admin/views_generator.rb +19 -0
  339. data/lib/geoblacklight_admin/engine.rb +20 -0
  340. data/lib/geoblacklight_admin/version.rb +5 -0
  341. data/lib/geoblacklight_admin.rb +7 -0
  342. data/lib/tasks/.keep +0 -0
  343. data/lib/tasks/geoblacklight_admin.rake +209 -0
  344. data/spec/test_app_templates/lib/generators/test_app_generator.rb +35 -0
  345. data/template.rb +16 -0
  346. metadata +1037 -0
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "csv"
4
+
5
+ # CSV Duplicates Validator
6
+ #
7
+ # * Checks the CSV file for duplicate IDs.
8
+ # * Fails import if duplicate ID is found.
9
+ #
10
+ class Import
11
+ # CsvDuplicatesValidator
12
+ class CsvDuplicatesValidator < ActiveModel::Validator
13
+ def validate(record)
14
+ valid_csv_file = true
15
+ duplicate_id = validate_csv_file(record.csv_file)
16
+ unless duplicate_id.nil?
17
+ valid_csv_file = false
18
+ record.errors.add(:csv_file, "Duplicate ID value found: #{duplicate_id}. Please clean up the CSV file and reimport.")
19
+ end
20
+
21
+ valid_csv_file
22
+ end
23
+
24
+ def validate_csv_file(csv_file)
25
+ ids = Set.new
26
+ duplicate_id = nil
27
+ csv = CSV.parse(csv_file.download, headers: true)
28
+
29
+ csv["ID"].each do |id|
30
+ duplicate_id = id unless ids.add?(id)
31
+ end
32
+
33
+ duplicate_id
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "csv"
4
+
5
+ # CSV Header Validation
6
+ class Import
7
+ # CsvHeaderValidator
8
+ class CsvHeaderValidator < ActiveModel::Validator
9
+ def validate(record)
10
+ valid_csv_header = true
11
+ unless valid_csv_headers?(record.csv_file)
12
+ valid_csv_header = false
13
+ record.errors.add(:csv_file, "Missing a required CSV header. Title, Resource Class, Access Rights, and ID are required.")
14
+ end
15
+
16
+ valid_csv_header
17
+ end
18
+
19
+ def valid_csv_headers?(csv_file)
20
+ headers = CSV.parse(csv_file.download)[0]
21
+ (["Title", "Resource Class", "Access Rights", "ID"] - headers).empty?
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,186 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "csv"
4
+
5
+ # Import class
6
+ class Import < ApplicationRecord
7
+ include ActiveModel::Validations
8
+
9
+ # Callbacks (keep at top)
10
+ after_commit :set_csv_file_attributes, if: :persisted?
11
+ after_commit :check_if_mapped, if: :persisted?
12
+
13
+ # Associations
14
+ has_one_attached :csv_file
15
+ has_many :documents
16
+ has_many :import_documents, dependent: :destroy
17
+ has_many :import_transitions, autosave: false, dependent: :destroy
18
+ has_many :mappings, -> { order(:id) }, dependent: :destroy, inverse_of: :import
19
+ accepts_nested_attributes_for :mappings
20
+
21
+ # Validations
22
+ validates :name, :type, presence: true
23
+ validates :csv_file, attached: true, content_type: {in: "text/csv", message: "is not a CSV file"}
24
+
25
+ validates_with Import::CsvHeaderValidator
26
+ validates_with Import::CsvDuplicatesValidator
27
+
28
+ # States
29
+ include Statesman::Adapters::ActiveRecordQueries[
30
+ transition_class: ImportTransition,
31
+ initial_state: :created
32
+ ]
33
+
34
+ def state_machine
35
+ @state_machine ||= ImportStateMachine.new(self, transition_class: ImportTransition)
36
+ end
37
+
38
+ def set_csv_file_attributes
39
+ parsed = CSV.parse(csv_file.download)
40
+
41
+ update_columns(
42
+ headers: parsed[0],
43
+ row_count: parsed.size - 1,
44
+ content_type: csv_file.content_type.to_s,
45
+ filename: csv_file.filename.to_s,
46
+ extension: csv_file.filename.extension.to_s
47
+ )
48
+ end
49
+
50
+ def check_if_mapped
51
+ state_machine.transition_to!(:mapped) if mappings_valid? && state_machine.can_transition_to?(:mapped)
52
+ end
53
+
54
+ def all_mapping_keys
55
+ database = mappings.collect(&:destination_field)
56
+ default = default_mappings.collect(&:keys)
57
+ assumed = assumed_mappings.collect(&:values)
58
+
59
+ mappings = (database + default + assumed).flatten
60
+ mappings.map(&:to_s)
61
+ end
62
+
63
+ def mappings_valid?
64
+ (GEOMG_SCHEMA[:required] - all_mapping_keys.uniq).empty?
65
+ end
66
+
67
+ def run!
68
+ # @TODO: guard this call, unless mappings_valid?
69
+
70
+ # Queue Job
71
+ ImportRunJob.perform_later(self)
72
+
73
+ # Capture State
74
+ state_machine.transition_to!(:imported)
75
+ save
76
+ end
77
+
78
+ def convert_data(extract_hash)
79
+ converted_data = transform_extract(extract_hash)
80
+ converted_data = append_default_mappings(converted_data)
81
+ converted_data = append_assumed_mappings(converted_data)
82
+ converted_data = append_derived_mappings(converted_data)
83
+ append_required_mappings(converted_data)
84
+ end
85
+
86
+ private
87
+
88
+ def create_import_document(kithe_document)
89
+ end
90
+
91
+ def transform_extract(extract_hash)
92
+ transformed_data = {}
93
+ mappings.each do |mapping|
94
+ # logger.debug("Mapping: #{mapping.source_header} to #{mapping.destination_field}")
95
+
96
+ # Handle discards
97
+ if mapping.destination_field == "Discard"
98
+ next
99
+ end
100
+
101
+ # Handle repeatable dct_references_s entries
102
+ if mapping.destination_field == "dct_references_s"
103
+ transformed_data[mapping.destination_field] ||= []
104
+ if extract_hash[mapping.source_header].present?
105
+ transformed_data[mapping.destination_field] << {
106
+ category: GeoblacklightAdmin::Schema.instance.dct_references_mappings[mapping.source_header.to_sym],
107
+ value: extract_hash[mapping.source_header]
108
+ }
109
+ end
110
+ # Handle solr_geom transformation
111
+ elsif mapping.destination_field == "solr_geom"
112
+ transformed_data[mapping.destination_field] = solr_geom_mapping(extract_hash[mapping.source_header])
113
+
114
+ # Lastly, set existing values
115
+ else
116
+ transformed_data[mapping.destination_field] = extract_hash[mapping.source_header]
117
+ end
118
+
119
+ # Split delimited field values, if field has a value present
120
+ if mapping.delimited?
121
+ transformed_data[mapping.destination_field] = transformed_data[mapping.destination_field].present? ? transformed_data[mapping.destination_field].split(klass_delimiter) : ""
122
+ end
123
+ end
124
+
125
+ transformed_data
126
+ end
127
+
128
+ # Merges an array of hashes into the data hash
129
+ def append_default_mappings(data_hash)
130
+ default_mappings.each do |mapping|
131
+ data_hash.merge!(mapping.stringify_keys)
132
+ end
133
+
134
+ data_hash
135
+ end
136
+
137
+ # Merges copied value hashes into the data hash
138
+ def append_assumed_mappings(data_hash)
139
+ assumed_mappings.each do |mapping|
140
+ mapping.each do |key, value|
141
+ assumed_mapping = {}
142
+ assumed_mapping[value] = data_hash[key.to_s]
143
+ data_hash.merge!(assumed_mapping)
144
+ end
145
+ end
146
+
147
+ data_hash
148
+ end
149
+
150
+ # Merges derived value hashes into the data hash
151
+ # Takes value from data hash, manipulates it, stores in new hash entry
152
+ #
153
+ # Ex. solr_geom is used to calc the b1g_centroid_ss value
154
+ def append_derived_mappings(data_hash)
155
+ derived_mappings.each do |mapping|
156
+ mapping.each do |key, value|
157
+ derived_mapping = {}
158
+
159
+ args = {data_hash: data_hash.dup, field: value[:field]}
160
+ derived_mapping[key] = send(value[:method], args)
161
+
162
+ data_hash.merge!(derived_mapping.stringify_keys)
163
+ end
164
+ end
165
+
166
+ data_hash
167
+ end
168
+
169
+ # Ensures required values are in the data hash
170
+ #
171
+ # ex. b1g_status_s is required.
172
+ def append_required_mappings(data_hash)
173
+ required_mappings.each do |mapping|
174
+ mapping.each do |key, value|
175
+ required_mapping = {}
176
+ required_mapping[key] = value
177
+
178
+ unless data_hash.has_key?(key)
179
+ data_hash.merge!(required_mapping.stringify_keys)
180
+ end
181
+ end
182
+ end
183
+
184
+ data_hash
185
+ end
186
+ end
@@ -0,0 +1,91 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Import BTAA
4
+ class ImportBtaa < Import
5
+ # validations, constants and methods
6
+
7
+ def mapping_configuration
8
+ GeoblacklightAdmin::Schema.instance.importable_fields
9
+ end
10
+
11
+ def klass_delimiter
12
+ "|"
13
+ end
14
+
15
+ # Solr Field => Hard Value
16
+ def default_mappings
17
+ [
18
+ {gbl_mdVersion_s: "Aardvark"}
19
+ ]
20
+ end
21
+
22
+ # Copy Value from Field to Field
23
+ def assumed_mappings
24
+ # No longer assuming identfier == slug
25
+ # [
26
+ # { 'dc_identifier_s': 'layer_slug_s' }
27
+ # ]
28
+ # Return empty array
29
+ []
30
+ end
31
+
32
+ # Derived Values
33
+ def derived_mappings
34
+ [
35
+ {
36
+ dcat_centroid:
37
+ {
38
+ field: "dcat_bbox",
39
+ method: "derive_dcat_centroid"
40
+ }
41
+ },
42
+ {
43
+ b1g_child_record_b:
44
+ {
45
+ field: "b1g_child_record_b",
46
+ method: "derive_boolean"
47
+ }
48
+ },
49
+ {
50
+ gbl_georeferenced_b:
51
+ {
52
+ field: "gbl_georeferenced_b",
53
+ method: "derive_boolean"
54
+ }
55
+ },
56
+ {
57
+ gbl_suppressed_b:
58
+ {
59
+ field: "gbl_suppressed_b",
60
+ method: "derive_boolean"
61
+ }
62
+ }
63
+ ]
64
+ end
65
+
66
+ # Required Values
67
+ # Key / Default Value
68
+ # Example: { b1g_status_s: 'Active' }
69
+ def required_mappings
70
+ []
71
+ end
72
+
73
+ def derive_dcat_centroid(args)
74
+ data_hash = args[:data_hash]
75
+ field = args[:field]
76
+
77
+ return if data_hash[field].blank?
78
+
79
+ w, s, e, n = data_hash[field].split(",")
80
+ "#{(n.to_f + s.to_f) / 2},#{(e.to_f + w.to_f) / 2}"
81
+ end
82
+
83
+ def derive_boolean(args)
84
+ data_hash = args[:data_hash]
85
+ field = args[:field]
86
+
87
+ return false if data_hash[field].blank?
88
+
89
+ ActiveModel::Type::Boolean.new.cast(data_hash[field].downcase)
90
+ end
91
+ end
@@ -0,0 +1,109 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Import GBLv1
4
+ class ImportBtaaAardvark < Import
5
+ # validations, constants and methods
6
+
7
+ def mapping_configuration
8
+ Geomg.field_mappings_btaa_aardvark
9
+ end
10
+
11
+ def klass_delimiter
12
+ "|"
13
+ end
14
+
15
+ # Solr Field => Hard Value
16
+ def default_mappings
17
+ [
18
+ {gbl_mdVersion_s: "Aardvark"}
19
+ ]
20
+ end
21
+
22
+ # Copy Value from Field to Field
23
+ def assumed_mappings
24
+ # No longer assuming identfier == slug
25
+ # [
26
+ # { 'dc_identifier_s': 'layer_slug_s' }
27
+ # ]
28
+ # Return empty array
29
+ []
30
+ end
31
+
32
+ # Derived Values
33
+ def derived_mappings
34
+ [
35
+ {dct_references_s:
36
+ {
37
+ field: "dct_references_s",
38
+ method: "geomg_dct_references_s"
39
+ }},
40
+ {gbl_dateRange_drsim:
41
+ {
42
+ field: "gbl_dateRange_drsim",
43
+ method: "geomg_b1g_date_range_drsim"
44
+ }},
45
+ {locn_geometry:
46
+ {
47
+ field: "locn_geometry",
48
+ method: "solr_geom_mapping"
49
+ }}
50
+ ]
51
+ end
52
+
53
+ # Required Values
54
+ # Key / Default Value
55
+ def required_mappings
56
+ [
57
+ {b1g_status_s: "Active"}
58
+ ]
59
+ end
60
+
61
+ def solr_geom_mapping(args)
62
+ data_hash = args[:data_hash]
63
+ field = args[:field]
64
+
65
+ # Example: "ENVELOPE(-87\\, -85.76\\, 39.78\\, 37.96)"
66
+ geom = data_hash[field]
67
+ if geom.present?
68
+ geom = geom&.delete("ENVELOPE(")
69
+ geom = geom&.delete(")")
70
+ geom = geom&.delete("\\")
71
+ w, e, n, s = geom.split(",")
72
+ "#{w},#{s},#{e},#{n}"
73
+ else
74
+ ""
75
+ end
76
+ end
77
+
78
+ def geomg_b1g_date_range_drsim(args)
79
+ data_hash = args[:data_hash]
80
+ field = args[:field]
81
+
82
+ # Ex. [2020 TO 2020], [* TO 2020], [2020 TO *]
83
+ date_range = nil
84
+ date_range = data_hash[field][0] unless data_hash[field].empty?
85
+ date_range = date_range[1..12]&.gsub(" TO ", "-") unless date_range.nil?
86
+ date_range
87
+ end
88
+
89
+ def geomg_dct_references_s(args)
90
+ data_hash = args[:data_hash]
91
+ field = args[:field]
92
+ references = []
93
+
94
+ unless data_hash[field].empty?
95
+ dct_references = data_hash[field][0]
96
+ json_data = JSON.parse(dct_references[:value])
97
+
98
+ json_data.each do |key, value|
99
+ reference = {
100
+ value: value,
101
+ category: Geomg.uri_2_category_references_mappings[key]
102
+ }
103
+ references << reference
104
+ end
105
+ end
106
+
107
+ references
108
+ end
109
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ # ImportDocument class
4
+ class ImportDocument < ApplicationRecord
5
+ has_many :import_document_transitions, autosave: false, dependent: :destroy
6
+
7
+ include Statesman::Adapters::ActiveRecordQueries[
8
+ transition_class: ImportDocumentTransition,
9
+ initial_state: :queued
10
+ ]
11
+
12
+ def state_machine
13
+ @state_machine ||= ImportDocumentStateMachine.new(self, transition_class: ImportDocumentTransition)
14
+ end
15
+
16
+ def to_hash
17
+ {
18
+ friendlier_id: friendlier_id,
19
+ title: title,
20
+ json_attributes: nullify_empty_json_attributes,
21
+ import_id: import_id
22
+ }
23
+ end
24
+
25
+ def nullify_empty_json_attributes
26
+ clean_hash = {}
27
+
28
+ json_attributes.each do |key, value|
29
+ clean_hash[key] = value.present? ? value : nil
30
+ end
31
+
32
+ clean_hash
33
+ end
34
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ # ImportDocument Statesman
4
+ class ImportDocumentStateMachine
5
+ include Statesman::Machine
6
+
7
+ state :queued, initial: true
8
+ state :success
9
+ state :failed
10
+
11
+ transition from: :queued, to: %i[success failed]
12
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Add ImportDocument Statesman Transitions
4
+ class ImportDocumentTransition < ApplicationRecord
5
+ include Statesman::Adapters::ActiveRecordTransition
6
+
7
+ belongs_to :import_document, inverse_of: :import_document_transitions
8
+
9
+ after_destroy :update_most_recent, if: :most_recent?
10
+
11
+ private
12
+
13
+ def update_most_recent
14
+ last_transition = import_document.import_document_transitions.order(:sort_key).last
15
+ return if last_transition.blank?
16
+
17
+ last_transition.update_column(:most_recent, true)
18
+ end
19
+ end
@@ -0,0 +1,92 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Import GBLv1
4
+ class ImportGblv1 < Import
5
+ # validations, constants and methods
6
+
7
+ def mapping_configuration
8
+ Geomg.field_mappings_gblv1
9
+ end
10
+
11
+ def klass_delimiter
12
+ "|"
13
+ end
14
+
15
+ # Solr Field => Hard Value
16
+ def default_mappings
17
+ [
18
+ {geoblacklight_version: "1.0"}
19
+ ]
20
+ end
21
+
22
+ # Copy Value from Field to Field
23
+ def assumed_mappings
24
+ # No longer assuming identfier == slug
25
+ # [
26
+ # { 'dc_identifier_s': 'layer_slug_s' }
27
+ # ]
28
+ # Return empty array
29
+ []
30
+ end
31
+
32
+ # Derived Values
33
+ def derived_mappings
34
+ [
35
+ {dct_references_s:
36
+ {
37
+ field: "dct_references_s",
38
+ method: "geomg_dct_references_s"
39
+ }},
40
+ {b1g_date_range_drsim:
41
+ {
42
+ field: "b1g_date_range_drsim",
43
+ method: "geomg_b1g_date_range_drsim"
44
+ }}
45
+ ]
46
+ end
47
+
48
+ # Required Values
49
+ # Key / Default Value
50
+ def required_mappings
51
+ [
52
+ {b1g_status_s: "Active"}
53
+ ]
54
+ end
55
+
56
+ def solr_geom_mapping(geom)
57
+ # Example: "ENVELOPE(-87\\, -85.76\\, 39.78\\, 37.96)"
58
+ geom&.delete("\\")
59
+ end
60
+
61
+ def geomg_b1g_date_range_drsim(args)
62
+ data_hash = args[:data_hash]
63
+ field = args[:field]
64
+
65
+ # Ex. [2020 TO 2020], [* TO 2020], [2020 TO *]
66
+ date_range = nil
67
+ date_range = data_hash[field][0] unless data_hash[field].empty?
68
+ date_range = date_range[1..12]&.gsub(" TO ", "-") unless date_range.nil?
69
+ date_range
70
+ end
71
+
72
+ def geomg_dct_references_s(args)
73
+ data_hash = args[:data_hash]
74
+ field = args[:field]
75
+ references = []
76
+
77
+ unless data_hash[field].empty?
78
+ dct_references = data_hash[field][0]
79
+ json_data = JSON.parse(dct_references[:value])
80
+
81
+ json_data.each do |key, value|
82
+ reference = {
83
+ value: value,
84
+ category: Geomg::FieldMappingsGblv1.uri_2_category_references_mappings[key]
85
+ }
86
+ references << reference
87
+ end
88
+ end
89
+
90
+ references
91
+ end
92
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Import Statesman
4
+ class ImportStateMachine
5
+ include Statesman::Machine
6
+
7
+ state :created, initial: true
8
+ state :mapped
9
+ state :imported
10
+ state :success
11
+ state :failed
12
+
13
+ transition from: :created, to: [:mapped]
14
+ transition from: :mapped, to: [:imported]
15
+ transition from: :imported, to: %i[success failed]
16
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Add Import Statesman Transitions
4
+ class ImportTransition < ApplicationRecord
5
+ include Statesman::Adapters::ActiveRecordTransition
6
+
7
+ # If your transition table doesn't have the default `updated_at` timestamp column,
8
+ # you'll need to configure the `updated_timestamp_column` option, setting it to
9
+ # another column name (e.g. `:updated_on`) or `nil`.
10
+ #
11
+ # self.updated_timestamp_column = :updated_on
12
+ # self.updated_timestamp_column = nil
13
+
14
+ belongs_to :import, inverse_of: :import_transitions
15
+
16
+ after_destroy :update_most_recent, if: :most_recent?
17
+
18
+ private
19
+
20
+ def update_most_recent
21
+ last_transition = import.import_transitions.order(:sort_key).last
22
+ return if last_transition.blank?
23
+
24
+ last_transition.update_column(:most_recent, true)
25
+ end
26
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Mapping
4
+ class Mapping < ApplicationRecord
5
+ belongs_to :import
6
+
7
+ # Validations
8
+ validates :source_header, presence: true
9
+ validates :destination_field, presence: true
10
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Notification
4
+ class Notification < ApplicationRecord
5
+ include Noticed::Model
6
+ belongs_to :recipient, polymorphic: true
7
+
8
+ has_one_attached :file
9
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ # User
4
+ class User < ApplicationRecord
5
+ include Blacklight::User
6
+
7
+ # Include default devise modules. Others available are:
8
+ # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
9
+ devise :invitable, :database_authenticatable,
10
+ :recoverable, :rememberable, :validatable
11
+
12
+ has_many :bookmarks, dependent: :destroy, as: :user
13
+ has_many :notifications, dependent: :destroy, as: :recipient
14
+
15
+ def bookmarks_for_documents(documents = [])
16
+ if documents.any?
17
+ bookmarks.where(document_type: documents.first.class.base_class.to_s, document_id: documents.map(&:id))
18
+ else
19
+ []
20
+ end
21
+ end
22
+
23
+ def document_is_bookmarked?(document)
24
+ bookmarks_for_documents([document]).any?
25
+ end
26
+ end