<?php
// $Id: file_slideshow.module,v 1.20 2009/10/26 20:38:35 miglius Exp $

/**
 * @file
 * Supports slideshow and presentation file formats.
 */

//////////////////////////////////////////////////////////////////////////////

define('FILE_SLIDESHOW_PDF', variable_get('file_slideshow_pdf', 1));

//////////////////////////////////////////////////////////////////////////////
// Core API hooks

/**
 * Implementation of hook_theme().
 */
function file_slideshow_theme() {
  return array(
    'file_slideshow_admin_settings' => array(
      'arguments' => array('form' => NULL),
      'file' => 'file_slideshow.theme.inc'
    ),
  );
}

/**
 * Implementation of hook_menu().
 */
function file_slideshow_menu() {
  return array(
    'admin/settings/file/format/slideshow' => array(
      'title' => 'Slideshow',
      'description' => 'Manage the slideshow files.',
      'page callback' => 'drupal_get_form',
      'page arguments' => array('file_slideshow_admin_settings'),
      'access arguments' => array('administer site configuration'),
      'file' => 'file_slideshow.admin.inc',
    ),
  );
}

//////////////////////////////////////////////////////////////////////////////
// File API hooks

/**
 * Implementation of hook_mime_handlers().
 */
function file_slideshow_mime_handlers() {
  return array(
    'file_slideshow_pdf' => array(
      'name' => t('PDF'),
    ),
  );
}

/**
 * Implementation of hook_mime_types().
 */
function file_slideshow_mime_types() {
  return array(
    'application/pdf' => array(
      'name' => t('PDF document'),
      'icon' => 'acrobat.gif',
    ),
    'application/postscript' => array(
      'name' => t('PostScript document'),
      'icon' => 'ps.gif',
    ),
    'application/vnd.oasis.opendocument.presentation' => array(
      'name' => t('OpenDocument Presentation'),
      'icon' => 'oo-draw.gif',
    ),
    'application/vnd.ms-powerpoint' => array(
      'name' => t('PowerPoint presentation'),
      'icon' => 'powerpoint.gif',
    ),
    'application/vnd.openxmlformats-officedocument.presentationml.presentation' => array(
      'name' => t('PowerPoint presentation'),
      'icon' => 'powerpoint.gif',
    ),
  );
}

/**
 * Implementation of hook_mime_converters().
 */
