mirror of
https://github.com/Yetangitu/owncloud-apps.git
synced 2025-10-02 14:49:17 +02:00
files_opds v0.5.9: add calibre metadata and cover support, add new dist file
This commit is contained in:
parent
372d10af7b
commit
ede5449eec
7 changed files with 143 additions and 11 deletions
BIN
dist/files_opds-0.5.9.tar.gz
vendored
Normal file
BIN
dist/files_opds-0.5.9.tar.gz
vendored
Normal file
Binary file not shown.
|
@ -106,6 +106,15 @@
|
||||||
<length>1024</length>
|
<length>1024</length>
|
||||||
</field>
|
</field>
|
||||||
|
|
||||||
|
<field>
|
||||||
|
<!-- cover -->
|
||||||
|
<name>cover</name>
|
||||||
|
<type>text</type>
|
||||||
|
<default></default>
|
||||||
|
<notnull>false</notnull>
|
||||||
|
<length>512</length>
|
||||||
|
</field>
|
||||||
|
|
||||||
<field>
|
<field>
|
||||||
<!-- rescan (rescan if passed) -->
|
<!-- rescan (rescan if passed) -->
|
||||||
<name>rescan</name>
|
<name>rescan</name>
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<name>OPDS catalog</name>
|
<name>OPDS catalog</name>
|
||||||
<description>Personal OPDS catalog</description>
|
<description>Personal OPDS catalog</description>
|
||||||
<licence>AGPL</licence>
|
<licence>AGPL</licence>
|
||||||
<version>0.5.5</version>
|
<version>0.5.9</version>
|
||||||
<author>Frank de Lange</author>
|
<author>Frank de Lange</author>
|
||||||
<requiremin>7.0</requiremin>
|
<requiremin>7.0</requiremin>
|
||||||
<shipped>true</shipped>
|
<shipped>true</shipped>
|
||||||
|
|
91
files_opds/lib/calibre.php
Normal file
91
files_opds/lib/calibre.php
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ownCloud - Files_Opds App
|
||||||
|
*
|
||||||
|
* @author Frank de Lange
|
||||||
|
* @copyright 2014 Frank de Lange
|
||||||
|
*
|
||||||
|
* This file is licensed under the Affero General Public License version 3 or
|
||||||
|
* later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace OCA\Files_Opds;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calibre metadata class for OPDS
|
||||||
|
*/
|
||||||
|
class Calibre
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @brief get Calibre-generated metadata
|
||||||
|
*
|
||||||
|
* @param string $path path to file
|
||||||
|
* @param arrayref $meta reference to array of metadata
|
||||||
|
* @return bool true if metadata found
|
||||||
|
*/
|
||||||
|
public static function get($path,&$meta) {
|
||||||
|
$dir = pathinfo($path)['dirname'];
|
||||||
|
$opf = $dir . '/metadata.opf';
|
||||||
|
if ((file_exists($opf)) && ($package = simplexml_load_file($opf))) {
|
||||||
|
$package->registerXPathNamespace('o', "http://www.idpf.org/2007/opf");
|
||||||
|
if(($cover = $package->xpath('//o:reference[@type="cover"]/@href')[0]) && (file_exists($dir . '/' . $cover))) {
|
||||||
|
$meta['cover'] = $cover;
|
||||||
|
}
|
||||||
|
return self::parse($package->metadata->children('dc', true),$meta);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief parse Calibre metadata.opf into OPDS $meta array
|
||||||
|
*
|
||||||
|
* @param SimpleXMLElement $data SimpleXMLElement object containing DC/OPF metadata
|
||||||
|
* @param arrayref &$meta
|
||||||
|
* @return bool true if metadata is valid
|
||||||
|
*/
|
||||||
|
static function parse($data,&$meta) {
|
||||||
|
foreach ($data as $key => $value) {
|
||||||
|
switch ($key) {
|
||||||
|
case 'title':
|
||||||
|
$meta['title'] = strip_tags($value);
|
||||||
|
break;
|
||||||
|
case 'creator':
|
||||||
|
if(!($author = json_decode($meta['author'],true))) {
|
||||||
|
$author = array();
|
||||||
|
}
|
||||||
|
$fileAs = $value->attributes('opf',true)->{'file-as'};
|
||||||
|
$author[(string) $fileAs] = strip_tags($value);
|
||||||
|
$meta['author'] = json_encode($author);
|
||||||
|
break;
|
||||||
|
case 'description':
|
||||||
|
$meta['description'] = strip_tags($value);
|
||||||
|
break;
|
||||||
|
case 'publisher':
|
||||||
|
$meta['publisher'] = strip_tags($value);
|
||||||
|
break;
|
||||||
|
case 'identifier':
|
||||||
|
if('ISBN' == $value->attributes('opf',true)->scheme) {
|
||||||
|
$meta['isbn'] = strip_tags($value);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'subject':
|
||||||
|
if(!($subject = json_decode($meta['subjects'],true))) {
|
||||||
|
$subject = array();
|
||||||
|
}
|
||||||
|
array_push($subject,strip_tags($value));
|
||||||
|
$meta['subjects'] = json_encode($subject);
|
||||||
|
break;
|
||||||
|
case 'date':
|
||||||
|
$meta['date'] = strip_tags($value);
|
||||||
|
break;
|
||||||
|
case 'language':
|
||||||
|
$meta['language'] = strip_tags($value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Meta::isValid($meta);
|
||||||
|
}
|
||||||
|
}
|
|
@ -83,6 +83,14 @@ class Feed
|
||||||
\OCP\User::checkLoggedIn();
|
\OCP\User::checkLoggedIn();
|
||||||
\OC::$session->close();
|
\OC::$session->close();
|
||||||
$i = \OC\Files\Filesystem::getFileInfo($path,false);
|
$i = \OC\Files\Filesystem::getFileInfo($path,false);
|
||||||
|
|
||||||
|
/* check for predefined cover, if found replace $path with that of cover file */
|
||||||
|
$meta = Meta::get($i['fileid']);
|
||||||
|
if($meta['cover']) {
|
||||||
|
$path = pathinfo($path)['dirname'] .'/' . $meta['cover'];
|
||||||
|
$i = \OC\Files\Filesystem::getFileInfo($path,false);
|
||||||
|
}
|
||||||
|
|
||||||
if (\OC::$server->getPreviewManager()->isMimeSupported($i['mimetype'])) {
|
if (\OC::$server->getPreviewManager()->isMimeSupported($i['mimetype'])) {
|
||||||
$preview = new \OC\Preview(\OC_User::getUser(), 'files');
|
$preview = new \OC\Preview(\OC_User::getUser(), 'files');
|
||||||
$preview->setFile($path);
|
$preview->setFile($path);
|
||||||
|
|
|
@ -46,10 +46,15 @@ class Files extends \OCA\Files\Helper
|
||||||
$files = array();
|
$files = array();
|
||||||
/* if set, add only files with given extensions */
|
/* if set, add only files with given extensions */
|
||||||
$fileTypes = array_filter(explode(',', strtolower(Config::get('file_types', ''))));
|
$fileTypes = array_filter(explode(',', strtolower(Config::get('file_types', ''))));
|
||||||
|
$skipList = array_filter(explode(',', strtolower(Config::get('skip_list', 'metadata.opf,cover.jpg'))));
|
||||||
foreach ($fileInfos as $i) {
|
foreach ($fileInfos as $i) {
|
||||||
if((!empty($fileTypes)) && (!in_array(strtolower(substr(strrchr($i->getName(), "."), 1)), $fileTypes))) {
|
if((!empty($fileTypes)) && (!in_array(strtolower(substr(strrchr($i->getName(), "."), 1)), $fileTypes))) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if((!empty($skipList)) && (in_array($i->getName(),$skipList))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
$files[] = self::formatFileInfo($i);
|
$files[] = self::formatFileInfo($i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,11 +40,22 @@ class Meta
|
||||||
$meta['copyright'] = '';
|
$meta['copyright'] = '';
|
||||||
$meta['description'] = '';
|
$meta['description'] = '';
|
||||||
$meta['subjects'] = '';
|
$meta['subjects'] = '';
|
||||||
|
$meta['cover'] = null;
|
||||||
$meta['rescan'] = null;
|
$meta['rescan'] = null;
|
||||||
|
|
||||||
return $meta;
|
return $meta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief check whether metadata is valid (ie. title, author and language are defined)
|
||||||
|
*
|
||||||
|
* @param array $meta metadata
|
||||||
|
* @return bool true if valid
|
||||||
|
*/
|
||||||
|
public static function isValid($meta) {
|
||||||
|
return (!(empty($meta['title']) || empty($meta['author']) || empty($meta['language'])));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief load metadata from database
|
* @brief load metadata from database
|
||||||
*
|
*
|
||||||
|
@ -72,7 +83,7 @@ class Meta
|
||||||
$result = $query->execute($args);
|
$result = $query->execute($args);
|
||||||
$data = $result->fetchRow();
|
$data = $result->fetchRow();
|
||||||
if (isset($data['id'])) {
|
if (isset($data['id'])) {
|
||||||
$sql = "UPDATE *PREFIX*opds_metadata SET `updated`=?, `date`=?, `author`=?, `title`=?, `language`=?, `publisher`=?, `isbn`=?, `copyright`=?, `description`=?, `subjects`=?, `rescan`=? WHERE id=?";
|
$sql = "UPDATE *PREFIX*opds_metadata SET `updated`=?, `date`=?, `author`=?, `title`=?, `language`=?, `publisher`=?, `isbn`=?, `copyright`=?, `description`=?, `subjects`=?, `cover`=?, `rescan`=? WHERE id=?";
|
||||||
$args = array(
|
$args = array(
|
||||||
$meta['updated'],
|
$meta['updated'],
|
||||||
$meta['date'],
|
$meta['date'],
|
||||||
|
@ -84,12 +95,13 @@ class Meta
|
||||||
$meta['copyright'],
|
$meta['copyright'],
|
||||||
$meta['description'],
|
$meta['description'],
|
||||||
$meta['subjects'],
|
$meta['subjects'],
|
||||||
|
$meta['cover'],
|
||||||
$meta['rescan'],
|
$meta['rescan'],
|
||||||
$meta['id']
|
$meta['id']
|
||||||
);
|
);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
$sql = "INSERT INTO *PREFIX*opds_metadata (`id`, `updated`, `date`, `author`, `title`, `language`, `publisher`, `isbn`, `copyright`, `description`, `subjects`, `rescan`) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)";
|
$sql = "INSERT INTO *PREFIX*opds_metadata (`id`, `updated`, `date`, `author`, `title`, `language`, `publisher`, `isbn`, `copyright`, `description`, `subjects`, `cover`, `rescan`) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)";
|
||||||
$args = array(
|
$args = array(
|
||||||
$meta['id'],
|
$meta['id'],
|
||||||
$meta['updated'],
|
$meta['updated'],
|
||||||
|
@ -102,6 +114,7 @@ class Meta
|
||||||
$meta['copyright'],
|
$meta['copyright'],
|
||||||
$meta['description'],
|
$meta['description'],
|
||||||
$meta['subjects'],
|
$meta['subjects'],
|
||||||
|
$meta['cover'],
|
||||||
$meta['rescan']
|
$meta['rescan']
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -138,6 +151,10 @@ class Meta
|
||||||
$meta = self::create($id);
|
$meta = self::create($id);
|
||||||
$path = \OC\Files\Filesystem::getLocalFile(\OC\Files\Filesystem::getPath($id));
|
$path = \OC\Files\Filesystem::getLocalFile(\OC\Files\Filesystem::getPath($id));
|
||||||
|
|
||||||
|
/* scan for Calibre-generated metadata.opf first. If found, use it as metadata source,
|
||||||
|
* if not found continue file/isbn/etc scan
|
||||||
|
*/
|
||||||
|
if(!(Calibre::get($path,$meta))) {
|
||||||
/* try to call function named 'type' with signature type($path,$meta)
|
/* try to call function named 'type' with signature type($path,$meta)
|
||||||
* eg, pdf(), epub(), etc
|
* eg, pdf(), epub(), etc
|
||||||
*/
|
*/
|
||||||
|
@ -149,6 +166,7 @@ class Meta
|
||||||
Util::logWarn("no metadata scanner for format " . $type);
|
Util::logWarn("no metadata scanner for format " . $type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* if title is not set, assume metadata was invalid or not present
|
/* if title is not set, assume metadata was invalid or not present
|
||||||
* use filename as title
|
* use filename as title
|
||||||
|
@ -157,6 +175,7 @@ class Meta
|
||||||
$info = pathinfo($path);
|
$info = pathinfo($path);
|
||||||
$meta['title'] = basename($path,'.'.$info['extension']);
|
$meta['title'] = basename($path,'.'.$info['extension']);
|
||||||
}
|
}
|
||||||
|
|
||||||
self::save($meta);
|
self::save($meta);
|
||||||
return $meta;
|
return $meta;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue