From ab067033472e75df52641a6eb65911f2baf62a92 Mon Sep 17 00:00:00 2001 From: frankdelange Date: Sat, 13 Dec 2014 02:47:12 +0100 Subject: [PATCH] version 0.3: - added metadata extraction for epub documents, these will now have full entries where metadata is available - metadata is cached in the database - feed 'entry' template updated to 'full entry' according to OPDS v1.1 --- README.md | 3 +- dist/files_opds-0.3.tar.gz | Bin 0 -> 24515 bytes files_opds/appinfo/database.xml | 110 ++++++++++++++++++++++++++++++++ files_opds/appinfo/info.xml | 2 +- files_opds/lib/epub.php | 15 ++++- files_opds/lib/files.php | 1 + files_opds/lib/util.php | 72 +++++++++++++++++++++ files_opds/templates/feed.php | 32 ++++++++-- 8 files changed, 224 insertions(+), 11 deletions(-) create mode 100644 dist/files_opds-0.3.tar.gz create mode 100644 files_opds/appinfo/database.xml diff --git a/README.md b/README.md index 5eee95f..11bb468 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ The first method gives you the latest, greatest and potentially buggiest version files_opds ---------- -The OPDS catalog app enables Owncloud users to publish a sub-tree of their personal filesystem as an OPDS feed. Since Owncloud currently has limited to no support for metadata, the OPDS entries are rather sparse for now: only title (as in 'filename'), file size, cover image (where available), modification time and content links are provided. +The OPDS catalog app enables Owncloud users to publish a sub-tree of their personal filesystem as an OPDS feed. Since Owncloud currently has limited to no support for metadata, these are for now stored in a separate table. As of v0.3 OPDS catalog can extract all relevant metadata from EPUB documents; other document types will appear with sparse entries for now: only title (as in 'filename'), file size, cover image (where available), modification time and content links are provided. The root feed links to a hierarchical navigation feed mirroring the directory structure as well as a 'personal bookshelf' containing all downloaded books in order (most recent download first). This 'personal bookshelf' will be empty (0 books) at first. Use the 'Browse catalog' link to download a book and it'll appear on the 'personal bookshelf'. Download another, and it will appear above the one you previously downloaded. This makes it possible to get at books you are in the process of reading from different devices, or to easily re-visit a book you downloaded earlier. @@ -44,6 +44,7 @@ The feed has been tested on these clients: - KyBook on iOS: OK - Marvin on iOS: OK - eBook Search on iOS: browsing works, downloading does not (401 error, 'Unauthorised') + - Gecko-based browsers: OK, feed can be browsed and books can be downloaded without additional software. diff --git a/dist/files_opds-0.3.tar.gz b/dist/files_opds-0.3.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..2100775898051b8d4b55e9345d29d4aaac41bbf4 GIT binary patch literal 24515 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 + + *dbname* + true + false + utf8 + + + *dbprefix*opds_metadata + + + + id + integer + 0 + true + 11 + + + + + updated + timestamp + 1970-01-01 00:00:00 + false + + + + + date + text + + true + 32 + + + + + author + text + + true + 256 + + + + + title + text + + true + 256 + + + + + language + text + + true + 64 + + + + + publisher + text + + true + 64 + + + + + isbn + text + + true + 16 + + + + + copyright + text + + true + 128 + + + + + description + text + + true + 2048 + + + + + subjects + text + + true + 1024 + + +
+
diff --git a/files_opds/appinfo/info.xml b/files_opds/appinfo/info.xml index c82b8d8..334bae9 100644 --- a/files_opds/appinfo/info.xml +++ b/files_opds/appinfo/info.xml @@ -4,7 +4,7 @@ OPDS catalog Personal OPDS catalog AGPL - 0.2 + 0.3 Frank de Lange 7.0 true diff --git a/files_opds/lib/epub.php b/files_opds/lib/epub.php index afb099b..bf96bab 100644 --- a/files_opds/lib/epub.php +++ b/files_opds/lib/epub.php @@ -21,7 +21,7 @@ use \DOMDocument; * based on https://github.com/splitbrain/php-epub-meta */ class Epub { - protected $xml; + public $xml; protected $xpath; protected $file; protected $meta; @@ -75,7 +75,7 @@ class Epub { * @brief file name getter * @return string filename */ - public static function file() { + public function file() { return $this->file; } @@ -84,7 +84,7 @@ class Epub { * * @return array $authors */ - public static function Authors() { + public function Authors() { // read current data $rolefix = false; $authors = array(); @@ -127,6 +127,15 @@ class Epub { return $this->get('dc:language'); } + /** + * @brief get date + * + * @param string $date + */ + public function Date(){ + return $this->get('dc:date'); + } + /** * @brief get publisher info * diff --git a/files_opds/lib/files.php b/files_opds/lib/files.php index cfa57ff..64caf4b 100644 --- a/files_opds/lib/files.php +++ b/files_opds/lib/files.php @@ -35,6 +35,7 @@ class Files extends \OCA\Files\Helper $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); } diff --git a/files_opds/lib/util.php b/files_opds/lib/util.php index 1c1cfb9..2159bf1 100644 --- a/files_opds/lib/util.php +++ b/files_opds/lib/util.php @@ -148,4 +148,76 @@ 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 265619f..8878dcf 100644 --- a/files_opds/templates/feed.php +++ b/files_opds/templates/feed.php @@ -59,10 +59,19 @@ echo ''; - <?php p($file['name']); ?> - + <?php p($file['meta']['title']); ?> + id: + + + + + + urn:isbn: + + + @@ -75,7 +84,8 @@ echo ''; - + + @@ -95,10 +105,19 @@ echo ''; - <?php p($file['name']); ?> - + <?php p($file['meta']['title']); ?> + id: + + + + + + urn:isbn: + + + @@ -111,7 +130,8 @@ echo ''; - + +