Add v0.0.4
|
@ -1,3 +1,11 @@
|
||||||
|
0.0.4 - 20120523
|
||||||
|
* More code refactoring to simplify code.
|
||||||
|
* Changed OPDS Page id to match Calibre2Opds
|
||||||
|
* Add icons to author, serie, tags and recent items (there is config item to disable it)
|
||||||
|
* Fixed author URL
|
||||||
|
* Added publishing date (works on Mantano)
|
||||||
|
* Added Tags support
|
||||||
|
|
||||||
0.0.3 - 20120507
|
0.0.3 - 20120507
|
||||||
* Fixed many things blocking opensearch from working
|
* Fixed many things blocking opensearch from working
|
||||||
* There was a bug introduced in 0.0.2
|
* There was a bug introduced in 0.0.2
|
||||||
|
|
|
@ -68,7 +68,7 @@ class OPDSRenderer
|
||||||
return $xml->outputMemory(true);
|
return $xml->outputMemory(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function startXmlDocument ($title) {
|
private function startXmlDocument ($title, $idPage) {
|
||||||
self::getXmlStream ()->startDocument('1.0','UTF-8');
|
self::getXmlStream ()->startDocument('1.0','UTF-8');
|
||||||
self::getXmlStream ()->startElement ("feed");
|
self::getXmlStream ()->startElement ("feed");
|
||||||
self::getXmlStream ()->writeAttribute ("xmlns", "http://www.w3.org/2005/Atom");
|
self::getXmlStream ()->writeAttribute ("xmlns", "http://www.w3.org/2005/Atom");
|
||||||
|
@ -80,7 +80,14 @@ class OPDSRenderer
|
||||||
self::getXmlStream ()->text ($title);
|
self::getXmlStream ()->text ($title);
|
||||||
self::getXmlStream ()->endElement ();
|
self::getXmlStream ()->endElement ();
|
||||||
self::getXmlStream ()->startElement ("id");
|
self::getXmlStream ()->startElement ("id");
|
||||||
self::getXmlStream ()->text ($_SERVER['REQUEST_URI']);
|
if ($idPage)
|
||||||
|
{
|
||||||
|
self::getXmlStream ()->text ($idPage);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
self::getXmlStream ()->text ($_SERVER['REQUEST_URI']);
|
||||||
|
}
|
||||||
self::getXmlStream ()->endElement ();
|
self::getXmlStream ()->endElement ();
|
||||||
self::getXmlStream ()->startElement ("updated");
|
self::getXmlStream ()->startElement ("updated");
|
||||||
self::getXmlStream ()->text (self::getUpdatedTime ());
|
self::getXmlStream ()->text (self::getUpdatedTime ());
|
||||||
|
@ -159,7 +166,7 @@ class OPDSRenderer
|
||||||
self::getXmlStream ()->text ($author->name);
|
self::getXmlStream ()->text ($author->name);
|
||||||
self::getXmlStream ()->endElement ();
|
self::getXmlStream ()->endElement ();
|
||||||
self::getXmlStream ()->startElement ("uri");
|
self::getXmlStream ()->startElement ("uri");
|
||||||
self::getXmlStream ()->text ($author->getUri ());
|
self::getXmlStream ()->text ("feed.php" . $author->getUri ());
|
||||||
self::getXmlStream ()->endElement ();
|
self::getXmlStream ()->endElement ();
|
||||||
self::getXmlStream ()->endElement ();
|
self::getXmlStream ()->endElement ();
|
||||||
}
|
}
|
||||||
|
@ -173,12 +180,15 @@ class OPDSRenderer
|
||||||
self::getXmlStream ()->startElement ("dcterms:issued");
|
self::getXmlStream ()->startElement ("dcterms:issued");
|
||||||
self::getXmlStream ()->text (date ("Y-m-d", $entry->book->pubdate));
|
self::getXmlStream ()->text (date ("Y-m-d", $entry->book->pubdate));
|
||||||
self::getXmlStream ()->endElement ();
|
self::getXmlStream ()->endElement ();
|
||||||
|
self::getXmlStream ()->startElement ("published");
|
||||||
|
self::getXmlStream ()->text (date ("Y-m-d", $entry->book->pubdate) . "T08:08:08Z");
|
||||||
|
self::getXmlStream ()->endElement ();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function render ($page) {
|
public function render ($page) {
|
||||||
self::startXmlDocument ($page->title);
|
self::startXmlDocument ($page->title, $page->idPage);
|
||||||
if ($page->query)
|
if ($page->query)
|
||||||
{
|
{
|
||||||
self::getXmlStream ()->startElement ("opensearch:totalResults");
|
self::getXmlStream ()->startElement ("opensearch:totalResults");
|
||||||
|
|
|
@ -54,10 +54,10 @@ order by sort');
|
||||||
return $entryArray;
|
return $entryArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getAuthorName ($authorId) {
|
public static function getAuthorById ($authorId) {
|
||||||
$result = parent::getDb ()->prepare('select sort from authors where id = ?');
|
$result = parent::getDb ()->prepare('select sort from authors where id = ?');
|
||||||
$result->execute (array ($authorId));
|
$result->execute (array ($authorId));
|
||||||
return $result->fetchColumn ();
|
return new Author ($authorId, $result->fetchColumn ());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getAuthorByBookId ($bookId) {
|
public static function getAuthorByBookId ($bookId) {
|
||||||
|
|
88
base.php
|
@ -15,6 +15,11 @@ function getURLParam ($name, $default = NULL) {
|
||||||
|
|
||||||
class Link
|
class Link
|
||||||
{
|
{
|
||||||
|
const OPDS_THUMBNAIL_TYPE = "http://opds-spec.org/image/thumbnail";
|
||||||
|
const OPDS_IMAGE_TYPE = "http://opds-spec.org/image";
|
||||||
|
const OPDS_ACQUISITION_TYPE = "http://opds-spec.org/acquisition";
|
||||||
|
const OPDS_NAVIGATION_TYPE = "application/atom+xml;profile=opds-catalog;kind=navigation";
|
||||||
|
|
||||||
public $href;
|
public $href;
|
||||||
public $type;
|
public $type;
|
||||||
public $rel;
|
public $rel;
|
||||||
|
@ -34,10 +39,8 @@ class Link
|
||||||
|
|
||||||
class LinkNavigation extends Link
|
class LinkNavigation extends Link
|
||||||
{
|
{
|
||||||
const OPDS_NAVIGATION_TYPE = "application/atom+xml;profile=opds-catalog;kind=navigation";
|
|
||||||
|
|
||||||
public function __construct($phref, $prel = NULL, $ptitle = NULL) {
|
public function __construct($phref, $prel = NULL, $ptitle = NULL) {
|
||||||
parent::__construct ($phref, self::OPDS_NAVIGATION_TYPE, $prel, $ptitle);
|
parent::__construct ($phref, Link::OPDS_NAVIGATION_TYPE, $prel, $ptitle);
|
||||||
$this->href = $_SERVER["SCRIPT_NAME"] . $this->href;
|
$this->href = $_SERVER["SCRIPT_NAME"] . $this->href;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,6 +56,15 @@ class Entry
|
||||||
public $localUpdated;
|
public $localUpdated;
|
||||||
private static $updated = NULL;
|
private static $updated = NULL;
|
||||||
|
|
||||||
|
public static $icons = array(
|
||||||
|
Author::ALL_AUTHORS_ID => 'images/author.png',
|
||||||
|
Serie::ALL_SERIES_ID => 'images/serie.png',
|
||||||
|
Book::ALL_RECENT_BOOKS_ID => 'images/recent.png',
|
||||||
|
Tag::ALL_TAGS_ID => 'images/tag.png',
|
||||||
|
"calibre:books$" => 'images/allbook.png',
|
||||||
|
"calibre:books:letter" => 'images/allbook.png'
|
||||||
|
);
|
||||||
|
|
||||||
public function getUpdatedTime () {
|
public function getUpdatedTime () {
|
||||||
if (!is_null ($this->localUpdated)) {
|
if (!is_null ($this->localUpdated)) {
|
||||||
return date (DATE_ATOM, $this->localUpdated);
|
return date (DATE_ATOM, $this->localUpdated);
|
||||||
|
@ -64,11 +76,23 @@ class Entry
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __construct($ptitle, $pid, $pcontent, $pcontentType, $plinkArray) {
|
public function __construct($ptitle, $pid, $pcontent, $pcontentType, $plinkArray) {
|
||||||
|
global $config;
|
||||||
$this->title = $ptitle;
|
$this->title = $ptitle;
|
||||||
$this->id = $pid;
|
$this->id = $pid;
|
||||||
$this->content = $pcontent;
|
$this->content = $pcontent;
|
||||||
$this->contentType = $pcontentType;
|
$this->contentType = $pcontentType;
|
||||||
$this->linkArray = $plinkArray;
|
$this->linkArray = $plinkArray;
|
||||||
|
|
||||||
|
if ($config['cops_show_icons'] == 1)
|
||||||
|
{
|
||||||
|
foreach (self::$icons as $reg => $image)
|
||||||
|
{
|
||||||
|
if (preg_match ("/" . $reg . "/", $pid)) {
|
||||||
|
array_push ($this->linkArray, new Link ($image, "image/png", Link::OPDS_THUMBNAIL_TYPE));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,7 +108,15 @@ class EntryBook extends Entry
|
||||||
|
|
||||||
public function getCoverThumbnail () {
|
public function getCoverThumbnail () {
|
||||||
foreach ($this->linkArray as $link) {
|
foreach ($this->linkArray as $link) {
|
||||||
if ($link->rel == "http://opds-spec.org/image/thumbnail")
|
if ($link->rel == Link::OPDS_THUMBNAIL_TYPE)
|
||||||
|
return $link->hrefXhtml ();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCover () {
|
||||||
|
foreach ($this->linkArray as $link) {
|
||||||
|
if ($link->rel == Link::OPDS_IMAGE_TYPE)
|
||||||
return $link->hrefXhtml ();
|
return $link->hrefXhtml ();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -106,6 +138,10 @@ class Page
|
||||||
return new PageAllAuthors ($id, $query);
|
return new PageAllAuthors ($id, $query);
|
||||||
case Base::PAGE_AUTHOR_DETAIL :
|
case Base::PAGE_AUTHOR_DETAIL :
|
||||||
return new PageAuthorDetail ($id, $query);
|
return new PageAuthorDetail ($id, $query);
|
||||||
|
case Base::PAGE_ALL_TAGS :
|
||||||
|
return new PageAllTags ($id, $query);
|
||||||
|
case Base::PAGE_TAG_DETAIL :
|
||||||
|
return new PageTagDetail ($id, $query);
|
||||||
case Base::PAGE_ALL_SERIES :
|
case Base::PAGE_ALL_SERIES :
|
||||||
return new PageAllSeries ($id, $query);
|
return new PageAllSeries ($id, $query);
|
||||||
case Base::PAGE_ALL_BOOKS :
|
case Base::PAGE_ALL_BOOKS :
|
||||||
|
@ -120,7 +156,9 @@ class Page
|
||||||
return new PageQueryResult ($id, $query);
|
return new PageQueryResult ($id, $query);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return new Page ($id, $query);
|
$page = new Page ($id, $query);
|
||||||
|
$page->idPage = "cops:catalog";
|
||||||
|
return $page;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,6 +173,7 @@ class Page
|
||||||
$this->title = $config['cops_title_default'];
|
$this->title = $config['cops_title_default'];
|
||||||
array_push ($this->entryArray, Author::getCount());
|
array_push ($this->entryArray, Author::getCount());
|
||||||
array_push ($this->entryArray, Serie::getCount());
|
array_push ($this->entryArray, Serie::getCount());
|
||||||
|
array_push ($this->entryArray, Tag::getCount());
|
||||||
$this->entryArray = array_merge ($this->entryArray, Book::getCount());
|
$this->entryArray = array_merge ($this->entryArray, Book::getCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,6 +185,7 @@ class PageAllAuthors extends Page
|
||||||
{
|
{
|
||||||
$this->title = "All authors";
|
$this->title = "All authors";
|
||||||
$this->entryArray = Author::getAllAuthors();
|
$this->entryArray = Author::getAllAuthors();
|
||||||
|
$this->idPage = Author::ALL_AUTHORS_ID;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,17 +193,41 @@ class PageAuthorDetail extends Page
|
||||||
{
|
{
|
||||||
public function InitializeContent ()
|
public function InitializeContent ()
|
||||||
{
|
{
|
||||||
$this->title = Author::getAuthorName ($this->idGet);
|
$author = Author::getAuthorById ($this->idGet);
|
||||||
|
$this->idPage = $author->getEntryId ();
|
||||||
|
$this->title = $author->name;
|
||||||
$this->entryArray = Book::getBooksByAuthor ($this->idGet);
|
$this->entryArray = Book::getBooksByAuthor ($this->idGet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class PageAllTags extends Page
|
||||||
|
{
|
||||||
|
public function InitializeContent ()
|
||||||
|
{
|
||||||
|
$this->title = "All tags";
|
||||||
|
$this->entryArray = Tag::getAllTags();
|
||||||
|
$this->idPage = Tag::ALL_TAGS_ID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PageTagDetail extends Page
|
||||||
|
{
|
||||||
|
public function InitializeContent ()
|
||||||
|
{
|
||||||
|
$tag = Tag::getTagById ($this->idGet);
|
||||||
|
$this->idPage = $tag->getEntryId ();
|
||||||
|
$this->title = $tag->name;
|
||||||
|
$this->entryArray = Book::getBooksByTag ($this->idGet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class PageAllSeries extends Page
|
class PageAllSeries extends Page
|
||||||
{
|
{
|
||||||
public function InitializeContent ()
|
public function InitializeContent ()
|
||||||
{
|
{
|
||||||
$this->title = "All series";
|
$this->title = "All series";
|
||||||
$this->entryArray = Serie::getAllSeries();
|
$this->entryArray = Serie::getAllSeries();
|
||||||
|
$this->idPage = Serie::ALL_SERIES_ID;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,8 +235,10 @@ class PageSerieDetail extends Page
|
||||||
{
|
{
|
||||||
public function InitializeContent ()
|
public function InitializeContent ()
|
||||||
{
|
{
|
||||||
$this->title = "Series : " . Serie::getSerieById ($this->idGet)->name;
|
$serie = Serie::getSerieById ($this->idGet);
|
||||||
|
$this->title = "Series : " . $serie->name;
|
||||||
$this->entryArray = Book::getBooksBySeries ($this->idGet);
|
$this->entryArray = Book::getBooksBySeries ($this->idGet);
|
||||||
|
$this->idPage = $serie->getEntryId ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,6 +248,7 @@ class PageAllBooks extends Page
|
||||||
{
|
{
|
||||||
$this->title = "All books by starting letter";
|
$this->title = "All books by starting letter";
|
||||||
$this->entryArray = Book::getAllBooks ();
|
$this->entryArray = Book::getAllBooks ();
|
||||||
|
$this->idPage = Book::ALL_BOOKS_ID;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,6 +258,7 @@ class PageAllBooksLetter extends Page
|
||||||
{
|
{
|
||||||
$this->title = "All books starting by " . $this->idGet;
|
$this->title = "All books starting by " . $this->idGet;
|
||||||
$this->entryArray = Book::getBooksByStartingLetter ($this->idGet);
|
$this->entryArray = Book::getBooksByStartingLetter ($this->idGet);
|
||||||
|
$this->idPage = Book::getEntryIdByLetter ($this->idGet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,6 +268,7 @@ class PageRecentBooks extends Page
|
||||||
{
|
{
|
||||||
$this->title = "Most recent books";
|
$this->title = "Most recent books";
|
||||||
$this->entryArray = Book::getAllRecentBooks ();
|
$this->entryArray = Book::getAllRecentBooks ();
|
||||||
|
$this->idPage = Book::ALL_RECENT_BOOKS_ID;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,7 +276,7 @@ class PageQueryResult extends Page
|
||||||
{
|
{
|
||||||
public function InitializeContent ()
|
public function InitializeContent ()
|
||||||
{
|
{
|
||||||
$this->title = "Search result for query <" . $this->query . ">";
|
$this->title = "Search result for query *" . $this->query . "*";
|
||||||
$this->entryArray = Book::getBooksByQuery ($this->query);
|
$this->entryArray = Book::getBooksByQuery ($this->query);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -225,6 +294,9 @@ abstract class Base
|
||||||
const PAGE_OPENSEARCH = "8";
|
const PAGE_OPENSEARCH = "8";
|
||||||
const PAGE_OPENSEARCH_QUERY = "9";
|
const PAGE_OPENSEARCH_QUERY = "9";
|
||||||
const PAGE_ALL_RECENT_BOOKS = "10";
|
const PAGE_ALL_RECENT_BOOKS = "10";
|
||||||
|
const PAGE_ALL_TAGS = "11";
|
||||||
|
const PAGE_TAG_DETAIL = "12";
|
||||||
|
|
||||||
const COMPATIBILITY_XML_ALDIKO = "aldiko";
|
const COMPATIBILITY_XML_ALDIKO = "aldiko";
|
||||||
|
|
||||||
private static $db = NULL;
|
private static $db = NULL;
|
||||||
|
|
85
book.php
|
@ -13,6 +13,7 @@ require_once('author.php');
|
||||||
class Book extends Base {
|
class Book extends Base {
|
||||||
const ALL_BOOKS_ID = "calibre:books";
|
const ALL_BOOKS_ID = "calibre:books";
|
||||||
const ALL_RECENT_BOOKS_ID = "calibre:recentbooks";
|
const ALL_RECENT_BOOKS_ID = "calibre:recentbooks";
|
||||||
|
const BOOK_COLUMNS = "books.id as id, books.title as title, text as comment, path, timestamp, pubdate, series_index";
|
||||||
|
|
||||||
public $id;
|
public $id;
|
||||||
public $title;
|
public $title;
|
||||||
|
@ -31,24 +32,27 @@ class Book extends Base {
|
||||||
'mobi' => 'application/x-mobipocket-ebook',
|
'mobi' => 'application/x-mobipocket-ebook',
|
||||||
'pdf' => 'application/pdf'
|
'pdf' => 'application/pdf'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
public function __construct($line) {
|
||||||
public function __construct($pid, $ptitle, $ptimestamp, $ppubdate, $ppath, $pseriesIndex, $pcomment) {
|
|
||||||
global $config;
|
global $config;
|
||||||
$this->id = $pid;
|
$this->id = $line->id;
|
||||||
$this->title = $ptitle;
|
$this->title = $line->title;
|
||||||
$this->timestamp = strtotime ($ptimestamp);
|
$this->timestamp = strtotime ($line->timestamp);
|
||||||
$this->pubdate = strtotime ($ppubdate);
|
$this->pubdate = strtotime ($line->pubdate);
|
||||||
$this->path = $config['calibre_directory'] . $ppath;
|
$this->path = $config['calibre_directory'] . $line->path;
|
||||||
$this->relativePath = $ppath;
|
$this->relativePath = $line->path;
|
||||||
$this->seriesIndex = $pseriesIndex;
|
$this->seriesIndex = $line->series_index;
|
||||||
$this->comment = $pcomment;
|
$this->comment = $line->comment;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getEntryId () {
|
public function getEntryId () {
|
||||||
return self::ALL_BOOKS_ID.":".$this->id;
|
return self::ALL_BOOKS_ID.":".$this->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function getEntryIdByLetter ($startingLetter) {
|
||||||
|
return self::ALL_BOOKS_ID.":letter:".$startingLetter;
|
||||||
|
}
|
||||||
|
|
||||||
public function getTitle () {
|
public function getTitle () {
|
||||||
return $this->title;
|
return $this->title;
|
||||||
}
|
}
|
||||||
|
@ -150,13 +154,21 @@ class Book extends Base {
|
||||||
if (preg_match ('/jpg$/', $file)) {
|
if (preg_match ('/jpg$/', $file)) {
|
||||||
if (preg_match ('/^\//', $config['calibre_directory']))
|
if (preg_match ('/^\//', $config['calibre_directory']))
|
||||||
{
|
{
|
||||||
array_push ($linkArray, new Link ("fetch.php?id=$this->id", "image/jpeg", "http://opds-spec.org/image"));
|
array_push ($linkArray, new Link ("fetch.php?id=$this->id", "image/jpeg", Link::OPDS_IMAGE_TYPE));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
array_push ($linkArray, new Link (str_replace('%2F','/',rawurlencode ($this->path."/".$file)), "image/jpeg", "http://opds-spec.org/image"));
|
array_push ($linkArray, new Link (str_replace('%2F','/',rawurlencode ($this->path."/".$file)), "image/jpeg", Link::OPDS_IMAGE_TYPE));
|
||||||
}
|
}
|
||||||
array_push ($linkArray, new Link ("fetch.php?id=$this->id&height=70", "image/jpeg", "http://opds-spec.org/image/thumbnail"));
|
$height = "50";
|
||||||
|
if (preg_match ('/feed.php/', $_SERVER["SCRIPT_NAME"])) {
|
||||||
|
$height = $config['cops_opds_thumbnail_height'];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$height = $config['cops_html_thumbnail_height'];
|
||||||
|
}
|
||||||
|
array_push ($linkArray, new Link ("fetch.php?id=$this->id&height=" . $height, "image/jpeg", Link::OPDS_THUMBNAIL_TYPE));
|
||||||
}
|
}
|
||||||
foreach (self::$mimetypes as $ext => $mime)
|
foreach (self::$mimetypes as $ext => $mime)
|
||||||
{
|
{
|
||||||
|
@ -164,11 +176,11 @@ class Book extends Base {
|
||||||
$this->format [$ext] = $file;
|
$this->format [$ext] = $file;
|
||||||
if (preg_match ('/^\//', $config['calibre_directory']))
|
if (preg_match ('/^\//', $config['calibre_directory']))
|
||||||
{
|
{
|
||||||
array_push ($linkArray, new Link ("fetch.php?id=$this->id&type=" . $ext, $mime, "http://opds-spec.org/acquisition", "Download"));
|
array_push ($linkArray, new Link ("fetch.php?id=$this->id&type=" . $ext, $mime, Link::OPDS_ACQUISITION_TYPE, "Download"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
array_push ($linkArray, new Link (str_replace('%2F','/',rawurlencode ($this->path."/".$file)), $mime, "http://opds-spec.org/acquisition", "Download"));
|
array_push ($linkArray, new Link (str_replace('%2F','/',rawurlencode ($this->path."/".$file)), $mime, Link::OPDS_ACQUISITION_TYPE, "Download"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -212,7 +224,7 @@ class Book extends Base {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getBooksByAuthor($authorId) {
|
public static function getBooksByAuthor($authorId) {
|
||||||
$result = parent::getDb ()->prepare('select books.id as id, books.title as title, text as comment, path, timestamp, pubdate, series_index
|
$result = parent::getDb ()->prepare('select ' . self::BOOK_COLUMNS . '
|
||||||
from books_authors_link, books left outer join comments on comments.book = books.id
|
from books_authors_link, books left outer join comments on comments.book = books.id
|
||||||
where books_authors_link.book = books.id
|
where books_authors_link.book = books.id
|
||||||
and author = ?
|
and author = ?
|
||||||
|
@ -221,7 +233,7 @@ order by pubdate');
|
||||||
$result->execute (array ($authorId));
|
$result->execute (array ($authorId));
|
||||||
while ($post = $result->fetchObject ())
|
while ($post = $result->fetchObject ())
|
||||||
{
|
{
|
||||||
$book = new Book ($post->id, $post->title, $post->timestamp, $post->pubdate, $post->path, $post->series_index, $post->comment);
|
$book = new Book ($post);
|
||||||
array_push ($entryArray, $book->getEntry ());
|
array_push ($entryArray, $book->getEntry ());
|
||||||
}
|
}
|
||||||
return $entryArray;
|
return $entryArray;
|
||||||
|
@ -229,7 +241,7 @@ order by pubdate');
|
||||||
|
|
||||||
|
|
||||||
public static function getBooksBySeries($serieId) {
|
public static function getBooksBySeries($serieId) {
|
||||||
$result = parent::getDb ()->prepare('select books.id as id, books.title as title, text as comment, path, timestamp, pubdate, series_index
|
$result = parent::getDb ()->prepare('select ' . self::BOOK_COLUMNS . '
|
||||||
from books_series_link, books left outer join comments on comments.book = books.id
|
from books_series_link, books left outer join comments on comments.book = books.id
|
||||||
where books_series_link.book = books.id and series = ?
|
where books_series_link.book = books.id and series = ?
|
||||||
order by series_index');
|
order by series_index');
|
||||||
|
@ -237,28 +249,43 @@ order by series_index');
|
||||||
$result->execute (array ($serieId));
|
$result->execute (array ($serieId));
|
||||||
while ($post = $result->fetchObject ())
|
while ($post = $result->fetchObject ())
|
||||||
{
|
{
|
||||||
$book = new Book ($post->id, $post->title, $post->timestamp, $post->pubdate, $post->path, $post->series_index, $post->comment);
|
$book = new Book ($post);
|
||||||
|
array_push ($entryArray, $book->getEntry ());
|
||||||
|
}
|
||||||
|
return $entryArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getBooksByTag($tagId) {
|
||||||
|
$result = parent::getDb ()->prepare('select ' . self::BOOK_COLUMNS . '
|
||||||
|
from books_tags_link, books left outer join comments on comments.book = books.id
|
||||||
|
where books_tags_link.book = books.id and tag = ?
|
||||||
|
order by sort');
|
||||||
|
$entryArray = array();
|
||||||
|
$result->execute (array ($tagId));
|
||||||
|
while ($post = $result->fetchObject ())
|
||||||
|
{
|
||||||
|
$book = new Book ($post);
|
||||||
array_push ($entryArray, $book->getEntry ());
|
array_push ($entryArray, $book->getEntry ());
|
||||||
}
|
}
|
||||||
return $entryArray;
|
return $entryArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getBookById($bookId) {
|
public static function getBookById($bookId) {
|
||||||
$result = parent::getDb ()->prepare('select books.id as id, books.title as title, text as comment, path, timestamp, pubdate, series_index
|
$result = parent::getDb ()->prepare('select ' . self::BOOK_COLUMNS . '
|
||||||
from books left outer join comments on book = books.id
|
from books left outer join comments on book = books.id
|
||||||
where books.id = ?');
|
where books.id = ?');
|
||||||
$entryArray = array();
|
$entryArray = array();
|
||||||
$result->execute (array ($bookId));
|
$result->execute (array ($bookId));
|
||||||
while ($post = $result->fetchObject ())
|
while ($post = $result->fetchObject ())
|
||||||
{
|
{
|
||||||
$book = new Book ($post->id, $post->title, $post->timestamp, $post->pubdate, $post->path, $post->series_index, $post->comment);
|
$book = new Book ($post);
|
||||||
return $book;
|
return $book;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getBooksByQuery($query) {
|
public static function getBooksByQuery($query) {
|
||||||
$result = parent::getDb ()->prepare("select books.id as id, books.title as title, text as comment, path, timestamp, pubdate, series_index
|
$result = parent::getDb ()->prepare("select " . self::BOOK_COLUMNS . "
|
||||||
from books left outer join comments on book = books.id
|
from books left outer join comments on book = books.id
|
||||||
where exists (select null from authors, books_authors_link where book = books.id and author = authors.id and authors.name like ?)
|
where exists (select null from authors, books_authors_link where book = books.id and author = authors.id and authors.name like ?)
|
||||||
or title like ?");
|
or title like ?");
|
||||||
|
@ -267,7 +294,7 @@ or title like ?");
|
||||||
$result->execute (array ($queryLike, $queryLike));
|
$result->execute (array ($queryLike, $queryLike));
|
||||||
while ($post = $result->fetchObject ())
|
while ($post = $result->fetchObject ())
|
||||||
{
|
{
|
||||||
$book = new Book ($post->id, $post->title, $post->timestamp, $post->pubdate, $post->path, $post->series_index, $post->comment);
|
$book = new Book ($post);
|
||||||
array_push ($entryArray, $book->getEntry ());
|
array_push ($entryArray, $book->getEntry ());
|
||||||
}
|
}
|
||||||
return $entryArray;
|
return $entryArray;
|
||||||
|
@ -281,7 +308,7 @@ order by substr (upper (sort), 1, 1)");
|
||||||
$entryArray = array();
|
$entryArray = array();
|
||||||
while ($post = $result->fetchObject ())
|
while ($post = $result->fetchObject ())
|
||||||
{
|
{
|
||||||
array_push ($entryArray, new Entry ($post->title, "allbooks_" . $post->title,
|
array_push ($entryArray, new Entry ($post->title, Book::getEntryIdByLetter ($post->title),
|
||||||
"$post->count books", "text",
|
"$post->count books", "text",
|
||||||
array ( new LinkNavigation ("?page=".parent::PAGE_ALL_BOOKS_LETTER."&id=".$post->title))));
|
array ( new LinkNavigation ("?page=".parent::PAGE_ALL_BOOKS_LETTER."&id=".$post->title))));
|
||||||
}
|
}
|
||||||
|
@ -289,7 +316,7 @@ order by substr (upper (sort), 1, 1)");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getBooksByStartingLetter($letter) {
|
public static function getBooksByStartingLetter($letter) {
|
||||||
$result = parent::getDb ()->prepare('select books.id as id, books.title as title, text as comment, path, timestamp, pubdate, series_index
|
$result = parent::getDb ()->prepare('select ' . self::BOOK_COLUMNS . '
|
||||||
from books left outer join comments on book = books.id
|
from books left outer join comments on book = books.id
|
||||||
where upper (books.sort) like ?');
|
where upper (books.sort) like ?');
|
||||||
$entryArray = array();
|
$entryArray = array();
|
||||||
|
@ -297,7 +324,7 @@ where upper (books.sort) like ?');
|
||||||
$result->execute (array ($queryLike));
|
$result->execute (array ($queryLike));
|
||||||
while ($post = $result->fetchObject ())
|
while ($post = $result->fetchObject ())
|
||||||
{
|
{
|
||||||
$book = new Book ($post->id, $post->title, $post->timestamp, $post->pubdate, $post->path, $post->series_index, $post->comment);
|
$book = new Book ($post);
|
||||||
array_push ($entryArray, $book->getEntry ());
|
array_push ($entryArray, $book->getEntry ());
|
||||||
}
|
}
|
||||||
return $entryArray;
|
return $entryArray;
|
||||||
|
@ -306,13 +333,13 @@ where upper (books.sort) like ?');
|
||||||
|
|
||||||
public static function getAllRecentBooks() {
|
public static function getAllRecentBooks() {
|
||||||
global $config;
|
global $config;
|
||||||
$result = parent::getDb ()->query("select books.id as id, books.title as title, text as comment, path, timestamp, pubdate, series_index
|
$result = parent::getDb ()->query("select " . self::BOOK_COLUMNS . "
|
||||||
from books left outer join comments on book = books.id
|
from books left outer join comments on book = books.id
|
||||||
order by timestamp desc limit " . $config['cops_recentbooks_limit']);
|
order by timestamp desc limit " . $config['cops_recentbooks_limit']);
|
||||||
$entryArray = array();
|
$entryArray = array();
|
||||||
while ($post = $result->fetchObject ())
|
while ($post = $result->fetchObject ())
|
||||||
{
|
{
|
||||||
$book = new Book ($post->id, $post->title, $post->timestamp, $post->pubdate, $post->path, $post->series_index, $post->comment);
|
$book = new Book ($post);
|
||||||
array_push ($entryArray, $book->getEntry ());
|
array_push ($entryArray, $book->getEntry ());
|
||||||
}
|
}
|
||||||
return $entryArray;
|
return $entryArray;
|
||||||
|
|
|
@ -49,4 +49,21 @@
|
||||||
* X-Sendfile : For Lightttpd or Apache (with mod_xsendfile)
|
* X-Sendfile : For Lightttpd or Apache (with mod_xsendfile)
|
||||||
*/
|
*/
|
||||||
$config['cops_x_accel_redirect'] = "X-Accel-Redirect";
|
$config['cops_x_accel_redirect'] = "X-Accel-Redirect";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Height of thumbnail image for OPDS
|
||||||
|
*/
|
||||||
|
$config['cops_opds_thumbnail_height'] = "40";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Height of thumbnail image for HTML
|
||||||
|
*/
|
||||||
|
$config['cops_html_thumbnail_height'] = "70";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Show icon for authors, series, tags and books on OPDS feed
|
||||||
|
* 1 : enable
|
||||||
|
* 0 : disable
|
||||||
|
*/
|
||||||
|
$config['cops_show_icons'] = "1";
|
||||||
?>
|
?>
|
1
feed.php
|
@ -11,6 +11,7 @@
|
||||||
require_once ("base.php");
|
require_once ("base.php");
|
||||||
require_once ("author.php");
|
require_once ("author.php");
|
||||||
require_once ("serie.php");
|
require_once ("serie.php");
|
||||||
|
require_once ("tag.php");
|
||||||
require_once ("book.php");
|
require_once ("book.php");
|
||||||
require_once ("OPDS_renderer.php");
|
require_once ("OPDS_renderer.php");
|
||||||
|
|
||||||
|
|
BIN
images/ajax-loader.gif
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
images/allbook.png
Normal file
After Width: | Height: | Size: 622 B |
BIN
images/author.png
Normal file
After Width: | Height: | Size: 741 B |
BIN
images/home.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
images/recent.png
Normal file
After Width: | Height: | Size: 626 B |
BIN
images/search.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
images/serie.png
Normal file
After Width: | Height: | Size: 748 B |
BIN
images/tag.png
Normal file
After Width: | Height: | Size: 586 B |
|
@ -22,6 +22,10 @@ class Serie extends Base {
|
||||||
public function getUri () {
|
public function getUri () {
|
||||||
return "?page=".parent::PAGE_SERIE_DETAIL."&id=$this->id";
|
return "?page=".parent::PAGE_SERIE_DETAIL."&id=$this->id";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getEntryId () {
|
||||||
|
return self::ALL_SERIES_ID.":".$this->id;
|
||||||
|
}
|
||||||
|
|
||||||
public static function getCount() {
|
public static function getCount() {
|
||||||
$nSeries = parent::getDb ()->query('select count(*) from series')->fetchColumn();
|
$nSeries = parent::getDb ()->query('select count(*) from series')->fetchColumn();
|
||||||
|
@ -60,9 +64,10 @@ order by series.sort');
|
||||||
$entryArray = array();
|
$entryArray = array();
|
||||||
while ($post = $result->fetchObject ())
|
while ($post = $result->fetchObject ())
|
||||||
{
|
{
|
||||||
array_push ($entryArray, new Entry ($post->sort, self::ALL_SERIES_ID.":".$post->id,
|
$serie = new Serie ($post->id, $post->sort);
|
||||||
|
array_push ($entryArray, new Entry ($serie->name, $serie->getEntryId (),
|
||||||
"$post->count books", "text",
|
"$post->count books", "text",
|
||||||
array ( new LinkNavigation ("?page=".parent::PAGE_SERIE_DETAIL."&id=$post->id"))));
|
array ( new LinkNavigation ($serie->getUri ()))));
|
||||||
}
|
}
|
||||||
return $entryArray;
|
return $entryArray;
|
||||||
}
|
}
|
||||||
|
|
64
tag.php
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* COPS (Calibre OPDS PHP Server) class file
|
||||||
|
*
|
||||||
|
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
|
||||||
|
* @author Sébastien Lucas <sebastien@slucas.fr>
|
||||||
|
*/
|
||||||
|
|
||||||
|
require_once('base.php');
|
||||||
|
|
||||||
|
class tag extends Base {
|
||||||
|
const ALL_TAGS_ID = "calibre:tags";
|
||||||
|
|
||||||
|
public $id;
|
||||||
|
public $name;
|
||||||
|
|
||||||
|
public function __construct($pid, $pname) {
|
||||||
|
$this->id = $pid;
|
||||||
|
$this->name = $pname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUri () {
|
||||||
|
return "?page=".parent::PAGE_TAG_DETAIL."&id=$this->id";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getEntryId () {
|
||||||
|
return self::ALL_TAGS_ID.":".$this->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getCount() {
|
||||||
|
$nTags = parent::getDb ()->query('select count(*) from tags')->fetchColumn();
|
||||||
|
$entry = new Entry ("Tags", self::ALL_TAGS_ID,
|
||||||
|
"Alphabetical index of the $nTags tags", "text",
|
||||||
|
array ( new LinkNavigation ("?page=".parent::PAGE_ALL_TAGS)));
|
||||||
|
return $entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getTagById ($tagId) {
|
||||||
|
$result = parent::getDb ()->prepare('select id, name from tags where id = ?');
|
||||||
|
$result->execute (array ($tagId));
|
||||||
|
if ($post = $result->fetchObject ()) {
|
||||||
|
return new Tag ($post->id, $post->name);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getAllTags() {
|
||||||
|
$result = parent::getDb ()->query('select tags.id as id, tags.name as name, count(*) as count
|
||||||
|
from tags, books_tags_link
|
||||||
|
where tags.id = tag
|
||||||
|
group by tags.id, tags.name
|
||||||
|
order by tags.name');
|
||||||
|
$entryArray = array();
|
||||||
|
while ($post = $result->fetchObject ())
|
||||||
|
{
|
||||||
|
$tag = new Tag ($post->id, $post->name);
|
||||||
|
array_push ($entryArray, new Entry ($tag->name, $tag->getEntryId (),
|
||||||
|
"$post->count books", "text",
|
||||||
|
array ( new LinkNavigation ($tag->getUri ()))));
|
||||||
|
}
|
||||||
|
return $entryArray;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|