Browse Source

Merge branch '8.x-1.x' of https://github.com/Islandora-CLAW/islandora into 8.x-1.x

pull/756/head
Alan Stanley 6 years ago
parent
commit
4688a57e32
  1. 12
      .travis.yml
  2. 16
      CONTRIBUTING.md
  3. 8
      composer.json
  4. 4
      config/install/islandora.settings.yml
  5. 13
      config/install/system.action.delete_media.yml
  6. 66
      config/schema/islandora.schema.yml
  7. 5
      drush.services.yml
  8. 2
      islandora.info.yml
  9. 12
      islandora.install
  10. 8
      islandora.links.action.yml
  11. 147
      islandora.module
  12. 12
      islandora.services.yml
  13. 25
      islandora.views.inc
  14. 4
      migrate/tags.csv
  15. 339
      modules/islandora_audio/LICENSE
  16. 23
      modules/islandora_audio/README.md
  17. 28
      modules/islandora_audio/config/schema/islandora_audio.info.yml
  18. 7
      modules/islandora_audio/islandora_audio.info.yml
  19. 32
      modules/islandora_audio/islandora_audio.module
  20. 56
      modules/islandora_audio/src/Plugin/Action/GenerateAudioDerivative.php
  21. 1
      modules/islandora_audio/tests/fixtures/test_file.txt
  22. 85
      modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php
  23. 3
      modules/islandora_breadcrumbs/config/install/islandora.breadcrumbs.yml
  24. 12
      modules/islandora_breadcrumbs/config/schema/islandora_breadcrumbs.schema.yml
  25. 7
      modules/islandora_breadcrumbs/islandora_breadcrumbs.info.yml
  26. 6
      modules/islandora_breadcrumbs/islandora_breadcrumbs.services.yml
  27. 111
      modules/islandora_breadcrumbs/src/IslandoraBreadcrumbBuilder.php
  28. 109
      modules/islandora_breadcrumbs/tests/src/Functional/BreadcrumbsTest.php
  29. 1
      modules/islandora_core_feature/config/install/core.entity_view_display.media.file.source.yml
  30. 5
      modules/islandora_core_feature/config/install/core.entity_view_display.media.image.source.yml
  31. 2
      modules/islandora_core_feature/config/install/field.field.media.audio.field_media_use.yml
  32. 2
      modules/islandora_core_feature/config/install/field.field.media.file.field_media_use.yml
  33. 2
      modules/islandora_core_feature/config/install/field.field.media.image.field_media_use.yml
  34. 2
      modules/islandora_core_feature/config/install/field.field.media.video.field_media_use.yml
  35. 2
      modules/islandora_core_feature/config/install/field.storage.media.field_media_use.yml
  36. 2
      modules/islandora_core_feature/config/install/field.storage.node.field_display_hints.yml
  37. 19
      modules/islandora_core_feature/config/install/field.storage.node.field_weight.yml
  38. 3
      modules/islandora_core_feature/config/install/rdf.mapping.media.audio.yml
  39. 3
      modules/islandora_core_feature/config/install/rdf.mapping.media.file.yml
  40. 3
      modules/islandora_core_feature/config/install/rdf.mapping.media.image.yml
  41. 3
      modules/islandora_core_feature/config/install/rdf.mapping.media.video.yml
  42. 30
      modules/islandora_core_feature/config/install/rdf.mapping.taxonomy_term.islandora_display.yml
  43. 12
      modules/islandora_core_feature/config/install/system.action.delete_file_as_fedora_external_content.yml
  44. 2
      modules/islandora_core_feature/config/install/system.action.delete_media_from_triplestore.yml
  45. 2
      modules/islandora_core_feature/config/install/system.action.delete_node_from_fedora.yml
  46. 2
      modules/islandora_core_feature/config/install/system.action.delete_node_from_triplestore.yml
  47. 12
      modules/islandora_core_feature/config/install/system.action.index_file_as_fedora_external_content.yml
  48. 2
      modules/islandora_core_feature/config/install/system.action.index_file_in_fedora.yml
  49. 2
      modules/islandora_core_feature/config/install/system.action.index_media_in_fedora.yml
  50. 2
      modules/islandora_core_feature/config/install/system.action.index_media_in_triplestore.yml
  51. 2
      modules/islandora_core_feature/config/install/system.action.index_node_in_fedora.yml
  52. 2
      modules/islandora_core_feature/config/install/system.action.index_node_in_triplestore.yml
  53. 78
      modules/islandora_core_feature/config/install/views.view.display_media.yml
  54. 2
      modules/islandora_core_feature/config/install/views.view.manage_members.yml
  55. 2
      modules/islandora_core_feature/config/install/views.view.members.yml
  56. 271
      modules/islandora_core_feature/config/install/views.view.reorder_children.yml
  57. 2
      modules/islandora_core_feature/islandora_core_feature.features.yml
  58. 0
      modules/islandora_core_feature/islandora_core_feature.info.yml
  59. 1
      modules/islandora_iiif/config/install/islandora_iiif.settings.yml
  60. 7
      modules/islandora_iiif/config/schema/islandora_iiif.schema.yml
  61. 7
      modules/islandora_iiif/islandora_iiif.info.yml
  62. 6
      modules/islandora_iiif/islandora_iiif.links.menu.yml
  63. 24
      modules/islandora_iiif/islandora_iiif.module
  64. 9
      modules/islandora_iiif/islandora_iiif.routing.yml
  65. 92
      modules/islandora_iiif/src/Form/IslandoraIIIFConfigForm.php
  66. 329
      modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php
  67. 41
      modules/islandora_image/.travis.yml
  68. 339
      modules/islandora_image/LICENSE
  69. 23
      modules/islandora_image/README.md
  70. 28
      modules/islandora_image/config/schema/islandora_image.info.yml
  71. 7
      modules/islandora_image/islandora_image.info.yml
  72. 24
      modules/islandora_image/islandora_image.module
  73. 56
      modules/islandora_image/src/Plugin/Action/GenerateImageDerivative.php
  74. 1
      modules/islandora_image/tests/fixtures/test_file.txt
  75. 87
      modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php
  76. 339
      modules/islandora_text_extraction/LICENSE
  77. 44
      modules/islandora_text_extraction/README.md
  78. 7
      modules/islandora_text_extraction/islandora_text_extraction.info.yml
  79. 23
      modules/islandora_text_extraction/islandora_text_extraction.install
  80. 53
      modules/islandora_text_extraction/islandora_text_extraction.module
  81. 58
      modules/islandora_text_extraction/src/Plugin/Action/GenerateOCRDerivative.php
  82. 82
      modules/islandora_text_extraction/src/Plugin/Field/FieldFormatter/OcrTextFormatter.php
  83. 46
      modules/islandora_text_extraction/tests/src/Functional/LoadTest.php
  84. 81
      modules/islandora_text_extraction_defaults/config/install/core.entity_form_display.media.extracted_text.default.yml
  85. 65
      modules/islandora_text_extraction_defaults/config/install/core.entity_view_display.media.extracted_text.default.yml
  86. 20
      modules/islandora_text_extraction_defaults/config/install/field.field.media.extracted_text.field_edited_text.yml
  87. 26
      modules/islandora_text_extraction_defaults/config/install/field.field.media.extracted_text.field_media_file.yml
  88. 24
      modules/islandora_text_extraction_defaults/config/install/field.field.media.extracted_text.field_media_of.yml
  89. 28
      modules/islandora_text_extraction_defaults/config/install/field.field.media.extracted_text.field_media_use.yml
  90. 20
      modules/islandora_text_extraction_defaults/config/install/field.field.media.extracted_text.field_mime_type.yml
  91. 18
      modules/islandora_text_extraction_defaults/config/install/field.storage.media.field_edited_text.yml
  92. 10
      modules/islandora_text_extraction_defaults/config/install/language.content_settings.media.extracted_text.yml
  93. 12
      modules/islandora_text_extraction_defaults/config/install/media.type.extracted_text.yml
  94. 19
      modules/islandora_text_extraction_defaults/config/install/system.action.get_ocr_from_image.yml
  95. 2
      modules/islandora_text_extraction_defaults/islandora_text_extraction_defaults.features.yml
  96. 16
      modules/islandora_text_extraction_defaults/islandora_text_extraction_defaults.info.yml
  97. 339
      modules/islandora_video/LICENSE
  98. 23
      modules/islandora_video/README.md
  99. 28
      modules/islandora_video/config/schema/islandora_video.info.yml
  100. 7
      modules/islandora_video/islandora_video.info.yml
  101. Some files were not shown because too many files have changed in this diff Show More

12
.travis.yml

@ -3,6 +3,8 @@ language: php
php: php:
- 7.1 - 7.1
- 7.2 - 7.2
services:
- mysql
matrix: matrix:
fast_finish: true fast_finish: true
@ -24,12 +26,14 @@ install:
- COMPOSER_MEMORY_LIMIT=-1 php -d memory_limit=-1 $COMPOSER_PATH config repositories.local path "$TRAVIS_BUILD_DIR" - COMPOSER_MEMORY_LIMIT=-1 php -d memory_limit=-1 $COMPOSER_PATH config repositories.local path "$TRAVIS_BUILD_DIR"
- COMPOSER_MEMORY_LIMIT=-1 php -d memory_limit=-1 $COMPOSER_PATH require "islandora/islandora:dev-travis-testing as dev-8.x-1.x" --prefer-source --update-with-dependencies - COMPOSER_MEMORY_LIMIT=-1 php -d memory_limit=-1 $COMPOSER_PATH require "islandora/islandora:dev-travis-testing as dev-8.x-1.x" --prefer-source --update-with-dependencies
- cd web; drush --uri=127.0.0.1:8282 en -y islandora - cd web; drush --uri=127.0.0.1:8282 en -y islandora
- (drush -y --uri=127.0.0.1:8282 en islandora_core_feature; drush -y --uri=127.0.0.1:8282 fim islandora_core_feature)
- drush -y --uri=127.0.0.1:8282 en islandora_audio islandora_breadcrumbs islandora_iiif islandora_image islandora_video
- (drush -y --uri=127.0.0.1:8282 en islandora_text_extraction_defaults; drush -y --uri=127.0.0.1:8282 fim islandora_text_extraction_defaults)
script: script:
- $SCRIPT_DIR/line_endings.sh $TRAVIS_BUILD_DIR - $SCRIPT_DIR/travis_scripts.sh
- phpcs --standard=Drupal --ignore=*.md --extensions=php,module,inc,install,test,profile,theme,css,info $TRAVIS_BUILD_DIR - $SCRIPT_DIR/run-tests.sh "islandora"
- phpcpd --names *.module,*.inc,*.test,*.php $TRAVIS_BUILD_DIR - $SCRIPT_DIR/run-tests.sh "islandora_breadcrumbs"
- php core/scripts/run-tests.sh --suppress-deprecations --url http://127.0.0.1:8282 --verbose --php `which php` --module "islandora"
notifications: notifications:
irc: irc:

16
CONTRIBUTING.md

