newspaper_works 0.1.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 (461) hide show
  1. checksums.yaml +7 -0
  2. data/.fcrepo_wrapper +4 -0
  3. data/.gitignore +43 -0
  4. data/.rubocop.yml +143 -0
  5. data/.solr_wrapper +8 -0
  6. data/.travis.yml +50 -0
  7. data/Gemfile +47 -0
  8. data/LICENSE +203 -0
  9. data/README.md +159 -0
  10. data/Rakefile +38 -0
  11. data/app/actors/hyrax/actors/newspaper_article_actor.rb +8 -0
  12. data/app/actors/hyrax/actors/newspaper_container_actor.rb +8 -0
  13. data/app/actors/hyrax/actors/newspaper_issue_actor.rb +8 -0
  14. data/app/actors/hyrax/actors/newspaper_page_actor.rb +8 -0
  15. data/app/actors/hyrax/actors/newspaper_title_actor.rb +8 -0
  16. data/app/actors/newspaper_works/actors/newspaper_works_upload_actor.rb +88 -0
  17. data/app/assets/config/newspaper_works_manifest.js +2 -0
  18. data/app/assets/images/newspaper_works/.keep +0 -0
  19. data/app/assets/javascripts/newspaper_works/autocomplete_fix.js +33 -0
  20. data/app/assets/javascripts/newspaper_works/ocr_search.js.erb +6 -0
  21. data/app/assets/javascripts/newspaper_works/thumbnail_highlights.js.erb +102 -0
  22. data/app/assets/javascripts/newspaper_works.js +4 -0
  23. data/app/assets/stylesheets/newspaper_works/_issue_search.scss +13 -0
  24. data/app/assets/stylesheets/newspaper_works/_issues_calendar.scss +18 -0
  25. data/app/assets/stylesheets/newspaper_works/_newspaper_works.scss +4 -0
  26. data/app/assets/stylesheets/newspaper_works/_newspapers_search.scss +38 -0
  27. data/app/assets/stylesheets/newspaper_works/_search_results.scss +12 -0
  28. data/app/controllers/hyrax/newspaper_articles_controller.rb +14 -0
  29. data/app/controllers/hyrax/newspaper_containers_controller.rb +14 -0
  30. data/app/controllers/hyrax/newspaper_issues_controller.rb +14 -0
  31. data/app/controllers/hyrax/newspaper_pages_controller.rb +14 -0
  32. data/app/controllers/hyrax/newspaper_titles_controller.rb +13 -0
  33. data/app/controllers/newspaper_works/newspapers_controller.rb +117 -0
  34. data/app/controllers/newspaper_works/newspapers_search_controller.rb +26 -0
  35. data/app/forms/hyrax/newspaper_article_form.rb +11 -0
  36. data/app/forms/hyrax/newspaper_container_form.rb +11 -0
  37. data/app/forms/hyrax/newspaper_issue_form.rb +11 -0
  38. data/app/forms/hyrax/newspaper_page_form.rb +15 -0
  39. data/app/forms/hyrax/newspaper_title_form.rb +12 -0
  40. data/app/forms/newspaper_works/newspaper_core_form_data.rb +17 -0
  41. data/app/helpers/hyrax/newspaper_articles_helper.rb +5 -0
  42. data/app/helpers/hyrax/newspaper_containers_helper.rb +5 -0
  43. data/app/helpers/hyrax/newspaper_issues_helper.rb +5 -0
  44. data/app/helpers/hyrax/newspaper_pages_helper.rb +5 -0
  45. data/app/helpers/newspaper_works/application_helper.rb +5 -0
  46. data/app/helpers/newspaper_works/breadcrumb_helper.rb +92 -0
  47. data/app/helpers/newspaper_works/newspaper_works_helper_behavior.rb +103 -0
  48. data/app/helpers/newspaper_works/newspapers_helper.rb +5 -0
  49. data/app/indexers/concerns/newspaper_works/indexes_full_text.rb +17 -0
  50. data/app/indexers/concerns/newspaper_works/indexes_place_of_publication.rb +67 -0
  51. data/app/indexers/concerns/newspaper_works/indexes_publication_date_range.rb +35 -0
  52. data/app/indexers/concerns/newspaper_works/indexes_relationships.rb +125 -0
  53. data/app/indexers/newspaper_article_indexer.rb +16 -0
  54. data/app/indexers/newspaper_container_indexer.rb +18 -0
  55. data/app/indexers/newspaper_issue_indexer.rb +26 -0
  56. data/app/indexers/newspaper_page_indexer.rb +9 -0
  57. data/app/indexers/newspaper_title_indexer.rb +19 -0
  58. data/app/indexers/newspaper_works/newspaper_core_indexer.rb +21 -0
  59. data/app/jobs/newspaper_works/application_job.rb +4 -0
  60. data/app/jobs/newspaper_works/compose_issue_pdf_job.rb +13 -0
  61. data/app/jobs/newspaper_works/create_issue_pages_job.rb +19 -0
  62. data/app/mailers/newspaper_works/application_mailer.rb +8 -0
  63. data/app/models/concerns/newspaper_works/blacklight_iiif_search/annotation_behavior.rb +82 -0
  64. data/app/models/concerns/newspaper_works/blacklight_iiif_search/search_behavior.rb +27 -0
  65. data/app/models/concerns/newspaper_works/newspaper_core_metadata.rb +67 -0
  66. data/app/models/concerns/newspaper_works/place_of_publication_behavior.rb +15 -0
  67. data/app/models/concerns/newspaper_works/scanned_media_metadata.rb +43 -0
  68. data/app/models/concerns/newspaper_works/solr/document.rb +25 -0
  69. data/app/models/file_set.rb +10 -0
  70. data/app/models/newspaper_article.rb +158 -0
  71. data/app/models/newspaper_container.rb +86 -0
  72. data/app/models/newspaper_issue.rb +115 -0
  73. data/app/models/newspaper_page.rb +70 -0
  74. data/app/models/newspaper_title.rb +111 -0
  75. data/app/models/newspaper_works/application_record.rb +6 -0
  76. data/app/models/newspaper_works/derivative_attachment.rb +8 -0
  77. data/app/models/newspaper_works/ingest_file_relation.rb +14 -0
  78. data/app/presenters/hyrax/newspaper_article_presenter.rb +38 -0
  79. data/app/presenters/hyrax/newspaper_container_presenter.rb +11 -0
  80. data/app/presenters/hyrax/newspaper_issue_presenter.rb +62 -0
  81. data/app/presenters/hyrax/newspaper_page_presenter.rb +72 -0
  82. data/app/presenters/hyrax/newspaper_title_presenter.rb +86 -0
  83. data/app/presenters/newspaper_works/iiif_manifest_presenter_behavior.rb +29 -0
  84. data/app/presenters/newspaper_works/issue_info_presenter.rb +29 -0
  85. data/app/presenters/newspaper_works/newspaper_core_presenter.rb +9 -0
  86. data/app/presenters/newspaper_works/persistent_url_presenter_behavior.rb +16 -0
  87. data/app/presenters/newspaper_works/place_of_publication_presenter_behavior.rb +8 -0
  88. data/app/presenters/newspaper_works/scanned_media_presenter.rb +7 -0
  89. data/app/presenters/newspaper_works/title_info_presenter.rb +13 -0
  90. data/app/search_builders/concerns/newspaper_works/exclude_models.rb +16 -0
  91. data/app/search_builders/concerns/newspaper_works/highlight_search_params.rb +14 -0
  92. data/app/search_builders/newspaper_works/newspapers_search_builder.rb +26 -0
  93. data/app/services/hyrax/article_genre_service.rb +9 -0
  94. data/app/services/newspaper_works/jp2_derivative_service.rb +120 -0
  95. data/app/services/newspaper_works/newspaper_page_derivative_service.rb +91 -0
  96. data/app/services/newspaper_works/pdf_derivative_service.rb +45 -0
  97. data/app/services/newspaper_works/pluggable_derivative_service.rb +114 -0
  98. data/app/services/newspaper_works/text_extraction_derivative_service.rb +56 -0
  99. data/app/services/newspaper_works/text_formats_from_alto_service.rb +77 -0
  100. data/app/services/newspaper_works/tiff_derivative_service.rb +54 -0
  101. data/app/validators/newspaper_works/publication_date_start_end_validator.rb +48 -0
  102. data/app/validators/newspaper_works/publication_date_validator.rb +16 -0
  103. data/app/views/catalog/_index_gallery_newspaper_article_wrapper.html.erb +9 -0
  104. data/app/views/catalog/_index_gallery_newspaper_page_wrapper.html.erb +9 -0
  105. data/app/views/catalog/_index_header_gallery_newspaper_article.html.erb +23 -0
  106. data/app/views/catalog/_index_header_gallery_newspaper_page.html.erb +23 -0
  107. data/app/views/catalog/_index_header_list_newspaper_article.html.erb +7 -0
  108. data/app/views/catalog/_index_header_list_newspaper_page.html.erb +7 -0
  109. data/app/views/catalog/_snippets_more.html.erb +16 -0
  110. data/app/views/catalog/_thumbnail_list_newspaper_article.html.erb +6 -0
  111. data/app/views/catalog/_thumbnail_list_newspaper_page.html.erb +6 -0
  112. data/app/views/hyrax/file_sets/_actions.html.erb +45 -0
  113. data/app/views/hyrax/newspaper_articles/_newspaper_article.html.erb +2 -0
  114. data/app/views/hyrax/newspaper_articles/show.html.erb +1 -0
  115. data/app/views/hyrax/newspaper_containers/_newspaper_container.html.erb +2 -0
  116. data/app/views/hyrax/newspaper_containers/show.html.erb +1 -0
  117. data/app/views/hyrax/newspaper_issues/_newspaper_issue.html.erb +2 -0
  118. data/app/views/hyrax/newspaper_issues/show.html.erb +1 -0
  119. data/app/views/hyrax/newspaper_pages/_newspaper_page.html.erb +2 -0
  120. data/app/views/hyrax/newspaper_pages/show.html.erb +1 -0
  121. data/app/views/hyrax/newspaper_titles/_all_front_pages_form.html.erb +5 -0
  122. data/app/views/hyrax/newspaper_titles/_issue_search_form.html.erb +33 -0
  123. data/app/views/hyrax/newspaper_titles/_issues_calendar.html.erb +63 -0
  124. data/app/views/hyrax/newspaper_titles/_newspaper_title.html.erb +2 -0
  125. data/app/views/hyrax/newspaper_titles/show.html.erb +54 -0
  126. data/app/views/newspaper_works/base/_attribute_rows.html.erb +42 -0
  127. data/app/views/newspaper_works/base/_attributes.html.erb +16 -0
  128. data/app/views/newspaper_works/base/_metadata.html.erb +6 -0
  129. data/app/views/newspaper_works/base/_newspaper_hierarchy.html.erb +14 -0
  130. data/app/views/newspaper_works/base/_persistent_url.html.erb +1 -0
  131. data/app/views/newspaper_works/base/_show.html.erb +45 -0
  132. data/app/views/newspaper_works/newspapers_search/_date_fields.html.erb +29 -0
  133. data/app/views/newspaper_works/newspapers_search/_facet_layout.html.erb +8 -0
  134. data/app/views/newspaper_works/newspapers_search/_facet_limit.html.erb +17 -0
  135. data/app/views/newspaper_works/newspapers_search/_front_pages_input.html.erb +5 -0
  136. data/app/views/newspaper_works/newspapers_search/_keyword_input.html.erb +18 -0
  137. data/app/views/newspaper_works/newspapers_search/_newspapers_facets.html.erb +5 -0
  138. data/app/views/newspaper_works/newspapers_search/_newspapers_search_form.html.erb +13 -0
  139. data/app/views/newspaper_works/newspapers_search/_newspapers_search_help.html.erb +8 -0
  140. data/app/views/newspaper_works/newspapers_search/search.html.erb +13 -0
  141. data/app/views/records/edit_fields/_alternate_title.html.erb +4 -0
  142. data/app/views/records/edit_fields/_genre.html.erb +4 -0
  143. data/app/views/records/edit_fields/_place_of_publication.html.erb +14 -0
  144. data/app/views/records/edit_fields/_subtitle.html.erb +4 -0
  145. data/bin/rails +13 -0
  146. data/config/fcrepo_wrapper_test.yml +5 -0
  147. data/config/initializers/assets.rb +2 -0
  148. data/config/locales/newspaper_article.de.yml +12 -0
  149. data/config/locales/newspaper_article.en.yml +12 -0
  150. data/config/locales/newspaper_article.es.yml +12 -0
  151. data/config/locales/newspaper_article.fr.yml +12 -0
  152. data/config/locales/newspaper_article.it.yml +12 -0
  153. data/config/locales/newspaper_article.pt-BR.yml +12 -0
  154. data/config/locales/newspaper_article.zh.yml +12 -0
  155. data/config/locales/newspaper_container.de.yml +8 -0
  156. data/config/locales/newspaper_container.en.yml +8 -0
  157. data/config/locales/newspaper_container.es.yml +8 -0
  158. data/config/locales/newspaper_container.fr.yml +8 -0
  159. data/config/locales/newspaper_container.it.yml +8 -0
  160. data/config/locales/newspaper_container.pt-BR.yml +8 -0
  161. data/config/locales/newspaper_container.zh.yml +8 -0
  162. data/config/locales/newspaper_issue.de.yml +8 -0
  163. data/config/locales/newspaper_issue.en.yml +8 -0
  164. data/config/locales/newspaper_issue.es.yml +8 -0
  165. data/config/locales/newspaper_issue.fr.yml +8 -0
  166. data/config/locales/newspaper_issue.it.yml +8 -0
  167. data/config/locales/newspaper_issue.pt-BR.yml +8 -0
  168. data/config/locales/newspaper_issue.zh.yml +8 -0
  169. data/config/locales/newspaper_page.de.yml +15 -0
  170. data/config/locales/newspaper_page.en.yml +15 -0
  171. data/config/locales/newspaper_page.es.yml +15 -0
  172. data/config/locales/newspaper_page.fr.yml +15 -0
  173. data/config/locales/newspaper_page.it.yml +15 -0
  174. data/config/locales/newspaper_page.pt-BR.yml +15 -0
  175. data/config/locales/newspaper_page.zh.yml +15 -0
  176. data/config/locales/newspaper_title.de.yml +8 -0
  177. data/config/locales/newspaper_title.en.yml +8 -0
  178. data/config/locales/newspaper_title.es.yml +8 -0
  179. data/config/locales/newspaper_title.fr.yml +8 -0
  180. data/config/locales/newspaper_title.it.yml +8 -0
  181. data/config/locales/newspaper_title.pt-BR.yml +8 -0
  182. data/config/locales/newspaper_title.zh.yml +8 -0
  183. data/config/locales/newspaper_works.de.yml +50 -0
  184. data/config/locales/newspaper_works.en.yml +52 -0
  185. data/config/locales/newspaper_works.es.yml +52 -0
  186. data/config/locales/newspaper_works.fr.yml +52 -0
  187. data/config/locales/newspaper_works.it.yml +52 -0
  188. data/config/locales/newspaper_works.pt-BR.yml +52 -0
  189. data/config/locales/newspaper_works.zh.yml +52 -0
  190. data/config/routes.rb +9 -0
  191. data/config/solr_wrapper_test.yml +9 -0
  192. data/config/test-fixture/solr-config/_rest_managed.json +3 -0
  193. data/config/test-fixture/solr-config/admin-extra.html +31 -0
  194. data/config/test-fixture/solr-config/elevate.xml +36 -0
  195. data/config/test-fixture/solr-config/mapping-ISOLatin1Accent.txt +246 -0
  196. data/config/test-fixture/solr-config/protwords.txt +21 -0
  197. data/config/test-fixture/solr-config/schema.xml +366 -0
  198. data/config/test-fixture/solr-config/scripts.conf +24 -0
  199. data/config/test-fixture/solr-config/solrconfig.xml +322 -0
  200. data/config/test-fixture/solr-config/spellings.txt +2 -0
  201. data/config/test-fixture/solr-config/stopwords.txt +58 -0
  202. data/config/test-fixture/solr-config/stopwords_en.txt +58 -0
  203. data/config/test-fixture/solr-config/synonyms.txt +31 -0
  204. data/config/test-fixture/solr-config/xslt/example.xsl +132 -0
  205. data/config/test-fixture/solr-config/xslt/example_atom.xsl +67 -0
  206. data/config/test-fixture/solr-config/xslt/example_rss.xsl +66 -0
  207. data/config/test-fixture/solr-config/xslt/luke.xsl +337 -0
  208. data/config/vendor/imagemagick-6-policy.xml +76 -0
  209. data/db/migrate/20181214181358_create_newspaper_works_derivative_attachments.rb +12 -0
  210. data/db/migrate/20190107165909_create_newspaper_works_ingest_file_relations.rb +11 -0
  211. data/lib/generators/newspaper_works/assets_generator.rb +29 -0
  212. data/lib/generators/newspaper_works/blacklight_advanced_search_generator.rb +44 -0
  213. data/lib/generators/newspaper_works/blacklight_iiif_search_generator.rb +41 -0
  214. data/lib/generators/newspaper_works/catalog_controller_generator.rb +60 -0
  215. data/lib/generators/newspaper_works/install_generator.rb +97 -0
  216. data/lib/generators/newspaper_works/templates/annotation_behavior.rb +6 -0
  217. data/lib/generators/newspaper_works/templates/config/authorities/newspaper_article_genres.yml +86 -0
  218. data/lib/generators/newspaper_works/templates/config/initializers/newspaper_works.rb +12 -0
  219. data/lib/generators/newspaper_works/templates/config/initializers/patch_blacklight_advanced_search.rb +74 -0
  220. data/lib/generators/newspaper_works/templates/custom_search_builder.rb +23 -0
  221. data/lib/generators/newspaper_works/templates/newspaper_works.scss +1 -0
  222. data/lib/generators/newspaper_works/templates/newspaper_works_helper.rb +3 -0
  223. data/lib/generators/newspaper_works/templates/search_behavior.rb +6 -0
  224. data/lib/newspaper_works/configuration.rb +14 -0
  225. data/lib/newspaper_works/data/fileset_helper.rb +25 -0
  226. data/lib/newspaper_works/data/path_helper.rb +40 -0
  227. data/lib/newspaper_works/data/work_derivatives.rb +314 -0
  228. data/lib/newspaper_works/data/work_file.rb +92 -0
  229. data/lib/newspaper_works/data/work_files.rb +181 -0
  230. data/lib/newspaper_works/data.rb +35 -0
  231. data/lib/newspaper_works/engine.rb +42 -0
  232. data/lib/newspaper_works/errors.rb +14 -0
  233. data/lib/newspaper_works/ingest/base_ingest.rb +69 -0
  234. data/lib/newspaper_works/ingest/base_publication_info.rb +35 -0
  235. data/lib/newspaper_works/ingest/batch_ingest_helper.rb +44 -0
  236. data/lib/newspaper_works/ingest/batch_issue_ingester.rb +129 -0
  237. data/lib/newspaper_works/ingest/chronam_publication_info.rb +133 -0
  238. data/lib/newspaper_works/ingest/from_command.rb +52 -0
  239. data/lib/newspaper_works/ingest/image_ingest_issues.rb +43 -0
  240. data/lib/newspaper_works/ingest/issue_images.rb +51 -0
  241. data/lib/newspaper_works/ingest/lc_publication_info.rb +144 -0
  242. data/lib/newspaper_works/ingest/named_issue_metadata.rb +60 -0
  243. data/lib/newspaper_works/ingest/ndnp/batch_ingester.rb +64 -0
  244. data/lib/newspaper_works/ingest/ndnp/batch_xml_ingest.rb +72 -0
  245. data/lib/newspaper_works/ingest/ndnp/container_ingest.rb +99 -0
  246. data/lib/newspaper_works/ingest/ndnp/container_ingester.rb +84 -0
  247. data/lib/newspaper_works/ingest/ndnp/container_metadata.rb +87 -0
  248. data/lib/newspaper_works/ingest/ndnp/issue_ingest.rb +81 -0
  249. data/lib/newspaper_works/ingest/ndnp/issue_ingester.rb +101 -0
  250. data/lib/newspaper_works/ingest/ndnp/issue_metadata.rb +96 -0
  251. data/lib/newspaper_works/ingest/ndnp/ndnp_asset_helper.rb +20 -0
  252. data/lib/newspaper_works/ingest/ndnp/ndnp_mets_helper.rb +70 -0
  253. data/lib/newspaper_works/ingest/ndnp/page_ingest.rb +47 -0
  254. data/lib/newspaper_works/ingest/ndnp/page_ingester.rb +157 -0
  255. data/lib/newspaper_works/ingest/ndnp/page_metadata.rb +112 -0
  256. data/lib/newspaper_works/ingest/ndnp.rb +21 -0
  257. data/lib/newspaper_works/ingest/newspaper_issue_ingest.rb +56 -0
  258. data/lib/newspaper_works/ingest/newspaper_page_ingest.rb +6 -0
  259. data/lib/newspaper_works/ingest/page_image.rb +52 -0
  260. data/lib/newspaper_works/ingest/path_enumeration.rb +52 -0
  261. data/lib/newspaper_works/ingest/pdf_images.rb +85 -0
  262. data/lib/newspaper_works/ingest/pdf_issue.rb +20 -0
  263. data/lib/newspaper_works/ingest/pdf_issues.rb +39 -0
  264. data/lib/newspaper_works/ingest/pdf_pages.rb +114 -0
  265. data/lib/newspaper_works/ingest/pub_finder.rb +89 -0
  266. data/lib/newspaper_works/ingest/publication_info.rb +44 -0
  267. data/lib/newspaper_works/ingest.rb +90 -0
  268. data/lib/newspaper_works/issue_pdf_composer.rb +111 -0
  269. data/lib/newspaper_works/logging.rb +54 -0
  270. data/lib/newspaper_works/page_finder.rb +62 -0
  271. data/lib/newspaper_works/resource_fetcher.rb +78 -0
  272. data/lib/newspaper_works/text_extraction/alto_reader.rb +122 -0
  273. data/lib/newspaper_works/text_extraction/page_ocr.rb +100 -0
  274. data/lib/newspaper_works/text_extraction/render_alto.rb +84 -0
  275. data/lib/newspaper_works/text_extraction/word_coords_builder.rb +30 -0
  276. data/lib/newspaper_works/text_extraction.rb +10 -0
  277. data/lib/newspaper_works/version.rb +3 -0
  278. data/lib/newspaper_works.rb +19 -0
  279. data/lib/tasks/newspaper_works_tasks.rake +39 -0
  280. data/newspaper_works.gemspec +49 -0
  281. data/spec/.keep.txt +1 -0
  282. data/spec/actors/newspaper_works/actors/newspaper_works_upload_actor_spec.rb +69 -0
  283. data/spec/controllers/catalog_controller_spec.rb +63 -0
  284. data/spec/controllers/newspaper_works/newspapers_controller_spec.rb +114 -0
  285. data/spec/controllers/newspaper_works/newspapers_search_controller_spec.rb +21 -0
  286. data/spec/factories/ability.rb +6 -0
  287. data/spec/factories/newspaper_issue.rb +7 -0
  288. data/spec/factories/newspaper_issue_ingest.rb +6 -0
  289. data/spec/factories/newspaper_page.rb +7 -0
  290. data/spec/factories/newspaper_page_ingest.rb +6 -0
  291. data/spec/factories/newspaper_page_solr_document.rb +12 -0
  292. data/spec/factories/newspaper_title.rb +8 -0
  293. data/spec/factories/uploaded_pdf_file.rb +9 -0
  294. data/spec/factories/user.rb +13 -0
  295. data/spec/features/front_pages_for_title_spec.rb +19 -0
  296. data/spec/features/newspaper_title_search_spec.rb +30 -0
  297. data/spec/features/newspapers_search_spec.rb +49 -0
  298. data/spec/features/search_results_thumbnail_highlights_spec.rb +33 -0
  299. data/spec/features_shared.rb +71 -0
  300. data/spec/fixtures/files/4.1.07.jp2 +0 -0
  301. data/spec/fixtures/files/4.1.07.tiff +0 -0
  302. data/spec/fixtures/files/README.md +7 -0
  303. data/spec/fixtures/files/alto-2-0.xsd +714 -0
  304. data/spec/fixtures/files/broken-truncated.pdf +0 -0
  305. data/spec/fixtures/files/credits.md +16 -0
  306. data/spec/fixtures/files/lowres-gray-via-ndnp-sample.tiff +0 -0
  307. data/spec/fixtures/files/minimal-1-page.pdf +0 -0
  308. data/spec/fixtures/files/minimal-2-page.pdf +0 -0
  309. data/spec/fixtures/files/minimal-alto.xml +31 -0
  310. data/spec/fixtures/files/ndnp-alto-sample.xml +24 -0
  311. data/spec/fixtures/files/ndnp-sample1-json.json +1 -0
  312. data/spec/fixtures/files/ndnp-sample1-txt.txt +1 -0
  313. data/spec/fixtures/files/ndnp-sample1.pdf +0 -0
  314. data/spec/fixtures/files/ocr_alto.xml +202 -0
  315. data/spec/fixtures/files/ocr_alto_scaled_4pts_per_px.xml +202 -0
  316. data/spec/fixtures/files/ocr_color.tiff +0 -0
  317. data/spec/fixtures/files/ocr_gray.jp2 +0 -0
  318. data/spec/fixtures/files/ocr_gray.tiff +0 -0
  319. data/spec/fixtures/files/ocr_mono.tiff +0 -0
  320. data/spec/fixtures/files/page1.tiff +0 -0
  321. data/spec/fixtures/files/resource_mocks/chronam/http404-expected +0 -0
  322. data/spec/fixtures/files/resource_mocks/chronam/sn84038814.rdf +1028 -0
  323. data/spec/fixtures/files/resource_mocks/chronam/sn93059126.rdf +36 -0
  324. data/spec/fixtures/files/resource_mocks/chronam/sn94051019.rdf +37 -0
  325. data/spec/fixtures/files/resource_mocks/geonames/Chicopee +1104 -0
  326. data/spec/fixtures/files/resource_mocks/geonames/Denver +1104 -0
  327. data/spec/fixtures/files/resource_mocks/geonames/Marysville +279 -0
  328. data/spec/fixtures/files/resource_mocks/geonames/Marysville2 +279 -0
  329. data/spec/fixtures/files/resource_mocks/geonames/SLC +1104 -0
  330. data/spec/fixtures/files/resource_mocks/lccn/sn2099999999 +1 -0
  331. data/spec/fixtures/files/resource_mocks/lccn/sn82014496 +2 -0
  332. data/spec/fixtures/files/resource_mocks/lccn/sn83020109 +1 -0
  333. data/spec/fixtures/files/resource_mocks/lccn/sn83021453 +2 -0
  334. data/spec/fixtures/files/resource_mocks/lccn/sn83045396 +2 -0
  335. data/spec/fixtures/files/resource_mocks/lccn/sn84038814 +2 -0
  336. data/spec/fixtures/files/resource_mocks/lccn/sn93059126 +1 -0
  337. data/spec/fixtures/files/resource_mocks/lccn/sn94051019 +1 -0
  338. data/spec/fixtures/files/resource_mocks/lccn/sn99999999 +1 -0
  339. data/spec/fixtures/files/resource_mocks/urls.json +82 -0
  340. data/spec/fixtures/files/sample-4page-issue.pdf +0 -0
  341. data/spec/fixtures/files/sample-color-newsletter.pdf +0 -0
  342. data/spec/fixtures/files/thumbnail.jpg +0 -0
  343. data/spec/forms/hyrax/newspaper_article_form_spec.rb +33 -0
  344. data/spec/forms/hyrax/newspaper_container_form_spec.rb +30 -0
  345. data/spec/forms/hyrax/newspaper_issue_form_spec.rb +31 -0
  346. data/spec/forms/hyrax/newspaper_page_form_spec.rb +28 -0
  347. data/spec/forms/hyrax/newspaper_title_form_spec.rb +31 -0
  348. data/spec/forms/newspaper_works/newspaper_core_form_data_spec.rb +12 -0
  349. data/spec/helpers/newspaper_works/breadcrumb_helper_spec.rb +82 -0
  350. data/spec/helpers/newspaper_works_helper_spec.rb +57 -0
  351. data/spec/indexers/concerns/newspaper_works/indexes_full_text_spec.rb +31 -0
  352. data/spec/indexers/concerns/newspaper_works/indexes_place_of_publication_spec.rb +53 -0
  353. data/spec/indexers/concerns/newspaper_works/indexes_publication_date_range_spec.rb +39 -0
  354. data/spec/indexers/concerns/newspaper_works/indexes_relationships_spec.rb +86 -0
  355. data/spec/indexers/newspaper_article_indexer_spec.rb +29 -0
  356. data/spec/indexers/newspaper_issue_indexer_spec.rb +19 -0
  357. data/spec/indexers/newspaper_title_indexer_spec.rb +22 -0
  358. data/spec/indexers/newspaper_works/newspaper_core_indexer_spec.rb +23 -0
  359. data/spec/lib/newspaper_works/configuration_spec.rb +18 -0
  360. data/spec/lib/newspaper_works/data/work_derivatives_spec.rb +245 -0
  361. data/spec/lib/newspaper_works/data/work_file_spec.rb +99 -0
  362. data/spec/lib/newspaper_works/data/work_files_spec.rb +224 -0
  363. data/spec/lib/newspaper_works/ingest/batch_issue_ingester_spec.rb +158 -0
  364. data/spec/lib/newspaper_works/ingest/chronam_publication_info_spec.rb +35 -0
  365. data/spec/lib/newspaper_works/ingest/from_command_spec.rb +75 -0
  366. data/spec/lib/newspaper_works/ingest/image_ingest_issues_spec.rb +62 -0
  367. data/spec/lib/newspaper_works/ingest/ingest_shared.rb +75 -0
  368. data/spec/lib/newspaper_works/ingest/issue_images_spec.rb +65 -0
  369. data/spec/lib/newspaper_works/ingest/lc_publication_info_spec.rb +34 -0
  370. data/spec/lib/newspaper_works/ingest/ndnp/batch_ingester_spec.rb +131 -0
  371. data/spec/lib/newspaper_works/ingest/ndnp/batch_xml_ingest_spec.rb +64 -0
  372. data/spec/lib/newspaper_works/ingest/ndnp/container_ingest_spec.rb +44 -0
  373. data/spec/lib/newspaper_works/ingest/ndnp/container_ingester_spec.rb +126 -0
  374. data/spec/lib/newspaper_works/ingest/ndnp/container_metadata_spec.rb +36 -0
  375. data/spec/lib/newspaper_works/ingest/ndnp/issue_ingest_spec.rb +108 -0
  376. data/spec/lib/newspaper_works/ingest/ndnp/issue_ingester_spec.rb +155 -0
  377. data/spec/lib/newspaper_works/ingest/ndnp/issue_metadata_spec.rb +84 -0
  378. data/spec/lib/newspaper_works/ingest/ndnp/page_ingest_spec.rb +79 -0
  379. data/spec/lib/newspaper_works/ingest/ndnp/page_ingester_spec.rb +184 -0
  380. data/spec/lib/newspaper_works/ingest/ndnp/page_metadata_spec.rb +85 -0
  381. data/spec/lib/newspaper_works/ingest/newspaper_issue_ingest_spec.rb +83 -0
  382. data/spec/lib/newspaper_works/ingest/newspaper_page_ingest_spec.rb +77 -0
  383. data/spec/lib/newspaper_works/ingest/page_image_spec.rb +29 -0
  384. data/spec/lib/newspaper_works/ingest/pdf_images_spec.rb +32 -0
  385. data/spec/lib/newspaper_works/ingest/pdf_issue_spec.rb +29 -0
  386. data/spec/lib/newspaper_works/ingest/pdf_issues_spec.rb +62 -0
  387. data/spec/lib/newspaper_works/ingest/pdf_pages_spec.rb +110 -0
  388. data/spec/lib/newspaper_works/ingest/pub_finder_spec.rb +58 -0
  389. data/spec/lib/newspaper_works/ingest/publication_info_spec.rb +61 -0
  390. data/spec/lib/newspaper_works/ingest_spec.rb +45 -0
  391. data/spec/lib/newspaper_works/issue_pdf_composer_spec.rb +101 -0
  392. data/spec/lib/newspaper_works/logging_spec.rb +53 -0
  393. data/spec/lib/newspaper_works/page_finder_spec.rb +53 -0
  394. data/spec/lib/newspaper_works/resource_fetcher_spec.rb +65 -0
  395. data/spec/lib/newspaper_works/text_extraction/alto_reader_spec.rb +49 -0
  396. data/spec/lib/newspaper_works/text_extraction/page_ocr_spec.rb +84 -0
  397. data/spec/lib/newspaper_works/text_extraction/render_alto_spec.rb +54 -0
  398. data/spec/lib/newspaper_works/text_extraction/word_coords_builder_spec.rb +30 -0
  399. data/spec/lib/tasks/newspaper_works_rake_spec.rb +124 -0
  400. data/spec/misc_shared.rb +109 -0
  401. data/spec/model_shared.rb +134 -0
  402. data/spec/models/concerns/newspaper_works/blacklight_iiif_search/annotation_behavior_spec.rb +45 -0
  403. data/spec/models/concerns/newspaper_works/blacklight_iiif_search/search_behavior_spec.rb +27 -0
  404. data/spec/models/concerns/newspaper_works/newspaper_core_metadata_spec.rb +45 -0
  405. data/spec/models/concerns/newspaper_works/place_of_publication_behavior_spec.rb +17 -0
  406. data/spec/models/concerns/newspaper_works/scanned_media_metadata_spec.rb +35 -0
  407. data/spec/models/newspaper_article_spec.rb +73 -0
  408. data/spec/models/newspaper_container_spec.rb +111 -0
  409. data/spec/models/newspaper_issue_spec.rb +91 -0
  410. data/spec/models/newspaper_page_spec.rb +44 -0
  411. data/spec/models/newspaper_title_spec.rb +116 -0
  412. data/spec/models/newspaper_works/derivative_attachment_spec.rb +37 -0
  413. data/spec/models/newspaper_works/ingest_file_relation_spec.rb +56 -0
  414. data/spec/models/solr_document_spec.rb +14 -0
  415. data/spec/ndnp_shared.rb +48 -0
  416. data/spec/presenters/hyrax/newspaper_article_presenter_spec.rb +53 -0
  417. data/spec/presenters/hyrax/newspaper_container_presenter_spec.rb +20 -0
  418. data/spec/presenters/hyrax/newspaper_issue_presenter_spec.rb +65 -0
  419. data/spec/presenters/hyrax/newspaper_page_presenter_spec.rb +75 -0
  420. data/spec/presenters/hyrax/newspaper_title_presenter_spec.rb +153 -0
  421. data/spec/presenters/newspaper_works/iiif_manifest_presenter_behavior_spec.rb +32 -0
  422. data/spec/presenters/newspaper_works/issue_info_presenter_spec.rb +51 -0
  423. data/spec/presenters/newspaper_works/newspaper_core_presenter_spec.rb +22 -0
  424. data/spec/presenters/newspaper_works/persistent_url_presenter_behavior_spec.rb +24 -0
  425. data/spec/presenters/newspaper_works/place_of_publication_presenter_behavior_spec.rb +17 -0
  426. data/spec/presenters/newspaper_works/scanned_media_presenter_spec.rb +18 -0
  427. data/spec/presenters/newspaper_works/title_info_presenter_spec.rb +23 -0
  428. data/spec/routing/route_spec.rb +52 -0
  429. data/spec/search_builders/custom_search_builder_spec.rb +34 -0
  430. data/spec/search_builders/newspaper_works/newspapers_search_builder_spec.rb +33 -0
  431. data/spec/services/hyrax/article_genre_service_spec.rb +12 -0
  432. data/spec/services/hyrax/resource_types_service_spec.rb +12 -0
  433. data/spec/services/newspaper_works/jp2_derivative_service_spec.rb +62 -0
  434. data/spec/services/newspaper_works/newspaper_page_derivative_service_spec.rb +125 -0
  435. data/spec/services/newspaper_works/pdf_derivative_service_spec.rb +62 -0
  436. data/spec/services/newspaper_works/pluggable_derivative_service_spec.rb +204 -0
  437. data/spec/services/newspaper_works/text_extraction_derivative_service_spec.rb +82 -0
  438. data/spec/services/newspaper_works/text_formats_from_alto_service_spec.rb +129 -0
  439. data/spec/services/newspaper_works/tiff_derivative_service_spec.rb +58 -0
  440. data/spec/spec_helper.rb +261 -0
  441. data/spec/support/controller_level_helpers.rb +28 -0
  442. data/spec/test_app_templates/lib/generators/test_app_generator.rb +22 -0
  443. data/spec/views/catalog/_index_gallery_newspaper_page_wrapper.html.erb_spec.rb +36 -0
  444. data/spec/views/catalog/_index_header_list_newspaper_page.html.erb_spec.rb +26 -0
  445. data/spec/views/catalog/_thumbnail_list_newspaper_page.html.erb_spec.rb +35 -0
  446. data/spec/views/hyrax/newspaper_titles/_all_front_pages_form.html.erb_spec.rb +16 -0
  447. data/spec/views/hyrax/newspaper_titles/_issue_search_form.html.erb_spec.rb +33 -0
  448. data/spec/views/hyrax/newspaper_titles/_issues_calendar.html.erb_spec.rb +37 -0
  449. data/spec/views/hyrax/newspaper_titles/show.html.erb_spec.rb +87 -0
  450. data/spec/views/newspaper_works/base/_attribute_rows.html.erb_spec.rb +60 -0
  451. data/spec/views/newspaper_works/base/_newspaper_hierarchy.html.erb_spec.rb +80 -0
  452. data/spec/views/newspaper_works/base/_show.html.erb_spec.rb +78 -0
  453. data/spec/views/newspaper_works/newspapers_search/search.html.erb_spec.rb +54 -0
  454. data/spec/views/records/edit_fields/_place_of_publication.html.erb_spec.rb +26 -0
  455. data/tasks/newspaperworks_dev.rake +26 -0
  456. data/test/integration/navigation_test.rb +7 -0
  457. data/test/lib/generators/newspaper_works/install_generator_test.rb +16 -0
  458. data/test/newspaper_works_test.rb +7 -0
  459. data/test/test_helper.rb +17 -0
  460. data/tmp/.keep +0 -0
  461. metadata +1037 -0
