Commit e1483b4e authored by ale's avatar ale

add online ePub reader using epub.js

parent 2a742483
body {
overflow: hidden;
}
#main {
position: absolute;
width: 100%;
height: 100%;
}
#area {
width: 80%;
height: 80%;
margin: 5% auto;
max-width: 1250px;
}
#area iframe {
border: none;
}
#prev {
left: 40px;
}
#next {
right: 40px;
}
.arrow {
position: absolute;
top: 50%;
margin-top: -32px;
font-size: 64px;
color: #e2e2e2;
font-family: arial, sans-serif;
font-weight: bold;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}
.arrow:hover {
color: #777;
}
.arrow:active {
color: #000;
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -2,11 +2,10 @@
<html lang="en">
<head>
<title>LIBER</title>
<meta charset="utf-8">
<link rel="shortcut icon" href="/static/favicon.ico">
<link rel="stylesheet" href="/static/css/bootstrap.min.css">
<link rel="stylesheet" href="/static/css/liber.css">
</head>
<body>
......
......@@ -41,6 +41,15 @@
</p>
{{end}}
{{if .HasEpub}}
<p>
<a class="btn btn-large btn-primary"
href="/read/{{.Book.Id}}/{{.EpubIndex}}">
Read Online
</a>
</p>
{{end}}
</div>
</div>
......
<!DOCTYPE html>
<html lang="en">
<head>
<title>
LIBER - "{{.Book.Metadata.Title}}"
</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<meta name="apple-mobile-web-app-capable" content="yes">
<link rel="shortcut icon" href="/static/favicon.ico">
<link rel="stylesheet" href="/static/css/reader.css">
</head>
<body>
<div id="main">
<div id="prev" class="arrow"></div>
<div id="area"></div>
<div id="next" class="arrow"></div>
</div>
<script src="/static/js/jquery-2.1.1.min.js"></script>
<script src="/static/js/epub.min.js"></script>
<script src="/static/js/zip.min.js"></script>
<script>
EPUBJS.filePath = "/static/js/";
$(function() {
var Book = ePub("/dl/{{.Book.Id}}/{{.FileIndex}}",
{restore: true, contained: true});
$("#prev").click(function() { Book.prevPage(); });
$("#next").click(function() { Book.nextPage(); });
$(window).keydown(function(event) {
//console.log('keydown(): ' + event.which);
if (event.which == 33 || event.which == 37 || event.which == 38) {
Book.prevPage();
} else if (event.which == 32 || event.which == 34 || event.which == 39 || event.which == 40) {
Book.nextPage();
}
});
Book.renderTo("area");
});
</script>
</body>
</html>
......@@ -141,6 +141,38 @@ func (s *uiServer) withBook(f func(*Book, http.ResponseWriter, *http.Request)) h
})
}
func (s *uiServer) withFile(f func(*Book, *File, int, http.ResponseWriter, *http.Request)) http.HandlerFunc {
return s.withBook(func(book *Book, w http.ResponseWriter, req *http.Request) {
vars := mux.Vars(req)
fileIndex, err := strconv.Atoi(vars["fid"])
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
files, err := s.db.GetBookFiles(book.Id)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
if fileIndex < 0 || fileIndex >= len(files) {
http.NotFound(w, req)
return
}
f(book, files[fileIndex], fileIndex, w, req)
})
}
func findEpub(files []*File) int {
for i, f := range files {
if f.FileType == ".epub" {
return i
}
}
return -1
}
func (s *uiServer) handleShowBook(book *Book, w http.ResponseWriter, req *http.Request) {
files, err := s.db.GetBookFiles(book.Id)
if err != nil {
......@@ -149,6 +181,9 @@ func (s *uiServer) handleShowBook(book *Book, w http.ResponseWriter, req *http.R
return
}
// Only offer the online reader if we have an EPUB file.
epubIndex := findEpub(files)
// The book's Description, if present, should be rendered
// directly as HTML. So we deal with it separately.
ctx := struct {
......@@ -156,34 +191,43 @@ func (s *uiServer) handleShowBook(book *Book, w http.ResponseWriter, req *http.R
Book *Book
Files []*File
Description template.HTML
HasEpub bool
EpubIndex int
}{
Book: book,
Files: files,
Description: template.HTML(book.Metadata.Description),
HasEpub: (epubIndex >= 0),
EpubIndex: epubIndex,
}
render("book.html", w, &ctx)
}
func (s *uiServer) handleReadBook(book *Book, file *File, fileIndex int, w http.ResponseWriter, req *http.Request) {
if file.FileType != ".epub" {
http.NotFound(w, req)
return
}
ctx := struct {
Book *Book
File *File
FileIndex int
}{
Book: book,
File: file,
FileIndex: fileIndex,
}
render("reader.html", w, &ctx)
}
var contentTypeMap = map[string]string{
".epub": "application/epub+zip",
".mobi": "application/octet-stream",
".pdf": "application/pdf",
}
func (s *uiServer) handleDownloadBook(book *Book, w http.ResponseWriter, req *http.Request) {
idx, _ := strconv.Atoi(mux.Vars(req)["n"])
files, err := s.db.GetBookFiles(book.Id)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
if idx < 0 || idx >= len(files) {
http.NotFound(w, req)
return
}
file := files[idx]
func (s *uiServer) handleDownloadBook(book *Book, file *File, fileIndex int, w http.ResponseWriter, req *http.Request) {
f, err := s.storage.Open(file.Path)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
......@@ -289,7 +333,8 @@ func NewHttpServer(db *Database, storage, cache *FileStorage, addr string) *http
r.Handle("/book/cover/{id:[0-9]+}", uisrv.withBook(uisrv.handleShowCover))
r.Handle("/book/thumb/{id:[0-9]+}", uisrv.withBook(uisrv.handleShowThumbnail))
r.Handle("/book/{id:[0-9]+}", uisrv.withBook(uisrv.handleShowBook))
r.Handle("/dl/{id:[0-9]+}/{n:[0-9]+}", uisrv.withBook(uisrv.handleDownloadBook))
r.Handle("/read/{id:[0-9]+}/{fid:[0-9]+}", uisrv.withFile(uisrv.handleReadBook))
r.Handle("/dl/{id:[0-9]+}/{fid:[0-9]+}", uisrv.withFile(uisrv.handleDownloadBook))
r.HandleFunc("/suggest", uisrv.handleAutocomplete)
r.HandleFunc("/search", uisrv.handleSearch)
r.HandleFunc("/", uisrv.handleHome)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment