Calibre OPDS (and HTML) PHP Server : web-based light alternative to Calibre content server / Calibre2OPDS to serve ebooks (epub, mobi, pdf, ...) http://blog.slucas.fr/en/oss/calibre-opds-php-server
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

208 lines
7.0KB

  1. <?php
  2. /**
  3. * COPS (Calibre OPDS PHP Server) class file
  4. *
  5. * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
  6. * @author Sébastien Lucas <sebastien@slucas.fr>
  7. */
  8. require_once('base.php');
  9. class Data extends Base {
  10. public $id;
  11. public $name;
  12. public $format;
  13. public $realFormat;
  14. public $extension;
  15. public $book;
  16. public static $mimetypes = array(
  17. 'aac' => 'audio/aac',
  18. 'azw' => 'application/x-mobipocket-ebook',
  19. 'azw1' => 'application/x-topaz-ebook',
  20. 'azw2' => 'application/x-kindle-application',
  21. 'azw3' => 'application/x-mobi8-ebook',
  22. 'cbz' => 'application/x-cbz',
  23. 'cbr' => 'application/x-cbr',
  24. 'djv' => 'image/vnd.djvu',
  25. 'djvu' => 'image/vnd.djvu',
  26. 'doc' => 'application/msword',
  27. 'epub' => 'application/epub+zip',
  28. 'fb2' => 'text/fb2+xml',
  29. 'ibooks'=> 'application/x-ibooks+zip',
  30. 'kepub' => 'application/epub+zip',
  31. 'kobo' => 'application/x-koboreader-ebook',
  32. 'm4a' => 'audio/mp4',
  33. 'mobi' => 'application/x-mobipocket-ebook',
  34. 'mp3' => 'audio/mpeg',
  35. 'lit' => 'application/x-ms-reader',
  36. 'lrs' => 'text/x-sony-bbeb+xml',
  37. 'lrf' => 'application/x-sony-bbeb',
  38. 'lrx' => 'application/x-sony-bbeb',
  39. 'ncx' => 'application/x-dtbncx+xml',
  40. 'opf' => 'application/oebps-package+xml',
  41. 'otf' => 'application/x-font-opentype',
  42. 'pdb' => 'application/vnd.palm',
  43. 'pdf' => 'application/pdf',
  44. 'prc' => 'application/x-mobipocket-ebook',
  45. 'rtf' => 'application/rtf',
  46. 'svg' => 'image/svg+xml',
  47. 'ttf' => 'application/x-font-truetype',
  48. 'tpz' => 'application/x-topaz-ebook',
  49. 'wav' => 'audio/wav',
  50. 'wmf' => 'image/wmf',
  51. 'xhtml' => 'application/xhtml+xml',
  52. 'xpgt' => 'application/adobe-page-template+xml',
  53. 'zip' => 'application/zip'
  54. );
  55. public function __construct($post, $book = null) {
  56. $this->id = $post->id;
  57. $this->name = $post->name;
  58. $this->format = $post->format;
  59. $this->realFormat = str_replace ("ORIGINAL_", "", $post->format);
  60. $this->extension = strtolower ($this->realFormat);
  61. $this->book = $book;
  62. }
  63. public function isKnownType () {
  64. return array_key_exists ($this->extension, self::$mimetypes);
  65. }
  66. public function getMimeType () {
  67. $result = "application/octet-stream";
  68. if ($this->isKnownType ()) {
  69. return self::$mimetypes [$this->extension];
  70. } elseif (function_exists('finfo_open') === true) {
  71. $finfo = finfo_open(FILEINFO_MIME_TYPE);
  72. if (is_resource($finfo) === true)
  73. {
  74. $result = finfo_file($finfo, $this->getLocalPath ());
  75. }
  76. finfo_close($finfo);
  77. }
  78. return $result;
  79. }
  80. public function isEpubValidOnKobo () {
  81. return $this->format == "EPUB" || $this->format == "KEPUB";
  82. }
  83. public function getFilename () {
  84. return $this->name . "." . strtolower ($this->format);
  85. }
  86. public function getUpdatedFilename () {
  87. return $this->book->getAuthorsSort () . " - " . $this->book->title;
  88. }
  89. public function getUpdatedFilenameEpub () {
  90. return $this->getUpdatedFilename () . ".epub";
  91. }
  92. public function getUpdatedFilenameKepub () {
  93. return $this->getUpdatedFilename () . ".kepub.epub";
  94. }
  95. public function getDataLink ($rel, $title = NULL) {
  96. global $config;
  97. if ($rel == Link::OPDS_ACQUISITION_TYPE && $config['cops_use_url_rewriting'] == "1") {
  98. return $this->getHtmlLinkWithRewriting($title);
  99. }
  100. return self::getLink ($this->book, $this->extension, $this->getMimeType (), $rel, $this->getFilename (), $this->id, $title);
  101. }
  102. public function getHtmlLink () {
  103. return $this->getDataLink(Link::OPDS_ACQUISITION_TYPE)->href;
  104. }
  105. public function getLocalPath () {
  106. return $this->book->path . "/" . $this->getFilename ();
  107. }
  108. public function getHtmlLinkWithRewriting ($title = NULL) {
  109. global $config;
  110. $database = "";
  111. if (!is_null (GetUrlParam (DB))) $database = GetUrlParam (DB) . "/";
  112. $href = "download/" . $this->id . "/" . $database;
  113. if ($config['cops_provide_kepub'] == "1" &&
  114. $this->isEpubValidOnKobo () &&
  115. preg_match("/Kobo/", $_SERVER['HTTP_USER_AGENT'])) {
  116. $href .= rawurlencode ($this->getUpdatedFilenameKepub ());
  117. } else {
  118. $href .= rawurlencode ($this->getFilename ());
  119. }
  120. return new Link ($href, $this->getMimeType (), Link::OPDS_ACQUISITION_TYPE, $title);
  121. }
  122. public static function getDataByBook ($book) {
  123. $out = array ();
  124. $result = parent::getDb ()->prepare('select id, format, name
  125. from data where book = ?');
  126. $result->execute (array ($book->id));
  127. while ($post = $result->fetchObject ())
  128. {
  129. array_push ($out, new Data ($post, $book));
  130. }
  131. return $out;
  132. }
  133. public static function handleThumbnailLink ($urlParam, $height) {
  134. global $config;
  135. if (is_null ($height)) {
  136. if (preg_match ('/feed.php/', $_SERVER["SCRIPT_NAME"])) {
  137. $height = $config['cops_opds_thumbnail_height'];
  138. }
  139. else
  140. {
  141. $height = $config['cops_html_thumbnail_height'];
  142. }
  143. }
  144. if ($config['cops_thumbnail_handling'] != "1") {
  145. $urlParam = addURLParameter($urlParam, "height", $height);
  146. }
  147. return $urlParam;
  148. }
  149. public static function getLink ($book, $type, $mime, $rel, $filename, $idData, $title = NULL, $height = NULL)
  150. {
  151. global $config;
  152. $urlParam = addURLParameter("", "data", $idData);
  153. if (Base::useAbsolutePath () ||
  154. $rel == Link::OPDS_THUMBNAIL_TYPE ||
  155. ($type == "epub" && $config['cops_update_epub-metadata']))
  156. {
  157. if ($type != "jpg") $urlParam = addURLParameter($urlParam, "type", $type);
  158. if ($rel == Link::OPDS_THUMBNAIL_TYPE) {
  159. $urlParam = self::handleThumbnailLink($urlParam, $height);
  160. }
  161. $urlParam = addURLParameter($urlParam, "id", $book->id);
  162. if (!is_null (GetUrlParam (DB))) $urlParam = addURLParameter ($urlParam, DB, GetUrlParam (DB));
  163. if ($config['cops_thumbnail_handling'] != "1" &&
  164. !empty ($config['cops_thumbnail_handling']) &&
  165. $rel == Link::OPDS_THUMBNAIL_TYPE) {
  166. return new Link ($config['cops_thumbnail_handling'], $mime, $rel, $title);
  167. } else {
  168. return new Link ("fetch.php?" . $urlParam, $mime, $rel, $title);
  169. }
  170. }
  171. else
  172. {
  173. return new Link (str_replace('%2F','/',rawurlencode ($book->path."/".$filename)), $mime, $rel, $title);
  174. }
  175. }
  176. }