Posted By

minky on 06/13/10


Tagged

curl php php5 pixaweb calibre


Versions (?)

Calibre Remote - PHP5 Class


 / Published in: PHP
 

URL: http://www.pixaweb.co.uk/calibre/

forms part of our Calibre Remote Web App. basically an alternate gui for calibre ebooks content-server.

  1. <?php
  2.  
  3. class calibre {
  4.  
  5. public $settings = array(
  6. "server" => array(
  7. // calibre server details
  8. "host" => "minky.mine.nu",
  9. "port" => "8080",
  10. "username" => "",
  11. "password" => "",
  12. ),
  13. // calibre server tokens/values
  14. "start" => 0,
  15. "num" => 20,
  16. "order" => "ascending",
  17. "sort" => "title",
  18. "search" => "",
  19. );
  20.  
  21. // .. curl data
  22. private $curl_meta, $curl_data;
  23.  
  24. // xml, object (simplexml) data
  25. private $xml, $object;
  26.  
  27. // html data
  28. private $paginate;
  29.  
  30. private $authors = array();
  31. private $series = array();
  32.  
  33. public function __construct() {}
  34.  
  35. public function debug() {
  36.  
  37. echo "<pre>";
  38. print_r($this);
  39. echo "</pre>";
  40. die;
  41.  
  42. }
  43.  
  44. private function fetch_query_string() {
  45.  
  46. $data = $this->settings;
  47.  
  48. unset($data["server"]);
  49.  
  50. return "?". http_build_query($data, "&amp;");
  51.  
  52. }
  53.  
  54. private function parse_response() {
  55.  
  56. try {
  57.  
  58. $this->object = new SimpleXMLElement($this->curl_data);
  59.  
  60. $this->xml = $this->object->asXML();
  61.  
  62. } catch(Exception $e) {
  63. throw new CalibreException($e->getMessage());
  64. }
  65.  
  66. }
  67.  
  68. public function set($settings) {
  69.  
  70. if(is_array($settings)) {
  71.  
  72. foreach($settings AS $key => $value) {
  73.  
  74. if(empty($key) || empty($value)) continue;
  75.  
  76. $this->settings[$key] = $value;
  77.  
  78. }
  79. }
  80.  
  81. return $this;
  82.  
  83. }
  84.  
  85. public function fetch_library() {
  86.  
  87. if(empty($this->settings["server"]["host"]) || empty($this->settings["server"]["port"]))
  88. throw new CalibreException('No Server/Port Defined! <a class="button define server" href="#define">Define Server Settings</a>');
  89.  
  90. $qs = $this->fetch_query_string();
  91.  
  92. $curl = curl_init();
  93.  
  94. if(!empty($this->settings["server"]["username"]) && !empty($this->settings["server"]["password"])) {
  95.  
  96. curl_setopt($curl, CURLOPT_USERPWD, "{$this->settings["server"]["username"]}:{$this->settings["server"]["password"]}");
  97. curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
  98.  
  99. }
  100.  
  101. curl_setopt_array($curl, array(
  102. CURLOPT_RETURNTRANSFER => TRUE,
  103. CURLOPT_HEADER => 0,
  104. CURLOPT_USERAGENT => "",
  105. CURLOPT_URL => "http://{$this->settings["server"]["host"]}/library{$qs}",
  106. CURLOPT_PORT => $this->settings["server"]["port"],
  107. CURLOPT_TIMEOUT => 3,
  108. ));
  109.  
  110. $this->curl_data = curl_exec($curl);
  111. $this->curl_meta = curl_getinfo($curl);
  112.  
  113. curl_close($curl);
  114.  
  115. if($this->curl_data === FALSE)
  116. throw new CalibreException('cURL Data is empty! Is the Server running? <a class="button define server" href="#define">Define Server Settings</a>');
  117.  
  118. try {
  119. $this->parse_response();
  120. } catch(CalibreException $e) {
  121. throw new CalibreException($e->getMessage());
  122. }
  123.  
  124. return $this;
  125.  
  126. }
  127.  
  128. public function as_json() {
  129. return json_encode($this->object);
  130. }
  131.  
  132. public function as_object() {
  133. return $this->object;
  134. }
  135.  
  136. public function as_xml() {
  137. return $this->xml;
  138. }
  139.  
  140. private function page_select($page_count, $current = 1) {
  141.  
  142. $options = array();
  143.  
  144. for($i = 1; $i <= $page_count; $i++) {
  145.  
  146. $selected = $i == $current ? "selected" : "" ;
  147.  
  148. $options[] = '<option value="'. $i .'" '. $selected .'>'. $i .'</option>';
  149.  
  150. }
  151.  
  152. return '<select class="paginate">'. implode("", $options) .'</select>';
  153.  
  154. }
  155.  
  156. public function paginate($total) {
  157.  
  158. $page_count = ceil($total / $this->settings["num"]);
  159.  
  160. $current = ceil($this->settings["start"] / $this->settings["num"]);
  161. $current = empty($current) ? 1 : $current ;
  162.  
  163. $prev = $current == 1 ? 1 : $current - 1 ;
  164. $next = $current == $page_count ? $page_count : $current + 1 ;
  165.  
  166. $links = array();
  167.  
  168. $links[] = '
  169. <section class="paginate">
  170. <ul>
  171. <li class="prev">
  172. <a href="page/'. $prev .'" class="button">&laquo; Prev</a>
  173. </li>
  174. <li class="current">'. $this->page_select($page_count, $current) .' of '. $page_count .'</li>
  175. <li class="next">
  176. <a href="page/'. $next .'" class="button">Next &raquo;</a>
  177. </li>
  178. </ul>
  179. </section>
  180. ';
  181.  
  182. $this->paginate = implode("", $links);
  183.  
  184. }
  185.  
  186. public function parse_html($book) {
  187.  
  188. $data = array();
  189.  
  190. foreach($book->attributes() AS $key => $value) {
  191.  
  192. if($key == "formats") {
  193. $data[$key] = $this->parse_formats((string) $value, $data["title"], $data["id"]);
  194. } elseif($key == "authors") {
  195. $data[$key] = $this->parse_authors((string) $value);
  196. } elseif($key == "series") {
  197. $data[$key] = $this->parse_series((string) $value);
  198. } else {
  199. $data[$key] = (string) $value;
  200. }
  201. }
  202.  
  203. return $data;
  204.  
  205. }
  206.  
  207. private function parse_formats($format, $title, $id) {
  208.  
  209. $formats = stristr($format, ",") ? explode(",", $format) : array($format) ;
  210.  
  211. $output = array();
  212.  
  213. foreach($formats AS $f)
  214. $output[] = '<a href="http://'. $this->settings["server"]["host"] .':'. $this->settings["server"]["port"] .'/get/'. strtolower($f) .'/'. $title .'_'. $id .'.'. strtolower($f) .'" class="file button">'. strtoupper($f) .'</a>';
  215.  
  216. return implode("", $output);
  217.  
  218. }
  219.  
  220. private function parse_authors($authors) {
  221.  
  222. $authors = stristr($authors, ",") ? explode(",", $authors) : array($authors) ;
  223.  
  224. $output = array();
  225.  
  226. foreach($authors AS $author)
  227. $output[] = ucwords(trim($author));
  228.  
  229. $this->authors = array_merge($this->authors, $output);
  230.  
  231. return implode("", $output);
  232.  
  233. }
  234.  
  235. private function parse_series($series) {
  236. return empty($series) ? "Unknown" : ucwords($series) ;
  237. }
  238.  
  239. public function as_html() {
  240.  
  241. $books = array();
  242.  
  243. $attrib = $this->object->attributes();
  244.  
  245. $this->paginate((int) $attrib->total);
  246.  
  247. foreach($this->object->children() AS $key => $value) {
  248.  
  249. $book = $this->parse_html($value);
  250.  
  251. $this->series[] = $book["series"];
  252.  
  253. $books[] = '
  254. <article class="book">
  255.  
  256. <header><h2>'. $book["title"] .'</h2></header>
  257.  
  258. <section class="content">
  259.  
  260. <section class="details float-left">
  261.  
  262. <ul>
  263.  
  264. <li class="author">
  265. <span class="label">Author</span>
  266. <span class="data">'. $book["authors"] .'</span>
  267. </li>
  268. <li class="author">
  269. <span class="label">Series</span>
  270. <span class="data">'. $book["series"] .'</span>
  271. </li>
  272. <li class="formats">
  273. <span class="label">Download</span>
  274. <span class="data">'. $book["formats"] .'</span>
  275. </li>
  276.  
  277. </ul>
  278.  
  279. </section>
  280.  
  281. <section class="image float-right">
  282.  
  283. <img src="http://'. $this->settings["server"]["host"] .':'. $this->settings["server"]["port"] .'/get/cover/'. $book["id"] .'" alt="Cover Image" />
  284.  
  285. </section>
  286.  
  287. </section>
  288.  
  289. </article>
  290. ';
  291. }
  292.  
  293. $paginate = $this->paginate;
  294.  
  295. return $paginate . implode("", $books) . $paginate;
  296.  
  297. }
  298.  
  299. }
  300.  
  301. class CalibreException extends Exception {
  302. public function __construct($message, $code = 0) {
  303. parent::__construct($message, $code);
  304. }
  305. }
  306. //
  307. $calibre = new calibre;
  308. //
  309. $sort = empty($_GET['sort']) ? $calibre->settings["sort"] : $_GET['sort'] ;
  310. $order = empty($_GET['order']) ? $calibre->settings["order"] : $_GET['order'] ;
  311. $search = empty($_GET['search']) ? "" : $_GET['search'] ;
  312. //
  313. $start = empty($_GET['start']) ? 0 : (int) $_GET['start'] ;
  314. $per_page = $calibre->settings["num"];
  315.  
  316. $server = array(
  317. "host" => $_GET['host'],
  318. "port" => $_GET['port'],
  319. "username" => $_GET['username'],
  320. "password" => $_GET['password'],
  321. );
  322. //
  323. $settings = array(
  324. "start" => $start * $per_page,
  325. "num" => $per_page,
  326. "sort" => $sort,
  327. "order" => $order,
  328. "search"=> $search,
  329. "server"=> $server,
  330. );
  331.  
  332. // try getting library as html
  333. try {
  334. echo $calibre->set($settings)->fetch_library()->as_html();
  335. } catch(CalibreException $e) {
  336. echo '<article class="error">'. $e->getMessage() .'</article>';
  337. }
  338.  
  339. die;
  340.  
  341. //$calibre->debug(); // very long page
  342.  
  343. ?>

Report this snippet  

You need to login to post a comment.