From a1df078f90bc3d9407ebbc8b0cfaa2a3d9273c56 Mon Sep 17 00:00:00 2001 From: Meutel Date: Tue, 1 Aug 2017 20:00:20 +0200 Subject: [PATCH] Book page --- bouquins/bouquins.go | 43 +++++++++---- bouquins/db.go | 145 +++++++++++++++++++++++++++++++++++------- main.go | 30 +++------ templates/book.html | 51 +++++++++------ templates/footer.html | 2 +- 5 files changed, 197 insertions(+), 74 deletions(-) diff --git a/bouquins/bouquins.go b/bouquins/bouquins.go index 9d3ecb7..44d8d96 100644 --- a/bouquins/bouquins.go +++ b/bouquins/bouquins.go @@ -6,6 +6,8 @@ import ( "html/template" "log" "net/http" + "strconv" + "strings" ) const ( @@ -21,6 +23,14 @@ const ( LIST_AUTHORS = "authors" LIST_SERIES = "series" LIST_BOOKS = "books" + + URL_INDEX = "/" + URL_BOOKS = "/books/" + URL_AUTHORS = "/authors/" + URL_SERIES = "/series/" + URL_JS = "/js/" + URL_CSS = "/css/" + URL_FONTS = "/fonts/" ) type Bouquins struct { @@ -42,7 +52,7 @@ type Series struct { type Book struct { Id int64 `json:"id,omitempty"` Title string `json:"title,omitempty"` - SeriesIndex int `json:"series_idx,omitempty"` + SeriesIndex float64 `json:"series_idx,omitempty"` Series *Series `json:"series,omitempty"` } @@ -87,16 +97,16 @@ type AuthorFull struct { type BookFull struct { BookAdv - Data []BookData `json:"data,omitempty"` - Timestamp int64 `json:"timestamp,omitempty"` - Pubdate int64 `json:"pubdate,omitempty"` - Isbn string `json:"isbn,omitempty"` - Lccn string `json:"lccn,omitempty"` - Path string `json:"path,omitempty"` - Uuid string `json:"uuid,omitempty"` - Has_cover bool `json:"has_cover,omitempty"` - Lang string `json:"lang,omitempty"` - Publisher string `json:"publisher,omitempty"` + Data []*BookData `json:"data,omitempty"` + Timestamp int64 `json:"timestamp,omitempty"` + Pubdate int64 `json:"pubdate,omitempty"` + Isbn string `json:"isbn,omitempty"` + Lccn string `json:"lccn,omitempty"` + Path string `json:"path,omitempty"` + Uuid string `json:"uuid,omitempty"` + Has_cover bool `json:"has_cover,omitempty"` + Lang string `json:"lang,omitempty"` + Publisher string `json:"publisher,omitempty"` } type SeriesAdv struct { @@ -187,7 +197,16 @@ func (app *Bouquins) IndexPage(res http.ResponseWriter, req *http.Request) { } } func (app *Bouquins) BooksPage(res http.ResponseWriter, req *http.Request) { - book, err := app.BookFull(123) + if !strings.HasPrefix(req.URL.Path, URL_BOOKS) { + // FIXME 404 + log.Fatalln("Invalid URL") + } + id, err := strconv.Atoi(req.URL.Path[len(URL_BOOKS):]) + if err != nil { + // FIXME 404 + log.Fatalln(err) + } + book, err := app.BookFull(int64(id)) if err != nil { // FIXME 500 log.Fatalln(err) diff --git a/bouquins/db.go b/bouquins/db.go index d51dab8..fdfb47a 100644 --- a/bouquins/db.go +++ b/bouquins/db.go @@ -53,22 +53,20 @@ const ( DEF_LIM = 10 - BOOKS QueryType = 0 - BOOKS_TAGS QueryType = 1 - BOOKS_AUTHORS QueryType = 2 + BOOKS QueryType = iota + BOOKS_TAGS QueryType = iota + BOOKS_AUTHORS QueryType = iota ) var QUERIES = map[Query]string{ - Query{BOOKS, true, true}: STMT_BOOKS_TITLE_DESC, - Query{BOOKS, true, false}: STMT_BOOKS_TITLE_ASC, - Query{BOOKS, false, true}: STMT_BOOKS_ID_DESC, - Query{BOOKS, false, false}: STMT_BOOKS_ID_ASC, - - Query{BOOKS_TAGS, true, true}: STMT_BOOKS_TAGS_TITLE_DESC, - Query{BOOKS_TAGS, true, false}: STMT_BOOKS_TAGS_TITLE_ASC, - Query{BOOKS_TAGS, false, true}: STMT_BOOKS_TAGS_ID_DESC, - Query{BOOKS_TAGS, false, false}: STMT_BOOKS_TAGS_ID_ASC, - + Query{BOOKS, true, true}: STMT_BOOKS_TITLE_DESC, + Query{BOOKS, true, false}: STMT_BOOKS_TITLE_ASC, + Query{BOOKS, false, true}: STMT_BOOKS_ID_DESC, + Query{BOOKS, false, false}: STMT_BOOKS_ID_ASC, + Query{BOOKS_TAGS, true, true}: STMT_BOOKS_TAGS_TITLE_DESC, + Query{BOOKS_TAGS, true, false}: STMT_BOOKS_TAGS_TITLE_ASC, + Query{BOOKS_TAGS, false, true}: STMT_BOOKS_TAGS_ID_DESC, + Query{BOOKS_TAGS, false, false}: STMT_BOOKS_TAGS_ID_ASC, Query{BOOKS_AUTHORS, true, true}: STMT_BOOKS_AUTHORS_TITLE_DESC, Query{BOOKS_AUTHORS, true, false}: STMT_BOOKS_AUTHORS_TITLE_ASC, Query{BOOKS_AUTHORS, false, true}: STMT_BOOKS_AUTHORS_ID_DESC, @@ -83,7 +81,7 @@ type Query struct { } // PREPARED STATEMENTS // -func (app *Bouquins) ps(qt QueryType, sort, order string) (*sql.Stmt, error) { +func (app *Bouquins) psBooks(qt QueryType, sort, order string) (*sql.Stmt, error) { //TODO cache query := QUERIES[Query{qt, sort == "title", order == "desc"}] log.Println(query) @@ -102,7 +100,7 @@ func assignAuthorsTagsBooks(books []*BookAdv, authors map[int64][]*Author, tags func (app *Bouquins) queryBooks(limit, offset int, sort, order string) ([]*BookAdv, error) { books := make([]*BookAdv, 0, limit) - stmt, err := app.ps(BOOKS, sort, order) + stmt, err := app.psBooks(BOOKS, sort, order) if err != nil { return nil, err } @@ -133,7 +131,7 @@ func (app *Bouquins) queryBooks(limit, offset int, sort, order string) ([]*BookA func (app *Bouquins) queryBooksAuthors(limit, offset int, sort, order string) (map[int64][]*Author, error) { authors := make(map[int64][]*Author) - stmt, err := app.ps(BOOKS_AUTHORS, sort, order) + stmt, err := app.psBooks(BOOKS_AUTHORS, sort, order) if err != nil { return nil, err } @@ -160,8 +158,7 @@ func (app *Bouquins) queryBooksAuthors(limit, offset int, sort, order string) (m } func (app *Bouquins) queryBooksTags(limit, offset int, sort, order string) (map[int64][]string, error) { - tags := make(map[int64][]string) - stmt, err := app.ps(BOOKS_TAGS, sort, order) + stmt, err := app.psBooks(BOOKS_TAGS, sort, order) if err != nil { return nil, err } @@ -169,6 +166,7 @@ func (app *Bouquins) queryBooksTags(limit, offset int, sort, order string) (map[ if err != nil { return nil, err } + tags := make(map[int64][]string) for rows.Next() { var tag string var book int64 @@ -187,6 +185,96 @@ func (app *Bouquins) queryBooksTags(limit, offset int, sort, order string) (map[ } return tags, nil } +func (app *Bouquins) queryBook(id int64) (*BookFull, error) { + stmt, err := app.DB.Prepare(STMT_BOOK) + if err != nil { + return nil, err + } + book := new(BookFull) + var seriesIdx sql.NullFloat64 + var seriesId, timestamp, pubdate sql.NullInt64 + var seriesName, isbn, lccn, uuid, lang, publisher sql.NullString + var cover sql.NullBool + err = stmt.QueryRow(id).Scan(&book.Id, &book.Title, &seriesIdx, &seriesName, &seriesId, + ×tamp, &pubdate, &isbn, &lccn, &book.Path, &uuid, &cover, &lang, &publisher) + if err != nil { + return nil, err + } + if seriesId.Valid && seriesName.Valid && seriesIdx.Valid { + book.SeriesIndex = seriesIdx.Float64 + book.Series = &Series{seriesId.Int64, seriesName.String} + } + if timestamp.Valid { + book.Timestamp = timestamp.Int64 + } + if pubdate.Valid { + book.Pubdate = pubdate.Int64 + } + if isbn.Valid { + book.Isbn = isbn.String + } + if lccn.Valid { + book.Lccn = lccn.String + } + if uuid.Valid { + book.Uuid = uuid.String + } + if lang.Valid { + book.Lang = lang.String + } + if publisher.Valid { + book.Publisher = publisher.String + } + if cover.Valid { + book.Has_cover = cover.Bool + } + return book, nil +} +func (app *Bouquins) queryBookTags(book *BookFull) error { + stmt, err := app.DB.Prepare(STMT_BOOK_TAGS) + if err != nil { + return err + } + rows, err := stmt.Query(book.Id) + if err != nil { + return err + } + for rows.Next() { + var tag string + if err = rows.Scan(&tag); err != nil { + return err + } + book.Tags = append(book.Tags, tag) + } + if err := rows.Err(); err != nil { + return err + } + return nil +} +func (app *Bouquins) queryBookAuthors(book *BookFull) error { + stmt, err := app.DB.Prepare(STMT_BOOK_DATA) + if err != nil { + return err + } + rows, err := stmt.Query(book.Id) + if err != nil { + return err + } + for rows.Next() { + data := new(BookData) + if err = rows.Scan(&data.Name, &data.Format, &data.Size); err != nil { + return err + } + book.Data = append(book.Data, data) + } + if err := rows.Err(); err != nil { + return err + } + return nil +} +func (app *Bouquins) queryBookData(book *BookFull) error { + return nil +} // DB LOADS // @@ -204,10 +292,23 @@ func (app *Bouquins) AuthorsAdv(limit, offset int, sort, order string) ([]*Autho } func (app *Bouquins) BookFull(id int64) (*BookFull, error) { - b := new(BookFull) - b.Id = id - b.Title = "test" - return b, nil + book, err := app.queryBook(id) + if err != nil { + return nil, err + } + err = app.queryBookTags(book) + if err != nil { + return nil, err + } + err = app.queryBookAuthors(book) + if err != nil { + return nil, err + } + err = app.queryBookData(book) + if err != nil { + return nil, err + } + return book, nil } func (app *Bouquins) BooksAdv(limit, offset int, sort, order string) ([]*BookAdv, error) { diff --git a/main.go b/main.go index 0fd43e2..4b65a82 100644 --- a/main.go +++ b/main.go @@ -10,7 +10,7 @@ import ( _ "github.com/mattn/go-sqlite3" - "meutel.net/meutel/go-bouquins/bouquins" + . "meutel.net/meutel/go-bouquins/bouquins" ) type BouquinsConf struct { @@ -18,16 +18,6 @@ type BouquinsConf struct { DbPath string `json:"db-path"` } -const ( - INDEX = "/" - BOOKS = "/books/" - AUTHORS = "/authors/" - SERIES = "/series/" - JS = "/js/" - CSS = "/css/" - FONTS = "/fonts/" -) - var db *sql.DB // load config @@ -69,7 +59,7 @@ func initApp() *BouquinsConf { if err != nil { log.Fatalln(err) } - app := &bouquins.Bouquins{ + app := &Bouquins{ tpl, db, } @@ -79,16 +69,16 @@ func initApp() *BouquinsConf { } func assets() { - http.Handle(JS, http.FileServer(http.Dir("assets"))) - http.Handle(CSS, http.FileServer(http.Dir("assets"))) - http.Handle(FONTS, http.FileServer(http.Dir("assets"))) + http.Handle(URL_JS, http.FileServer(http.Dir("assets"))) + http.Handle(URL_CSS, http.FileServer(http.Dir("assets"))) + http.Handle(URL_FONTS, http.FileServer(http.Dir("assets"))) } -func router(app *bouquins.Bouquins) { - http.HandleFunc(INDEX, app.IndexPage) - http.HandleFunc(BOOKS, app.BooksPage) - http.HandleFunc(AUTHORS, app.AuthorsPage) - http.HandleFunc(SERIES, app.SeriesPage) +func router(app *Bouquins) { + http.HandleFunc(URL_INDEX, app.IndexPage) + http.HandleFunc(URL_BOOKS, app.BooksPage) + http.HandleFunc(URL_AUTHORS, app.AuthorsPage) + http.HandleFunc(URL_SERIES, app.SeriesPage) } func main() { diff --git a/templates/book.html b/templates/book.html index e15102e..9fa9c0f 100644 --- a/templates/book.html +++ b/templates/book.html @@ -1,9 +1,12 @@ {{ template "header.html" . }}
-