This repository has been archived on 2025-03-01. You can view files and clone it, but cannot push or open issues or pull requests.
trantor/lib/template.go
2017-05-21 10:47:00 +00:00

225 lines
5.3 KiB
Go

package trantor
import (
html_tmpl "html/template"
txt_tmpl "text/template"
log "github.com/cihub/seelog"
"encoding/json"
"errors"
"net/http"
"path"
"time"
"gitlab.com/trantor/trantor/lib/database"
)
type Status struct {
BaseURL string
FullURL string
Title string
Search string
User string
Role string
Notif []Notification
Updated string
Home bool
About bool
News bool
Upload bool
Stats bool
Help bool
Dasboard bool
}
func GetStatus(h handler) Status {
var s Status
s.BaseURL = "http://" + h.hostname
s.FullURL = s.BaseURL + h.r.RequestURI
s.Title = "Imperial Library of Trantor"
s.User = h.sess.User
s.Role = h.sess.Role
s.Notif = h.sess.GetNotif()
s.Updated = time.Now().UTC().Format("2006-01-02T15:04:05Z")
h.sess.Save(h.w, h.r)
return s
}
type Template struct {
tmpl_html *html_tmpl.Template
tmpl_rss *txt_tmpl.Template
tmpl_opds *txt_tmpl.Template
}
func InitTemplate(assetsPath string) *Template {
var t Template
templatePath := path.Join(assetsPath, "templates")
t.tmpl_html = html_tmpl.Must(html_tmpl.ParseFiles(
path.Join(templatePath, "header.html"),
path.Join(templatePath, "footer.html"),
path.Join(templatePath, "404.html"),
path.Join(templatePath, "index.html"),
path.Join(templatePath, "about.html"),
path.Join(templatePath, "news.html"),
path.Join(templatePath, "edit_news.html"),
path.Join(templatePath, "book.html"),
path.Join(templatePath, "search.html"),
path.Join(templatePath, "upload.html"),
path.Join(templatePath, "login.html"),
path.Join(templatePath, "new.html"),
path.Join(templatePath, "read.html"),
path.Join(templatePath, "edit.html"),
path.Join(templatePath, "dashboard.html"),
path.Join(templatePath, "settings.html"),
path.Join(templatePath, "stats.html"),
path.Join(templatePath, "help.html"),
))
t.tmpl_rss = txt_tmpl.Must(txt_tmpl.ParseFiles(
path.Join(templatePath, "search.rss"),
path.Join(templatePath, "news.rss"),
))
t.tmpl_opds = txt_tmpl.Must(txt_tmpl.ParseFiles(
path.Join(templatePath, "index.opds"),
path.Join(templatePath, "search.opds"),
))
return &t
}
func (t Template) load(h handler, tmpl string, data interface{}) {
var err error
fmt := h.r.FormValue("fmt")
switch fmt {
case "rss":
err = t.tmpl_rss.ExecuteTemplate(h.w, tmpl+".rss", data)
case "opds":
err = t.tmpl_opds.ExecuteTemplate(h.w, tmpl+".opds", data)
case "json":
err = loadJson(h.w, tmpl, data)
default:
err = t.tmpl_html.ExecuteTemplate(h.w, tmpl+".html", data)
}
if err != nil {
t.tmpl_html.ExecuteTemplate(h.w, "404.html", data)
log.Warn("An error ocurred loading the template ", tmpl, ".", fmt, ": ", err)
}
}
func loadJson(w http.ResponseWriter, tmpl string, data interface{}) error {
var res []byte
var err error
switch tmpl {
case "index":
res, err = indexJson(data)
case "book":
res, err = bookJson(data)
case "news":
res, err = newsJson(data)
case "search":
res, err = searchJson(data)
}
if err != nil {
return err
}
_, err = w.Write(res)
return err
}
func indexJson(data interface{}) ([]byte, error) {
index, ok := data.(indexData)
if !ok {
return nil, errors.New("Data is not valid")
}
books := make([]map[string]interface{}, len(index.Books))
for i, book := range index.Books {
books[i] = bookJsonRaw(book)
}
news := newsJsonRaw(index.News)
return json.Marshal(map[string]interface{}{
"title": index.S.Title,
"url": index.S.BaseURL,
"count": index.Count,
"news": news,
"tags": index.Tags,
"last_added": books,
})
}
func bookJson(data interface{}) ([]byte, error) {
book, ok := data.(bookData)
if !ok {
return nil, errors.New("Data is not valid")
}
return json.Marshal(bookJsonRaw(book.Book))
}
func newsJson(data interface{}) ([]byte, error) {
news, ok := data.(newsData)
if !ok {
return nil, errors.New("Data is not valid")
}
return json.Marshal(newsJsonRaw(news.News))
}
func newsJsonRaw(news []newsEntry) []map[string]string {
list := make([]map[string]string, len(news))
for i, n := range news {
list[i] = map[string]string{
"date": n.Date,
"text": n.Text,
}
}
return list
}
func searchJson(data interface{}) ([]byte, error) {
search, ok := data.(searchData)
if !ok {
return nil, errors.New("Data is not valid")
}
books := make([]map[string]interface{}, len(search.Books))
for i, book := range search.Books {
books[i] = bookJsonRaw(book)
}
return json.Marshal(map[string]interface{}{
"found": search.Found,
"page": search.Page - 1,
"items": search.ItemsPage,
"books": books,
})
}
func bookJsonRaw(book database.Book) map[string]interface{} {
cover := ""
coverSmall := ""
if book.Cover {
cover = "/cover/" + book.Id + "/big/" + book.Title + ".jpg"
coverSmall = "/cover/" + book.Id + "/small/" + book.Title + ".jpg"
}
return map[string]interface{}{
"id": book.Id,
"title": book.Title,
"authors": book.Authors,
"contributor": book.Contributor,
"publisher": book.Publisher,
"description": book.Description,
"tags": book.Tags,
"date": book.Date,
"lang": book.Lang,
"isbn": book.Isbn,
"size": book.FileSize,
"cover": cover,
"cover_small": coverSmall,
"download": "/download/" + book.Id + "/" + book.Title + ".epub",
"read": "/read/" + book.Id,
}
}