Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add core image server settings #725

Open
wants to merge 7 commits into
base: 7.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 41 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,47 @@ By default, objects with the [Fedora state](https://wiki.duraspace.org/display/F
* A [detailed tutorial](https://github.com/Islandora/islandora/wiki/Multi-paged-Ingest-Forms) on extending the multi-page ingest forms is available on the Github (developers') Wiki.
* Additional modules developed by members of the Islandora community to extend Islandora can be found on the curated [Islandora Awesome](https://github.com/Islandora-Labs/islandora_awesome) list.

## Documentation
### Image Server configuration


#### Drupal

In Administration » Islandora » Image Server configuration

Choose the type of image server (Djatoka or IIIF).

Set the URL.

#### Djatoka

![Configuration](https://user-images.githubusercontent.com/2857697/63660444-1a24c400-c77c-11e9-831d-5f3fc71b085e.png)

#### IIIF

![Configuration](https://user-images.githubusercontent.com/2857697/63660476-43455480-c77c-11e9-8460-c3d2639e7575.png)

If using IIIF choose to send token as a header and choose the token to use.

Any [IIIF](http://iiif.io) image server can be used the the IIIF tile source. The IIIF tile source provides a full URL to the datastream to be displayed as the IIIF `identifier`. The IIIF server needs to be configured to resolve this full URL to retrieve the image.
adam-vessey marked this conversation as resolved.
Show resolved Hide resolved

The [Cantaloupe 🍈](https://medusa-project.github.io/cantaloupe/) IIIF image server can be configured to resolve these identifiers using the [`HttpResolver`](https://medusa-project.github.io/cantaloupe/manual/3.3/resolvers.html#HttpResolver) with no prefix specified.

#### Apache Reverse Proxy

Reverse proxy config: We make the assumption that we (reverse) proxy Djatoka, to fix the same-origin issue.

For Apache, with Drupal running on the same box as Apache, a couple lines like:

```
ProxyPass /adore-djatoka http://localhost:8080/adore-djatoka
ProxyPassReverse /adore-djatoka http://localhost:8080/adore-djatoka
```

in the Apache config somewhere (either the main apache.conf, httpd.conf, or in and arbitrarily named `*.conf` in your Apache's conf.d directory should suffice to establish the reverse proxy.

In Debian derived systems one will need to create location entries for each proxy or remove the Deny from All in mod_proxy's conf file.

# Documentation

Further documentation for this module is available at [our documentation wiki](https://wiki.duraspace.org/display/ISLANDORA/Islandora+Core+Module).

Expand Down
11 changes: 11 additions & 0 deletions includes/dublin_core.inc
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@
*/
class DublinCore {

/**
* Dublin Core fields.
*
* @var array|\DublinCore
*/
public $dc = array(
'dc:title' => array(),
'dc:creator' => array(),
Expand All @@ -30,6 +35,12 @@ class DublinCore {
'dc:coverage' => array(),
'dc:rights' => array(),
);

/**
* Owner name.
*
* @var string
*/
public $owner;

/**
Expand Down
276 changes: 276 additions & 0 deletions includes/imageserver.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,276 @@
<?php

/**
* @file
* Image server central configuration.
*/

/**
* Image server configuration form.
*
* @param array $form
* Drupal form.
* @param array $form_state
* Drupal form state.
*
* @return array
* Drupal form.
*
* @throws \Exception
* Thrown by theme() function.
*/
function islandora_imageserver_admin_form(array $form, array &$form_state) {
form_load_include($form_state, 'inc', 'islandora', 'includes/utilities');
$settings = islandora_imageserver_get_settings();

$form = array(
'type' => array(
'#type' => 'select',
'#title' => t('Image Server'),
'#description' => t('Select the image server to configure, used by the Paged Content, OpenSeadragon, & Internet Archive Bookreader modules.'),
adam-vessey marked this conversation as resolved.
Show resolved Hide resolved
'#default_value' => $settings['type'],
'#options' => array(
'none' => t('No image server configured'),
'iiif' => t('IIIF image server'),
'djatoka' => t('Adore-Djatoka image server'),
adam-vessey marked this conversation as resolved.
Show resolved Hide resolved
),
),
'url' => array(
'#prefix' => '<div id="islandora-imageserver-path-wrapper">',
'#suffix' => '</div>',
'#type' => 'textfield',
'#title' => t('Image Server Base URL'),
'#title_display' => 'invisible',
'#default_value' => $settings['url'],
'#description' => t('The location of the image server. <br/> !confirmation_message', array(
'!confirmation_message' => islandora_imageserver_admin_form_access_message($form_state),
)),
'#ajax' => array(
'callback' => 'islandora_imageserver_admin_ajax_url',
'wrapper' => 'islandora-imageserver-path-wrapper',
),
),
'iiif' => array(
'#type' => 'fieldset',
'#title' => t('IIIF Image Server Settings'),
'#description' => t('Settings for IIIF Image Server'),
'#states' => array(
'visible' => array(
':input[name="type"]' => array('value' => 'iiif'),
),
),
'iiif_token_header' => array(
'#type' => 'checkbox',
'#title' => t('Add token as header'),
'#default_value' => $settings['iiif_token_header'],
'#description' => t('Instead of sending the token as a query parameter, it will be sent in the X-ISLANDORA-TOKEN header.'),
),
'iiif_identifier' => array(
'#type' => 'textfield',
'#title' => t('IIIF Identifier'),
'#default_value' => $settings['iiif_identifier'],
'#element_validate' => array('token_element_validate'),
'#token_types' => array('islandora'),
),
'islandora_imageserver_iiif_token_tree' => array(
'#type' => 'fieldset',
'#title' => t('Replacement patterns'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#description' => theme('token_tree', array(
'token_types' => array('islandora'),
'global_types' => FALSE,
)),
),
),
'actions' => array(
'#type' => 'actions',
'save' => array(
'#type' => 'submit',
'#value' => t('Save configuration'),
'#weight' => 0,
),
'reset' => array(
'#type' => 'submit',
'#value' => t('Reset to defaults'),
'#weight' => 1,
'#submit' => array('islandora_imageserver_admin_submit_reset'),
),
),
);
return $form;
}

/**
* Delete configured settings, returning us to default settings.
*/
function islandora_imageserver_admin_submit_reset() {
variable_del('islandora_imageserver_settings');
adam-vessey marked this conversation as resolved.
Show resolved Hide resolved
drupal_set_message(t('Settings reset.'), 'status');
}

/**
* Implements hook_form_submit().
*/
function islandora_imageserver_admin_form_submit(array $form, array &$form_state) {
$type = $form_state['values']['type'];
if ($type == 'none') {
variable_del('islandora_imageserver_settings');
adam-vessey marked this conversation as resolved.
Show resolved Hide resolved
}
else {
$settings = islandora_imageserver_get_settings();
$settings['type'] = $type;
$settings['url'] = rtrim($form_state['values']['url'], '/');
if ($type == 'iiif') {
$settings['iiif_token_header'] = (bool) $form_state['values']['iiif_token_header'];
$settings['iiif_identifier'] = $form_state['values']['iiif_identifier'];
}
else {
$settings['iiif_token_header'] = FALSE;
$settings['iiif_identifier'] = ISLANDORA_IMAGESERVER_DEFAULT_TOKEN;
}
variable_set('islandora_imageserver_settings', $settings);
}
drupal_set_message(t("Settings saved successfully."), 'status');
}

/**
* Callback to check URL.
*
* @param array $form
* Drupal form.
* @param array $form_state
* Drupal form state.
*
* @return mixed
* The form element.
*/
function islandora_imageserver_admin_ajax_url(array $form, array $form_state) {
return $form['url'];
}

/**
* Gets a message which describes if Adore-Djatoka is accessible.
*
* @param array $form_state
* The current form state.
*
* @see islandora_imageserver_get_settings()
*
* @return string
* A message describing the accessibility of the Adore-Djatoka image resolver.
*/
function islandora_imageserver_admin_form_access_message(array &$form_state) {
$confirmation_message = '';

$type = islandora_imageserver_get_default_value($form_state, 'type');
$url = islandora_imageserver_get_default_value($form_state, 'url');

if ($type == 'djatoka') {
$url = url("{$url}", array(
adam-vessey marked this conversation as resolved.
Show resolved Hide resolved
'absolute' => TRUE,
'query' => array(
'url_ver' => 'Z39.88-2004',
'rft_id' => 'http://memory.loc.gov/gmd/gmd433/g4330/g4330/np000066.jp2',
'svc_id' => 'info:lanl-repo/svc/getRegion',
'svc_val_fmt' => 'info:ofi/fmt:kev:mtx:jpeg2000',
'svc.format' => 'image/jpeg',
'svc.level' => '1',
),
));
}
elseif ($type == 'iiif') {
$url = url(rtrim($url, '/'),
array(
'absolute' => TRUE,
)
);
}

if (isset($url) && !empty($url)) {
$result = drupal_http_request($url);
if ($result->code == 200) {
$confirmation_message = theme_image(array(
'path' => 'misc/watchdog-ok.png',
'attributes' => array(),
));
$confirmation_message .= t('Successfully connected to image server.');
}
else {
$confirmation_message = theme_image(array(
'path' => 'misc/watchdog-error.png',
'attributes' => array(),
));
$confirmation_message .= t('Unable to connect to image server at !path', array(
'!path' => $url,
));
}
}
return $confirmation_message;
}

/**
* Get image server settings.
*
* @return array
* Configuration to access the image server.
*/
function islandora_imageserver_get_settings() {
$defaults = array(
'type' => 'none',
'url' => '',
'iiif_token_header' => FALSE,
'iiif_identifier' => ISLANDORA_IMAGESERVER_DEFAULT_TOKEN,
);

$settings = variable_get('islandora_imageserver_settings', array()) + $defaults;

return $settings;
}

/**
* Utility to check form_state or return the default.
*
* @param array $form_state
* Drupal form state.
* @param string $name
* Name of the form element/settings key.
*
* @return mixed
* The Form value or currently saved value.
*/
function islandora_imageserver_get_default_value(array &$form_state, $name) {
$settings = islandora_imageserver_get_settings();
return isset($form_state['values'][$name]) ? $form_state['values'][$name] : $settings[$name];
}

/**
* Generate a replacement string using tokens.
*
* @param string $string_token
* The replacement token to generate.
* @param string $pid
* The pid of the object.
* @param string $dsid
* The dsid to return.
* @param string $authtoken
* The authentication token.
*
* @return mixed
* The token replaced string.
*/
function islandora_imageserver_get_identifier($string_token, $pid, $dsid, $authtoken) {
$settings = islandora_imageserver_get_settings();
if ($settings['type'] == 'djatoka') {
// We use the token_replace to generate the rft_id.
$string_token = '[islandora:url_token]';
}
$parts = array(
'islandora' => array(
'pid' => $pid,
'dsid' => $dsid,
'token' => $authtoken,
),
);
return token_replace($string_token, $parts);
}
10 changes: 10 additions & 0 deletions includes/mime_detect.inc
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,17 @@ class MimeDetect {
* $this->get_extension('image/jpeg') will always return 'jpg'.
*/
protected $protectedMimeTypes = array();
/**
* Protected file extensions.
*
* @var array
*/
protected $protectedFileExtensions;
/**
* Extension exceptions.
*
* @var array
*/
protected $extensionExceptions = array(
// XXX: Deprecated... Only here due to old 'tif' => 'image/tif' mapping...
// The correct MIMEtype is 'image/tiff'.
Expand Down
Loading