From 379460676093bcaf5cb6f0f459ddff1eac97ce37 Mon Sep 17 00:00:00 2001 From: frankdelange Date: Sat, 13 Dec 2014 18:40:47 +0100 Subject: [PATCH] refactor, internalised serving of cover/thumbnail images to reduce feed size (shorter links) --- files_opds/appinfo/info.xml | 2 +- files_opds/index.php | 20 +++++- files_opds/lib/feed.php | 114 +++++++++++++++++++++++++++++++ files_opds/lib/files.php | 35 +--------- files_opds/lib/meta.php | 124 ++++++++++++++++++++++++++++++++++ files_opds/lib/util.php | 123 --------------------------------- files_opds/templates/feed.php | 8 +-- 7 files changed, 263 insertions(+), 163 deletions(-) create mode 100644 files_opds/lib/feed.php create mode 100644 files_opds/lib/meta.php diff --git a/files_opds/appinfo/info.xml b/files_opds/appinfo/info.xml index 334bae9..a378c62 100644 --- a/files_opds/appinfo/info.xml +++ b/files_opds/appinfo/info.xml @@ -4,7 +4,7 @@ OPDS catalog Personal OPDS catalog AGPL - 0.3 + 0.3.1 Frank de Lange 7.0 true diff --git a/files_opds/index.php b/files_opds/index.php index c524ee3..963d2f9 100644 --- a/files_opds/index.php +++ b/files_opds/index.php @@ -33,6 +33,18 @@ if (Config::get('enable', 'false') === 'false') { /* id defaults to 'root' (meaning 'serve root feed') */ $id = isset($_GET['id']) ? $_GET['id'] : 'root'; + +/* if either pid or tid is set, serve preview image for id */ +if (isset($_GET['pid'])) { + $id = (int) $_GET['pid']; + $type = 'cover'; +} + +if (isset($_GET['tid'])) { + $id = (int) $_GET['tid']; + $type = 'thumbnail'; +} + $dir = \OC\Files\Filesystem::normalizePath(\OC\Files\Filesystem::getPath($id)); $root = Config::get('root_path', '/Library'); @@ -46,10 +58,14 @@ $dirInfo = \OC\Files\Filesystem::getFileInfo($dir); /* If requested resource is a file, serve it, otherwise produce opds feed */ switch ($dirInfo->getType()) { case 'file': - Util::serveFile($dir,$id); + if ($type) { + Feed::servePreview($dir,$type); + } else { + Feed::serveFile($dir,$id); + } break; case 'dir': - Util::serveFeed($dir, $id); + Feed::serveFeed($dir, $id); break; default: Util::logWarn("I don't know how to handle files of type " . $dirInfo->getType()); diff --git a/files_opds/lib/feed.php b/files_opds/lib/feed.php new file mode 100644 index 0000000..0edccb7 --- /dev/null +++ b/files_opds/lib/feed.php @@ -0,0 +1,114 @@ +close(); + Bookshelf::add($id); + $dirName = dirname($path); + $fileName = basename($path); + \OC_Files::get($dirName, array($fileName), $_SERVER['REQUEST_METHOD'] == 'HEAD'); + } + + /** + * @brief serve opds feed for given directory + * + * @param string $dir full path to directory + * @param int $id requested id + */ + public static function serveFeed($dir, $id) { + if (isset($_SERVER['HTTP_ACCEPT']) && stristr($_SERVER['HTTP_ACCEPT'], 'application/atom+xml')) { + header('Content-Type: application/atom+xml'); + } else { + header('Content-Type: text/xml; charset=UTF-8'); + } + $sortAttribute = 'name'; + $sortDirection = false; + $defaults = new \OC_Defaults(); + $tmpl = new \OCP\Template('files_opds', 'feed'); + $tmpl->assign('files', Files::formatFileInfos(Files::getFiles($dir, $sortAttribute, $sortDirection))); + $tmpl->assign('bookshelf', Files::formatFileInfos(Bookshelf::get())); + $tmpl->assign('bookshelf-count', Bookshelf::count()); + $tmpl->assign('feed_id', self::getFeedId()); + $tmpl->assign('id', $id); + $tmpl->assign('dir', $dir); + $tmpl->assign('user', \OCP\User::getDisplayName()); + $tmpl->assign('ocname', $defaults->getName()); + $tmpl->printPage(); + } + + /** + * @brief offer preview for download + * + * if no preview exists for this file, send icon instead + * + * @param string $path full path to file + * @param string type type of preview requested + */ + public static function servePreview($path, $type) { + \OCP\User::checkLoggedIn(); + \OC::$session->close(); + $i = \OC\Files\Filesystem::getFileInfo($path,false); + if (\OC::$server->getPreviewManager()->isMimeSupported($i['mimetype'])) { + $preview = new \OC\Preview(\OC_User::getUser(), 'files'); + $preview->setFile($path); + switch ($type) { + case 'cover': + $preview->setMaxX(Config::getApp('cover-x', '200')); + $preview->setMaxY(Config::getApp('cover-y', '200')); + break; + case 'thumbnail': + $preview->setMaxX(Config::getApp('thumb-x', '36')); + $preview->setMaxY(Config::getApp('thumb-y', '36')); + break; + } + $preview->showPreview(); + } else { + // no preview, serve icon instead + $scheme = ((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') + || $_SERVER['SERVER_PORT'] == 443) ? 'https' : 'http'; + header("Location: " + . $scheme + . "://" + . $_SERVER['HTTP_HOST'] + . \OC_Helper::mimetypeIcon($i->getMimeType()) + ); + /* Note: relative URL should be enough (RFC7231) but some OPDS clients + * (especially those in dedicated book readers) might not support them + * + * header("Location: " . \OC_Helper::mimetypeIcon($i->getMimeType())); + */ + } + } +} diff --git a/files_opds/lib/files.php b/files_opds/lib/files.php index 64caf4b..929677b 100644 --- a/files_opds/lib/files.php +++ b/files_opds/lib/files.php @@ -32,13 +32,9 @@ class Files extends \OCA\Files\Helper $entry['type'] = $i['type']; if ($i['type'] === 'file') { $entry['mimetype'] = $i['mimetype']; - $entry['preview'] = self::getPreview($i); - $entry['thumbnail'] = self::getThumbnail($i); $entry['humansize'] = \OC_Helper::humanFileSize($i['size']); - $entry['meta'] = Util::getMeta($i['fileid']); - } else { - $entry['icon'] = self::determineIcon($i); - } + $entry['meta'] = Meta::get($i['fileid']); + } return $entry; } @@ -60,33 +56,6 @@ class Files extends \OCA\Files\Helper return $files; } - /** - * @brief get preview for file - * @param \OCP\Files\FileInfo $i - * @return string preview URL - */ - public static function getPreview($i) { - if (\OC::$server->getPreviewManager()->isMimeSupported($i['mimetype'])) { - return \OC_Helper::linkToRoute( 'core_ajax_preview', array('x' => Config::getApp('cover-x', '200'), 'y' => Config::getApp('cover-y', '200'), 'file' => \OC\Files\Filesystem::normalizePath(\OC\Files\Filesystem::getPath($i['fileid'])))); - } else { - return self::determineIcon($i); - } - } - - - /** - * @brief get thumbnail for file - * @param \OCP\Files\FileInfo $i - * @return string preview URL - */ - public static function getThumbnail($i) { - if (\OC::$server->getPreviewManager()->isMimeSupported($i['mimetype'])) { - return \OC_Helper::linkToRoute( 'core_ajax_preview', array('x' => Config::getApp('thumb-x', '36'), 'y' => Config::getApp('thumb-y', '36'), 'file' => \OC\Files\Filesystem::normalizePath(\OC\Files\Filesystem::getPath($i['fileid'])))); - } else { - return self::determineIcon($i); - } - } - /* * @brief check if $child is a subdirectory of $parent * diff --git a/files_opds/lib/meta.php b/files_opds/lib/meta.php new file mode 100644 index 0000000..a736459 --- /dev/null +++ b/files_opds/lib/meta.php @@ -0,0 +1,124 @@ +execute($args); + + return ($row = $result->fetchRow()) ? $row : false; + } + + /** + * @brief write metadata to database + * + * @param array $meta metadata + * @return OC_DB_StatementWrapper + */ + protected static function save($meta) { + $sql = "INSERT INTO *PREFIX*opds_metadata (`id`, `updated`, `date`, `author`, `title`, `language`, `publisher`, `isbn`, `copyright`, `description`, `subjects`) VALUES (?,?,?,?,?,?,?,?,?,?,?)"; + $args = array( + $meta['id'], + $meta['updated'], + $meta['date'], + $meta['author'], + $meta['title'], + $meta['language'], + $meta['publisher'], + $meta['isbn'], + $meta['copyright'], + $meta['description'], + $meta['subjects'] + ); + $query = \OCP\DB::prepare($sql); + + return $query->execute($args); + } + + /** + * @brief get metadata for fileid + * + * Long function, to be split later + * + * @param int $id fileid + * @return array of metadata + */ + public static function get($id) { + if ($meta = self::load($id)) { + return $meta; + } else { + $meta = self::create($id); + $path = \OC\Files\Filesystem::getLocalFile(\OC\Files\Filesystem::getPath($id)); + switch (strtolower(substr(strrchr($path, "."), 1))) { + case 'epub': + $epub = new Epub($path); + $meta['author'] = json_encode($epub->Authors()); + $meta['title'] = $epub->Title(); + $meta['date'] = $epub->Date(); + $meta['publisher'] = $epub->Publisher(); + $meta['copyright'] = $epub->Copyright(); + $meta['language'] = $epub->Language(); + $meta['description'] = strip_tags($epub->Description()); + $meta['isbn'] = $epub->ISBN(); + $meta['subjects'] = $epub->Subjects(); + break; + default: + // set title to filename minus extension + $info = pathinfo($path); + $meta['title'] = basename($path,'.'.$info['extension']); + break; + } + self::save($meta); + return $meta; + } + } +} diff --git a/files_opds/lib/util.php b/files_opds/lib/util.php index 2159bf1..a3b8044 100644 --- a/files_opds/lib/util.php +++ b/files_opds/lib/util.php @@ -74,48 +74,6 @@ class Util header('HTTP/1.0 ' . $statusCode . ' ' . $message); } - /** - * @brief offer single file for download - * - * @param string $path full path to file - * @param int $id file id - */ - public static function serveFile($path, $id) { - \OCP\User::checkLoggedIn(); - \OC::$session->close(); - Bookshelf::add($id); - $dirName = dirname($path); - $fileName = basename($path); - \OC_Files::get($dirName, array($fileName), $_SERVER['REQUEST_METHOD'] == 'HEAD'); - } - - /** - * @brief serve opds feed for given directory - * - * @param string $dir full path to directory - * @param int $id requested id - */ - public static function serveFeed($dir, $id) { - if (isset($_SERVER['HTTP_ACCEPT']) && stristr($_SERVER['HTTP_ACCEPT'], 'application/atom+xml')) { - header('Content-Type: application/atom+xml'); - } else { - header('Content-Type: text/xml; charset=UTF-8'); - } - $sortAttribute = 'name'; - $sortDirection = false; - $defaults = new \OC_Defaults(); - $tmpl = new \OCP\Template('files_opds', 'feed'); - $tmpl->assign('files', Files::formatFileInfos(Files::getFiles($dir, $sortAttribute, $sortDirection))); - $tmpl->assign('bookshelf', Files::formatFileInfos(Bookshelf::get())); - $tmpl->assign('bookshelf-count', Bookshelf::count()); - $tmpl->assign('feed_id', self::getFeedId()); - $tmpl->assign('id', $id); - $tmpl->assign('dir', $dir); - $tmpl->assign('user', \OCP\User::getDisplayName()); - $tmpl->assign('ocname', $defaults->getName()); - $tmpl->printPage(); - } - /** * @brief generate v3 UUID based on display name and site url * @@ -132,15 +90,6 @@ class Util return $hash; } - /** - * @brief get feed id - * - * @return string feed id - */ - public static function getFeedId() { - return Config::get('id', ''); - } - /** * @brief log warning * @param string message to write to log @@ -148,76 +97,4 @@ class Util public static function logWarn($msg) { \OCP\Util::writeLog('files_opds', $msg, \OCP\Util::WARN); } - - /** - * @brief get metadata for fileid - * - * Long function, to be split later - * - * @param int $id fileid - * @return array of metadata - */ - public static function getMeta($id) { - $sql = 'SELECT * FROM `*PREFIX*opds_metadata` WHERE id = ?'; - $args = array($id); - $query = \OCP\DB::prepare($sql); - $result = $query->execute($args); - if ($row = $result->fetchRow()) { - return $row; - } else { - /* start with empty values, except for id. This way, files only get - * scanned once, even if they don't contain valid metadate. - */ - $meta = array(); - $meta['id'] = $id; - $meta['updated'] = date("Y-m-d\TH:i:sP"); - $meta['date'] = ''; - $meta['author'] = ''; - $meta['title'] = ''; - $meta['language'] = ''; - $meta['publisher'] = ''; - $meta['isbn'] = ''; - $meta['copyright'] = ''; - $meta['description'] = ''; - $meta['subjects'] = ''; - - $path = \OC\Files\Filesystem::getLocalFile(\OC\Files\Filesystem::getPath($id)); - switch (strtolower(substr(strrchr($path, "."), 1))) { - case 'epub': - $epub = new Epub($path); - $meta['author'] = json_encode($epub->Authors()); - $meta['title'] = $epub->Title(); - $meta['date'] = $epub->Date(); - $meta['publisher'] = $epub->Publisher(); - $meta['copyright'] = $epub->Copyright(); - $meta['language'] = $epub->Language(); - $meta['description'] = strip_tags($epub->Description()); - $meta['isbn'] = $epub->ISBN(); - $meta['subjects'] = $epub->Subjects(); - break; - default: - // set title to filename minus extension - $info = pathinfo($path); - $meta['title'] = basename($path,'.'.$info['extension']); - break; - } - $sql = "INSERT INTO *PREFIX*opds_metadata (`id`, `updated`, `date`, `author`, `title`, `language`, `publisher`, `isbn`, `copyright`, `description`, `subjects`) VALUES (?,?,?,?,?,?,?,?,?,?,?)"; - $args = array( - $meta['id'], - $meta['updated'], - $meta['date'], - $meta['author'], - $meta['title'], - $meta['language'], - $meta['publisher'], - $meta['isbn'], - $meta['copyright'], - $meta['description'], - $meta['subjects'] - ); - $query = \OCP\DB::prepare($sql); - $result = $query->execute($args); - return $meta; - } - } } diff --git a/files_opds/templates/feed.php b/files_opds/templates/feed.php index 8878dcf..75e7e94 100644 --- a/files_opds/templates/feed.php +++ b/files_opds/templates/feed.php @@ -78,10 +78,10 @@ echo ''; - - @@ -124,10 +124,10 @@ echo ''; - -