aboutsummaryrefslogtreecommitdiff
path: root/cmd
diff options
context:
space:
mode:
Diffstat (limited to 'cmd')
-rw-r--r--cmd/web/handlers/blog.go81
-rw-r--r--cmd/web/handlers/routes.go1
2 files changed, 82 insertions, 0 deletions
diff --git a/cmd/web/handlers/blog.go b/cmd/web/handlers/blog.go
index 472b270..51b5771 100644
--- a/cmd/web/handlers/blog.go
+++ b/cmd/web/handlers/blog.go
@@ -24,6 +24,7 @@ type blogContext struct {
Rows []models.Post
Comments []models.Comment
Name string
+ SearchTerm string
IsAuth bool
PagePopulated bool
Offset int
@@ -315,10 +316,90 @@ func (ctx *blogContext) post(w http.ResponseWriter, r *http.Request) {
return
}
+func (ctx *blogContext) search(w http.ResponseWriter, r *http.Request) {
+ ctx.Rows = []models.Post{}
+ ctx.IsAuth = false
+ ctx.PagePopulated = false
+
+ _, err := r.Cookie("paterissa_session_token")
+ if err == nil {
+ ctx.IsAuth = true
+ }
+
+ ctx.Offset, _ = strconv.Atoi(r.URL.Query().Get("offset"))
+ ctx.SearchTerm = r.URL.Query().Get("query")
+
+ stmt, err := ctx.db.Prepare("SELECT p.id, u.name, p.time, p.brief FROM posts p INNER JOIN logins u ON p.user_id = u.id WHERE word_similarity($1, p.brief) > 0.1 ORDER BY word_similarity($1, p.brief) DESC LIMIT 20 OFFSET $2;")
+ if err != nil {
+ w.WriteHeader(http.StatusInternalServerError)
+ w.Write([]byte("Internal Error"))
+ ctx.err.Printf("Could not prepare statement for DB: %v\n", err)
+ return
+ }
+ defer stmt.Close()
+
+ rows, err := stmt.Query(ctx.SearchTerm, strconv.Itoa(ctx.Offset))
+ if err != nil {
+ w.WriteHeader(http.StatusInternalServerError)
+ w.Write([]byte("Internal Error"))
+ ctx.err.Printf("Could not load posts from DB: %v\n", err)
+ return
+ }
+ defer rows.Close()
+
+ for rows.Next() {
+ var p models.Post
+
+ if err = rows.Scan(&p.Id, &p.Name, &p.Time, &p.Brief); err != nil {
+ w.WriteHeader(http.StatusInternalServerError)
+ w.Write([]byte("Internal Error"))
+ ctx.err.Printf("Could not load row: %v\n", err)
+ return
+ }
+
+ p.FormattedTime = p.Time.Format(time.ANSIC)
+
+ ctx.Rows = append(ctx.Rows, p)
+ ctx.PagePopulated = true
+ }
+
+ files := []string{
+ "ui/html/base.tmpl.html",
+ "ui/html/music_player.tmpl.html",
+ "ui/html/pages/index.tmpl.html",
+ }
+
+ funcMap := template.FuncMap{
+ "add": func(a int, b int) int {
+ return a + b
+ },
+ "sub": func(a int, b int) int {
+ return a - b
+ },
+ }
+
+ compiled, err := template.New("blog").Funcs(funcMap).ParseFiles(files...)
+ if err != nil {
+ w.WriteHeader(http.StatusInternalServerError)
+ w.Write([]byte("Internal Error"))
+ ctx.err.Printf("Could not parse template: %v\n", err)
+ return
+ }
+
+ err = compiled.ExecuteTemplate(w, "base", ctx)
+ if err != nil {
+ w.WriteHeader(http.StatusInternalServerError)
+ w.Write([]byte("Internal Error"))
+ ctx.err.Printf("Could not execute template: %v\n", err)
+ return
+ }
+}
+
func (ctx *blogContext) index(w http.ResponseWriter, r *http.Request) {
ctx.Rows = []models.Post{}
ctx.IsAuth = false
ctx.PagePopulated = false
+ ctx.SearchTerm = ""
if r.URL.Path != "/" {
http.NotFound(w, r)
diff --git a/cmd/web/handlers/routes.go b/cmd/web/handlers/routes.go
index f6d8dc3..074e3e9 100644
--- a/cmd/web/handlers/routes.go
+++ b/cmd/web/handlers/routes.go
@@ -45,6 +45,7 @@ func RegisterEndpoints(app types.Application, db *sql.DB) *http.ServeMux {
blogRouter := http.NewServeMux()
blogRouter.HandleFunc("/", auth.CheckAndInvalidate(blog.index))
+ blogRouter.HandleFunc("/search", auth.CheckAndInvalidate(blog.search))
blogRouter.HandleFunc("/post/new", auth.Resolve(blog.post))
blogRouter.HandleFunc("/post", blog.viewPost)
blogRouter.HandleFunc("/comments/verify", auth.Resolve(blog.verifyComment))