function file_slideshow_mime_converters() {
  return array(
    'application/postscript' => array(
      'text/plain' => array(
        'pipeline' => '{pstotext} -output "[out_file]" "[in_file]"',
        'handlers' => array('file_text_text'),
      ),
    ),
    'application/pdf' => array(
      'text/plain' => array(
        'pipeline' => '{pdftotext} "[in_file]" "[out_file]"',
        'handlers' => array('file_text_text'),
      ),
      'image/jpeg' => array(
        'pipeline' => '{gs} -q -sDEVICE=jpeg -dBATCH -dNOPAUSE -dFirstPage=1 -dLastPage=1 -r300 -sOutputFile="[out_file]" "[in_file]"',
        //'pipeline' => '{mv} "[in_file]" "[in_file].pdf"; {convert} "[in_file].pdf"\[0\] "[out_file].jpeg"; {mv} "[in_file].pdf" "[in_file]"; {mv} "[out_file].jpeg" "[out_file]"',
        'handlers' => array('file_image_image'),
      ),
      'application/x-shockwave-flash' => array(
        'pipeline' => 'cd "[tmpdir]"; {pdf2swf} -lb "[in_file_base]" "[out_file_base]"',
        'handlers' => array('file_video_flash_swf'),
      ),
      'application/zip' => array(
        'pipeline' => 'pwd="`{pwd}`"; {mkdir} "[in_file].tmp"; {mv} "[in_file]" "[in_file].tmp/[filename]"; cd "[in_file].tmp"; {gzip} -c "[filename]" > "file.zip"; cd "$pwd"; mv "[in_file].tmp/file.zip" "[out_file]"; {touch} "[in_file]"; {rm} -rf "[in_file].tmp"',
      ),
    ),
    'application/vnd.oasis.opendocument.presentation' => array(
      'application/pdf' => array(
        'pipeline' => '{localhost:8100}{mv} "[in_file]" "[in_file].odp"; {java} -jar {{/opt/jodconverter/lib/jodconverter-cli.jar}} -f pdf "[in_file].odp"; {mv} "[in_file].odp" "[in_file]"; {mv} "[in_file].pdf" "[out_file]"',
        'handlers' => array('file_slideshow_pdf'),
      ),
      'application/vnd.ms-powerpoint' => array(
        'pipeline' => '{localhost:8100}{mv} "[in_file]" "[in_file].odp"; {java} -jar {{/opt/jodconverter/lib/jodconverter-cli.jar}} -f ppt "[in_file].odp"; {mv} "[in_file].odp" "[in_file]"; {mv} "[in_file].ppt" "[out_file]"',
      ),
      'application/zip' => array(
        'pipeline' => 'pwd="`{pwd}`"; {mkdir} "[in_file].tmp"; {mv} "[in_file]" "[in_file].tmp/[filename]"; cd "[in_file].tmp"; {gzip} -c "[filename]" > "file.zip"; cd "$pwd"; mv "[in_file].tmp/file.zip" "[out_file]"; {touch} "[in_file]"; {rm} -rf "[in_file].tmp"',
      ),
    ),
    'application/vnd.ms-powerpoint' => array(
      'application/pdf' => array(
        'pipeline' => '{localhost:8100}{mv} "[in_file]" "[in_file].ppt"; {java} -jar {{/opt/jodconverter/lib/jodconverter-cli.jar}} -f pdf "[in_file].ppt"; {mv} "[in_file].ppt" "[in_file]"; {mv} "[in_file].pdf" "[out_file]"',
        'handlers' => array('file_slideshow_pdf'),
      ),
      'application/vnd.oasis.opendocument.presentation' => array(
        'pipeline' => '{localhost:8100}{mv} "[in_file]" "[in_file].ppt"; {java} -jar {{/opt/jodconverter/lib/jodconverter-cli.jar}} -f odp "[in_file].ppt"; {mv} "[in_file].ppt" "[in_file]"; {mv} "[in_file].odp" "[out_file]"',
      ),
      'application/zip' => array(
        'pipeline' => 'pwd="`{pwd}`"; {mkdir} "[in_file].tmp"; {mv} "[in_file]" "[in_file].tmp/[filename]"; cd "[in_file].tmp"; {gzip} -c "[filename]" > "file.zip"; cd "$pwd"; mv "[in_file].tmp/file.zip" "[out_file]"; {touch} "[in_file]"; {rm} -rf "[in_file].tmp"',
      ),
    ),
    'application/vnd.openxmlformats-officedocument.presentationml.presentation' => array(
      'application/pdf' => array(
        'pipeline' => '{localhost:8100}{mv} "[in_file]" "[in_file].pptx"; {java} -jar {{/opt/jodconverter/lib/jodconverter-cli.jar}} -f pdf "[in_file].pptx"; {mv} "[in_file].pptx" "[in_file]"; {mv} "[in_file].pdf" "[out_file]"',
        'handlers' => array('file_slideshow_pdf'),
      ),
      'application/vnd.oasis.opendocument.presentation' => array(
        'pipeline' => '{localhost:8100}{mv} "[in_file]" "[in_file].pptx"; {java} -jar {{/opt/jodconverter/lib/jodconverter-cli.jar}} -f odp "[in_file].pptx"; {mv} "[in_file].pptx" "[in_file]"; {mv} "[in_file].odp" "[out_file]"',
      ),
      'application/vnd.ms-powerpoint' => array(
        'pipeline' => '{localhost:8100}{mv} "[in_file]" "[in_file].pptx"; {java} -jar {{/opt/jodconverter/lib/jodconverter-cli.jar}} -f ppt "[in_file].pptx"; {mv} "[in_file].pptx" "[in_file]"; {mv} "[in_file].ppt" "[out_file]"',
      ),
      'application/zip' => array(
        'pipeline' => 'pwd="`{pwd}`"; {mkdir} "[in_file].tmp"; {mv} "[in_file]" "[in_file].tmp/[filename]"; cd "[in_file].tmp"; {gzip} -c "[filename]" > "file.zip"; cd "$pwd"; mv "[in_file].tmp/file.zip" "[out_file]"; {touch} "[in_file]"; {rm} -rf "[in_file].tmp"',
      ),
    ),
  );
}

/**
 * Implementation of hook_metadata_info().
 */
function file_slideshow_metadata_info() {
  $info = array();
  foreach (_file_slideshow_pdf() as $name => $data) {
    $info[$data['rdf']] = array('name' => t($data['name']));
    if (isset($data['theme']))
      $info[$data['rdf']]['theme'] = $data['theme'];
  }
  return $info;
}

/**
 * Implementation of hook_metadata_parse().
 */
function file_slideshow_metadata_parse($filename, $mimetype) {
  if ($mimetype != 'application/pdf')
    return NULL;

  if (!($pdfinfo = _file_command_exists('pdfinfo')))
    return NULL;

  $metadata = array();

  $pdf = _file_slideshow_pdf();
  foreach ($pdf as $name => $data) {
    $pdf_data_default[$name] = $data['default'];
  }
  $pdf_data = variable_get('file_slideshow_pdf_data', $pdf_data_default);

  if (_file_command_run('pdfinfo '. escapeshellarg($filename), $pipes) === 0 && !empty($pipes['stdout'])) {
    $info = array();
    foreach (explode("\n", $pipes['stdout']) as $line) {
      if (preg_match('/^([^:]+):(.*)$/', $line, $matches))
        $info[trim($matches[1])] = trim($matches[2]);
    }

    $rdf_pdf = array();
    foreach ($pdf as $name => $data) {
      if (isset($pdf_data[$name]) && $element = file_get_recursive($info, $data['pdf'])) {
        switch ($data['type']) {
          case 'int' :
            $rdf_pdf[$data['rdf']] = array((int)$element);
            break;
          default :
            $rdf_pdf[$data['rdf']] = array($element);
            break;
        }
      }
    }
    $metadata =  array_merge($rdf_pdf, $metadata);
  }

  return $metadata;
}