@ -1,6 +1,10 @@
# Welcome! # Welcome!
If you are reading this document then you are interested in contributing to the Islandora CLAW. All contributions are welcome: use-cases, documentation, code, patches, bug reports, feature requests, etc. You do not need to be a programmer to speak up! If you are reading this document then you are interested in contributing to Islandora 8. All contributions are welcome: use-cases, documentation, code, patches, bug reports, feature requests, etc. You do not need to be a programmer to speak up!
We also have an irc channel -- #islandora -- on freenode.net. Feel free to hang out there, ask questions, and help others out if you can.
Please note that this project operates under the [Islandora Community Code of Conduct](http://islandora.ca/codeofconduct). By participating in this project you agree to abide by its terms.
## Workflows ## Workflows
@ -8,7 +12,7 @@ The group meets each Wednesday at 1:00 PM Eastern. Meeting notes and announcemen
### Use cases ### Use cases
If you would like to submit a use case to the Islandora CLAW project, please submit an issue [here](https://github.com/Islandora-CLAW/CLAW/issues/new) using the [Use Case template](https://github.com/Islandora-CLAW/CLAW/wiki/Use-Case-template), prepending "Use Case:" to the title of the issue. If you would like to submit a use case to the Islandora 8 project, please submit an issue [here](https://github.com/Islandora-CLAW/CLAW/issues/new) using the [Use Case template](https://github.com/Islandora-CLAW/CLAW/wiki/Use-Case-template), prepending "Use Case:" to the title of the issue.
### Documentation ### Documentation
@ -16,11 +20,11 @@ You can contribute documentation in two different ways. One way is to create an
### Request a new feature ### Request a new feature
To request a new feature you should [open an issue in the CLAW repository](https://github.com/Islandora-CLAW/CLAW/issues/new) or create a use case (see the _Use cases_ section above), and summarize the desired functionality. Prepend "Enhancement:" if creating an issue on the project repo, and "Use Case:" if creating a use case. To request a new feature you should [open an issue in the Islandora 8 repository](https://github.com/Islandora-CLAW/CLAW/issues/new) or create a use case (see the _Use cases_ section above), and summarize the desired functionality. Prepend "Enhancement:" if creating an issue on the project repo, and "Use Case:" if creating a use case.
### Report a bug ### Report a bug
To report a bug you should [open an issue in the CLAW repository](https://github.com/Islandora-CLAW/CLAW/issues/new) that summarizes the bug. Prepend the label "Bug:" to the title of the issue. To report a bug you should [open an issue in the Islandora 8 repository](https://github.com/Islandora-CLAW/CLAW/issues/new) that summarizes the bug. Prepend the label "Bug:" to the title of the issue.
In order to help us understand and fix the bug it would be great if you could provide us with: In order to help us understand and fix the bug it would be great if you could provide us with:
@ -36,7 +40,7 @@ That is great! In this case please send us a pull request as described in the se
### Contribute code ### Contribute code
Before you set out to contribute code you will need to have completed a [Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_cla.pdf) or be covered by a [Corporate Contributor Licencse Agreement](http://islandora.ca/sites/default/files/islandora_ccla.pdf). The signed copy of the license agreement should be sent to <mailto:community@islandora.ca> Before you set out to contribute code you will need to have completed a [Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_cla.pdf) or be covered by a [Corporate Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_ccla.pdf). The signed copy of the license agreement should be sent to <mailto:community@islandora.ca>
_If you are interested in contributing code to Islandora but do not know where to begin:_ _If you are interested in contributing code to Islandora but do not know where to begin:_
@ -66,4 +70,4 @@ You may want to read [Syncing a fork](https://help.github.com/articles/syncing-a
## License Agreements ## License Agreements
The Islandora Foundation requires that contributors complete a [Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_cla.pdf) or be covered by a [Corporate Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_ccla.pdf). The signed copy of the license agreement should be sent to <a href="mailto:community@islandora.ca?Subject=Contributor%20License%20Agreement" target="_top">community@islandora.ca</a>. This license is for your protection as a contributor as well as the protection of the Foundation and its users; it does not change your rights to use your own contributions for any other purpose. The Islandora Foundation requires that contributors complete a [Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_cla.pdf) or be covered by a [Corporate Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_ccla.pdf). The signed copy of the license agreement should be sent to <a href="mailto:community@islandora.ca?Subject=Contributor%20License%20Agreement" target="_top">community@islandora.ca</a>. This license is for your protection as a contributor as well as the protection of the Foundation and its users; it does not change your rights to use your own contributions for any other purpose. A list of current CLAs is kept [here](https://github.com/Islandora/islandora/wiki/Contributor-License-Agreements).

8
composer.json

@ -21,15 +21,15 @@
"stomp-php/stomp-php": "4.*", "stomp-php/stomp-php": "4.*",
"drupal/jwt": "1.0.0-alpha6", "drupal/jwt": "1.0.0-alpha6",
"drupal/filehash": "^1.1", "drupal/filehash": "^1.1",
"drupal/prepopulate" : "^2.0@alpha", "drupal/prepopulate" : "^2.2",
"drupal/eva" : "^1.3", "drupal/eva" : "^1.3",
"drupal/features" : "^3.7", "drupal/features" : "^3.7",
"drupal/migrate_plus" : "4.0-beta3", "drupal/migrate_plus" : "^4.1",
"drupal/migrate_tools" : "4.0-beta3", "drupal/migrate_tools" : "^4.1",
"drupal/migrate_source_csv" : "^2.1", "drupal/migrate_source_csv" : "^2.1",
"drupal/token" : "^1.3", "drupal/token" : "^1.3",
"drupal/flysystem" : "^1.0", "drupal/flysystem" : "^1.0",
"islandora/chullo" : "dev-master" "islandora/crayfish-commons": "dev-dev"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "^6", "phpunit/phpunit": "^6",

4
config/install/islandora.settings.yml

@ -0,0 +1,4 @@
broker_url: 'tcp://localhost:61613'
jwt_expiry: '+2 hour'
gemini_url: ''
gemini_pseudo_bundles: []

13
config/install/system.action.delete_media.yml

@ -1,13 +0,0 @@
langcode: en
status: true
dependencies:
enforced:
module:
- islandora
module:
- islandora
id: delete_media
label: 'Delete media'
type: media
plugin: delete_media
configuration: { }

66
config/schema/islandora.schema.yml

@ -3,14 +3,26 @@ islandora.settings:
label: 'Islandora Core Settings' label: 'Islandora Core Settings'
mapping: mapping:
broker_url: broker_url:
type: string type: string
label: 'Url to connect to message broker' label: 'Url to connect to message broker'
fedora_rest_endpoint: fedora_rest_endpoint:
type: string type: string
label: 'Url to Fedora instance' label: 'Url to Fedora instance'
broadcast_queue: broadcast_queue:
type: string type: string
label: 'Queue that handles distributing messages amongst multiple recipients' label: 'Queue that handles distributing messages amongst multiple recipients'
jwt_expiry:
type: string
label: 'How long JWTs should last before expiring.'
gemini_url:
type: uri
label: 'Url to Gemini microservice'
gemini_pseudo_bundles:
type: sequence
label: 'List of node, media and taxonomy terms that should include the linked Fedora URI'
sequence:
type: string
action.configuration.emit_node_event: action.configuration.emit_node_event:
type: mapping type: mapping
@ -56,10 +68,6 @@ action.configuration.emit_term_event:
type: text type: text
label: 'Event Type' label: 'Event Type'
action.configuration.delete_media:
type: action_configuration_default
label: 'Delete media'
action.configuration.delete_media_and_file: action.configuration.delete_media_and_file:
type: action_configuration_default type: action_configuration_default
label: 'Delete media and file' label: 'Delete media and file'
@ -68,21 +76,31 @@ condition.plugin.node_has_term:
type: condition.plugin type: condition.plugin
mapping: mapping:
uri: uri:
type: text type: text
label: 'Taxonomy Term URI' label: 'Taxonomy Term URI'
condition.plugin.node_has_parent:
type: condition.plugin
mapping:
parent_nid:
type: integer
label: 'Parent node'
parent_reference_field:
type: string
label: 'Parent reference field'
condition.plugin.media_has_term: condition.plugin.media_has_term:
type: condition.plugin type: condition.plugin
mapping: mapping:
uri: uri:
type: text type: text
label: 'Taxonomy Term URI' label: 'Taxonomy Term URI'
condition.plugin.parent_node_has_term: condition.plugin.parent_node_has_term:
type: condition.plugin type: condition.plugin
mapping: mapping:
uri: uri:
type: text type: text
label: 'Taxonomy Term URI' label: 'Taxonomy Term URI'
condition.plugin.file_uses_filesystem: condition.plugin.file_uses_filesystem:
@ -101,6 +119,13 @@ condition.plugin.media_uses_filesystem:
sequence: sequence:
type: string type: string
condition.plugin.media_has_mimetype:
type: condition.plugin
mapping:
mimetypes:
type: text
label: 'Mime types'
condition.plugin.content_entity_type: condition.plugin.content_entity_type:
type: condition.plugin type: condition.plugin
mapping: mapping:
@ -108,3 +133,24 @@ condition.plugin.content_entity_type:
type: sequence type: sequence
sequence: sequence:
type: string type: string
condition.plugin.node_had_namespace:
type: condition.plugin
mapping:
namespace:
type: text
label: 'Namespace'
pid_field:
type: ignore
label: 'PID field'
field.formatter.settings.islandora_image:
type: mapping
label: 'Image field display format settings'
mapping:
image_link:
type: string
label: 'Link image to'
image_style:
type: string
label: 'Image style'

5
drush.services.yml

@ -0,0 +1,5 @@
services:
islandora.commands:
class: \Drupal\islandora\Commands\IslandoraCommands
tags:
- { name: drush.command }

2
islandora.info.yml

@ -3,7 +3,7 @@
name: 'islandora' name: 'islandora'
description: "Islandora Core" description: "Islandora Core"
type: module type: module
package: islandora package: Islandora
core: 8.x core: 8.x
dependencies: dependencies:
- block - block

12
islandora.install

@ -40,3 +40,15 @@ function islandora_schema() {
]; ];
return $schema; return $schema;
} }
/**
* Delete the 'delete_media' action we used to provide, if it exists.
*
* Use the core 'media_delete_action' instead.
*/
function islandora_update_8001(&$sandbox) {
$action = \Drupal::service('entity_type.manager')->getStorage('action')->load('delete_media');
if ($action) {
$action->delete();
}
}

8
islandora.links.action.yml

@ -6,6 +6,12 @@ islandora.add_media_to_node:
islandora.add_member_to_node: islandora.add_member_to_node:
route_name: islandora.add_member_to_node_page route_name: islandora.add_member_to_node_page
title: Add member title: Add child
appears_on:
- view.manage_members.page_1
islandora.reorder_children:
route_name: view.reorder_children.page_1
title: Reorder Children
appears_on: appears_on:
- view.manage_members.page_1 - view.manage_members.page_1

147
islandora.module

@ -14,8 +14,12 @@
* @author Diego Pino Navarro <dpino@metro.org> https://github.com/diegopino * @author Diego Pino Navarro <dpino@metro.org> https://github.com/diegopino
*/ */
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
use Drupal\islandora\Form\IslandoraSettingsForm;
use Drupal\islandora\GeminiLookup;
use Drupal\node\NodeInterface; use Drupal\node\NodeInterface;
use Drupal\media\MediaInterface; use Drupal\media\MediaInterface;
use Drupal\file\FileInterface; use Drupal\file\FileInterface;
@ -56,6 +60,8 @@ function islandora_rdf_namespaces() {
'pcdm' => 'http://pcdm.org/models#', 'pcdm' => 'http://pcdm.org/models#',
'use' => 'http://pcdm.org/use#', 'use' => 'http://pcdm.org/use#',
'iana' => 'http://www.iana.org/assignments/relation/', 'iana' => 'http://www.iana.org/assignments/relation/',
'premis' => 'http://www.loc.gov/premis/rdf/v1#',
'co' => 'http://purl.org/co/',
]; ];
} }
@ -257,23 +263,27 @@ function islandora_entity_view_mode_alter(&$view_mode, EntityInterface $entity)
// ContextReaction. // ContextReaction.
$storage = \Drupal::service('entity_type.manager')->getStorage('entity_view_mode'); $storage = \Drupal::service('entity_type.manager')->getStorage('entity_view_mode');
$context_manager = \Drupal::service('context.manager'); $context_manager = \Drupal::service('context.manager');
$current_entity = \Drupal::routeMatch()->getParameter('node');
foreach ($context_manager->getActiveReactions('\Drupal\islandora\Plugin\ContextReaction\ViewModeAlterReaction') as $reaction) { $current_id = ($current_entity instanceof NodeInterface) ? $current_entity->id() : NULL;
// Construct the new view mode's machine name. if (isset($current_id) && $current_id == $entity->id()) {
$entity_type = $entity->getEntityTypeId(); foreach ($context_manager->getActiveReactions('\Drupal\islandora\Plugin\ContextReaction\ViewModeAlterReaction') as $reaction) {
$mode = $reaction->execute(); // Construct the new view mode's machine name.
$machine_name = "$entity_type.$mode"; $entity_type = $entity->getEntityTypeId();
$mode = $reaction->execute();
// Try to load it. $machine_name = "$entity_type.$mode";
$new_mode = $storage->load($machine_name);
// Try to load it.
// If successful, alter the view mode. $new_mode = $storage->load($machine_name);
if ($new_mode) {
$view_mode = $mode; // If successful, alter the view mode.
} if ($new_mode) {
else { $view_mode = $mode;
// Otherwise, leave it be, but log a message. }
\Drupal::logger('islandora')->info("EntityViewMode $machine_name does not exist. View mode cannot be altered."); else {
// Otherwise, leave it be, but log a message.
\Drupal::logger('islandora')
->info("EntityViewMode $machine_name does not exist. View mode cannot be altered.");
}
} }
} }
} }
@ -335,8 +345,111 @@ function islandora_form_block_form_alter(&$form, FormStateInterface $form_state,
// to alter block layout. // to alter block layout.
unset($form['visibility']['content_entity_type']); unset($form['visibility']['content_entity_type']);
unset($form['visibility']['parent_node_has_term']); unset($form['visibility']['parent_node_has_term']);
unset($form['visibility']['node_had_namespace']);
unset($form['visibility']['media_has_term']); unset($form['visibility']['media_has_term']);
unset($form['visibility']['file_uses_filesystem']); unset($form['visibility']['file_uses_filesystem']);
unset($form['visibility']['node_has_term']); unset($form['visibility']['node_has_term']);
unset($form['visibility']['node_has_parent']);
unset($form['visibility']['media_uses_filesystem']); unset($form['visibility']['media_uses_filesystem']);
unset($form['visibility']['media_has_mimetype']);
}
/**
* Implements hook_entity_extra_field_info().
*/
function islandora_entity_extra_field_info() {
$config_factory = \Drupal::service('config.factory')->get(IslandoraSettingsForm::CONFIG_NAME);
$extra_field = [];
$pseudo_bundles = $config_factory->get(IslandoraSettingsForm::GEMINI_PSEUDO);
foreach ($pseudo_bundles as $key) {
list($bundle, $content_entity) = explode(":", $key);
$extra_field[$content_entity][$bundle]['display']['field_gemini_uri'] = [
'label' => t('Fedora URI'),
'description' => t('The URI to the persistent'),
'weight' => 100,
'visible' => TRUE,
];
}
return $extra_field;
}
/**
* Implements hook_entity_view().
*/
function islandora_entity_view(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) {
$route_match_item = \Drupal::routeMatch()->getParameters()->all();
// Get the parameter, which might be node, media or taxonomy term.
$current_entity = reset($route_match_item);
// Match exactly to ensure they are the same entity type too.
if ($entity === $current_entity) {
if ($display->getComponent('field_gemini_uri')) {
$gemini = \Drupal::service('islandora.gemini.lookup');
if ($gemini instanceof GeminiLookup) {
$fedora_uri = $gemini->lookup($entity);
if (!is_null($fedora_uri)) {
$build['field_gemini_uri'] = [
'#type' => 'container',
'#attributes' => [
'id' => 'field-gemini-uri',
],
'internal_label' => [
'#type' => 'item',
'#title' => t('Fedora URI'),
'internal_uri' => [
'#type' => 'link',
'#title' => t("@url", ['@url' => $fedora_uri]),
'#url' => Url::fromUri($fedora_uri),
],
],
];
}
}
}
}
}
/**
* Implements hook_preprocess_views_view_table().
*
* Used for the integer-weight drag-n-drop. Taken almost
* verbatim from the weight module.
*/
function islandora_preprocess_views_view_table(&$variables) {
// Check for a weight selector field.
foreach ($variables['view']->field as $field_key => $field) {
if ($field->options['plugin_id'] == 'integer_weight_selector') {
// Check if the weight selector is on the first column.
$is_first_column = array_search($field_key, array_keys($variables['view']->field)) > 0 ? FALSE : TRUE;
// Add the tabledrag attributes.
foreach ($variables['rows'] as $key => $row) {
if ($is_first_column) {
// If the weight selector is the first column move it to the last
// column, in order to make the draggable widget appear.
$weight_selector = $variables['rows'][$key]['columns'][$field->field];
unset($variables['rows'][$key]['columns'][$field->field]);
$variables['rows'][$key]['columns'][$field->field] = $weight_selector;
}
// Add draggable attribute.
$variables['rows'][$key]['attributes']->addClass('draggable');
}
// The row key identify in an unique way a view grouped by a field.
// Without row number, all the groups will share the same table_id
// and just the first table can be draggable.
$table_id = 'weight-table-' . $variables['view']->dom_id . '-row-' . $key;
$variables['attributes']['id'] = $table_id;
$options = [
'table_id' => $table_id,
'action' => 'order',
'relationship' => 'sibling',
'group' => 'weight-selector',
];
drupal_attach_tabledrag($variables, $options);
}
}
} }

