353 lines
11 KiB
Plaintext
353 lines
11 KiB
Plaintext
<?php
|
|
|
|
/**
|
|
* @file media_archive/media_archive.module
|
|
*
|
|
* Media: Archive provides a stream wrapper and formatters for videos provided
|
|
* by Archive, available at http://archive.org/.
|
|
*
|
|
* @TODO:
|
|
* Tie in Archive API.
|
|
* Allow editors to search for videos to display on the browser.
|
|
* Allow editors to put in a archive username to display on the browser.
|
|
* Allow editors to log in w/ their credentials.
|
|
* Allow editors to upload videos to Archive.
|
|
*/
|
|
|
|
// A registry of variable_get defaults.
|
|
include_once('includes/media_archive.variables.inc');
|
|
|
|
/**
|
|
* Create stream wrapper for Archive videos.
|
|
*/
|
|
function media_archive_stream_wrappers() {
|
|
return array(
|
|
'archive' => array(
|
|
'name' => t('Archive videos'),
|
|
'class' => 'MediaArchiveStreamWrapper',
|
|
'description' => t('Videos provided by Archive.'),
|
|
'type' => STREAM_WRAPPERS_READ_VISIBLE,
|
|
),
|
|
);
|
|
}
|
|
|
|
function media_archive_media_format_form_prepare_alter(&$form, &$form_state, $media) {
|
|
$settings = array('autosubmit' => ($media->type == "video"));
|
|
drupal_add_js(array('media_format_form' => $settings), 'setting');
|
|
}
|
|
|
|
/**
|
|
* Implements hook_theme().
|
|
*/
|
|
function media_archive_theme($existing, $type, $theme, $path) {
|
|
return array(
|
|
'media_archive_preview_style' => array(
|
|
'variables' => array('style_name' => NULL),
|
|
'file' => 'media_archive.theme.inc',
|
|
'path' => $path . '/includes/themes',
|
|
),
|
|
'media_archive_field_formatter_styles' => array(
|
|
'variables' => array('element' => NULL, 'style' => NULL),
|
|
'file' => 'media_archive.theme.inc',
|
|
'path' => $path . '/includes/themes',
|
|
),
|
|
'media_archive_video' => array(
|
|
'variables' => array('uri' => NULL, 'width' => NULL, 'height' => NULL, 'autoplay' => NULL, 'fullscreen' => NULL),
|
|
'file' => 'media_archive.theme.inc',
|
|
'path' => $path . '/includes/themes',
|
|
'template' => 'media-archive-video',
|
|
),
|
|
'media_archive_embed' => array(
|
|
'variables' => array('style_name' => NULL, 'uri' => NULL, 'alt' => NULL, 'title' => NULL),
|
|
'file' => 'media_archive.theme.inc',
|
|
'path' => $path . '/includes/themes',
|
|
),
|
|
'media_archive_styles' => array(
|
|
'variables' => array('element' => NULL, 'style' => NULL),
|
|
'file' => 'media_archive.theme.inc',
|
|
'path' => $path . '/includes/themes',
|
|
),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Implementation of Styles module hook_styles_register().
|
|
*/
|
|
function media_archive_styles_register() {
|
|
return array(
|
|
'MediaArchiveStyles' => array(
|
|
'field_types' => 'file',
|
|
'name' => t('MediaArchive'),
|
|
'description' => t('Media Archive styles.'),
|
|
'path' => drupal_get_path('module', 'media_archive') .'/includes',
|
|
'file' => 'media_archive.styles.inc',
|
|
),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Implements hook_styles_containers(). (Deprecated in version 2)
|
|
*/
|
|
function media_archive_styles_containers() {
|
|
return array(
|
|
'file' => array(
|
|
'containers' => array(
|
|
'media_archive' => array(
|
|
'label' => t('Archive Styles'),
|
|
'data' => array(
|
|
'streams' => array(
|
|
'archive',
|
|
),
|
|
'mimetypes' => array(
|
|
'video/archive',
|
|
),
|
|
),
|
|
'weight' => 0,
|
|
'filter callback' => 'media_archive_formatter_filter',
|
|
'themes' => array(
|
|
'field_formatter_styles' => 'media_archive_field_formatter_styles',
|
|
'styles' => 'media_archive_styles',
|
|
'preview' => 'media_archive_preview_style',
|
|
),
|
|
'description' => t('Archive Styles will display embedded Archive videos and thumbnails to your choosing, such as by resizing, setting colors, and autoplay. You can !manage.', array('!manage' => l(t('manage your Archive styles here'), 'admin/config/media/media-archive-styles'))),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
function media_archive_formatter_filter($variables) {
|
|
if (isset($variables['object'])) {
|
|
$object = $variables['object'];
|
|
return (file_uri_scheme($object->uri) == 'archive') && ($object->filemime == 'video/archive');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Implementation of the File Styles module's hook_file_styles_filter().
|
|
*/
|
|
function media_archive_file_styles_filter($object) {
|
|
if ((file_uri_scheme($object->uri) == 'archive') && ($object->filemime == 'video/archive')) {
|
|
return 'media_archive';
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Implements hook_styles_styles().
|
|
*/
|
|
function media_archive_styles_styles() {
|
|
$styles = array(
|
|
'file' => array(
|
|
'containers' => array(
|
|
'media_archive' => array(
|
|
'styles' => array(
|
|
'archive_thumbnail' => array(
|
|
'name' => 'archive_thumbnail',
|
|
'effects' => array(
|
|
array('label' => t('Thumbnail'), 'name' => 'thumbnail', 'data' => array('thumbnail' => 1)),
|
|
array('label' => t('Resize'), 'name' => 'resize', 'data' => array('width' => 100, 'height' => 75)),
|
|
),
|
|
),
|
|
'archive_preview' => array(
|
|
'name' => 'archive_preview',
|
|
'effects' => array(
|
|
array('label' => t('Autoplay'), 'name' => 'autoplay', 'data' => array('autoplay' => 1)),
|
|
array('label' => t('Resize'), 'name' => 'resize', 'data' => array('width' => 220, 'height' => 165)),
|
|
),
|
|
),
|
|
'archive_full' => array(
|
|
'name' => 'archive_full',
|
|
'effects' => array(
|
|
array('label' => t('Autoplay'), 'name' => 'autoplay', 'data' => array('autoplay' => 0)),
|
|
array('label' => t('Resize'), 'name' => 'resize', 'data' => array('width' => 640, 'height' => 480)),
|
|
array('label' => t('Full screen'), 'name' => 'fullscreen', 'data' => array('fullscreen' => 1)),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
// Allow any image style to be applied to the thumbnail.
|
|
foreach (image_styles() as $style_name => $image_style) {
|
|
$styles['file']['containers']['media_archive']['styles']['archive_thumbnail_' . $style_name] = array(
|
|
'name' => 'archive_thumbnail_' . $style_name,
|
|
'image_style' => $style_name,
|
|
'effects' => array(
|
|
array('label' => t('Thumbnail'), 'name' => 'thumbnail', 'data' => array('thumbnail' => 1)),
|
|
),
|
|
);
|
|
}
|
|
|
|
return $styles;
|
|
}
|
|
|
|
/**
|
|
* Implements hook_styles_presets().
|
|
*/
|
|
function media_archive_styles_presets() {
|
|
$presets = array(
|
|
'file' => array(
|
|
'square_thumbnail' => array(
|
|
'media_archive' => array(
|
|
'archive_thumbnail_square_thumbnail',
|
|
),
|
|
),
|
|
'thumbnail' => array(
|
|
'media_archive' => array(
|
|
'archive_thumbnail',
|
|
),
|
|
),
|
|
'small' => array(
|
|
'media_archive' => array(
|
|
'archive_preview',
|
|
),
|
|
),
|
|
'large' => array(
|
|
'media_archive' => array(
|
|
'archive_full',
|
|
),
|
|
),
|
|
'original' => array(
|
|
'media_archive' => array(
|
|
'archive_full',
|
|
),
|
|
),
|
|
),
|
|
);
|
|
return $presets;
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Implements hook_media_parse().
|
|
*
|
|
* @todo: this might be deprecated now that we have media_internet,
|
|
* but the hook is still being called in a couple places in media.
|
|
*/
|
|
function media_archive_media_parse($url, $options = array()) {
|
|
$scheme = 'archive://';
|
|
preg_match('@archive\.org/details/([^"\& ]+)@i', $url, $matches);
|
|
|
|
|
|
if (isset($matches[1])) {
|
|
$org = media_archive_embedcode_lookup($matches[1]);
|
|
return file_stream_wrapper_uri_normalize($scheme . 'v/' . $matches[1] . '/org/' . $org);
|
|
}
|
|
// @TODO: Validate for malformed archive urls.
|
|
}
|
|
|
|
/**
|
|
* Implements hook_media_internet_providers();
|
|
*/
|
|
function media_archive_media_internet_providers() {
|
|
$path = drupal_get_path('module', 'media_archive');
|
|
return array(
|
|
'MediaInternetArchiveHandler' => array(
|
|
'title' => 'archive',
|
|
'image' => $path . '/images/stream-archive.png'
|
|
),
|
|
);
|
|
}
|
|
|
|
class MediaInternetArchiveHandler extends MediaInternetBaseHandler {
|
|
public function claim($embedCode) {
|
|
if (media_archive_media_parse($embedCode)) {
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
public function validate() {
|
|
// @todo Media module currently fails when two files try to have the same
|
|
// URI, so catch that in the validation step. Some day, it would be nice
|
|
// to allow it, however. See http://drupal.org/node/952422.
|
|
$uri = media_archive_media_parse($this->embedCode);
|
|
$existing_files = file_load_multiple(array(), array('uri' => $uri));
|
|
if (count($existing_files)) {
|
|
throw new MediaInternetValidationException(t('You have entered a URL for a video that is already in your library.'));
|
|
}
|
|
}
|
|
|
|
public function save() {
|
|
$file = $this->getFileObject();
|
|
file_save($file);
|
|
return $file;
|
|
}
|
|
|
|
public function getFileObject() {
|
|
$uri = media_archive_media_parse($this->embedCode);
|
|
//@todo: this is terribly broken in some ways because the function is really
|
|
// made for local files which are 'real'
|
|
return file_uri_to_object($uri);
|
|
}
|
|
|
|
/**
|
|
* Returns information about the media. See http://video.search.yahoo.com/mrss.
|
|
*
|
|
* @return
|
|
* If ATOM+MRSS information is available, a SimpleXML element containing
|
|
* ATOM and MRSS elements, as per those respective specifications.
|
|
*
|
|
* @todo Would be better for the return value to be an array rather than a
|
|
* SimpleXML element, but media_retrieve_xml() needs to be upgraded to
|
|
* handle namespaces first.
|
|
*/
|
|
|
|
//http://archive.org/file/4035623?skin=rss
|
|
|
|
public function getMRSS() {
|
|
$uri = media_archive_media_parse($this->embedCode);
|
|
$video_id = arg(1, file_uri_target($uri));
|
|
$rss_url = url('http://gdata.archive.org/feeds/api/videos/' . $video_id, array('query' => array('v' => '2')));
|
|
// @todo Use media_retrieve_xml() once it's upgraded to include elements
|
|
// from all namespaces, not just the document default namespace.
|
|
$entry = simplexml_load_file($rss_url);
|
|
return $entry;
|
|
}
|
|
|
|
/**
|
|
* Returns information about the media. See http://www.oembed.com/.
|
|
*
|
|
* @return
|
|
* If oEmbed information is available, an array containing 'title', 'type',
|
|
* 'url', and other information as specified by the oEmbed standard.
|
|
* Otherwise, NULL.
|
|
*/
|
|
|
|
//http://archive.org/oembed/?url=http://archive.org/file/12345
|
|
|
|
public function getOEmbed() {
|
|
$uri = media_archive_media_parse($this->embedCode);
|
|
$external_url = drupal_realpath($uri);
|
|
$oembed_url = url('http://archive.org/oembed', array('query' => array('url' => $external_url, 'format' => 'json')));
|
|
$response = drupal_http_request($oembed_url);
|
|
if (!isset($response->error)) {
|
|
return drupal_json_decode($response->data);
|
|
}
|
|
}
|
|
}
|
|
|
|
function media_archive_embedcode_lookup($video_id) {
|
|
|
|
//http://www.archive.org/download/bavc-77620-dominotheory/bavc-77620-dominotheory_files.xml
|
|
|
|
//<original>Domino_Theory.mpeg</original>
|
|
|
|
// I hate this, but after reading http://data.agaric.com/node/2378 I'm
|
|
// begining to think there isn't an easier way
|
|
// if there isn't a better way, this needs to be done once and stored
|
|
$url = 'http://www.archive.org/download/' . $video_id . '/' . $video_id;
|
|
$rss_source = $url . '_files.xml';
|
|
$rss = file_get_contents($rss_source);
|
|
|
|
preg_match('/<original>(.+)<\/original>/', $rss, $matches);
|
|
|
|
if (isset($matches[1])) {
|
|
$info = pathinfo($matches[1]);
|
|
$file_name = basename($matches[1],'.'.$info['extension']);
|
|
return $file_name;
|
|
}
|
|
}
|