WIP: author page
This commit is contained in:
parent
c76ba90fa1
commit
3ab0198f21
@ -162,6 +162,11 @@ type SeriesModel struct {
|
|||||||
*SeriesFull
|
*SeriesFull
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type AuthorModel struct {
|
||||||
|
BouquinsModel
|
||||||
|
*AuthorFull
|
||||||
|
}
|
||||||
|
|
||||||
func (app *Bouquins) render(res http.ResponseWriter, tpl string, model interface{}) {
|
func (app *Bouquins) render(res http.ResponseWriter, tpl string, model interface{}) {
|
||||||
err := app.Template.ExecuteTemplate(res, tpl, model)
|
err := app.Template.ExecuteTemplate(res, tpl, model)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -243,18 +248,24 @@ func (app *Bouquins) BooksPage(res http.ResponseWriter, req *http.Request) {
|
|||||||
app.render(res, TPL_BOOKS, model)
|
app.render(res, TPL_BOOKS, model)
|
||||||
}
|
}
|
||||||
func (app *Bouquins) AuthorsPage(res http.ResponseWriter, req *http.Request) {
|
func (app *Bouquins) AuthorsPage(res http.ResponseWriter, req *http.Request) {
|
||||||
/*
|
if !strings.HasPrefix(req.URL.Path, URL_AUTHORS) {
|
||||||
if !strings.HasPrefix(req.URL.Path, URL_AUTHORS) {
|
// FIXME 404
|
||||||
// FIXME 404
|
log.Fatalln("Invalid URL")
|
||||||
log.Fatalln("Invalid URL")
|
}
|
||||||
}
|
id, err := strconv.Atoi(req.URL.Path[len(URL_AUTHORS):])
|
||||||
id, err := strconv.Atoi(req.URL.Path[len(URL_AUTHORS):])
|
if err != nil {
|
||||||
if err != nil {
|
// FIXME 404
|
||||||
// FIXME 404
|
log.Fatalln(err)
|
||||||
log.Fatalln(err)
|
}
|
||||||
}
|
author, err := app.AuthorFull(int64(id))
|
||||||
*/
|
if err != nil {
|
||||||
app.render(res, TPL_AUTHORS, nil)
|
// FIXME 500
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
app.render(res, TPL_AUTHORS, &AuthorModel{
|
||||||
|
*NewBouquinsModel(author.Name),
|
||||||
|
author,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
func (app *Bouquins) SeriesPage(res http.ResponseWriter, req *http.Request) {
|
func (app *Bouquins) SeriesPage(res http.ResponseWriter, req *http.Request) {
|
||||||
if !strings.HasPrefix(req.URL.Path, URL_SERIES) {
|
if !strings.HasPrefix(req.URL.Path, URL_SERIES) {
|
||||||
@ -267,6 +278,10 @@ func (app *Bouquins) SeriesPage(res http.ResponseWriter, req *http.Request) {
|
|||||||
log.Fatalln(err)
|
log.Fatalln(err)
|
||||||
}
|
}
|
||||||
series, err := app.SeriesFull(int64(id))
|
series, err := app.SeriesFull(int64(id))
|
||||||
|
if err != nil {
|
||||||
|
// FIXME 500
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
app.render(res, TPL_SERIES, &SeriesModel{
|
app.render(res, TPL_SERIES, &SeriesModel{
|
||||||
*NewBouquinsModel(series.Name),
|
*NewBouquinsModel(series.Name),
|
||||||
series,
|
series,
|
||||||
|
@ -8,7 +8,6 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
STMT_PAGE = " LIMIT ? OFFSET ?"
|
|
||||||
STMT_BOOKS0 = `SELECT books.id AS id,title,series_index,name as series_name,series.id AS series_id
|
STMT_BOOKS0 = `SELECT books.id AS id,title,series_index,name as series_name,series.id AS series_id
|
||||||
FROM books LEFT OUTER JOIN books_series_link ON books.id = books_series_link.book
|
FROM books LEFT OUTER JOIN books_series_link ON books.id = books_series_link.book
|
||||||
LEFT OUTER JOIN series ON series.id = books_series_link.series `
|
LEFT OUTER JOIN series ON series.id = books_series_link.series `
|
||||||
@ -29,6 +28,12 @@ const (
|
|||||||
STMT_SERIES_SEARCH = "SELECT series.id, series.name FROM series WHERE "
|
STMT_SERIES_SEARCH = "SELECT series.id, series.name FROM series WHERE "
|
||||||
STMT_SEARCH_TERM_SERIES = " series.sort like ? "
|
STMT_SEARCH_TERM_SERIES = " series.sort like ? "
|
||||||
|
|
||||||
|
STMT_AUTHORS0 = `SELECT authors.id, authors.name, count(book) as count FROM authors, books_authors_link
|
||||||
|
WHERE authors.id = books_authors_link.author GROUP BY author`
|
||||||
|
STMT_AUTHORS_SEARCH = "SELECT id, name FROM authors WHERE "
|
||||||
|
STMT_SEARCH_TERM_AUTHOR = " sort like ? "
|
||||||
|
|
||||||
|
STMT_PAGE = " LIMIT ? OFFSET ?"
|
||||||
STMT_WHERE = " WHERE "
|
STMT_WHERE = " WHERE "
|
||||||
STMT_BOOL_AND = " AND "
|
STMT_BOOL_AND = " AND "
|
||||||
STMT_BOOL_OR = " OR "
|
STMT_BOOL_OR = " OR "
|
||||||
@ -81,6 +86,21 @@ const (
|
|||||||
WHERE books_authors_link.book = books_series_link.book AND books_authors_link.author = authors.id
|
WHERE books_authors_link.book = books_series_link.book AND books_authors_link.author = authors.id
|
||||||
AND books_series_link.series = ?`
|
AND books_series_link.series = ?`
|
||||||
|
|
||||||
|
STMT_AUTHORS_ID_ASC = STMT_AUTHORS0 + "ORDER BY authors.id " + STMT_PAGE
|
||||||
|
STMT_AUTHORS_ID_DESC = STMT_AUTHORS0 + "ORDER BY authors.id DESC " + STMT_PAGE
|
||||||
|
STMT_AUTHORS_NAME_ASC = STMT_AUTHORS0 + "ORDER BY authors.sort " + STMT_PAGE
|
||||||
|
STMT_AUTHORS_NAME_DESC = STMT_AUTHORS0 + "ORDER BY authors.sort DESC " + STMT_PAGE
|
||||||
|
STMT_AUTHOR_BOOKS = `SELECT books.id AS id,title,series_index,name as series_name,series.id AS series_id
|
||||||
|
FROM books LEFT OUTER JOIN books_series_link ON books.id = books_series_link.book
|
||||||
|
LEFT OUTER JOIN series ON series.id = books_series_link.series
|
||||||
|
LEFT OUTER JOIN books_authors_link ON books.id = books_authors_link.book
|
||||||
|
WHERE books_authors_link.author = ? ORDER BY id`
|
||||||
|
STMT_AUTHORS_AUTHORS = `SELECT authors.id, authors.name, books_authors_link.book as book
|
||||||
|
FROM authors, books_authors_link WHERE books_authors_link.author = authors.id
|
||||||
|
AND books_authors_link.book IN ( SELECT books.id FROM books LEFT OUTER JOIN books_authors_link
|
||||||
|
ON books.id = books_authors_link.book WHERE books_authors_link.author = ? ORDER BY books.id)`
|
||||||
|
STMT_AUTHOR = "SELECT name FROM authors WHERE id = ?"
|
||||||
|
|
||||||
DEF_LIM = 10
|
DEF_LIM = 10
|
||||||
|
|
||||||
BOOKS QueryType = iota
|
BOOKS QueryType = iota
|
||||||
@ -94,6 +114,8 @@ const (
|
|||||||
SERIES QueryType = iota
|
SERIES QueryType = iota
|
||||||
SERIES_AUTHORS QueryType = iota
|
SERIES_AUTHORS QueryType = iota
|
||||||
SERIES_BOOKS QueryType = iota
|
SERIES_BOOKS QueryType = iota
|
||||||
|
AUTHOR QueryType = iota
|
||||||
|
AUTHOR_BOOKS QueryType = iota
|
||||||
)
|
)
|
||||||
|
|
||||||
var QUERIES = map[Query]string{
|
var QUERIES = map[Query]string{
|
||||||
@ -117,6 +139,8 @@ var QUERIES = map[Query]string{
|
|||||||
Query{SERIES, false, false}: STMT_SERIE,
|
Query{SERIES, false, false}: STMT_SERIE,
|
||||||
Query{SERIES_AUTHORS, false, false}: STMT_SERIE_AUTHORS,
|
Query{SERIES_AUTHORS, false, false}: STMT_SERIE_AUTHORS,
|
||||||
Query{SERIES_BOOKS, false, false}: STMT_SERIE_BOOKS,
|
Query{SERIES_BOOKS, false, false}: STMT_SERIE_BOOKS,
|
||||||
|
Query{AUTHOR, false, false}: STMT_AUTHOR,
|
||||||
|
Query{AUTHOR_BOOKS, false, false}: STMT_AUTHOR_BOOKS,
|
||||||
}
|
}
|
||||||
var STMTS = make(map[Query]*sql.Stmt)
|
var STMTS = make(map[Query]*sql.Stmt)
|
||||||
|
|
||||||
|
73
bouquins/dbauthors.go
Normal file
73
bouquins/dbauthors.go
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
package bouquins
|
||||||
|
|
||||||
|
import "database/sql"
|
||||||
|
|
||||||
|
// SUB QUERIES //
|
||||||
|
|
||||||
|
func (app *Bouquins) queryAuthorBooks(author *AuthorFull) error {
|
||||||
|
stmt, err := app.ps(AUTHOR_BOOKS)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
rows, err := stmt.Query(author.Id)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
for rows.Next() {
|
||||||
|
book := new(BookAdv)
|
||||||
|
var seriesId sql.NullInt64
|
||||||
|
var seriesName sql.NullString
|
||||||
|
if err = rows.Scan(&book.Id, &book.Title, &book.SeriesIndex, &seriesName, &seriesId); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if seriesId.Valid && seriesName.Valid {
|
||||||
|
book.Series = &Series{
|
||||||
|
seriesId.Int64,
|
||||||
|
seriesName.String,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
author.Books = append(author.Books, book)
|
||||||
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (app *Bouquins) queryAuthorAuthors(author *AuthorFull) error {
|
||||||
|
// TODO
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (app *Bouquins) queryAuthor(id int64) (*AuthorFull, error) {
|
||||||
|
stmt, err := app.ps(AUTHOR)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
author := new(AuthorFull)
|
||||||
|
author.Id = id
|
||||||
|
err = stmt.QueryRow(id).Scan(&author.Name)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return author, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DB LOADS //
|
||||||
|
|
||||||
|
func (app *Bouquins) AuthorFull(id int64) (*AuthorFull, error) {
|
||||||
|
author, err := app.queryAuthor(id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
err = app.queryAuthorBooks(author)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
err = app.queryAuthorAuthors(author)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return author, nil
|
||||||
|
}
|
@ -1,43 +1,61 @@
|
|||||||
{{ template "header.html" . }}
|
{{ template "header.html" . }}
|
||||||
<div class="container" id="app">
|
<div class="container" id="app">
|
||||||
<div class="page-header" v-if="author.id">
|
{{ if .Id }}
|
||||||
|
<div class="page-header">
|
||||||
<h1>
|
<h1>
|
||||||
<span class="glyphicon glyphicon-user"></span>
|
<span class="glyphicon glyphicon-user"></span>
|
||||||
{{ .Author.Name }}
|
{{ .Name }}
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
<div class="alert alert-danger" role="alert" v-else>Aucun livre sélectionné</div>
|
|
||||||
<ul class="nav nav-pills">
|
<ul class="nav nav-pills">
|
||||||
<li role="presentation" :class="{ active: tab == 'books' }"><a href="#" @click="showBooks">Livres</a></li>
|
<li role="presentation" :class="{ active: tab == 'books' }"><a href="#" @click="showBooks">Livres</a></li>
|
||||||
<li v-if="author.series && author.series.length > 0" role="presentation" :class="{ active: tab == 'series' }"><a href="#" @click="showSeries">Series</a></li>
|
{{/* if gt (len .Series) 0 */}}
|
||||||
<li v-if="author.authors && author.authors.length > 0"role="presentation" :class="{ active: tab == 'authors' }"><a href="#" @click="showAuthors">Co-auteurs</a></li>
|
<li role="presentation" :class="{ active: tab == 'series' }"><a href="#" @click="showSeries">Series</a></li>
|
||||||
|
{{/* end */}}
|
||||||
|
{{/* if gt (len .Authors) 0 */}}
|
||||||
|
<li role="presentation" :class="{ active: tab == 'authors' }"><a href="#" @click="showAuthors">Co-auteurs</a></li>
|
||||||
|
{{/* end */}}
|
||||||
</ul>
|
</ul>
|
||||||
<div class="panel panel-default" :class="{ hidden: tab != 'books' }">
|
<div class="panel panel-default" :class="{ hidden: tab != 'books' }">
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<ul v-for="book in author.books" class="list-unstyled">
|
{{ range .Books }}
|
||||||
|
<ul class="list-unstyled">
|
||||||
<li><span class="glyphicon glyphicon-book"></span>
|
<li><span class="glyphicon glyphicon-book"></span>
|
||||||
<a :href="'book.html?id='+book.id">{{ .Book.Title }}</a>
|
<a href="/books/{{ .Id }}">{{ .Title }}</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
{{ end }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel panel-default" :class="{ hidden: tab != 'series' }">
|
<div class="panel panel-default" :class="{ hidden: tab != 'series' }">
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<ul v-for="series in author.series" class="list-unstyled">
|
{{ range .Books }}
|
||||||
|
{{/* FIXME unicity */}}
|
||||||
|
{{ with .Series }}
|
||||||
|
<ul class="list-unstyled">
|
||||||
<li><span class="glyphicon glyphicon-list"></span>
|
<li><span class="glyphicon glyphicon-list"></span>
|
||||||
<a :href="'series.html?id='+series.id">{{ .Series.Name }}</a>
|
<a href="/series/{{ .Id }}">{{ .Name }}</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
{{ end }}
|
||||||
|
{{ end }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel panel-default" :class="{ hidden: tab != 'authors' }">
|
<div class="panel panel-default" :class="{ hidden: tab != 'authors' }">
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<ul v-for="coauthor in author.authors" class="list-unstyled">
|
{{ range .Books }}
|
||||||
|
{{ range .Authors }}
|
||||||
|
<ul class="list-unstyled">
|
||||||
<li> <span class="glyphicon glyphicon-user"></span>
|
<li> <span class="glyphicon glyphicon-user"></span>
|
||||||
<a :href="'author.html?id='+coauthor.id">{{ .Coauthor.Name }}</a>
|
<a href="/authors/{{ .Id }}">{{ .Name }}</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
{{ end }}
|
||||||
|
{{ end }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{{ else }}
|
||||||
|
<div class="alert alert-danger" role="alert">Aucun auteur sélectionné</div>
|
||||||
|
{{ end }}
|
||||||
</div>
|
</div>
|
||||||
{{ template "footer.html" . }}
|
{{ template "footer.html" . }}
|
||||||
|
Loading…
Reference in New Issue
Block a user