12
islandora.services.yml

@ -3,6 +3,7 @@
services: services:
islandora.eventgenerator: islandora.eventgenerator:
class: Drupal\islandora\EventGenerator\EventGenerator class: Drupal\islandora\EventGenerator\EventGenerator
arguments: ['@islandora.utils', '@islandora.media_source_service']
islandora.stomp: islandora.stomp:
class: Stomp\StatefulStomp class: Stomp\StatefulStomp
factory: ['Drupal\islandora\StompFactory', create] factory: ['Drupal\islandora\StompFactory', create]
@ -15,7 +16,7 @@ services:
- { name: event_subscriber } - { name: event_subscriber }
islandora.media_link_header_subscriber: islandora.media_link_header_subscriber:
class: Drupal\islandora\EventSubscriber\MediaLinkHeaderSubscriber class: Drupal\islandora\EventSubscriber\MediaLinkHeaderSubscriber
arguments: ['@entity_type.manager', '@entity_field.manager', '@access_manager', '@current_user', '@current_route_match', '@request_stack'] arguments: ['@entity_type.manager', '@entity_field.manager', '@access_manager', '@current_user', '@current_route_match', '@request_stack', '@islandora.utils']
tags: tags:
- { name: event_subscriber } - { name: event_subscriber }
islandora.node_link_header_subscriber: islandora.node_link_header_subscriber:
@ -50,4 +51,11 @@ services:
arguments: ['@entity_type.manager', '@current_user', '@language_manager', '@entity.query', '@file_system', '@islandora.utils'] arguments: ['@entity_type.manager', '@current_user', '@language_manager', '@entity.query', '@file_system', '@islandora.utils']
islandora.utils: islandora.utils:
class: Drupal\islandora\IslandoraUtils class: Drupal\islandora\IslandoraUtils
arguments: ['@entity_type.manager', '@entity_field.manager', '@entity.query', '@context.manager', '@flysystem_factory'] arguments: ['@entity_type.manager', '@entity_field.manager', '@entity.query', '@context.manager', '@flysystem_factory', '@language_manager']
islandora.gemini.client:
class: Islandora\Crayfish\Commons\Client\GeminiClient
factory: ['Drupal\islandora\GeminiClientFactory', create]
arguments: ['@config.factory', '@logger.channel.islandora']
islandora.gemini.lookup:
class: Drupal\islandora\GeminiLookup
arguments: ['@islandora.gemini.client', '@jwt.authentication.jwt', '@islandora.media_source_service', '@http_client', '@logger.channel.islandora']

25
islandora.views.inc

@ -0,0 +1,25 @@
<?php
/**
* @file
* Provide Views data for integer-weight fields.
*/
/**
* Implements hook_views_data_alter().
*/
function islandora_views_data_alter(&$data) {
// For now only support Nodes.
$fields = \Drupal::service('entity_field.manager')->getFieldStorageDefinitions('node');
foreach ($fields as $field => $field_storage_definition) {
if ($field_storage_definition->getType() == 'integer' && strpos($field, "field_") === 0) {
$data['node__' . $field][$field . '_value']['field'] = $data['node__' . $field][$field]['field'];
$data['node__' . $field][$field]['title'] = t('Integer Weight Selector (@field)', [
'@field' => $field,
]);
$data['node__' . $field][$field]['help'] = t('Provides a drag-n-drop reordering of integer-based weight fields.');
$data['node__' . $field][$field]['title short'] = t('Integer weight selector');
$data['node__' . $field][$field]['field']['id'] = 'integer_weight_selector';
}
}
}

4
migrate/tags.csv

@ -11,3 +11,7 @@ islandora_models,"Binary","A generic binary file for repository items that don't
islandora_models,"Collection","A collection is an aggregation of items",http://purl.org/dc/dcmitype/Collection islandora_models,"Collection","A collection is an aggregation of items",http://purl.org/dc/dcmitype/Collection
islandora_models,"Image","A visual representation other than text, including all types of moving image and still image",http://purl.org/coar/resource_type/c_c513 islandora_models,"Image","A visual representation other than text, including all types of moving image and still image",http://purl.org/coar/resource_type/c_c513
islandora_models,"Video","A recording of visual images, usually in motion and with sound accompaniment",http://purl.org/coar/resource_type/c_12ce islandora_models,"Video","A recording of visual images, usually in motion and with sound accompaniment",http://purl.org/coar/resource_type/c_12ce
islandora_models,"Digital Document","An electronic file or document.",https://schema.org/DigitalDocument
islandora_models,"Paged Content","An Electronic Book, object with pages",https://schema.org/Book
islandora_models,"Page","A page in an Electronic Paged Content Object",http://id.loc.gov/ontologies/bibframe/part
islandora_models,"Publication Issue","A part of a successively published publication such as a periodical or publication volume, often numbered, usually containing a grouping of works such as articles.",https://schema.org/PublicationIssue

1 vid name description external_uri
11 islandora_models Collection A collection is an aggregation of items http://purl.org/dc/dcmitype/Collection
12 islandora_models Image A visual representation other than text, including all types of moving image and still image http://purl.org/coar/resource_type/c_c513
13 islandora_models Video A recording of visual images, usually in motion and with sound accompaniment http://purl.org/coar/resource_type/c_12ce
14 islandora_models Digital Document An electronic file or document. https://schema.org/DigitalDocument
15 islandora_models Paged Content An Electronic Book, object with pages https://schema.org/Book
16 islandora_models Page A page in an Electronic Paged Content Object http://id.loc.gov/ontologies/bibframe/part
17 islandora_models Publication Issue A part of a successively published publication such as a periodical or publication volume, often numbered, usually containing a grouping of works such as articles. https://schema.org/PublicationIssue

339
modules/islandora_audio/LICENSE

@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

23
modules/islandora_audio/README.md

