Commit 7d4b4c6c authored by jcnventura's avatar jcnventura

Add EPUB generation module.

parent ffcfdfa6
......@@ -59,6 +59,19 @@
* - @link print_pdf_wkhtmltopdf.admin.inc Settings form @endlink
* - @link print_pdf_wkhtmltopdf.install (Un)Install routines @endlink
* - @link print_pdf_wkhtmltopdf.drush.inc Drush commands @endlink
* - EPUB version
* - @link print_epub.api.php API @endlink
* - @link print_epub.module Module main file @endlink
* - @link print_epub.pages.inc EPUB generation @endlink
* - @link print_epub.admin.inc Settings form @endlink
* - @link print_epub.install (Un)Install routines @endlink
* - @link print_epub.drush.inc Drush commands @endlink
* - @link print_epub.views.inc Views integration @endlink
* - EPUB library handlers:
* - phpepub
* - @link print_epub_phpepub.module Module main file @endlink
* - @link print_epub_phpepub.pages.inc EPUB generation @endlink
* - @link print_epub_phpepub.drush.inc Drush commands @endlink
* - User Interface (Links)
* - @link print_ui.api.php API @endlink
* - @link print_ui.module Module main file @endlink
......
<?php
/**
* @file
* drush integration for print_epub_phpepub module EPUB libraries download.
*/
/**
* The EPUB project download URL
*/
// URI to the the latest PHPePub version.. Hardcoded version unfortunately
define('PHPEPUB_DOWNLOAD_URI', 'https://github.com/Grandt/PHPePub/tarball/2.04');
/**
* Implements hook_drush_command().
*/
function print_epub_phpepub_drush_epub_libs_alter(&$epub_libs) {
$epub_libs['phpepub'] = array(
'callback' => '_print_epub_phpepub_drush_download_url',
);
}
/**
* Discover the correct URL of the package to download.
*
* @return string
* URL of the file to download, FALSE if not known
*/
function _print_epub_phpepub_drush_download_url() {
return PHPEPUB_DOWNLOAD_URI;
}
name = "PHPePub library handler"
description = "EPUB generation library using PHPePub."
core=7.x
package = "Printer, email and PDF versions"
dependencies[] = print_epub
files[] = print_epub_phpepub.module
files[] = print_epub_phpepub.pages.inc
<?php
/**
* @file
* Generate a EPUB for the print_epub module using the PHPePub library.
*
* @ingroup print
*/
/**
* Implements hook_requirements().
*/
function print_epub_phpepub_requirements($phase) {
$requirements = array();
$t = get_t();
switch ($phase) {
// At runtime, make sure that a EPUB generation tool is selected
case 'runtime':
$print_epub_epub_tool = variable_get('print_epub_epub_tool', PRINT_EPUB_EPUB_TOOL_DEFAULT);
if (!empty($print_epub_epub_tool)) {
$tool = explode('|', $print_epub_epub_tool);
if (is_file($tool[1]) && is_readable($tool[1])) {
if (basename($tool[1]) == 'EPub.php') {
$version = _print_epub_phpepub_version($tool[1]);
$requirements['print_epub_tool_version'] = array(
'title' => $t('Printer, email and EPUB versions - EPUB generation library'),
'value' => $t('PHPePub') . ' ' . $version,
);
}
}
}
break;
}
return $requirements;
}
/**
* Find out the version of the PHPePub library
*
* @param string $epub_tool
* Filename of the tool to be analysed.
*
* @return string
* version number of the library
*/
function _print_epub_phpepub_version($epub_tool) {
require_once(DRUPAL_ROOT . '/' . $epub_tool);
return EPub::VERSION;
}
/**
* Implements hook_print_epub_available_libs_alter().
*/
function print_epub_phpepub_print_epub_available_libs_alter(&$epub_tools) {
$tools = _print_scan_libs('phpepub', '!^EPub.php$!');
foreach ($tools as $tool) {
$epub_tools['print_epub_phpepub|' . $tool] = 'PHPePub (' . dirname($tool) . ')';
}
}
<?php
/**
* @file
* Generates the EPUB version using PHPePub
*
* This file is included by the print_epub_phpepub module and includes the
* functions that interface with the PHPePub library
*
* @ingroup print
*/
/**
* Implements hook_print_epub_generate().
*/
function print_epub_phpepub_print_epub_generate($html, $meta, $filename = NULL) {
global $language, $base_url;
$epub_tool = explode('|', variable_get('print_epub_epub_tool', PRINT_EPUB_EPUB_TOOL_DEFAULT));
require_once(DRUPAL_ROOT . '/' . $epub_tool[1]);
// Try to use local file access for image files
$html = _print_epub_file_access_images($html);
// set document information
$epub = new EPub();
$epub->setTitle(html_entity_decode($meta['title'], ENT_QUOTES, 'UTF-8'));
$epub->setIdentifier($meta['url'], EPub::IDENTIFIER_URI);
$epub->setLanguage($language->language);
if (isset($meta['name'])) {
$epub->setAuthor(strip_tags($meta['name']), strip_tags($meta['name']));
}
$epub->setPublisher(variable_get('site_name', 'Drupal'), $base_url);
$epub->setSourceURL($meta['url']);
@$epub->addChapter("Chapter", "epub.html", $html, FALSE, EPub::EXTERNAL_REF_ADD);
$epub->finalize(); // Finalize the book, and build the archive.
// Close and output EPUB document
$epub->sendBook(empty($filename) ? 'page' : $filename);
return TRUE;
}
<?php
/**
* @file
* Contains the administrative functions of the EPUB version module.
*
* This file is included by the EPUB version module, and includes the
* settings form.
*
* @ingroup print
*/
/**
* Form constructor for the EPUB version module settings form.
*
* @ingroup forms
*/
function print_epub_settings() {
$epub_tools = array();
drupal_alter('print_epub_available_libs', $epub_tools);
if (!empty($epub_tools)) {
$link = print_epub_print_link();
$current_epub_tool = variable_get('print_epub_epub_tool', PRINT_EPUB_EPUB_TOOL_DEFAULT);
$epub_tool_default = array_key_exists($current_epub_tool, $epub_tools) ? $current_epub_tool : PRINT_EPUB_EPUB_TOOL_DEFAULT;
$form['settings'] = array(
'#type' => 'fieldset',
'#title' => t('EPUB options'),
);
$form['settings']['print_epub_epub_tool'] = array(
'#type' => 'radios',
'#title' => t('EPUB generation tool'),
'#options' => $epub_tools,
'#default_value' => $epub_tool_default,
'#description' => t('This option selects the EPUB generation tool being used by this module to create the EPUB version.'),
);
$form['settings']['print_epub_images_via_file'] = array(
'#type' => 'checkbox',
'#title' => t('Access images via local file access'),
'#default_value' => variable_get('print_epub_images_via_file', PRINT_EPUB_IMAGES_VIA_FILE_DEFAULT),
'#description' => t("Enabling this option will make the tool use local file access for image files. This option is not recommended to use in conjunction with modules like imagecache which generate the image after it's first accessed. However, it may be necessary in low-end hosting services where the web server is not allowed to open URLs and the user can't modify that configuration setting."),
);
$form['settings']['print_epub_filename'] = array(
'#type' => 'textfield',
'#title' => t('EPUB filename'),
'#default_value' => variable_get('print_epub_filename', PRINT_EPUB_FILENAME_DEFAULT),
'#description' => t("If left empty the generated filename defaults to the node's path. Tokens may be used to build the filename (see following list). The .epub extension will be appended automatically."),
);
if (module_exists('token')) {
$form['settings']['print_epub_filename_patterns'] = array(
'#type' => 'fieldset',
'#title' => t('Replacement patterns'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
);
$form['settings']['print_epub_filename_patterns']['descriptions'] = array(
'#theme' => 'token_tree',
'#token_types' => array('node'),
);
}
$form['settings']['print_epub_display_sys_urllist'] = array(
'#type' => 'checkbox',
'#title' => t('Printer-friendly URLs list in system pages'),
'#default_value' => variable_get('print_epub_display_sys_urllist', PRINT_TYPE_SYS_URLLIST_DEFAULT),
'#description' => t('Enabling this option will display a list of printer-friendly destination URLs at the bottom of the page.'),
);
$form['settings']['link_text'] = array(
'#type' => 'fieldset',
'#title' => t('Custom link text'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
);
$form['settings']['link_text']['print_epub_link_text_enabled'] = array(
'#type' => 'checkbox',
'#title' => t('Enable custom link text'),
'#default_value' => variable_get('print_epub_link_text_enabled', PRINT_TYPE_LINK_TEXT_ENABLED_DEFAULT),
);
$form['settings']['link_text']['print_epub_link_text'] = array(
'#type' => 'textfield',
'#default_value' => variable_get('print_epub_link_text', $link['text']),
'#description' => t('Text used in the link to the EPUB version.'),
);
$form['#validate'][] = '_print_epub_settings_validate';
}
else {
variable_set('print_epub_epub_tool', PRINT_EPUB_EPUB_TOOL_DEFAULT);
$form['settings'] = array(
'#type' => 'markup',
'#markup' => '<p>' . t("No EPUB generation tool found! Please dowload a supported PHP EPUB generation tool. Check this module's INSTALL.txt for more details.") . '</p>',
);
}
return system_settings_form($form);
}
/**
* Form validation handler for print_epub_settings().
*
* @see print_epub_settings()
* @ingroup forms
*/
function _print_epub_settings_validate($form, &$form_state) {
if (empty($form_state['values']['print_epub_epub_tool'])) {
form_set_error('print_epub_epub_tool', t("No EPUB tool selected"));
}
}
<?php
/**
* @file
* Hooks provided by the EPUB version module.
*/
/**
* @addtogroup hooks
* @{
*/
/**
* Generate a EPUB version of the provided HTML.
*
* @param string $html
* HTML content of the EPUB
* @param array $meta
* Meta information to be used in the EPUB
* - url: original URL
* - name: author's name
* - title: Page title
* - node: node object
* @param string $filename
* (optional) Filename of the generated EPUB
*
* @return
* generated EPUB page, or NULL in case of error
*
* @see print_epub_controller_html()
* @ingroup print_hooks
*/
function hook_print_epub_generate($html, $meta, $filename = NULL) {
$epub = new EPUB();
$epub->writeHTML($html);
if ($filename) {
$epub->Output($filename);
return TRUE;
}
else {
return $epub->Output();
}
}
/**
* Alters the list of available EPUB libraries.
*
* During the configuration of the EPUB library to be used, the module needs
* to discover and display the available libraries. This function should use
* the internal _print_scan_libs() function which will scan both the module
* and the libraries directory in search of the unique file pattern that can
* be used to identify the library location.
*
* @param array $epub_tools
* An associative array using as key the format 'module|path', and as value
* a string describing the discovered library, where:
* - module: the machine name of the module that handles this library.
* - path: the path where the library is installed, relative to DRUPAL_ROOT.
* If the recommended path is used, it begins with sites/all/libraries.
* As a recommendation, the value should contain in parantheses the path
* where the library was found, to allow the user to distinguish between
* multiple install paths of the same library version.
*
* @ingroup print_hooks
*/
function hook_print_epub_available_libs_alter(&$epub_tools) {
$tools = _print_scan_libs('foo', '!^foo.php$!');
foreach ($tools as $tool) {
$epub_tools['print_epub_foo|' . $tool] = 'foo (' . dirname($tool) . ')';
}
}
/**
* Alters the EPUB filename.
*
* Changes the value of the EPUB filename variable, just before it is used to
* create the file. When altering the variable, do not suffix it with the
* '.epub' extension, as the module will do that automatically.
*
* @param string $epub_filename
* current value of the epub_filename variable, after processing tokens and
* any transliteration steps.
* @param string $path
* original alias/system path of the page being converted to EPUB.
*
* @ingroup print_hooks
*/
function hook_print_epub_filename_alter(&$epub_filename, &$path) {
$epub_filename = 'foo';
}
/**
* @} End of "addtogroup hooks".
*/
<?php
/**
* @file
* drush integration for print_epub module EPUB libraries download.
*/
/**
* Implements hook_drush_command().
*/
function print_epub_drush_command() {
$items = array();
$epub_libs = array();
drush_command_invoke_all_ref('drush_epub_libs_alter', $epub_libs);
$items['print-epub-download'] = array(
'description' => 'Download and extract a EPUB library.',
'arguments' => array(
'library' => dt('The EPUB library to download. Available choices: !libs.', array('!libs' => implode(', ', array_keys($epub_libs)))),
),
'options' => array(
'path' => dt('A path to the download folder. If omitted Drush will use the default location (@path).', array('@path' => 'sites/all/libraries')),
),
'aliases' => array('epubdl'),
'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_ROOT, // No site or config needed.
);
return $items;
}
/**
* Implements of drush_hook_COMMAND_validate().
*/
function drush_print_epub_download_validate($library = NULL) {
if (is_null($library)) {
$epub_libs = array();
drush_command_invoke_all_ref('drush_epub_libs_alter', $epub_libs);
drush_set_error('DRUSH_EPUBDL_MISSING_ARG', dt("Usage: drush !cmd <library>\nWhere <library> is one of the following: !libs\n\nTry 'drush !cmd --help' for more information.", array('!cmd' => 'print-epub-download', '!libs' => implode(', ', array_keys($epub_libs)))));
}
}
/**
* Download and extract EPUB archive.
*
* @param string $library
* library to download
*/
function drush_print_epub_download($library) {
$epub_libs = array();
drush_command_invoke_all_ref('drush_epub_libs_alter', $epub_libs);
if (isset($library) && isset($epub_libs[drupal_strtolower($library)])) {
$func = $epub_libs[drupal_strtolower($library)]['callback'];
$download_url = $func();
if ($download_url) {
$path = drush_get_option('path');
if (empty($path)) {
$path = drush_get_context('DRUSH_DRUPAL_ROOT') . '/sites/all/libraries';
}
// Create the path if it does not exist.
if (!is_dir($path)) {
drush_op('mkdir', $path);
drush_log(dt('Directory @path was created', array('@path' => $path)), 'notice');
}
// Chdir to the download location.
$olddir = getcwd();
drush_op('chdir', $path);
// Warn about an existing dir
if (is_dir($library)) {
// drush_op('rmdir', $library); // Directory must be empty for the php rmdir to work..
drush_log(dt('An existing @library was overwritten at @path', array('@library' => $library, '@path' => $path . '/' . $library)), 'notice');
}
// Download the archive
$filename = _print_epub_drush_download_file($download_url);
if ($filename) {
$extract_ret = _print_epub_drush_download_extract($filename);
if ($extract_ret) {
// Remove the archive
drush_op('unlink', $filename);
drush_log(dt('@file has been downloaded and extracted in @path', array('@file' => $filename, '@path' => $path)), 'success');
}
else {
drush_log(dt('@file has been downloaded to @path, but extract failed. Check that you have the necessary program installed, and if necessary extract it manually.',
array('@file' => $filename, '@path' => $path)), 'warning');
}
}
else {
drush_log(dt('Drush was unable to download @library to @path', array('@library' => $library, '@path' => $path)), 'error');
}
// Set working directory back to the previous working directory.
drush_op('chdir', $olddir);
}
}
else {
drush_log(dt('Please specify a EPUB library. Available choices: !libs.', array('!libs' => implode(', ', array_keys($epub_libs)))), 'error');
}
}
/**
* Download a file using wget or curl
*
* Adapted from a function in drush/includes/drush.inc to support 302 redirects.
*
* @param string $download_url
* The path to the file to download
*
* @return string
* The filename that was downloaded, or NULL if the file could not be
* downloaded.
*/
function _print_epub_drush_download_file($download_url) {
$wget_ret = drush_shell_exec("wget -nv --trust-server-names %s", $download_url);
if (!drush_get_context('DRUSH_SIMULATE')) {
if ($wget_ret) {
// Get the filename of the saved file from the output
$wget_out = explode('"', array_shift(drush_shell_exec_output()));
$filename = $wget_out[1];
}
else {
$tempnam = uniqid('print_epub_drush_');
$curl_ret = drush_shell_exec("curl -s -L -o %s %s -w '%%{url_effective}'", $tempnam, $download_url);
if ($curl_ret) {
// File was donwloaded with the tempname
// Find the effective name
$filename = explode('/', array_shift(drush_shell_exec_output()));
$filename = array_pop($filename);
// Rename file from tempname to effective name
if (!drush_op('rename', $tempnam, './' . $filename)) {
$filename = $tempnam;
}
}
else {
$filename = FALSE;
}
}
}
else {
$filename = basename($download_url);
}
return $filename;
}
/**
* Helper to extract the downloaded zip/tar archive.
*
* @param string $filename
* filename of the file to extract
*
* @return bool
* TRUE on success, FALSE on failure
*/
function _print_epub_drush_download_extract($filename) {
$arch_ret = FALSE;
if (drush_op('is_file', $filename)) {
switch (drush_op('mime_content_type', $filename)) {
case 1:
$arch_ret = TRUE;
break;
case 'application/zip':
// Decompress the zip archive
$arch_ret = drush_shell_exec('unzip -qq -o ' . $filename);
// ZIP archives usually get the access rights wrong
drush_log(dt('@filename is a Zip file. Check the access permissions of the extracted files.', array('@filename' => $filename)), 'warning');
break;
case 'application/x-gzip':
// Decompress the tar gz archive
$arch_ret = drush_shell_exec('tar xzf ' . $filename);
break;
case 'application/x-bzip2':
// Decompress the tar bz2 archive
$arch_ret = drush_shell_exec('tar xjf ' . $filename);
break;
}
}
else {
drush_log(dt('@filename not found.', array('@filename' => $filename)), 'error');
}
return $arch_ret;
}
name = "EPUB version"
description = "Adds the capability to export pages as EPUB."
core=7.x
package = "Printer, email and PDF versions"
dependencies[] = print
files[] = print_epub.module
files[] = print_epub.admin.inc
files[] = print_epub.pages.inc
files[] = print_epub.install
files[] = print_epub.views.inc
configure = admin/config/user-interface/print/epub
<?php
/**
* @file
* Install, update and uninstall functions for the print_epub module.
*
* @ingroup print
*/
/**
* Implements hook_enable().
*/
function print_epub_enable() {
$t = get_t();
// Module weight
db_update('system')
->fields(array(
'weight' => 3,
))
->condition('type', 'module')
->condition('name', 'print_epub')
->execute();
}
/**
* Implements hook_uninstall().
*/
function print_epub_uninstall() {
variable_del('print_epub_display_sys_urllist');
variable_del('print_epub_filename');
variable_del('print_epub_images_via_file');
variable_del('print_epub_link_text');
variable_del('print_epub_link_text_enabled');
variable_del('print_epub_epub_tool');
variable_del('print_epub_book_link');
variable_del('print_epub_link_class');
variable_del('print_epub_link_pos');
variable_del('print_epub_link_teaser');
variable_del('print_epub_link_use_alias');
variable_del('print_epub_show_link');
variable_del('print_epub_sys_link_pages');
variable_del('print_epub_sys_link_visibility');
$settings = db_query("SELECT name FROM {variable} WHERE name LIKE 'print\_epub\_display\_%'");
foreach ($settings as $variable) {
variable_del($variable->name);
}
}
/**
* Implements hook_schema().
*/
function print_epub_schema() {
$schema['print_epub_node_conf'] = array(
'description' => 'EPUB version node-specific configuration settings',
'fields' => array(
'nid' => array(
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'description' => 'The {node}.nid of the node.',
),
'link' => array(
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 1,
'size' => 'tiny',
'description' => 'Show link',
),
'comments' => array(
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 1,
'size' => 'tiny',
'description' => 'Show link in individual comments',
),
'url_list' => array(
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 1,
'size' => 'tiny',
'description' => 'Show Printer-friendly URLs list',
),
),
'primary key' => array('nid'),
);
$schema['print_epub_page_counter'] = array(
'description' => 'EPUB version access counter',
'fields' => array(
'path' => array(
'type' => 'varchar',
'length' => 128,
'not null' => TRUE,
'description' => 'Page path',
),
'totalcount' => array(
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
'size' => 'big',
'description' => 'Number of page accesses',
),
'timestamp' => array(
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
'description' => 'Last access',
),
),
'primary key' => array('path'),
);
return $schema;
}
/**
* Remove hardcoded numeric deltas from all blocks
*/
function print_epub_update_7000(&$sandbox) {
$renamed_deltas = array(
'print_epub' => array(
'0' => 'print_epub-top',
),
);