-
Notifications
You must be signed in to change notification settings - Fork 230
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
1,308 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
0.0.1 - 20120302 | ||
* First public release |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
= COPS = | ||
|
||
COPS stands for Calibre OPDS Php Server. | ||
|
||
COPS output is valid the unofficial OPDS validator : | ||
http://opds-validator.appspot.com/ | ||
|
||
= Why ? = | ||
|
||
In my opinion Calibre is a marvelous tool but is too big and has too much | ||
dependancies to be used for its content server. | ||
|
||
That's the main reason why I coded this OPDS server. I needed a simple | ||
tool to be installed on a small server (Seagate Dockstar in my case). | ||
|
||
I initially thought of Calibre2OPDS but as it generate static file no | ||
search was possible. | ||
|
||
So COPS's main advantages are : | ||
* No need for many dependancies. | ||
* No need for a lot of CPU or RAM. | ||
* Not much code. | ||
* Search is available. | ||
* With Dropbox it's very easy to have an up to date OPDS server. | ||
* It was fun to code. | ||
|
||
= Prerequisites = | ||
|
||
1. PHP 5.3 with GD image processing & SQLite3 support. | ||
2. A web server with PHP support. I only tested with Nginx 1.1.14. For now | ||
there is support for X-Accel-Redirect which is Nginx specific. | ||
3. The path to a calibre library (metadata.db, format, & cover files). | ||
|
||
On any Debian base Linux you can use : | ||
aptitude install php5-gd php5-sqlite | ||
|
||
= Install = | ||
|
||
1. Extract the zip file to a folder in web space (visible to the web server). | ||
2. If a first-time install, copy config_default.php to config_local.php | ||
3. Edit config_local.php to match your config. | ||
|
||
In my case I installed COPS in a subdomain. Here is my nginx config file : | ||
server { | ||
|
||
listen [::]:80; | ||
|
||
server_name opds.mydomain.com; | ||
|
||
access_log /var/log/nginx/opds.access.log; | ||
error_log /var/log/nginx/opds.error.log; | ||
root /var/www/opds; | ||
index feed.php; | ||
|
||
location ~ \.php$ { | ||
include /etc/nginx/fastcgi_params; | ||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; | ||
fastcgi_pass unix:/tmp/fcgi.sock; | ||
} | ||
|
||
location /Calibre { | ||
root /home/calibre/Dropbox; | ||
internal; | ||
} | ||
} | ||
|
||
Beware in this case my Calibre database is in /home/calibre/Dropbox/Calibre/ so | ||
the internal location of nginx has to split like that. | ||
|
||
If your Calibre database is inside your web directory then there is no need for | ||
an internal location. | ||
|
||
If you choose to put your Calibre directory inside your web directory then you | ||
will have to edit /etc/nginx/mime.types to add this line : | ||
application/epub+zip epub; | ||
|
||
= Known problems = | ||
|
||
* Only tested with Nginx. | ||
* Contain Nginx specific code. | ||
* Only works with EPUB (not MOBI or PDF). | ||
* certainly many many more. | ||
|
||
= Disclaimer = | ||
|
||
I only tested on Debian with Nginx so I have stricly no idea if it works | ||
with Apache or any other web server. | ||
|
||
On the OPDS client side I mainly tested with FBReader and Aldiko on Android. | ||
|
||
= Copyright & License = | ||
|
||
COPS - 2012 (c) S�bastien Lucas <[email protected]> | ||
|
||
See COPYING and file headers for license info | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
<?php | ||
/** | ||
* COPS (Calibre OPDS PHP Server) class file | ||
* | ||
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html) | ||
* @author Sébastien Lucas <[email protected]> | ||
*/ | ||
|
||
require_once('base.php'); | ||
|
||
class Author extends Base { | ||
const ALL_AUTHORS_ID = "calibre:authors"; | ||
|
||
public $id; | ||
public $name; | ||
public $sort; | ||
|
||
public function __construct($pid, $pname) { | ||
$this->id = $pid; | ||
$this->name = $pname; | ||
} | ||
|
||
public function getUri () { | ||
return "feed.php?page=".parent::PAGE_AUTHOR_DETAIL."&id=$this->id"; | ||
} | ||
|
||
public function getEntryId () { | ||
return self::ALL_AUTHORS_ID.":".$this->id; | ||
} | ||
|
||
|
||
public static function getCount() { | ||
$nAuthors = parent::getDb ()->query('select count(*) from authors')->fetchColumn(); | ||
parent::addEntryClass ( new Entry ("Authors", self::ALL_AUTHORS_ID, | ||
"Alphabetical index of the $nAuthors authors", "text", | ||
array ( new LinkNavigation ("feed.php?page=".parent::PAGE_ALL_AUTHORS)))); | ||
} | ||
|
||
public static function getAllAuthors() { | ||
$result = parent::getDb ()->query('select authors.id as id, authors.name as name, authors.sort as sort, count(*) as count | ||
from authors, books_authors_link | ||
where author = authors.id | ||
group by authors.id, authors.name, authors.sort | ||
order by sort'); | ||
while ($post = $result->fetchObject ()) | ||
{ | ||
$author = new Author ($post->id, $post->sort); | ||
parent::addEntryClass ( new Entry ($post->sort, $author->getEntryId (), | ||
"$post->count books", "text", | ||
array ( new LinkNavigation ($author->getUri ())))); | ||
} | ||
} | ||
|
||
public static function getAuthorName ($authorId) { | ||
$result = parent::getDb ()->prepare('select sort from authors where id = ?'); | ||
$result->execute (array ($authorId)); | ||
return $result->fetchColumn (); | ||
} | ||
|
||
public static function getAuthorByBookId ($bookId) { | ||
$result = parent::getDb ()->prepare('select authors.id as id, authors.sort as sort | ||
from authors, books_authors_link | ||
where author = authors.id | ||
and book = ?'); | ||
$result->execute (array ($bookId)); | ||
$authorArray = array (); | ||
while ($post = $result->fetchObject ()) { | ||
array_push ($authorArray, new Author ($post->id, $post->sort)); | ||
} | ||
return $authorArray; | ||
} | ||
} | ||
?> |
Oops, something went wrong.