template.go 4.95 KB
Newer Older
1
package trantor
2

Las Zenow's avatar
Las Zenow committed
3
import (
4
	html_tmpl "html/template"
Las Zenow's avatar
Las Zenow committed
5
	txt_tmpl "text/template"
Las Zenow's avatar
Las Zenow committed
6

7 8
	log "github.com/cihub/seelog"

Las Zenow's avatar
Las Zenow committed
9 10 11
	"encoding/json"
	"errors"
	"net/http"
12
	"path"
Las Zenow's avatar
Las Zenow committed
13
	"strings"
Las Zenow's avatar
Las Zenow committed
14
	"time"
Las Zenow's avatar
Las Zenow committed
15

16
	"gitlab.com/trantor/trantor/lib/database"
Las Zenow's avatar
Las Zenow committed
17
)
18

Las Zenow's avatar
Las Zenow committed
19
type Status struct {
Las Zenow's avatar
Las Zenow committed
20 21
	BaseURL  string
	FullURL  string
Las Zenow's avatar
Las Zenow committed
22
	Title    string
Las Zenow's avatar
Las Zenow committed
23 24
	Search   string
	User     string
Las Zenow's avatar
Las Zenow committed
25
	Role     string
Las Zenow's avatar
Las Zenow committed
26
	Notif    []Notification
Las Zenow's avatar
Las Zenow committed
27
	Updated  string
Las Zenow's avatar
Las Zenow committed
28 29 30 31 32 33 34
	Home     bool
	About    bool
	News     bool
	Upload   bool
	Stats    bool
	Help     bool
	Dasboard bool
Las Zenow's avatar
Las Zenow committed
35 36
}

37
func GetStatus(h handler) Status {
Las Zenow's avatar
Las Zenow committed
38
	var s Status
39
	s.BaseURL = "http://" + h.hostname
40
	s.FullURL = s.BaseURL + h.r.RequestURI
Las Zenow's avatar
Las Zenow committed
41
	s.Title = "Imperial Library of Trantor"
42
	s.User = h.sess.User
Las Zenow's avatar
Las Zenow committed
43
	s.Role = h.sess.Role
44
	s.Notif = h.sess.GetNotif()
Las Zenow's avatar
Las Zenow committed
45
	s.Updated = time.Now().UTC().Format("2006-01-02T15:04:05Z")
46
	h.sess.Save(h.w, h.r)
Las Zenow's avatar
Las Zenow committed
47 48 49
	return s
}

50
type Template struct {
51 52 53
	html *html_tmpl.Template
	rss  *txt_tmpl.Template
	opds *txt_tmpl.Template
54 55 56
}

func InitTemplate(assetsPath string) *Template {
57
	var err error
58 59 60
	var t Template
	templatePath := path.Join(assetsPath, "templates")

Las Zenow's avatar
Las Zenow committed
61 62 63
	t.html, err = html_tmpl.New("html").Funcs(html_tmpl.FuncMap{
		"strings_join": strings.Join,
	}).ParseGlob(path.Join(templatePath, "*.html"))
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
	if err != nil {
		log.Critical("Error loading html templates: ", err)
	}

	t.rss, err = txt_tmpl.New("rss").Funcs(txt_tmpl.FuncMap{
		"book_list": func(books, baseURL interface{}) (map[string]interface{}, error) {
			data := make(map[string]interface{}, 2)
			data["Books"] = books
			data["BaseURL"] = baseURL
			return data, nil
		},
	}).ParseGlob(path.Join(templatePath, "*.rss"))
	if err != nil {
		log.Critical("Error loading rss templates: ", err)
	}

	t.opds, err = txt_tmpl.ParseGlob(path.Join(templatePath, "*.opds"))
	if err != nil {
		log.Critical("Error loading opds templates: ", err)
	}
84 85 86 87

	return &t
}

Las Zenow's avatar
Las Zenow committed
88 89 90 91 92 93 94 95 96 97 98 99
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)
100 101
	case "list":
		res, err = listJson(data)
Las Zenow's avatar
Las Zenow committed
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
	}
	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{}{
Las Zenow's avatar
Las Zenow committed
123
		"title":      index.S.Title,
Las Zenow's avatar
Las Zenow committed
124 125 126 127
		"url":        index.S.BaseURL,
		"count":      index.Count,
		"news":       news,
		"tags":       index.Tags,
Las Zenow's avatar
Las Zenow committed
128
		"last_added": books,
Las Zenow's avatar
Las Zenow committed
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
	})
}

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)
	}
171 172 173 174 175 176
	return json.Marshal(map[string]interface{}{
		"found": search.Found,
		"page":  search.Page - 1,
		"items": search.ItemsPage,
		"books": books,
	})
Las Zenow's avatar
Las Zenow committed
177 178
}

179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197
func listJson(data interface{}) ([]byte, error) {
	list, ok := data.(listData)
	if !ok {
		return nil, errors.New("Data is not valid")
	}

	books := make([]map[string]interface{}, len(list.List.Books))
	for i, book := range list.List.Books {
		books[i] = bookJsonRaw(book)
	}
	return json.Marshal(map[string]interface{}{
		"ID":          list.List.ListID,
		"title":       list.List.Title,
		"description": list.List.Description,
		"user ":       list.List.User.Username,
		"books":       books,
	})
}

Las Zenow's avatar
Las Zenow committed
198 199 200 201
func bookJsonRaw(book database.Book) map[string]interface{} {
	cover := ""
	coverSmall := ""
	if book.Cover {
Las Zenow's avatar
Las Zenow committed
202 203
		cover = "/cover/" + book.ID + "/big/" + book.Title + ".jpg"
		coverSmall = "/cover/" + book.ID + "/small/" + book.Title + ".jpg"
Las Zenow's avatar
Las Zenow committed
204 205
	}
	return map[string]interface{}{
Las Zenow's avatar
Las Zenow committed
206
		"id":          book.ID,
Las Zenow's avatar
Las Zenow committed
207
		"title":       book.Title,
208
		"authors":     book.Authors,
Las Zenow's avatar
Las Zenow committed
209 210 211
		"contributor": book.Contributor,
		"publisher":   book.Publisher,
		"description": book.Description,
212
		"tags":        book.Tags,
Las Zenow's avatar
Las Zenow committed
213 214 215 216 217 218
		"date":        book.Date,
		"lang":        book.Lang,
		"isbn":        book.Isbn,
		"size":        book.FileSize,
		"cover":       cover,
		"cover_small": coverSmall,
Las Zenow's avatar
Las Zenow committed
219 220
		"download":    "/download/" + book.ID + "/" + book.Title + ".epub",
		"read":        "/read/" + book.ID,
Las Zenow's avatar
Las Zenow committed
221 222
	}
}