//////////////////////////////////////////////////////////////////////////////
// MIME handlers

/**
 * Generates a slideshow_pdf preview.
 */
function file_slideshow_pdf_generate($file, $tier = NULL) {
  if (isset($tier) && !in_array($file->handlers[$tier], isset($file->previews[$file->mimes[$tier]]) ? $file->previews[$file->mimes[$tier]] : array())) {
    if (!file_get_converted($file, $tier))
      return FALSE;
    if (!file_data_save($file, $tier))
      return FALSE;
    watchdog('file_slideshow', 'The %mime preview was generated for the file %name, uri=%uri.', array('%mime' => $file->mimes[$tier], '%name' => $file->filename, '%uri' => $file->uri), WATCHDOG_NOTICE, isset($file->nid) ? l(t('view'), 'node/'. $file->nid) : NULL);
  }

  // Create a plain text, image and swf previews.
  $previews = array(
    'file_text_text' => 'text/plain',
    'file_image_image' => 'image/jpeg',
    'file_video_flash_swf' => 'application/x-shockwave-flash',
  );

  $result = TRUE;
  $tier = isset($tier) ? $tier + 1 : 0;
  foreach ($previews as $handler => $to) {
    $file->handlers[$tier] = $handler;
    $file->mimes[$tier] = $to;
    $result = file_generate_secondary_previews($file, $tier) && $result;
  }
  return $result;
}

//////////////////////////////////////////////////////////////////////////////
// RDF API hooks

/**
 * Implementation of hook_rdf_namespaces().
 */
function file_slideshow_rdf_namespaces() {
  return array(
//    'wordnet' => 'http://xmlns.com/wordnet/1.6/',
  );
}

//////////////////////////////////////////////////////////////////////////////
// PDF info settings

/**
 * PDF info to RDF mapping.
 */
function _file_slideshow_pdf() {
  return array(
    'title'        => array('name' => 'Title',         'pdf' => array('Title' => NULL),        'rdf' => 'wordnet:title',         'type' => '',    'default' => 1),
    'subject'      => array('name' => 'Subject',       'pdf' => array('Subject' => NULL),      'rdf' => 'wordnet:subject',       'type' => '',    'default' => 1),
    'author'       => array('name' => 'Author',        'pdf' => array('Author' => NULL),       'rdf' => 'wordnet:author',        'type' => '',    'default' => 1),
    'creator'      => array('name' => 'Creator',       'pdf' => array('Creator' => NULL),      'rdf' => 'wordnet:creator',       'type' => '',    'default' => 1),
    'producer'     => array('name' => 'Producer',      'pdf' => array('Producer' => NULL),     'rdf' => 'wordnet:producer',      'type' => '',    'default' => 1),
    'creationdate' => array('name' => 'Creation Date', 'pdf' => array('CreationDate' => NULL), 'rdf' => 'wordnet:creation_date', 'type' => '',    'default' => 1),
    'moddate'      => array('name' => 'Modify Date',   'pdf' => array('ModDate' => NULL),      'rdf' => 'wordnet:mod_date',      'type' => '',    'default' => 1),
    'tagged'       => array('name' => 'Tagged',        'pdf' => array('Tagged' => NULL),       'rdf' => 'wordnet:tagged',        'type' => '',    'default' => 1),
    'pages'        => array('name' => 'Pages',         'pdf' => array('Pages' => NULL),        'rdf' => 'wordnet:pages',         'type' => 'int', 'default' => 1),
    'encrypted'    => array('name' => 'Encrypted',     'pdf' => array('Encrypted' => NULL),    'rdf' => 'wordnet:encrypted',     'type' => '',    'default' => 1),
    'pagesize'     => array('name' => 'Page size',     'pdf' => array('Page size' => NULL),    'rdf' => 'wordnet:page_size',     'type' => '',    'default' => 1),
    'filesize'     => array('name' => 'File size',     'pdf' => array('File size' => NULL),    'rdf' => 'wordnet:file_size',     'type' => '',    'default' => 1),
    'optimized'    => array('name' => 'Optimized',     'pdf' => array('Optimized' => NULL),    'rdf' => 'wordnet:optimized',     'type' => '',    'default' => 1),
    'pdfversion'   => array('name' => 'PDF version',   'pdf' => array('PDF version' => NULL),  'rdf' => 'wordnet:pdf_version',   'type' => '',    'default' => 1),
  );
}