@ -0,0 +1,23 @@
# Islandora Video
[![Contribution Guidelines](http://img.shields.io/badge/CONTRIBUTING-Guidelines-blue.svg)](../../CONTRIBUTING.md)
[![LICENSE](https://img.shields.io/badge/license-GPLv2-blue.svg?style=flat-square)](./LICENSE)
## Introduction
Islandora Video module for Drupal 8.2.x
## Maintainers
Current maintainers:
* [Danny Lamb](https://github.com/dannylamb)
## Development
If you would like to contribute, please get involved by attending our weekly [Tech Call](https://github.com/Islandora-CLAW/CLAW/wiki). We love to hear from you!
If you would like to contribute code to the project, you need to be covered by an Islandora Foundation [Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_cla.pdf) or [Corporate Contributor Licencse Agreement](http://islandora.ca/sites/default/files/islandora_ccla.pdf). Please see the [Contributors](http://islandora.ca/resources/contributors) pages on Islandora.ca for more information.
## License
[GPLv2](http://www.gnu.org/licenses/gpl-2.0.txt)

28
modules/islandora_audio/config/schema/islandora_audio.info.yml

@ -0,0 +1,28 @@
action.configuration.generate_audio_derivative:
type: mapping
label: 'Generate a audio derivative...'
mapping:
queue:
type: text
label: 'Queue'
event:
type: text
label: 'Event Type'
source_term_uri:
type: text
label: 'Source term uri'
derivative_term_uri:
type: text
label: 'Destination term uri'
mimetype:
type: text
label: 'Audio Mimetype'
args:
type: text
label: 'FFMpeg Arguments'
scheme:
type: text
label: 'Flysystem scheme'
path:
type: text
label: 'File path with extension'

7
modules/islandora_audio/islandora_audio.info.yml

@ -0,0 +1,7 @@
name: 'Islandora Audio'
description: 'Islandora audio derivative actions'
type: module
package: Islandora
core: 8.x
dependencies:
- islandora

32
modules/islandora_audio/islandora_audio.module

@ -0,0 +1,32 @@
<?php
/**
* @file
* Contains islandora_audio.module.
*
* This file is part of the Islandora Project.
*
* (c) Islandora Foundation
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Drupal\Core\Routing\RouteMatchInterface;
/**
* Implements hook_help().
*/
function islandora_audio_help($route_name, RouteMatchInterface $route_match) {
switch ($route_name) {
// Main module help for the islandora module.
case 'help.page.islandora_audio':
$output = '';
$output .= '<h3>' . t('About') . '</h3>';
$output .= '<p>' . t('Islandora Audio adds audio derivative actions.') . '</p>';
$output .= '<p>' . t('These can be used with microservices to automatically generate derivative audios.') . '</p>';
return $output;
default:
}
}

56
modules/islandora_audio/src/Plugin/Action/GenerateAudioDerivative.php

@ -0,0 +1,56 @@
<?php
namespace Drupal\islandora_audio\Plugin\Action;
use Drupal\Core\Form\FormStateInterface;
use Drupal\islandora\Plugin\Action\AbstractGenerateDerivative;
/**
* Emits a Node for generating audio derivatives event.
*
* @Action(
* id = "generate_audio_derivative",
* label = @Translation("Generate a audio derivative"),
* type = "node"
* )
*/
class GenerateAudioDerivative extends AbstractGenerateDerivative {
/**
* {@inheritdoc}
*/
public function defaultConfiguration() {
$config = parent::defaultConfiguration();
$config['path'] = '[date:custom:Y]-[date:custom:m]/[node:nid]-[term:name].mp3';
$config['mimetype'] = 'audio/mpeg';
$config['queue'] = 'islandora-connector-homarus';
$config['destination_media_type'] = 'audio';
$config['args'] = '-codec:a libmp3lame -q:a 5';
return $config;
}
/**
* {@inheritdoc}
*/
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
$form = parent::buildConfigurationForm($form, $form_state);
$form['mimetype']['#description'] = t('Mimetype to convert to (e.g. audio/mpeg, audio/m4a, etc...)');
$form['args']['#description'] = t('Additional command line parameters for FFMpeg');
return $form;
}
/**
* {@inheritdoc}
*/
public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
parent::validateConfigurationForm($form, $form_state);
$exploded_mime = explode('/', $form_state->getValue('mimetype'));
if ($exploded_mime[0] != 'audio') {
$form_state->setErrorByName(
'mimetype',
t('Please enter a audio mimetype (e.g. audio/mpeg, audio/m4a, etc...)')
);
}
}
}

1
modules/islandora_audio/tests/fixtures/test_file.txt vendored

@ -0,0 +1 @@
THIS IS A TEST

85
modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php

@ -0,0 +1,85 @@
<?php
namespace Drupal\Tests\islandora_audio\Functional;
use Drupal\Tests\islandora\Functional\GenerateDerivativeTestBase;
/**
* Tests the GenerateAudioDerivative action.
*
* @group islandora_audio
*/
class GenerateAudioDerivativeTest extends GenerateDerivativeTestBase {
/**
* {@inheritdoc}
*/
protected static $modules = ['context_ui', 'islandora_audio'];
/**
* @covers \Drupal\islandora_audio\Plugin\Action\GenerateAudioDerivative::defaultConfiguration
* @covers \Drupal\islandora_audio\Plugin\Action\GenerateAudioDerivative::buildConfigurationForm
* @covers \Drupal\islandora\Plugin\Action\AbstractGenerateDerivative::defaultConfiguration
* @covers \Drupal\islandora\Plugin\Action\AbstractGenerateDerivative::buildConfigurationForm
* @covers \Drupal\islandora\Plugin\Action\AbstractGenerateDerivative::submitConfigurationForm
* @covers \Drupal\islandora\Plugin\Action\AbstractGenerateDerivative::execute
*/
public function testGenerateAudioDerivativeFromScratch() {
// Create a test user.
$account = $this->drupalCreateUser([
'bypass node access',
'administer contexts',
'administer actions',
'view media',
'create media',
'update media',
]);
$this->drupalLogin($account);
// Create an action to generate a audio derivative.
$this->drupalGet('admin/config/system/actions');
$this->getSession()->getPage()->findById("edit-action")->selectOption("Generate a audio derivative");
$this->getSession()->getPage()->pressButton(t('Create'));
$this->assertSession()->statusCodeEquals(200);
$this->getSession()->getPage()->fillField('edit-label', "Generate audio test derivative");
$this->getSession()->getPage()->fillField('edit-id', "generate_audio_test_derivative");
$this->getSession()->getPage()->fillField('edit-queue', "generate-audio-test-derivative");
$this->getSession()->getPage()->fillField("edit-source-term", $this->preservationMasterTerm->label());
$this->getSession()->getPage()->fillField("edit-derivative-term", $this->serviceFileTerm->label());
$this->getSession()->getPage()->fillField('edit-mimetype', "audio/mpeg");
$this->getSession()->getPage()->fillField('edit-args', "-f mp3");
$this->getSession()->getPage()->fillField('edit-scheme', "public");
$this->getSession()->getPage()->fillField('edit-path', "derp.mov");
$this->getSession()->getPage()->pressButton(t('Save'));
$this->assertSession()->statusCodeEquals(200);
// Create a context and add the action as a derivative reaction.
$this->createContext('Test', 'test');
$this->addPresetReaction('test', 'derivative', "generate_audio_test_derivative");
$this->assertSession()->statusCodeEquals(200);
// Create a new preservation master belonging to the node.
$values = [
'name[0][value]' => 'Test Media',
'files[field_media_file_0]' => __DIR__ . '/../../fixtures/test_file.txt',
'field_media_of[0][target_id]' => 'Test Node',
'field_tags[0][target_id]' => 'Preservation Master',
];
$this->drupalPostForm('media/add/' . $this->testMediaType->id(), $values, t('Save'));
$expected = [
'source_uri' => 'test_file.txt',
'destination_uri' => "node/1/media/{$this->testMediaType->id()}/3",
'file_upload_uri' => 'public://derp.mov',
'mimetype' => 'audio/mpeg',
'args' => '-f mp3',
'queue' => 'islandora-connector-homarus',
];
// Check the message gets published and is of the right shape.
$this->checkMessage($expected);
}
}

3
modules/islandora_breadcrumbs/config/install/islandora.breadcrumbs.yml

@ -0,0 +1,3 @@
maxDepth: -1
includeSelf: FALSE
referenceField: field_member_of

12
modules/islandora_breadcrumbs/config/schema/islandora_breadcrumbs.schema.yml

@ -0,0 +1,12 @@
islandora.breadcrumbs:
type: config_object
mapping:
maxDepth:
type: integer
label: 'Max Depth'
includeSelf:
type: boolean
label: 'Include Self'
referenceField:
type: string
label: 'Reference Field'

7
modules/islandora_breadcrumbs/islandora_breadcrumbs.info.yml

@ -0,0 +1,7 @@
name: 'Islandora Breadcrumbs'
type: module
description: 'Builds breadcrumbs based on field_member_of relationships.'
core: 8.x
package: Islandora
dependencies:
- islandora

6
modules/islandora_breadcrumbs/islandora_breadcrumbs.services.yml

@ -0,0 +1,6 @@
services:
islandora_breadcrumbs.breadcrumb:
class: Drupal\islandora_breadcrumbs\IslandoraBreadcrumbBuilder
arguments: ['@entity_type.manager', '@config.factory']
tags:
- { name: breadcrumb_builder, priority: 100 }

111
modules/islandora_breadcrumbs/src/IslandoraBreadcrumbBuilder.php

@ -0,0 +1,111 @@
<?php
namespace Drupal\islandora_breadcrumbs;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Breadcrumb\Breadcrumb;
use Drupal\Core\Breadcrumb\BreadcrumbBuilderInterface;
use Drupal\Core\Routing\RouteMatchInterface;
/**
* Provides breadcrumbs for nodes using a configured entity reference field.
*/
class IslandoraBreadcrumbBuilder implements BreadcrumbBuilderInterface {
/**
* The configuration.
*
* @var \Drupal\Core\Config\ImmutableConfig
*/
protected $config;
/**
* Storage to load nodes.
*
* @var \Drupal\Core\Entity\EntityStorageInterface
*/
protected $nodeStorage;
/**
* Constructs a breadcrumb builder.
*
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_manager
* Storage to load nodes.
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
* The configuration factory.
*/
public function __construct(EntityTypeManagerInterface $entity_manager, ConfigFactoryInterface $config_factory) {
$this->nodeStorage = $entity_manager->getStorage('node');
$this->config = $config_factory->get('islandora.breadcrumbs');
}
/**
* {@inheritdoc}
*/
public function applies(RouteMatchInterface $attributes) {
// Using getRawParameters for consistency (always gives a
// node ID string) because getParameters sometimes returns
// a node ID string and sometimes returns a node object.
$nid = $attributes->getRawParameters()->get('node');
if (!empty($nid)) {
$node = $this->nodeStorage->load($nid);
return (!empty($node) && $node->hasField($this->config->get('referenceField')) && !$node->get($this->config->get('referenceField'))->isEmpty());
}
}
/**
* {@inheritdoc}
*/
public function build(RouteMatchInterface $route_match) {
$nid = $route_match->getRawParameters()->get('node');
$node = $this->nodeStorage->load($nid);
$breadcrumb = new Breadcrumb();
$chain = [];
$this->walkMembership($node, $chain);
if (!$this->config->get('includeSelf')) {
array_pop($chain);
}
$breadcrumb->addCacheableDependency($node);
// Add membership chain to the breadcrumb.
foreach ($chain as $chainlink) {
$breadcrumb->addCacheableDependency($chainlink);
$breadcrumb->addLink($chainlink->toLink());
}
$breadcrumb->addCacheContexts(['route']);
return $breadcrumb;
}
/**
* Follows chain of field_member_of links.
*
* We pass crumbs by reference to enable checking for looped chains.
*/
protected function walkMembership(EntityInterface $entity, &$crumbs) {
// Avoid infinate loops, return if we've seen this before.
foreach ($crumbs as $crumb) {
if ($crumb->uuid == $entity->uuid) {
return;
}
}
// Add this item onto the pile.
array_unshift($crumbs, $entity);
if ($this->config->get('maxDepth') > 0 && count($crumbs) >= $this->config->get('maxDepth')) {
return;
}
// Find the next in the chain, if there are any.
if ($entity->hasField($this->config->get('referenceField')) &&
!$entity->get($this->config->get('referenceField'))->isEmpty()) {
$this->walkMembership($entity->get($this->config->get('referenceField'))->entity, $crumbs);
}
}
}

109
modules/islandora_breadcrumbs/tests/src/Functional/BreadcrumbsTest.php

@ -0,0 +1,109 @@
<?php
namespace Drupal\Tests\islandora_breadcrumbs\Functional;
use Drupal\Tests\islandora\Functional\IslandoraFunctionalTestBase;
use Drupal\Tests\system\Functional\Menu\AssertBreadcrumbTrait;
/**
* Tests the Islandora Breadcrumbs Builder.
*
* @group islandora_breadcrumbs
*/
class BreadcrumbsTest extends IslandoraFunctionalTestBase {
use AssertBreadcrumbTrait;
/**
* Modules to enable.
*
* @var array
*/
public static $modules = [
'islandora_breadcrumbs',
];
/**
* A node.
*
* @var \Drupal\node\NodeInterface
*/
protected $nodeA;
/**
* Another node.
*
* @var \Drupal\node\NodeInterface
*/
protected $nodeB;
/**
* Yet another node.
*
* @var \Drupal\node\NodeInterface
*/
protected $nodeC;
/**
* Another one.
*
* @var \Drupal\node\NodeInterface
*/
protected $nodeD;
/**
* {@inheritdoc}
*/
public function setUp() {
parent::setUp();
// Create some nodes.
$this->nodeA = $this->container->get('entity_type.manager')->getStorage('node')->create([
'type' => $this->testType->id(),
'title' => 'Node A',
]);
$this->nodeA->save();
$this->nodeB = $this->container->get('entity_type.manager')->getStorage('node')->create([
'type' => $this->testType->id(),
'title' => 'Node B',
]);
$this->nodeB->set('field_member_of', [$this->nodeA->id()]);
$this->nodeB->save();
$this->nodeC = $this->container->get('entity_type.manager')->getStorage('node')->create([
'type' => $this->testType->id(),
'title' => 'Node C',
]);
$this->nodeC->set('field_member_of', [$this->nodeB->id()]);
$this->nodeC->save();
$this->nodeD = $this->container->get('entity_type.manager')->getStorage('node')->create([
'type' => $this->testType->id(),
'title' => 'Node D',
]);
$this->nodeD->set('field_member_of', [$this->nodeC->id()]);
$this->nodeD->save();
}
/**
* @covers \Drupal\islandora_breadcrumbs\IslandoraBreadcrumbBuilder::applies
*/
public function testDefaults() {
$breadcrumbs = [
$this->nodeC->toUrl()->toString() => $this->nodeC->label(),
$this->nodeB->toUrl()->toString() => $this->nodeB->label(),
$this->nodeA->toUrl()->toString() => $this->nodeA->label(),
];
$this->assertBreadcrumb($this->nodeD->toUrl()->toString(), $breadcrumbs);
// Create a reference loop.
$this->nodeA->set('field_member_of', [$this->nodeD->id()]);
$this->nodeA->save();
// We should still escape it and have the same trail as before.
$this->assertBreadcrumb($this->nodeD->toUrl()->toString(), $breadcrumbs);
}
}

1
modules/islandora_core_feature/config/install/core.entity_view_display.media.file.source.yml

@ -30,6 +30,7 @@ content:
hidden: hidden:
created: true created: true
field_file_size: true field_file_size: true
field_gemini_uri: true
field_media_of: true field_media_of: true
field_media_use: true field_media_use: true
field_mime_type: true field_mime_type: true

5
modules/islandora_core_feature/config/install/core.entity_view_display.media.image.source.yml

@ -15,7 +15,7 @@ dependencies:
module: module:
- islandora_core_feature - islandora_core_feature
module: module:
- image - islandora
id: media.image.source id: media.image.source
targetEntityType: media targetEntityType: media
bundle: image bundle: image
@ -27,12 +27,13 @@ content:
image_style: '' image_style: ''
image_link: content image_link: content
third_party_settings: { } third_party_settings: { }
type: image type: islandora_image
weight: 0 weight: 0
region: content region: content
hidden: hidden:
created: true created: true
field_file_size: true field_file_size: true
field_gemini_uri: true
field_height: true field_height: true
field_media_of: true field_media_of: true
field_media_use: true field_media_use: true

2
modules/islandora_core_feature/config/install/field.field.media.audio.field_media_use.yml

@ -10,7 +10,7 @@ field_name: field_media_use
entity_type: media entity_type: media
bundle: audio bundle: audio
label: 'Media Use' label: 'Media Use'
description: '' description: 'Defined by Portland Common Data Model: Use Extension https://pcdm.org/2015/05/12/use. ''Original File'' will trigger creation of derivatives.'
required: false required: false
translatable: false translatable: false
default_value: { } default_value: { }

2
modules/islandora_core_feature/config/install/field.field.media.file.field_media_use.yml

@ -10,7 +10,7 @@ field_name: field_media_use
entity_type: media entity_type: media
bundle: file bundle: file
label: 'Media Use' label: 'Media Use'
description: '' description: 'Defined by Portland Common Data Model: Use Extension https://pcdm.org/2015/05/12/use. ''Original File'' will trigger creation of derivatives.'
required: false required: false
translatable: true translatable: true
default_value: { } default_value: { }

2
modules/islandora_core_feature/config/install/field.field.media.image.field_media_use.yml

@ -10,7 +10,7 @@ field_name: field_media_use
entity_type: media entity_type: media
bundle: image bundle: image
label: 'Media Use' label: 'Media Use'
description: '' description: 'Defined by Portland Common Data Model: Use Extension https://pcdm.org/2015/05/12/use. ''Original File'' will trigger creation of derivatives.'
required: false required: false
translatable: true translatable: true
default_value: { } default_value: { }

2
modules/islandora_core_feature/config/install/field.field.media.video.field_media_use.yml

@ -10,7 +10,7 @@ field_name: field_media_use
entity_type: media entity_type: media
bundle: video bundle: video
label: 'Media Use' label: 'Media Use'
description: '' description: 'Defined by Portland Common Data Model: Use Extension https://pcdm.org/2015/05/12/use. ''Original File'' will trigger creation of derivatives.'
required: false required: false
translatable: true translatable: true
default_value: { } default_value: { }

2
modules/islandora_core_feature/config/install/field.storage.media.field_media_use.yml

@ -12,7 +12,7 @@ settings:
target_type: taxonomy_term target_type: taxonomy_term
module: core module: core
locked: false locked: false
cardinality: 1 cardinality: -1
translatable: true translatable: true
indexes: { } indexes: { }
persist_with_no_fields: false persist_with_no_fields: false

2
modules/islandora_core_feature/config/install/field.storage.node.field_display_hints.yml

@ -12,7 +12,7 @@ settings:
target_type: taxonomy_term target_type: taxonomy_term
module: core module: core
locked: false locked: false
cardinality: -1 cardinality: 1
translatable: true translatable: true
indexes: { } indexes: { }
persist_with_no_fields: false persist_with_no_fields: false

19
modules/islandora_core_feature/config/install/field.storage.node.field_weight.yml

@ -0,0 +1,19 @@
langcode: en
status: true
dependencies:
module:
- node
id: node.field_weight
field_name: field_weight
entity_type: node
type: integer
settings:
unsigned: false
size: normal
module: core
locked: false
cardinality: 1
translatable: true
indexes: { }
persist_with_no_fields: false
custom_storage: false

3
modules/islandora_core_feature/config/install/rdf.mapping.media.audio.yml

@ -43,3 +43,6 @@ fieldMappings:
properties: properties:
- 'schema:additionalType' - 'schema:additionalType'
mapping_type: rel mapping_type: rel
field_file_size:
properties:
- 'premis:hasSize'

3
modules/islandora_core_feature/config/install/rdf.mapping.media.file.yml

@ -43,3 +43,6 @@ fieldMappings:
properties: properties:
- 'schema:additionalType' - 'schema:additionalType'
mapping_type: rel mapping_type: rel
field_file_size:
properties:
- 'premis:hasSize'

3
modules/islandora_core_feature/config/install/rdf.mapping.media.image.yml

@ -49,3 +49,6 @@ fieldMappings:
field_height: field_height:
properties: properties:
- 'ebucore:height' - 'ebucore:height'
field_file_size:
properties:
- 'premis:hasSize'

3
modules/islandora_core_feature/config/install/rdf.mapping.media.video.yml

@ -43,3 +43,6 @@ fieldMappings:
properties: properties:
- 'schema:additionalType' - 'schema:additionalType'
mapping_type: rel mapping_type: rel
field_file_size:
properties:
- 'premis:hasSize'

30
modules/islandora_core_feature/config/install/rdf.mapping.taxonomy_term.islandora_display.yml

@ -0,0 +1,30 @@
langcode: en
status: true
dependencies:
config:
- taxonomy.vocabulary.islandora_display
enforced:
module:
- islandora_core_feature
module:
- taxonomy
id: taxonomy_term.islandora_display
targetEntityType: taxonomy_term
bundle: islandora_display
types:
- 'schema:Thing'
fieldMappings:
name:
properties:
- 'dc:title'
description:
properties:
- 'dc:description'
field_external_uri:
properties:
- 'owl:sameAs'
changed:
properties:
- 'schema:dateModified'
datatype_callback:
callable: 'Drupal\rdf\CommonDataConverter::dateIso8601Value'

12
modules/islandora_core_feature/config/install/system.action.delete_file_as_fedora_external_content.yml

@ -0,0 +1,12 @@
langcode: en
status: true
dependencies:
module:
- islandora
id: delete_file_as_fedora_external_content
label: 'Delete File as Fedora External Content'
type: file
plugin: emit_file_event
configuration:
queue: islandora-indexing-fcrepo-delete
event: Delete

2
modules/islandora_core_feature/config/install/system.action.delete_media_from_triplestore.yml

@ -12,4 +12,4 @@ type: media
plugin: emit_media_event plugin: emit_media_event
configuration: configuration:
queue: islandora-indexing-triplestore-delete queue: islandora-indexing-triplestore-delete
event: delete event: Delete

2
modules/islandora_core_feature/config/install/system.action.delete_node_from_fedora.yml

@ -12,4 +12,4 @@ type: node
plugin: emit_node_event plugin: emit_node_event
configuration: configuration:
queue: islandora-indexing-fcrepo-delete queue: islandora-indexing-fcrepo-delete
event: delete event: Delete

2
modules/islandora_core_feature/config/install/system.action.delete_node_from_triplestore.yml

@ -12,4 +12,4 @@ type: node
plugin: emit_node_event plugin: emit_node_event
configuration: configuration:
queue: islandora-indexing-triplestore-delete queue: islandora-indexing-triplestore-delete
event: delete event: Delete

12
modules/islandora_core_feature/config/install/system.action.index_file_as_fedora_external_content.yml

@ -0,0 +1,12 @@
langcode: en
status: true
dependencies:
module:
- islandora
id: index_file_as_fedora_external_content
label: 'Index File as Fedora External Content'
type: file
plugin: emit_file_event
configuration:
queue: islandora-indexing-fcrepo-file-external
event: Update

2
modules/islandora_core_feature/config/install/system.action.index_file_in_fedora.yml

@ -12,4 +12,4 @@ type: file
plugin: emit_file_event plugin: emit_file_event
configuration: configuration:
queue: islandora-indexing-fcrepo-file queue: islandora-indexing-fcrepo-file
event: Create event: Update

2
modules/islandora_core_feature/config/install/system.action.index_media_in_fedora.yml

@ -12,4 +12,4 @@ type: media
plugin: emit_media_event plugin: emit_media_event
configuration: configuration:
queue: islandora-indexing-fcrepo-media queue: islandora-indexing-fcrepo-media
event: update event: Update

2
modules/islandora_core_feature/config/install/system.action.index_media_in_triplestore.yml

@ -12,4 +12,4 @@ type: media
plugin: emit_media_event plugin: emit_media_event
configuration: configuration:
queue: islandora-indexing-triplestore-index queue: islandora-indexing-triplestore-index
event: update event: Update

2
modules/islandora_core_feature/config/install/system.action.index_node_in_fedora.yml

@ -12,4 +12,4 @@ type: node
plugin: emit_node_event plugin: emit_node_event
configuration: configuration:
queue: islandora-indexing-fcrepo-content queue: islandora-indexing-fcrepo-content
event: update event: Update

2
modules/islandora_core_feature/config/install/system.action.index_node_in_triplestore.yml

@ -12,4 +12,4 @@ type: node
plugin: emit_node_event plugin: emit_node_event
configuration: configuration:
queue: islandora-indexing-triplestore-index queue: islandora-indexing-triplestore-index
event: update event: Update

78
modules/islandora_core_feature/config/install/views.view.display_media.yml

@ -264,6 +264,84 @@ display:
- url - url
- user.permissions - user.permissions
tags: { } tags: { }
entity_view_2:
display_plugin: entity_view
id: entity_view_2
display_title: 'Original File - Download'
position: 1
display_options:
display_extenders: { }
display_description: 'The original creation format of a file'
filters:
status:
value: '1'
table: media_field_data
field: status
plugin_id: boolean
entity_type: media
entity_field: status
id: status
expose:
operator: ''
group: 1
field_external_uri_uri:
id: field_external_uri_uri
table: taxonomy_term__field_external_uri
field: field_external_uri_uri
relationship: field_media_use
group_type: group
admin_label: ''
operator: '='
value: 'http://pcdm.org/use#OriginalFile'
group: 1
exposed: false
expose:
operator_id: ''
label: ''
description: ''
use_operator: false
operator: ''
identifier: ''
required: false
remember: false
multiple: false
remember_roles:
authenticated: authenticated
placeholder: ''
is_grouped: false
group_info:
label: ''
description: ''
identifier: ''
optional: true
widget: select
multiple: false
remember: false
default_group: All
default_group_multiple: { }
group_items: { }
plugin_id: string
defaults:
filters: false
filter_groups: false
filter_groups:
operator: AND
groups:
1: AND
entity_type: node
bundles: { }
argument_mode: id
default_argument: null
title: 'Original File'
show_title: false
cache_metadata:
max-age: -1
contexts:
- 'languages:language_content'
- 'languages:language_interface'
- url
- user.permissions
tags: { }
service_file: service_file:
display_plugin: entity_view display_plugin: entity_view
id: service_file id: service_file

2
modules/islandora_core_feature/config/install/views.view.manage_members.yml

@ -294,7 +294,7 @@ display:
path: node/%node/members path: node/%node/members
menu: menu:
type: tab type: tab
title: Members title: Children
description: '' description: ''
expanded: false expanded: false
parent: '' parent: ''

2
modules/islandora_core_feature/config/install/views.view.members.yml

@ -225,7 +225,7 @@ display:
filter_groups: filter_groups:
operator: AND operator: AND
groups: { } groups: { }
title: Members title: Children
cache_metadata: cache_metadata:
max-age: -1 max-age: -1
contexts: contexts:

271
modules/islandora_core_feature/config/install/views.view.reorder_children.yml

@ -0,0 +1,271 @@
langcode: en
status: true
dependencies:
enforced:
module:
- islandora_core_feature
module:
- islandora
- node
- user
id: reorder_children
label: 'Reorder children'
module: views
description: 'Manage members belonging to a piece of content'
tag: ''
base_table: node_field_data
base_field: nid
core: 8.x
display:
default:
display_plugin: default
id: default
display_title: Master
position: 0
display_options:
access:
type: perm
options:
perm: 'manage members'
cache:
type: tag
options: { }
query:
type: views_query
options:
disable_sql_rewrite: false
distinct: false
replica: false
query_comment: ''
query_tags: { }
exposed_form:
type: basic
options:
submit_button: Apply
reset_button: false
reset_button_label: Reset
exposed_sorts_label: 'Sort by'
expose_sort_order: true
sort_asc_label: Asc
sort_desc_label: Desc
pager:
type: full
options:
items_per_page: 10
offset: 0
id: 0
total_pages: null
tags:
previous: ‹‹
next: ››
first: '« First'
last: 'Last »'
expose:
items_per_page: true
items_per_page_label: 'Items per page'
items_per_page_options: '10, 25, 50, 100'
items_per_page_options_all: true
items_per_page_options_all_label: '- All -'
offset: false
offset_label: Offset
quantity: 9
style:
type: table
row:
type: fields
fields:
title:
id: title
table: node_field_data
field: title
entity_type: node
entity_field: title
alter:
alter_text: false
make_link: false
absolute: false
trim: false
word_boundary: false
ellipsis: false
strip_tags: false
html: false
hide_empty: false
empty_zero: false
settings:
link_to_entity: true
plugin_id: field
relationship: none
group_type: group
admin_label: ''
label: Title
exclude: false
element_type: ''
element_class: ''
element_label_type: ''
element_label_class: ''
element_label_colon: true
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: true
empty: ''
hide_alter_empty: true
click_sort_column: value
type: string
group_column: value
group_columns: { }
group_rows: true
delta_limit: 0
delta_offset: 0
delta_reversed: false
delta_first_last: false
multi_type: separator
separator: ', '
field_api_classes: false
field_weight:
id: field_weight
table: node__field_weight
field: field_weight
relationship: none
group_type: group
admin_label: ''
label: ''
exclude: false
alter:
alter_text: false
text: ''
make_link: false
path: ''
absolute: false
external: false
replace_spaces: false
path_case: none
trim_whitespace: false
alt: ''
rel: ''
link_class: ''
prefix: ''
suffix: ''
target: ''
nl2br: false
max_length: 0
word_boundary: true
ellipsis: true
more_link: false
more_link_text: ''
more_link_path: ''
strip_tags: false
trim: false
preserve_tags: ''
html: false
element_type: ''
element_class: ''
element_label_type: ''
element_label_class: ''
element_label_colon: false
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: true
empty: ''
hide_empty: false
empty_zero: false
hide_alter_empty: true
plugin_id: integer_weight_selector
filters: { }
sorts:
field_weight_value:
id: field_weight_value
table: node__field_weight
field: field_weight_value
relationship: none
group_type: group
admin_label: ''
order: ASC
exposed: false
expose:
label: ''
plugin_id: standard
title: 'Reorder children'
header: { }
footer: { }
empty: { }
relationships: { }
arguments:
field_member_of_target_id:
id: field_member_of_target_id
table: node__field_member_of
field: field_member_of_target_id
relationship: none
group_type: group
admin_label: ''
default_action: default
exception:
value: all
title_enable: false
title: All
title_enable: false
title: ''
default_argument_type: node
default_argument_options: { }
default_argument_skip_url: false
summary_options:
base_path: ''
count: true
items_per_page: 25
override: false
summary:
sort_order: asc
number_of_records: 0
format: default_summary
specify_validation: true
validate:
type: 'entity:node'
fail: 'not found'
validate_options:
operation: view
multiple: 0
bundles: { }
access: false
break_phrase: false
not: false
plugin_id: numeric
display_extenders: { }
filter_groups:
operator: AND
groups: { }
cache_metadata:
max-age: -1
contexts:
- 'languages:language_content'
- 'languages:language_interface'
- url
- url.query_args
- 'user.node_grants:view'
- user.permissions
tags: { }
page_1:
display_plugin: page
id: page_1
display_title: Page
position: 1
display_options:
display_extenders: { }
path: node/%node/reorder
menu:
type: tab
title: 'Reorder Children'
description: ''
expanded: false
parent: ''
weight: 0
context: '0'
menu_name: main
cache_metadata:
max-age: -1
contexts:
- 'languages:language_content'
- 'languages:language_interface'
- url
- url.query_args
- 'user.node_grants:view'
- user.permissions
tags: { }

2
modules/islandora_core_feature/islandora_core_feature.features.yml

@ -10,7 +10,5 @@ excluded:
- core.entity_form_display.taxonomy_term.islandora_display.default - core.entity_form_display.taxonomy_term.islandora_display.default
- core.entity_form_display.taxonomy_term.islandora_media_use.default - core.entity_form_display.taxonomy_term.islandora_media_use.default
- core.entity_form_display.taxonomy_term.islandora_models.default - core.entity_form_display.taxonomy_term.islandora_models.default
- language.content_settings.taxonomy_term.islandora_access
- field.storage.node.field_access_terms
- taxonomy.vocabulary.islandora_access - taxonomy.vocabulary.islandora_access
required: true required: true

0
modules/islandora_core_feature/islandora_core_feature.info.yml

1
modules/islandora_iiif/config/install/islandora_iiif.settings.yml

@ -0,0 +1 @@
iiif_server:

7
modules/islandora_iiif/config/schema/islandora_iiif.schema.yml

@ -0,0 +1,7 @@
islandora_iiif.settings:
type: config_object
label: 'Islandora IIIF Settings'
mapping:
iiif_server:
type: string
label: 'IIIF Server Url'

7
modules/islandora_iiif/islandora_iiif.info.yml

@ -0,0 +1,7 @@
name: 'Islandora IIIF'
type: module
description: 'IIIF support for Islandora'
core: 8.x
package: Islandora
dependencies:
- islandora

6
modules/islandora_iiif/islandora_iiif.links.menu.yml

@ -0,0 +1,6 @@
islandora_iiif.islandora_iiif_config_form:
title: 'IIIF Settings'
route_name: islandora_iiif.islandora_iiif_config_form
description: 'Configure Islandora IIIF settings'
parent: system.admin_config_islandora
weight: 99

24
modules/islandora_iiif/islandora_iiif.module

@ -0,0 +1,24 @@
<?php
/**
* @file
* Contains islandora_iiif.module.
*/
use Drupal\Core\Routing\RouteMatchInterface;
/**
* Implements hook_help().
*/
function islandora_iiif_help($route_name, RouteMatchInterface $route_match) {
switch ($route_name) {
// Main module help for the islandora_iiif module.
case 'help.page.islandora_iiif':
$output = '';
$output .= '<h3>' . t('About') . '</h3>';
$output .= '<p>' . t('IIIF support for Islandora') . '</p>';
return $output;
default:
}
}

9
modules/islandora_iiif/islandora_iiif.routing.yml

@ -0,0 +1,9 @@
islandora_iiif.islandora_iiif_config_form:
path: '/admin/config/islandora/iiif'
defaults:
_form: '\Drupal\islandora_iiif\Form\IslandoraIIIFConfigForm'
_title: 'IslandoraIIIFConfigForm'
requirements:
_permission: 'access administration pages'
options:
_admin_route: TRUE

92
modules/islandora_iiif/src/Form/IslandoraIIIFConfigForm.php

@ -0,0 +1,92 @@
<?php
namespace Drupal\islandora_iiif\Form;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Component\Utility\UrlHelper;
use GuzzleHttp\Exception\ClientException;
/**
* Class IslandoraIIIFConfigForm.
*/
class IslandoraIIIFConfigForm extends ConfigFormBase {
/**
* {@inheritdoc}
*/
protected function getEditableConfigNames() {
return [
'islandora_iiif.settings',
];
}
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'islandora_iiif_config_form';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$config = $this->config('islandora_iiif.settings');
$form['iiif_server'] = [
'#type' => 'url',
'#title' => $this->t('IIIF Image server location'),
'#description' => $this->t('Please enter the image server location without trailing slash. e.g. http://www.example.org/iiif/2.'),
'#default_value' => $config->get('iiif_server'),
];
return parent::buildForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
public function validateForm(array &$form, FormStateInterface $form_state) {
if (!empty($form_state->getValue('iiif_server'))) {
$server = $form_state->getValue('iiif_server');
if (!UrlHelper::isValid($server, UrlHelper::isExternal($server))) {
$form_state->setErrorByName('iiif_server', "IIIF Server address is not a valid URL");
}
elseif (!$this->validateIiifUrl($server)) {
$form_state->setErrorByName('iiif_server', "IIIF Server does not seem to be accessible.");
}
}
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
parent::submitForm($form, $form_state);
$this->config('islandora_iiif.settings')
->set('iiif_server', $form_state->getValue('iiif_server'))
->save();
}
/**
* Ensure the IIIF server is accessible.
*
* @param string $server_uri
* The absolute or relative URI to the server.
*
* @return bool
* True if server returns 200 on a HEAD request.
*/
private function validateIiifUrl($server_uri) {
$client = \Drupal::httpClient();
try {
$result = $client->head($server_uri);
return ($result->getStatusCode() == 200);
}
catch (ClientException $e) {
return FALSE;
}
}
}

329
modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php

@ -0,0 +1,329 @@
<?php
namespace Drupal\islandora_iiif\Plugin\views\style;
use Drupal\views\Plugin\views\style\StylePluginBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\views\ResultRow;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Serializer\SerializerInterface;
use Symfony\Component\HttpFoundation\Request;
use Drupal\Core\Config\ImmutableConfig;
use Drupal\Core\File\FileSystem;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\ClientException;
use GuzzleHttp\Exception\ServerException;
/**
* Provide serializer format for IIIF Manifest.
*
* @ingroup views_style_plugins
*
* @ViewsStyle(
* id = "iiif_manifest",
* title = @Translation("IIIF Manifest"),
* help = @Translation("Display images as an IIIF Manifest."),
* display_types = {"data"}
* )
*/
class IIIFManifest extends StylePluginBase {
/**
* {@inheritdoc}
*/
protected $usesRowPlugin = TRUE;
/**
* {@inheritdoc}
*/
protected $usesGrouping = FALSE;
/**
* The allowed formats for this serializer. Default to only JSON.
*
* @var array
*/
protected $formats = ['json'];
/**
* The serializer which serializes the views result.
*
* @var \Symfony\Component\Serializer\Serializer
*/
protected $serializer;
/**
* The request service.
*
* @var \Symfony\Component\HttpFoundation\Request
*/
protected $request;
/**
* This module's config.
*
* @var \Drupal\Core\Config\ImmutableConfig
*/
protected $iiifConfig;
/**
* The Drupal Filesystem.
*
* @var \Drupal\Core\File\FileSystem
*/
protected $fileSystem;
/**
* {@inheritdoc}
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, SerializerInterface $serializer, Request $request, ImmutableConfig $iiif_config, FileSystem $file_system, Client $http_client) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->serializer = $serializer;
$this->request = $request;
$this->iiifConfig = $iiif_config;
$this->fileSystem = $file_system;
$this->httpClient = $http_client;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('serializer'),
$container->get('request_stack')->getCurrentRequest(),
$container->get('config.factory')->get('islandora_iiif.settings'),
$container->get('file_system'),
$container->get('http_client')
);
}
/**
* {@inheritdoc}
*/
public function render() {
$json = [];
$iiif_address = $this->iiifConfig->get('iiif_server');
if (!is_null($iiif_address) && !empty($iiif_address)) {
// Get the current URL being requested.
$request_url = $this->request->getSchemeAndHttpHost() . $this->request->getRequestUri();
// Strip off the last URI component to get the base ID of the URL.
// @todo assumming the view is a path like /node/1/manifest.json
$url_components = explode('/', $request_url);
array_pop($url_components);
$iiif_base_id = implode('/', $url_components);
// @see https://iiif.io/api/presentation/2.1/#manifest
$json += [
'@type' => 'sc:Manifest',
'@id' => $request_url,
// If the View has a title, set the View title as the manifest label.
'label' => $this->view->getTitle() ?: 'IIIF Manifest',
'@context' => 'http://iiif.io/api/presentation/2/context.json',
// @see https://iiif.io/api/presentation/2.1/#sequence
'sequences' => [
[
'@context' => 'http://iiif.io/api/presentation/2/context.json',
'@id' => $iiif_base_id . '/sequence/normal',
'@type' => 'sc:Sequence',
],
],
];
// For each row in the View result.
foreach ($this->view->result as $row) {
// Add the IIIF URL to the image to print out as JSON.
$canvases = $this->getTileSourceFromRow($row, $iiif_address, $iiif_base_id);
foreach ($canvases as $tile_source) {
$json['sequences'][0]['canvases'][] = $tile_source;
}
}
}
unset($this->view->row_index);
$content_type = 'json';
return $this->serializer->serialize($json, $content_type, ['views_style_plugin' => $this]);
}
/**
* Render array from views result row.
*
* @param \Drupal\views\ResultRow $row
* Result row.
* @param string $iiif_address
* The URL to the IIIF server endpoint.
* @param string $iiif_base_id
* The URL for the request, minus the last part of the URL,
* which is likely "manifest".
*
* @return array
* List of IIIF URLs to display in the Openseadragon viewer.
*/
protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_base_id) {
$canvases = [];
foreach ($this->options['iiif_tile_field'] as $iiif_tile_field) {
$viewsField = $this->view->field[$iiif_tile_field];
$entity = $viewsField->getEntity($row);
if (isset($entity->{$viewsField->definition['field_name']})) {
/** @var \Drupal\Core\Field\FieldItemListInterface $images */
$images = $entity->{$viewsField->definition['field_name']};
foreach ($images as $image) {
// Create the IIIF URL for this file
// Visiting $iiif_url will resolve to the info.json for the image.
$file_url = $image->entity->url();
$mime_type = $image->entity->getMimeType();
$iiif_url = rtrim($iiif_address, '/') . '/' . urlencode($file_url);
// Create the necessary ID's for the canvas and annotation.
$canvas_id = $iiif_base_id . '/canvas/' . $entity->id();
$annotation_id = $iiif_base_id . '/annotation/' . $entity->id();
// Try to fetch the IIIF metadata for the image.
try {
$info_json = $this->httpClient->get($iiif_url)->getBody();
$resource = json_decode($info_json, TRUE);
$width = $resource['width'];
$height = $resource['height'];
}
catch (ClientException $e) {
}
catch (ServerException $e) {
}
// If we couldn't get the info.json from IIIF
// try seeing if we can get it from Drupal.
if (empty($width) || empty($height)) {
// Get the image properties so we know the image width/height.
$properties = $image->getProperties();
$width = isset($properties['width']) ? $properties['width'] : 0;
$height = isset($properties['height']) ? $properties['height'] : 0;
// If this is a TIFF AND we don't know the width/height
// see if we can get the image size via PHP's core function.
if ($mime_type === 'image/tiff' && !$width || !$height) {
$uri = $image->entity->getFileUri();
$path = $this->fileSystem->realpath($uri);
$image_size = getimagesize($path);
if ($image_size) {
$width = $image_size[0];
$height = $image_size[1];
}
}
}
$canvases[] = [
// @see https://iiif.io/api/presentation/2.1/#canvas
'@id' => $canvas_id,
'@type' => 'sc:Canvas',
'label' => $image->entity->label(),
'height' => $height,
'width' => $width,
// @see https://iiif.io/api/presentation/2.1/#image-resources
'images' => [
[
'@id' => $annotation_id,
"@type" => "oa:Annotation",
'motivation' => 'sc:painting',
'resource' => [
'@id' => $iiif_url . '/full/full/0/default.jpg',
"@type" => "dctypes:Image",
'format' => $mime_type,
'height' => $height,
'width' => $width,
'service' => [
'@id' => $iiif_url,
'@context' => 'http://iiif.io/api/image/2/context.json',
'profile' => 'http://iiif.io/api/image/2/profiles/level2.json',
],
],
'on' => $canvas_id,
],
],
];
}
}
}
return $canvases;
}
/**
* {@inheritdoc}
*/
protected function defineOptions() {
$options = parent::defineOptions();
$options['iiif_tile_field'] = ['default' => ''];
return $options;
}
/**
* {@inheritdoc}
*/
public function buildOptionsForm(&$form, FormStateInterface $form_state) {
parent::buildOptionsForm($form, $form_state);
$field_options = [];
$fields = $this->displayHandler->getHandlers('field');
$islandora_default_file_fields = [
'field_media_file',
'field_media_image',
];
$file_views_field_formatters = [
// Image formatters.
'image', 'image_url',
// File formatters.
'file_default', 'file_url_plain',
];
/** @var \Drupal\views\Plugin\views\field\FieldPluginBase[] $fields */
foreach ($fields as $field_name => $field) {
// If this is a known Islandora file/image field
// OR it is another/custom field add it as an available option.
// @todo find better way to identify file fields
// Currently $field->options['type'] is storing the "formatter" of the
// file/image so there are a lot of possibilities.
// The default formatters are 'image' and 'file_default'
// so this approach should catch most...
if (in_array($field_name, $islandora_default_file_fields) ||
(!empty($field->options['type']) && in_array($field->options['type'], $file_views_field_formatters))) {
$field_options[$field_name] = $field->adminLabel();
}
}
// If no fields to choose from, add an error message indicating such.
if (count($field_options) == 0) {
drupal_set_message($this->t('No image or file fields were found in the View.
You will need to add a field to this View'), 'error');
}
$form['iiif_tile_field'] = [
'#title' => $this->t('Tile source field(s)'),
'#type' => 'checkboxes',
'#default_value' => $this->options['iiif_tile_field'],
'#description' => $this->t("The source of image for each entity."),
'#options' => $field_options,
// Only make the form element required if
// we have more than one option to choose from
// otherwise could lock up the form when setting up a View.
'#required' => count($field_options) > 0,
];
}
/**
* Returns an array of format options.
*
* @return string[]
* An array of the allowed serializer formats. In this case just JSON.
*/
public function getFormats() {
return ['json' => 'json'];
}
}

41
modules/islandora_image/.travis.yml

@ -0,0 +1,41 @@
sudo: true
language: php
php:
- 7.1
- 7.2
matrix:
fast_finish: true
branches:
only:
- /^8.x/
before_install:
- export SCRIPT_DIR=$HOME/CLAW/.scripts
- export DRUPAL_DIR=/opt/drupal
- export COMPOSER_PATH="/home/travis/.phpenv/versions/$TRAVIS_PHP_VERSION/bin/composer"
install:
- git clone https://github.com/Islandora-CLAW/CLAW.git $HOME/CLAW
- $SCRIPT_DIR/travis_setup_drupal.sh
- git -C "$TRAVIS_BUILD_DIR" checkout -b travis-testing
- cd $DRUPAL_DIR;
- php -dmemory_limit=-1 $COMPOSER_PATH config repositories.local path "$TRAVIS_BUILD_DIR"
- php -dmemory_limit=-1 $COMPOSER_PATH require "islandora/islandora_image:dev-travis-testing as dev-8.x-1.x" --prefer-source
- cd web; drush en -y islandora_image
script:
- $SCRIPT_DIR/line_endings.sh $TRAVIS_BUILD_DIR
- phpcs --standard=Drupal --ignore=*.md --extensions=php,module,inc,install,test,profile,theme,css,info $TRAVIS_BUILD_DIR
- phpcpd --names *.module,*.inc,*.test,*.php $TRAVIS_BUILD_DIR
- php core/scripts/run-tests.sh --url http://127.0.0.1:8282 --suppress-deprecations --verbose --php `which php` --module "islandora_image"
notifications:
irc:
channels:
- "irc.freenode.org#islandora"
on_success: change
on_failure: always
skip_join: true

339
modules/islandora_image/LICENSE

@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

23
modules/islandora_image/README.md

@ -0,0 +1,23 @@
# ![Islandora Image](https://cloud.githubusercontent.com/assets/2371345/24199472/6f7bfb7a-0ee8-11e7-9c94-754762fd5566.png) Islandora Image
[![Contribution Guidelines](http://img.shields.io/badge/CONTRIBUTING-Guidelines-blue.svg)](../../CONTRIBUTING.md)
[![LICENSE](https://img.shields.io/badge/license-GPLv2-blue.svg?style=flat-square)](./LICENSE)
## Introduction
Islandora Image module for Drupal 8.2.x
## Maintainers
Current maintainers:
* [Danny Lamb](https://github.com/dannylamb)
## Development
If you would like to contribute, please get involved by attending our weekly [Tech Call](https://github.com/Islandora-CLAW/CLAW/wiki). We love to hear from you!
If you would like to contribute code to the project, you need to be covered by an Islandora Foundation [Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_cla.pdf) or [Corporate Contributor Licencse Agreement](http://islandora.ca/sites/default/files/islandora_ccla.pdf). Please see the [Contributors](http://islandora.ca/resources/contributors) pages on Islandora.ca for more information.
## License
[GPLv2](http://www.gnu.org/licenses/gpl-2.0.txt)

28
modules/islandora_image/config/schema/islandora_image.info.yml

@ -0,0 +1,28 @@
action.configuration.generate_image_derivative:
type: mapping
label: 'Generate an image derivative...'
mapping:
queue:
type: text
label: 'Queue'
event:
type: text
label: 'Event Type'
source_term_uri:
type: text
label: 'Source term uri'
derivative_term_uri:
type: text
label: 'Destination term uri'
mimetype:
type: text
label: 'Image Mimetype'
args:
type: text
label: 'Convert Arguments'
scheme:
type: text
label: 'Flysystem scheme'
path:
type: text
label: 'File path with extension'

7
modules/islandora_image/islandora_image.info.yml

@ -0,0 +1,7 @@
name: 'Islandora Image'
type: module
description: 'Islandora Image derivative actions'
core: 8.x
package: Islandora
dependencies:
- islandora

24
modules/islandora_image/islandora_image.module

@ -0,0 +1,24 @@
<?php
/**
* @file
* Contains islandora_image.module.
*/
use Drupal\Core\Routing\RouteMatchInterface;
/**
* Implements hook_help().
*/
function islandora_image_help($route_name, RouteMatchInterface $route_match) {
switch ($route_name) {
// Main module help for the islandora_image module.
case 'help.page.islandora_image':
$output = '';
$output .= '<h3>' . t('About') . '</h3>';
$output .= '<p>' . t('Islandora Image') . '</p>';
return $output;
default:
}
}

56
modules/islandora_image/src/Plugin/Action/GenerateImageDerivative.php

@ -0,0 +1,56 @@
<?php
namespace Drupal\islandora_image\Plugin\Action;
use Drupal\Core\Form\FormStateInterface;
use Drupal\islandora\Plugin\Action\AbstractGenerateDerivative;
/**
* Emits a Node event.
*
* @Action(
* id = "generate_image_derivative",
* label = @Translation("Generate an image derivative"),
* type = "node"
* )
*/
class GenerateImageDerivative extends AbstractGenerateDerivative {
/**
* {@inheritdoc}
*/
public function defaultConfiguration() {
$config = parent::defaultConfiguration();
$config['mimetype'] = 'image/jpeg';
$config['path'] = '[date:custom:Y]-[date:custom:m]/[node:nid].jpg';
$config['destination_media_type'] = 'image';
return $config;
}
/**
* {@inheritdoc}
*/
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
$form = parent::buildConfigurationForm($form, $form_state);
$form['mimetype']['#description'] = t('Mimetype to convert to (e.g. image/jpeg, image/png, etc...)');
$form['args']['#description'] = t('Additional command line arguments for ImageMagick convert (e.g. -resize 50%');
return $form;
}
/**
* {@inheritdoc}
*/
public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
parent::validateConfigurationForm($form, $form_state);
$exploded_mime = explode('/', $form_state->getValue('mimetype'));
if ($exploded_mime[0] != "image") {
$form_state->setErrorByName(
'mimetype',
t('Please enter an image mimetype (e.g. image/jpeg, image/png, etc...)')
);
}
}
}

1
modules/islandora_image/tests/fixtures/test_file.txt vendored

@ -0,0 +1 @@
TEST FILE

87
modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php

@ -0,0 +1,87 @@
<?php
namespace Drupal\Tests\islandora_image\Functional;
use Drupal\Tests\islandora\Functional\GenerateDerivativeTestBase;
/**
* Tests the GenerateImageDerivative action.
*
* @group islandora_image
*/
class GenerateImageDerivativeTest extends GenerateDerivativeTestBase {
/**
* {@inheritdoc}
*/
protected static $modules = ['context_ui', 'islandora_image'];
/**
* @covers \Drupal\islandora_image\Plugin\Action\GenerateImageDerivative::defaultConfiguration
* @covers \Drupal\islandora_image\Plugin\Action\GenerateImageDerivative::buildConfigurationForm
* @covers \Drupal\islandora_image\Plugin\Action\GenerateImageDerivative::validateConfigurationForm
* @covers \Drupal\islandora\Plugin\Action\AbstractGenerateDerivative::defaultConfiguration
* @covers \Drupal\islandora\Plugin\Action\AbstractGenerateDerivative::buildConfigurationForm
* @covers \Drupal\islandora\Plugin\Action\AbstractGenerateDerivative::validateConfigurationForm
* @covers \Drupal\islandora\Plugin\Action\AbstractGenerateDerivative::submitConfigurationForm
* @covers \Drupal\islandora\Plugin\Action\AbstractGenerateDerivative::execute
*/
public function testGenerateImageDerivativeFromScratch() {
// Create a test user.
$account = $this->drupalCreateUser([
'bypass node access',
'administer contexts',
'administer actions',
'view media',
'create media',
'update media',
]);
$this->drupalLogin($account);
// Create an action to generate a jpeg thumbnail.
$this->drupalGet('admin/config/system/actions');
$this->getSession()->getPage()->findById("edit-action")->selectOption("Generate an image derivative");
$this->getSession()->getPage()->pressButton(t('Create'));
$this->assertSession()->statusCodeEquals(200);
$this->getSession()->getPage()->fillField('edit-label', "Generate image test derivative");
$this->getSession()->getPage()->fillField('edit-id', "generate_image_test_derivative");
$this->getSession()->getPage()->fillField('edit-queue', "generate-image-test-derivative");
$this->getSession()->getPage()->fillField("edit-source-term", $this->preservationMasterTerm->label());
$this->getSession()->getPage()->fillField("edit-derivative-term", $this->serviceFileTerm->label());
$this->getSession()->getPage()->fillField('edit-mimetype', "image/jpeg");
$this->getSession()->getPage()->fillField('edit-args', "-thumbnail 20x20");
$this->getSession()->getPage()->fillField('edit-scheme', "public");
$this->getSession()->getPage()->fillField('edit-path', "derp.jpeg");
$this->getSession()->getPage()->pressButton(t('Save'));
$this->assertSession()->statusCodeEquals(200);
// Create a context and add the action as a derivative reaction.
$this->createContext('Test', 'test');
$this->addPresetReaction('test', 'derivative', "generate_image_test_derivative");
$this->assertSession()->statusCodeEquals(200);
// Create a new preservation master belonging to the node.
$values = [
'name[0][value]' => 'Test Media',
'files[field_media_file_0]' => __DIR__ . '/../../fixtures/test_file.txt',
'field_media_of[0][target_id]' => 'Test Node',
'field_tags[0][target_id]' => 'Preservation Master',
];
$this->drupalPostForm('media/add/' . $this->testMediaType->id(), $values, t('Save'));
$expected = [
'source_uri' => 'test_file.txt',
'destination_uri' => "node/1/media/{$this->testMediaType->id()}/3",
'file_upload_uri' => 'public://derp.jpeg',
'mimetype' => 'image/jpeg',
'args' => '-thumbnail 20x20',
'queue' => 'islandora-connector-houdini',
];
// Check the message gets published and is of the right shape.
$this->checkMessage($expected);
}
}

339
modules/islandora_text_extraction/LICENSE

@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

44
modules/islandora_text_extraction/README.md

@ -0,0 +1,44 @@
# islandora_text_extraction
### Connects Islandora 8 to Hypercube microservice and extracts text from PDFs
Install module in the usual way,
then copy `assets/ca.islandora.alpaca.connector.ocr.blueprint.xml`
to `/opt/karaf/deploy` on the server.
_note:_ This config file assumes a url of `http://localhost:8000/hypercube`.
If your service is found elsewhere this must be changed.
There is no need to restart.
In the usual Ansible build this will require no modification.
If a parent node is tagged as `Digital Document` an `Image` tagged media
will extract text from that image at the time of ingestion.
The content type of the parent node should be configured to allow multiple tags.
_note:_ Media are linked to their parent nodes with the `Media Of`
entity reference field. If you wish to attach the PDF (or any other ) media type
to a parent node which has any content type other than Repository Item
(islandora_object) the parent content type will have to be added to the `Media Of`
field in the media type description.
## Prepare module for PDF text extraction
Install `texttopdf` on your server if not already present.
On an ubuntu/debian machine like the default claw playbook run
`sudo apt-get install poppler-utils`
test to see its been properly installed with `which pdftotext`
Install php libraries with `composer require spatie/pdf-to-text`
In the unlikely event that your `pdftotext` binary exists on your server
outside of the system path, the path to the binary can be set at
`/admin/config/islandora/text_extraction`.
## Using text extraction ##
The containing document must be tagged as `Digital Document`,
and the media must be tagged as `Original File`.
A new editable `Extracted Text` media will be created and attached when `PDF` or
`Image` media types are added to a node.

7
modules/islandora_text_extraction/islandora_text_extraction.info.yml

@ -0,0 +1,7 @@
name: 'Islandora Text Extraction'
type: module
description: 'Islandora 8 module to connect to Hypercube microservice, and to get text from PDF ingest'
core: 8.x
package: 'Islandora'
dependencies:
- islandora

23
modules/islandora_text_extraction/islandora_text_extraction.install

@ -0,0 +1,23 @@
<?php
/**
* @file
* Install/update hook implementations.
*/
use Drupal\field\Entity\FieldConfig;
/**
* Implements hook_install().
*/
function islandora_text_extraction_install() {
// Add txt extension if it doesn't already exist;.
$field = FieldConfig::load("media.file.field_media_file");
$fieldSettings = $field->getSettings();
$extensions = $fieldSettings['file_extensions'];
if (!strpos($extensions, 'txt')) {
$fieldSettings['file_extensions'] .= ' txt';
$field->set('settings', $fieldSettings);
$field->save();
}
}

53
modules/islandora_text_extraction/islandora_text_extraction.module

@ -0,0 +1,53 @@
<?php
/**
* @file
* Contains islandora_text_extraction.module.
*/
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\file\Entity\File;
use Drupal\media\MediaInterface;
/**
* Implements hook_help().
*/
function islandora_text_extraction_help($route_name, RouteMatchInterface $route_match) {
switch ($route_name) {
// Main module help for the islandora_text_extraction module.
case 'help.page.islandora_text_extraction':
$output = '';
$output .= '<h3>' . t('About') . '</h3>';
$output .= '<p>' . t('Islandora 8 module to connect to Hypercube microservice') . '</p>';
return $output;
default:
}
}
/**
* Implements hook_media_presave().
*/
function islandora_text_extraction_media_presave(MediaInterface $media) {
if ($media->bundle() != 'extracted_text') {
return;
}
$text = $media->get('field_edited_text')->getValue();
if (!$text) {
$file_id = $media->get('field_media_file')->getValue()[0]['target_id'];
$file = File::load($file_id);
$data = file_get_contents($file->getFileUri());
$data = nl2br($data);
$media->set('field_edited_text', $data);
$media->field_edited_text->format = 'basic_html';
}
}
/**
* Implements hook_form_form_id_alter().
*/
function islandora_text_extraction_form_block_form_alter(&$form, FormStateInterface $form_state, $form_id) {
unset($form['visibility']['ocr_requested']);
unset($form['visibility']['pdf_text_extraction_requested']);
}

58
modules/islandora_text_extraction/src/Plugin/Action/GenerateOCRDerivative.php

@ -0,0 +1,58 @@
<?php
namespace Drupal\islandora_text_extraction\Plugin\Action;
use Drupal\Core\Form\FormStateInterface;
use Drupal\islandora\Plugin\Action\AbstractGenerateDerivative;
/**
* Emits a Node for generating OCR derivatives event.
*
* @Action(
* id = "generate_ocr_derivative",
* label = @Translation("Get OCR from image"),
* type = "node"
* )
*/
class GenerateOCRDerivative extends AbstractGenerateDerivative {
/**
* {@inheritdoc}
*/
public function defaultConfiguration() {
$config = parent::defaultConfiguration();
$config['path'] = '[date:custom:Y]-[date:custom:m]/[node:nid]-[term:name].txt';
$config['mimetype'] = 'application/xml';
$config['queue'] = 'islandora-connector-ocr';
$config['destination_media_type'] = 'file';
return $config;
}
/**
* {@inheritdoc}
*/
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
$form = parent::buildConfigurationForm($form, $form_state);
$form['mimetype']['#description'] = t('Mimetype to convert to (e.g. application/xml, etc...)');
$form['mimetype']['#value'] = 'text/plain';
$form['mimetype']['#type'] = 'textfield';
unset($form['args']);
return $form;
}
/**
* {@inheritdoc}
*/
public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
parent::validateConfigurationForm($form, $form_state);
$exploded_mime = explode('/', $form_state->getValue('mimetype'));
if ($exploded_mime[0] != 'text') {
$form_state->setErrorByName(
'mimetype',
t('Please enter file mimetype (e.g. text/plain.)')
);
}
}
}

82
modules/islandora_text_extraction/src/Plugin/Field/FieldFormatter/OcrTextFormatter.php

@ -0,0 +1,82 @@
<?php
namespace Drupal\islandora_text_extraction\Plugin\Field\FieldFormatter;
use Drupal\Core\Field\FieldItemInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\FormatterBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\file\Entity\File;
/**
* Plugin implementation of the 'ocr_txt_formatter' formatter.
*
* @FieldFormatter(
* id = "ocr_formatter",
* label = @Translation("OCRed text formatter"),
* field_types = {"file"}
* )
*/
class OcrTextFormatter extends FormatterBase {
/**
* {@inheritdoc}
*/
public static function defaultSettings() {
return [
// Implement default settings.
] + parent::defaultSettings();
}
/**
* {@inheritdoc}
*/
public function settingsForm(array $form, FormStateInterface $form_state) {
return [
// Implement settings form.
] + parent::settingsForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
public function settingsSummary() {
$summary = [];
// Implement settings summary.
return $summary;
}
/**
* {@inheritdoc}
*/
public function viewElements(FieldItemListInterface $items, $langcode) {
$elements = [];
foreach ($items as $delta => $item) {
$elements[$delta] = ['#markup' => $this->viewValue($item)];
}
return $elements;
}
/**
* Generate the output appropriate for one field item.
*
* @param \Drupal\Core\Field\FieldItemInterface $item
* One field item.
*
* @return string
* The textual output generated.
*/
protected function viewValue(FieldItemInterface $item) {
$fileItem = $item->getValue();
$file = File::load($fileItem['target_id']);
$contents = file_get_contents($file->getFileUri());
if (mb_detect_encoding($contents) != 'UTF-8') {
$contents = utf8_encode($contents);
}
$contents = nl2br($contents);
return $contents;
}
}

46
modules/islandora_text_extraction/tests/src/Functional/LoadTest.php

@ -0,0 +1,46 @@
<?php
namespace Drupal\Tests\islandora_text_extraction\Functional;
use Drupal\Core\Url;
use Drupal\Tests\BrowserTestBase;
/**
* Simple test to ensure that main page loads with module enabled.
*
* @group islandora_text_extraction
*/
class LoadTest extends BrowserTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['islandora_text_extraction'];
/**
* A user with permission to administer site configuration.
*
* @var \Drupal\user\UserInterface
*/
protected $user;
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->user = $this->drupalCreateUser(['administer site configuration']);
$this->drupalLogin($this->user);
}
/**
* Tests that the home page loads with a 200 response.
*/
public function testLoad() {
$this->drupalGet(Url::fromRoute('<front>'));
$this->assertSession()->statusCodeEquals(200);
}
}

81
modules/islandora_text_extraction_defaults/config/install/core.entity_form_display.media.extracted_text.default.yml

@ -0,0 +1,81 @@
langcode: en
status: true
dependencies:
config:
- field.field.media.extracted_text.field_edited_text
- field.field.media.extracted_text.field_media_file
- field.field.media.extracted_text.field_media_of
- field.field.media.extracted_text.field_media_use
- field.field.media.extracted_text.field_mime_type
- media.type.extracted_text
module:
- file
- path
- text
id: media.extracted_text.default
targetEntityType: media
bundle: extracted_text
mode: default
content:
created:
type: datetime_timestamp
weight: 3
region: content
settings: { }
third_party_settings: { }
field_edited_text:
type: text_textarea
weight: 7
region: content
settings:
rows: 5
placeholder: ''
third_party_settings: { }
field_media_file:
type: file_generic
weight: 6
region: content
settings:
progress_indicator: throbber
third_party_settings: { }
langcode:
type: language_select
weight: 1
region: content
settings:
include_locked: true
third_party_settings: { }
name:
type: string_textfield
weight: 0
region: content
settings:
size: 60
placeholder: ''
third_party_settings: { }
path:
type: path
weight: 4
region: content
settings: { }
third_party_settings: { }
status:
type: boolean_checkbox
settings:
display_label: true
weight: 5
region: content
third_party_settings: { }
uid:
type: entity_reference_autocomplete
weight: 2
settings:
match_operator: CONTAINS
size: 60
placeholder: ''
region: content
third_party_settings: { }
hidden:
field_media_of: true
field_media_use: true
field_mime_type: true

65
modules/islandora_text_extraction_defaults/config/install/core.entity_view_display.media.extracted_text.default.yml

@ -0,0 +1,65 @@
langcode: en
status: true
dependencies:
config:
- field.field.media.extracted_text.field_edited_text
- field.field.media.extracted_text.field_media_file
- field.field.media.extracted_text.field_media_of
- field.field.media.extracted_text.field_media_use
- field.field.media.extracted_text.field_mime_type
- media.type.extracted_text
module:
- file
- text
- user
id: media.extracted_text.default
targetEntityType: media
bundle: extracted_text
mode: default
content:
created:
label: hidden
type: timestamp
weight: 1
region: content
settings:
date_format: medium
custom_date_format: ''
timezone: ''
third_party_settings: { }
field_edited_text:
type: text_default
weight: 3
region: content
label: above
settings: { }
third_party_settings: { }
field_media_file:
type: file_default
weight: 2
region: content
label: above
settings:
use_description_as_link_text: true
third_party_settings: { }
field_media_of:
type: entity_reference_label
weight: 4
region: content
label: above
settings:
link: true
third_party_settings: { }
uid:
label: hidden
type: author
weight: 0
region: content
settings: { }
third_party_settings: { }
hidden:
field_media_use: true
field_mime_type: true
langcode: true
name: true
thumbnail: true

20
modules/islandora_text_extraction_defaults/config/install/field.field.media.extracted_text.field_edited_text.yml

@ -0,0 +1,20 @@
langcode: en
status: true
dependencies:
config:
- field.storage.media.field_edited_text
- media.type.extracted_text
module:
- text
id: media.extracted_text.field_edited_text
field_name: field_edited_text
entity_type: media
bundle: extracted_text
label: 'Edited Text'
description: ''
required: false
translatable: true
default_value: { }
default_value_callback: ''
settings: { }
field_type: text_long

26
modules/islandora_text_extraction_defaults/config/install/field.field.media.extracted_text.field_media_file.yml

@ -0,0 +1,26 @@
langcode: en
status: true
dependencies:
config:
- field.storage.media.field_media_file
- media.type.extracted_text
module:
- file
id: media.extracted_text.field_media_file
field_name: field_media_file
entity_type: media
bundle: extracted_text
label: File
description: ''
required: true
translatable: true
default_value: { }
default_value_callback: ''
settings:
file_extensions: 'txt doc docx pdf'
file_directory: '[date:custom:Y]-[date:custom:m]'
max_filesize: ''
description_field: false
handler: 'default:file'
handler_settings: { }
field_type: file

24
modules/islandora_text_extraction_defaults/config/install/field.field.media.extracted_text.field_media_of.yml

@ -0,0 +1,24 @@
langcode: en
status: true
dependencies:
config:
- field.storage.media.field_media_of
- media.type.extracted_text
id: media.extracted_text.field_media_of
field_name: field_media_of
entity_type: media
bundle: extracted_text
label: 'Media of'
description: ''
required: false
translatable: true
default_value: { }
default_value_callback: ''
settings:
handler: 'default:node'
handler_settings:
target_bundles: null
sort:
field: _none
auto_create: false
field_type: entity_reference

28
modules/islandora_text_extraction_defaults/config/install/field.field.media.extracted_text.field_media_use.yml

@ -0,0 +1,28 @@
langcode: en
status: true
dependencies:
config:
- field.storage.media.field_media_use
- media.type.extracted_text
- taxonomy.vocabulary.islandora_media_use
id: media.extracted_text.field_media_use
field_name: field_media_use
entity_type: media
bundle: extracted_text
label: 'Media Use'
description: ''
required: false
translatable: true
default_value: { }
default_value_callback: ''
settings:
handler: 'default:taxonomy_term'
handler_settings:
target_bundles:
islandora_media_use: islandora_media_use
sort:
field: name
direction: asc
auto_create: false
auto_create_bundle: ''
field_type: entity_reference

20
modules/islandora_text_extraction_defaults/config/install/field.field.media.extracted_text.field_mime_type.yml

@ -0,0 +1,20 @@
langcode: en
status: true
dependencies:
config:
- field.storage.media.field_mime_type
- media.type.extracted_text
id: media.extracted_text.field_mime_type
field_name: field_mime_type
entity_type: media
bundle: extracted_text
label: 'MIME type'
description: ''
required: false
translatable: true
default_value:
-
value: text/plain
default_value_callback: ''
settings: { }
field_type: string

18
modules/islandora_text_extraction_defaults/config/install/field.storage.media.field_edited_text.yml

@ -0,0 +1,18 @@
langcode: en
status: true
dependencies:
module:
- media
- text
id: media.field_edited_text
field_name: field_edited_text
entity_type: media
type: text_long
settings: { }
module: text
locked: false
cardinality: 1
translatable: true
indexes: { }
persist_with_no_fields: false
custom_storage: false

10
modules/islandora_text_extraction_defaults/config/install/language.content_settings.media.extracted_text.yml

@ -0,0 +1,10 @@
langcode: en
status: true
dependencies:
config:
- media.type.extracted_text
id: media.extracted_text
target_entity_type_id: media
target_bundle: extracted_text
default_langcode: site_default
language_alterable: false

12
modules/islandora_text_extraction_defaults/config/install/media.type.extracted_text.yml

@ -0,0 +1,12 @@
langcode: en
status: true
dependencies: { }
id: extracted_text
label: 'Extracted Text'
description: 'Text extracted from Images or PDFs'
source: file
queue_thumbnail_downloads: false
new_revision: false
source_configuration:
source_field: field_media_file
field_map: { }

19
modules/islandora_text_extraction_defaults/config/install/system.action.get_ocr_from_image.yml

@ -0,0 +1,19 @@
langcode: en
status: true
dependencies:
module:
- islandora_text_extraction
id: get_ocr_from_image
label: 'Extract Text from Image or PDF'
type: node
plugin: generate_ocr_derivative
configuration:
queue: islandora-connector-ocr
event: 'Generate Derivative'
source_term_uri: 'http://pcdm.org/use#OriginalFile'
derivative_term_uri: 'http://pcdm.org/use#ExtractedText'
mimetype: text/plain
args: null
destination_media_type: extracted_text
scheme: public
path: '[date:custom:Y]-[date:custom:m]/[node:nid]-[term:name].txt'

2
modules/islandora_text_extraction_defaults/islandora_text_extraction_defaults.features.yml

@ -0,0 +1,2 @@
bundle: islandora
required: true

16
modules/islandora_text_extraction_defaults/islandora_text_extraction_defaults.info.yml

@ -0,0 +1,16 @@
name: 'Islandora Text Extraction Defaults'
type: module
description: 'Default config for the Islandora Text Extraction module.'
core: 8.x
package: Islandora
dependencies:
- field
- file
- islandora_core_feature
- islandora_text_extraction
- language
- media
- path
- system
- text
- user

339
modules/islandora_video/LICENSE

@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

23
modules/islandora_video/README.md

@ -0,0 +1,23 @@
# Islandora Video
[![Contribution Guidelines](http://img.shields.io/badge/CONTRIBUTING-Guidelines-blue.svg)](../../CONTRIBUTING.md)
[![LICENSE](https://img.shields.io/badge/license-GPLv2-blue.svg?style=flat-square)](./LICENSE)
## Introduction
Islandora Video module for Drupal 8.2.x
## Maintainers
Current maintainers:
* [Danny Lamb](https://github.com/dannylamb)
## Development
If you would like to contribute, please get involved by attending our weekly [Tech Call](https://github.com/Islandora-CLAW/CLAW/wiki). We love to hear from you!
If you would like to contribute code to the project, you need to be covered by an Islandora Foundation [Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_cla.pdf) or [Corporate Contributor Licencse Agreement](http://islandora.ca/sites/default/files/islandora_ccla.pdf). Please see the [Contributors](http://islandora.ca/resources/contributors) pages on Islandora.ca for more information.
## License
[GPLv2](http://www.gnu.org/licenses/gpl-2.0.txt)

28
modules/islandora_video/config/schema/islandora_video.info.yml

@ -0,0 +1,28 @@
action.configuration.generate_video_derivative:
type: mapping
label: 'Generate a video derivative...'
mapping:
queue:
type: text
label: 'Queue'
event:
type: text
label: 'Event Type'
source_term_uri:
type: text
label: 'Source term uri'
derivative_term_uri:
type: text
label: 'Destination term uri'
mimetype:
type: text
label: 'Video Mimetype'
args:
type: text
label: 'FFMpeg Arguments'
scheme:
type: text
label: 'Flysystem scheme'
path:
type: text
label: 'File path with extension'

7
modules/islandora_video/islandora_video.info.yml

@ -0,0 +1,7 @@
name: 'Islandora Video'
description: 'Islandora video derivative actions'
type: module
package: Islandora
core: 8.x
dependencies:
- islandora

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save