@@ -0,0 +1,70 @@
1
+ # Newspaper Page
2
+ class NewspaperPage < ActiveFedora::Base
3
+ # WorkBehavior mixes in minimal ::Hyrax::CoreMetadata fields of
4
+ # depositor, title, date_uploaded, and date_modified.
5
+ # https://samvera.github.io/customize-metadata-model.html#core-metadata
6
+ include ::Hyrax::WorkBehavior
7
+ include NewspaperWorks::ScannedMediaMetadata
8
+
9
+ self.indexer = NewspaperPageIndexer
10
+
11
+ # containment/aggregation:
12
+ # self.valid_child_concerns = []
13
+
14
+ # Validation and required fields:
15
+ validates :title, presence: { message: 'A newspaper page requires a label.' }
16
+ # TODO: Implement validations
17
+ # validates :height, presence: { message: 'A newspaper page requires a height.' }
18
+ # validates :width, presence: { message: 'A newspaper page requires a width.' }
19
+
20
+ # == Type-specific properties ==
21
+
22
+ # - Height
23
+ property(
24
+ :height,
25
+ predicate: ::RDF::URI.new('http://dbpedia.org/ontology/height'),
26
+ multiple: false
27
+ ) do |index|
28
+ index.as :stored_searchable
29
+ end
30
+
31
+ # - Width
32
+ property(
33
+ :width,
34
+ predicate: ::RDF::URI.new('http://dbpedia.org/ontology/width'),
35
+ multiple: false
36
+ ) do |index|
37
+ index.as :stored_searchable
38
+ end
39
+
40
+ # TODO: Add Reel number: https://github.com/samvera-labs/uri_selection_wg/issues/2
41
+
42
+ # BasicMetadata must be included last
43
+ include ::Hyrax::BasicMetadata
44
+
45
+ # relationship methods
46
+
47
+ # get publication (transitive)
48
+ def publication
49
+ # try transitive relation via issue first:
50
+ issue = self.issue
51
+ return issue.publication unless issue.nil?
52
+ # fallback to trying to see if there is an issue-less container with title:
53
+ container = self.container
54
+ return container.publication unless container.nil?
55
+ end
56
+
57
+ def articles
58
+ member_of.select { |v| v.instance_of?(NewspaperArticle) }
59
+ end
60
+
61
+ def issue
62
+ result = member_of.select { |v| v.instance_of?(NewspaperIssue) }
63
+ result[0] unless result.empty?
64
+ end
65
+
66
+ def container
67
+ result = member_of.select { |v| v.instance_of?(NewspaperContainer) }
68
+ result[0] unless result.empty?
69
+ end
70
+ end
@@ -0,0 +1,111 @@
1
+ # NewspaperTitle: object for a publication/title
2
+ class NewspaperTitle < ActiveFedora::Base
3
+ # WorkBehavior mixes in minimal ::Hyrax::CoreMetadata fields of
4
+ # depositor, title, date_uploaded, and date_modified.
5
+ # https://samvera.github.io/customize-metadata-model.html#core-metadata
6
+ include ::Hyrax::WorkBehavior
7
+ include NewspaperWorks::NewspaperCoreMetadata
8
+
9
+ self.indexer = NewspaperTitleIndexer
10
+
11
+ # containment/aggregation:
12
+ self.valid_child_concerns = [NewspaperContainer, NewspaperIssue]
13
+
14
+ # Validation and required fields:
15
+ validates :title, presence: {
16
+ message: 'A newspaper title requires a title (publication name).'
17
+ }
18
+
19
+ validates_with NewspaperWorks::PublicationDateStartEndValidator
20
+
21
+ # TODO: Implement validations
22
+ # validates :resource_type, presence: {
23
+ # message: 'A newspaper article requires a resource type.'
24
+ # }
25
+ # validates :language, presence: {
26
+ # message: 'A newspaper article requires a language.'
27
+ # }
28
+ # validates :held_by, presence: {
29
+ # message: 'A newspaper article requires a holding location.'
30
+ # }
31
+
32
+ # validations below causing save failures
33
+ # TODO: get them working || enforce validation elsewhere || remove
34
+
35
+ # validates :type, presence: {
36
+ # message: 'A newspaper title requires a type.'
37
+ # }
38
+
39
+ # == Type-specific properties ==
40
+
41
+ # - Edition name
42
+ property(
43
+ :edition_name,
44
+ predicate: ::RDF::Vocab::BF2.editionStatement,
45
+ multiple: false
46
+ ) do |index|
47
+ index.as :stored_searchable
48
+ end
49
+
50
+ # - Frequency
51
+ property(
52
+ :frequency,
53
+ predicate: ::RDF::URI.new('http://www.rdaregistry.info/Elements/u/P60538'),
54
+ multiple: true
55
+ ) do |index|
56
+ index.as :stored_searchable
57
+ end
58
+
59
+ # - Preceded by
60
+ property(
61
+ :preceded_by,
62
+ predicate: ::RDF::URI.new('http://rdaregistry.info/Elements/u/P60261'),
63
+ multiple: true
64
+ ) do |index|
65
+ index.as :stored_searchable, :facetable
66
+ end
67
+
68
+ # - Succeeded by
69
+ property(
70
+ :succeeded_by,
71
+ predicate: ::RDF::URI.new('http://rdaregistry.info/Elements/u/P60278'),
72
+ multiple: true
73
+ ) do |index|
74
+ index.as :stored_searchable, :facetable
75
+ end
76
+
77
+ # - Publication date start
78
+ property(
79
+ :publication_date_start,
80
+ predicate: ::RDF::Vocab::SCHEMA.startDate,
81
+ multiple: false
82
+ ) do |index|
83
+ index.type :date
84
+ index.as :stored_sortable
85
+ end
86
+
87
+ # - Publication date end
88
+ property(
89
+ :publication_date_end,
90
+ predicate: ::RDF::Vocab::SCHEMA.endDate,
91
+ multiple: false
92
+ ) do |index|
93
+ index.type :date
94
+ index.as :stored_sortable
95
+ end
96
+
97
+ # BasicMetadata must be included last
98
+ include ::Hyrax::BasicMetadata
99
+
100
+ # for GeoNames autocomplete lookup
101
+ include NewspaperWorks::PlaceOfPublicationBehavior
102
+
103
+ # relationship methods:
104
+ def issues
105
+ members.select { |v| v.instance_of?(NewspaperIssue) }
106
+ end
107
+
108
+ def containers
109
+ members.select { |v| v.instance_of?(NewspaperContainer) }
110
+ end
111
+ end
@@ -0,0 +1,6 @@
1
+ module NewspaperWorks
2
+ # Application Record Class
3
+ class ApplicationRecord < ActiveRecord::Base
4
+ self.abstract_class = true
5
+ end
6
+ end
@@ -0,0 +1,8 @@
1
+ module NewspaperWorks
2
+ class DerivativeAttachment < ApplicationRecord
3
+ # We can store nil/optional fileset as interim value before fileset
4
+ # construction, but we require at minimum, path, destination_name
5
+ validates :path, presence: true
6
+ validates :destination_name, presence: true
7
+ end
8
+ end
@@ -0,0 +1,14 @@
1
+ module NewspaperWorks
2
+ class IngestFileRelation < ApplicationRecord
3
+ validates :file_path, presence: true
4
+ validates :derivative_path, presence: true
5
+
6
+ # Query by file path for all derivatives, as de-duplicated array of
7
+ # derivative paths.
8
+ # @param path [String] Path to primary file
9
+ # @return [Array<String>] de-duplicated array of derivative paths.
10
+ def self.derivatives_for_file(path)
11
+ where(file_path: path).pluck(:derivative_path).uniq
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,38 @@
1
+ # Generated via
2
+ # `rails generate hyrax:work NewspaperArticle`
3
+ module Hyrax
4
+ class NewspaperArticlePresenter < Hyrax::WorkShowPresenter
5
+ include NewspaperWorks::NewspaperCorePresenter
6
+ include NewspaperWorks::ScannedMediaPresenter
7
+ include NewspaperWorks::TitleInfoPresenter
8
+ include NewspaperWorks::IssueInfoPresenter
9
+ include NewspaperWorks::IiifManifestPresenterBehavior
10
+
11
+ delegate :author, :photographer, :volume, :edition_number,
12
+ :edition_name, :issue_number, :geographic_coverage, :extent,
13
+ :genre, to: :solr_document
14
+
15
+ def publication_date
16
+ solr_document["publication_date_dtsi"]
17
+ end
18
+
19
+ def page_ids
20
+ solr_document['page_ids_ssim']
21
+ end
22
+
23
+ def page_titles
24
+ solr_document['page_titles_ssim']
25
+ end
26
+
27
+ private
28
+
29
+ def iiif_metadata_fields
30
+ [:title, :alternative_title, :place_of_publication, :issn, :lccn,
31
+ :oclcnum, :held_by, :text_direction, :page_number, :section, :genre,
32
+ :author, :photographer, :volume, :edition, :issue_number,
33
+ :geographic_coverage, :extent, :publication_date, :resource_type,
34
+ :creator, :contributor, :description, :license, :rights_statement,
35
+ :publisher, :subject, :language, :identifier]
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,11 @@
1
+ # Generated via
2
+ # `rails generate hyrax:work NewspaperContainer`
3
+ module Hyrax
4
+ class NewspaperContainerPresenter < Hyrax::WorkShowPresenter
5
+ include NewspaperWorks::NewspaperCorePresenter
6
+ include NewspaperWorks::TitleInfoPresenter
7
+
8
+ delegate :extent, :publication_date_start, :publication_date_end,
9
+ to: :solr_document
10
+ end
11
+ end
@@ -0,0 +1,62 @@
1
+ # Generated via
2
+ # `rails generate hyrax:work NewspaperIssue`
3
+ module Hyrax
4
+ class NewspaperIssuePresenter < Hyrax::WorkShowPresenter
5
+ include NewspaperWorks::NewspaperCorePresenter
6
+ include NewspaperWorks::TitleInfoPresenter
7
+ include NewspaperWorks::IiifManifestPresenterBehavior
8
+
9
+ delegate :volume, :edition_number, :edition_name,
10
+ :issue_number, :extent, to: :solr_document
11
+
12
+ # @return [Boolean] render the UniversalViewer
13
+ def iiif_viewer?
14
+ Hyrax.config.iiif_image_server? && members_include_viewable_page?
15
+ end
16
+
17
+ def publication_date
18
+ solr_document["publication_date_dtsi"]
19
+ end
20
+
21
+ def persistent_url
22
+ return nil unless publication_unique_id && issue_date_for_url
23
+ NewspaperWorks::Engine.routes.url_helpers.newspaper_issue_edition_url(unique_id: publication_unique_id,
24
+ date: issue_date_for_url,
25
+ edition: edition_for_url,
26
+ host: request.host)
27
+ end
28
+
29
+ private
30
+
31
+ # modeled on Hyrax::WorkShowPresenter#members_include_viewable_image?
32
+ # @return [Boolean] whether the member works will show in the IIIF viewer
33
+ def members_include_viewable_page?
34
+ work_presenters.any? do |presenter|
35
+ presenter.model_name == 'NewspaperPage' &&
36
+ presenter.iiif_viewer? &&
37
+ current_ability.can?(:read, presenter.id)
38
+ end
39
+ end
40
+
41
+ def publication_unique_id
42
+ solr_document['publication_unique_id_ssi'] || nil
43
+ end
44
+
45
+ def issue_date_for_url
46
+ return nil unless publication_date
47
+ publication_date.match(/\A[\d]{4}-[\d]{2}-[\d]{2}/).to_s
48
+ end
49
+
50
+ def edition_for_url
51
+ "ed-#{edition_number ? edition_number.first : '1'}"
52
+ end
53
+
54
+ def iiif_metadata_fields
55
+ [:title, :alternative_title, :place_of_publication_label, :issn, :lccn,
56
+ :oclcnum, :held_by, :volume, :edition_name, :edition_number,
57
+ :issue_number, :extent, :publication_date, :resource_type, :creator,
58
+ :contributor, :description, :license, :rights_statement, :publisher,
59
+ :language, :identifier]
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,72 @@
1
+ # Generated via
2
+ # `rails generate hyrax:work NewspaperPage`
3
+ module Hyrax
4
+ class NewspaperPagePresenter < Hyrax::WorkShowPresenter
5
+ include NewspaperWorks::ScannedMediaPresenter
6
+ include NewspaperWorks::TitleInfoPresenter
7
+ include NewspaperWorks::IssueInfoPresenter
8
+ include NewspaperWorks::IiifManifestPresenterBehavior
9
+ include NewspaperWorks::PersistentUrlPresenterBehavior
10
+ include NewspaperWorks::PageFinder
11
+ include NewspaperWorks::PlaceOfPublicationPresenterBehavior
12
+
13
+ delegate :height, :width, to: :solr_document
14
+
15
+ def persistent_url
16
+ return nil unless publication_unique_id && issue_date_for_url
17
+ NewspaperWorks::Engine.routes.url_helpers.newspaper_page_url(unique_id: publication_unique_id,
18
+ date: issue_date_for_url,
19
+ edition: edition_for_url,
20
+ page: page_index_for_url,
21
+ host: request.host)
22
+ end
23
+
24
+ def previous_page_id
25
+ solr_document['is_following_page_of_ssi']
26
+ end
27
+
28
+ def next_page_id
29
+ solr_document['is_preceding_page_of_ssi']
30
+ end
31
+
32
+ def container_id
33
+ solr_document['container_id_ssi']
34
+ end
35
+
36
+ def container_title
37
+ solr_document['container_title_ssi']
38
+ end
39
+
40
+ def article_ids
41
+ solr_document['article_ids_ssim']
42
+ end
43
+
44
+ def article_titles
45
+ solr_document['article_titles_ssim']
46
+ end
47
+
48
+ private
49
+
50
+ def publication_unique_id
51
+ solr_document['publication_unique_id_ssi'] || nil
52
+ end
53
+
54
+ def issue_date_for_url
55
+ return nil unless publication_date
56
+ publication_date.match(/\A[\d]{4}-[\d]{2}-[\d]{2}/).to_s
57
+ end
58
+
59
+ def edition_for_url
60
+ "ed-#{solr_document['issue_edition_number_ssi'] || '1'}"
61
+ end
62
+
63
+ def page_index_for_url
64
+ "seq-#{(get_page_index(id, solr_document['issue_id_ssi']) + 1)}"
65
+ end
66
+
67
+ def iiif_metadata_fields
68
+ [:title, :text_direction, :page_number, :section, :resource_type,
69
+ :license, :rights_statement, :identifier, :publication_date]
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,86 @@
1
+ # Generated via
2
+ # `rails generate hyrax:work NewspaperTitle`
3
+ module Hyrax
4
+ class NewspaperTitlePresenter < Hyrax::WorkShowPresenter
5
+ include NewspaperWorks::NewspaperCorePresenter
6
+ delegate :edition_name, :frequency, :preceded_by,
7
+ :succeeded_by, to: :solr_document
8
+
9
+ def title_search_params
10
+ { f: { "publication_title_ssi" => title } }
11
+ end
12
+
13
+ def front_page_search_params
14
+ { f: { "publication_title_ssi" => title, "first_page_bsi" => [true] }, sort: 'publication_date_dtsi asc' }
15
+ end
16
+
17
+ def issues
18
+ all_title_issues.select { |issue| year_or_nil(issue["publication_date_dtsi"]) == year }
19
+ end
20
+
21
+ def issue_years
22
+ all_title_issue_dates.map { |issue_date| year_or_nil(issue_date) }.compact.uniq.sort
23
+ end
24
+
25
+ def prev_year
26
+ return nil if issue_years.empty?
27
+ index = issue_years.index(year) - 1
28
+ return nil if index.negative?
29
+ issue_years[index]
30
+ end
31
+
32
+ def next_year
33
+ return nil if issue_years.empty?
34
+ issue_years[issue_years.index(year) + 1]
35
+ end
36
+
37
+ def publication_date_start
38
+ solr_document["publication_date_start_dtsi"]
39
+ end
40
+
41
+ def publication_date_end
42
+ solr_document["publication_date_end_dtsi"]
43
+ end
44
+
45
+ def year
46
+ return nil if issue_years.empty?
47
+ number_or_nil(request.params[:year]) || issue_years.first
48
+ end
49
+
50
+ def all_title_issues
51
+ issue_query = Blacklight.default_index.search(q: "has_model_ssim:NewspaperIssue AND publication_id_ssi:#{id} AND visibility_ssi:#{solr_document.visibility}",
52
+ rows: 50_000,
53
+ fl: "id, publication_date_dtsi")
54
+ issue_query.documents
55
+ end
56
+
57
+ def publication_unique_id
58
+ solr_document[NewspaperWorks.config.publication_unique_id_field]
59
+ end
60
+
61
+ def persistent_url
62
+ return nil unless publication_unique_id
63
+ NewspaperWorks::Engine.routes.url_helpers.newspaper_title_url(unique_id: publication_unique_id.first,
64
+ host: request.host)
65
+ end
66
+
67
+ private
68
+
69
+ def all_title_issue_dates
70
+ all_title_issues.pluck("publication_date_dtsi")
71
+ end
72
+
73
+ def number_or_nil(string)
74
+ Integer(string || '')
75
+ rescue ArgumentError
76
+ nil
77
+ end
78
+
79
+ def year_or_nil(date_value)
80
+ return nil unless date_value.is_a?(String)
81
+ Date.parse(date_value).year
82
+ rescue TypeError
83
+ nil
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,29 @@
1
+ # mixin to provide URL for IIIF Content Search service
2
+ module NewspaperWorks
3
+ module IiifManifestPresenterBehavior
4
+ extend ActiveSupport::Concern
5
+
6
+ def search_service
7
+ Rails.application.routes.url_helpers.solr_document_iiif_search_url(id,
8
+ host: request.base_url)
9
+ end
10
+
11
+ # based on Hyrax::WorkShowPresenter#manifest_metadata
12
+ # expects that individual presenters define #iiif_metadata_fields
13
+ def manifest_metadata
14
+ fields = iiif_metadata_fields || []
15
+ metadata = []
16
+ fields.each do |field|
17
+ label = Hyrax::Renderers::AttributeRenderer.new(field, nil).label
18
+ value = send(field)
19
+ next if value.blank?
20
+ value = Array.wrap(value) if value.is_a?(String)
21
+ metadata << {
22
+ 'label' => label,
23
+ 'value' => Array.wrap(value.map { |f| Loofah.fragment(f.to_s).scrub!(:whitewash).to_s })
24
+ }
25
+ end
26
+ metadata
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,29 @@
1
+ # NewspaperIssue ancestor data
2
+ module NewspaperWorks
3
+ # shared NewspaperIssue info for multiple newspaper models
4
+ module IssueInfoPresenter
5
+ def issue_id
6
+ solr_document['issue_id_ssi']
7
+ end
8
+
9
+ def issue_title
10
+ solr_document['issue_title_ssi']
11
+ end
12
+
13
+ def publication_date
14
+ solr_document['publication_date_dtsi']
15
+ end
16
+
17
+ def issue_volume
18
+ solr_document['issue_volume_ssi']
19
+ end
20
+
21
+ def issue_edition
22
+ solr_document['issue_edition_number_ssi']
23
+ end
24
+
25
+ def issue_number
26
+ solr_document['issue_number_ssi']
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,9 @@
1
+ # module comment...
2
+ module NewspaperWorks
3
+ # core presenter for newspaper models
4
+ module NewspaperCorePresenter
5
+ include NewspaperWorks::PersistentUrlPresenterBehavior
6
+ include NewspaperWorks::PlaceOfPublicationPresenterBehavior
7
+ delegate :alternative_title, :issn, :lccn, :oclcnum, :held_by, to: :solr_document
8
+ end
9
+ end
@@ -0,0 +1,16 @@
1
+ # mixin to provide persistent URL methods
2
+ module NewspaperWorks
3
+ module PersistentUrlPresenterBehavior
4
+ # Default for NewspaperContainer and NewspaperArticle,
5
+ # since we don't support ChronAm-style URLs for those object types.
6
+ # Override in individual presenters as needed.
7
+ def persistent_url
8
+ nil
9
+ end
10
+
11
+ def persistent_url_attribute
12
+ return nil unless persistent_url
13
+ renderer_for(:persistent_url, {}).new(:persistent_url, persistent_url).render_dl_row
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,8 @@
1
+ # mixin to provide methods to render place_of_publication
2
+ module NewspaperWorks
3
+ module PlaceOfPublicationPresenterBehavior
4
+ def place_of_publication_label
5
+ solr_document["place_of_publication_label_tesim"]
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,7 @@
1
+ # Scanned Media: Shared Metadata
2
+ module NewspaperWorks
3
+ # scanned media metadata for newspaper models (e.g. page, article images)
4
+ module ScannedMediaPresenter
5
+ delegate :text_direction, :page_number, :section, to: :solr_document
6
+ end
7
+ end
@@ -0,0 +1,13 @@
1
+ # NewspaperTitle ancestor data
2
+ module NewspaperWorks
3
+ # shared NewspaperTitle info for multiple newspaper models
4
+ module TitleInfoPresenter
5
+ def publication_id
6
+ solr_document['publication_id_ssi']
7
+ end
8
+
9
+ def publication_title
10
+ solr_document['publication_title_ssi']
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,16 @@
1
+ module NewspaperWorks
2
+ # hide Title, Container, and Issue objects if this is a keyword search
3
+ # can be added to default_processor_chain in a SearchBuilder class
4
+ module ExcludeModels
5
+ extend ActiveSupport::Concern
6
+
7
+ def exclude_models(solr_parameters)
8
+ return unless solr_parameters[:q] || solr_parameters[:all_fields]
9
+ type_field = 'human_readable_type_sim'
10
+ solr_parameters[:fq] ||= []
11
+ %w[Title Container Issue].each do |model|
12
+ solr_parameters[:fq] << '-' + type_field + ':"Newspaper ' + model + '"'
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,14 @@
1
+ module NewspaperWorks
2
+ # add highlighting on _stored_ full text field if this is a keyword search
3
+ # can be added to default_processor_chain in a SearchBuilder class
4
+ module HighlightSearchParams
5
+ # add highlights on full text field, if there is a keyword query
6
+ def highlight_search_params(solr_parameters = {})
7
+ return unless solr_parameters[:q] || solr_parameters[:all_fields]
8
+ solr_parameters[:hl] = true
9
+ solr_parameters[:'hl.fl'] = 'all_text_tsimv'
10
+ solr_parameters[:'hl.fragsize'] = 100
11
+ solr_parameters[:'hl.snippets'] = 5
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,26 @@
1
+ # based heavily on BlacklightAdvancedSearch::AdvancedSearchBuilder
2
+ # this class is used to set params on the search that is performed to
3
+ # display facet values on the Newspapers Search form,
4
+ # NOT the search results when a user submits the form
5
+ module NewspaperWorks
6
+ class NewspapersSearchBuilder < Hyrax::SearchBuilder
7
+ self.default_processor_chain += [:facets_for_newspapers_search_form, :newspaper_pages_only]
8
+
9
+ def facets_for_newspapers_search_form(solr_params)
10
+ # we only care about facets, we don't need any rows.
11
+ solr_params["rows"] = "0"
12
+
13
+ # add anything set in config as a literal
14
+ newspaper_facet_config = blacklight_config.advanced_search[:newspapers_search]
15
+ return if newspaper_facet_config.blank?
16
+ solr_params.merge!(newspaper_facet_config[:form_solr_parameters])
17
+ end
18
+
19
+ def newspaper_pages_only(solr_params)
20
+ type_field = Solrizer.solr_name('human_readable_type', :facetable)
21
+ type_value = NewspaperPage.human_readable_type
22
+ solr_params[:fq] ||= []
23
+ solr_params[:fq] << "#{type_field}:\"#{type_value}\""
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,9 @@
1
+ # based on Hyrax::RightsStatementService
2
+ module Hyrax
3
+ # Provide select options for the NewspaperArticle genre (edm:hasType) field
4
+ class ArticleGenreService < QaSelectService
5
+ def initialize(_authority_name = nil)
6
+ super('newspaper_article_genres')
7
+ end
8
+ end
9
+ end