Files
spyda/internal/handlers.go
2021-02-01 21:25:32 +10:00

148 lines
3.5 KiB
Go

package internal
import (
"fmt"
"html/template"
"net/http"
"strings"
rice "github.com/GeertJohan/go.rice"
"github.com/gomarkdown/markdown"
"github.com/gomarkdown/markdown/html"
"github.com/gomarkdown/markdown/parser"
"github.com/james4k/fmatter"
"github.com/julienschmidt/httprouter"
log "github.com/sirupsen/logrus"
)
const (
MaxFailedLogins = 3 // By default 3 failed login attempts per 5 minutes
)
func (s *Server) NotFoundHandler(w http.ResponseWriter, r *http.Request) {
if r.Header.Get("Accept") == "application/json" {
w.Header().Set("Content-Type", "application/json")
http.Error(w, "Endpoint Not Found", http.StatusNotFound)
return
}
ctx := NewContext(s.config, s.db, r)
ctx.Title = "Page Not Found"
w.WriteHeader(http.StatusNotFound)
s.render("404", w, ctx)
}
type FrontMatter struct {
Title string
}
// PageHandler ...
func (s *Server) PageHandler(name string) httprouter.Handle {
box := rice.MustFindBox("pages")
mdTpl := box.MustString(fmt.Sprintf("%s.md", name))
return func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
ctx := NewContext(s.config, s.db, r)
md, err := RenderString(mdTpl, ctx)
if err != nil {
log.WithError(err).Errorf("error rendering page %s", name)
ctx.Error = true
ctx.Message = "Error loading help page! Please contact support."
s.render("error", w, ctx)
return
}
var frontmatter FrontMatter
content, err := fmatter.Read([]byte(md), &frontmatter)
if err != nil {
log.WithError(err).Error("error parsing front matter")
ctx.Error = true
ctx.Message = "Error loading page! Please contact support."
s.render("error", w, ctx)
return
}
extensions := parser.CommonExtensions | parser.AutoHeadingIDs
p := parser.NewWithExtensions(extensions)
htmlFlags := html.CommonFlags
opts := html.RendererOptions{
Flags: htmlFlags,
Generator: "",
}
renderer := html.NewRenderer(opts)
html := markdown.ToHTML(content, p, renderer)
var title string
if frontmatter.Title != "" {
title = frontmatter.Title
} else {
title = strings.Title(name)
}
ctx.Title = title
ctx.Page = name
ctx.Content = template.HTML(html)
s.render("page", w, ctx)
}
}
// IndexHandler ...
func (s *Server) IndexHandler() httprouter.Handle {
return func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
ctx := NewContext(s.config, s.db, r)
s.render("index", w, ctx)
}
}
// AddHandler ...
func (s *Server) AddHandler() httprouter.Handle {
return func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
ctx := NewContext(s.config, s.db, r)
if r.Method == http.MethodGet {
s.render("add", w, ctx)
return
}
url := NormalizeURL(strings.TrimSpace(r.FormValue("url")))
if url == "" {
ctx.Error = true
ctx.Message = "Invalid URL"
s.render("error", w, ctx)
return
}
if err := s.crawler.Crawl(url); err != nil {
ctx.Error = true
ctx.Message = fmt.Sprintf("Error adding URL: %s", err)
s.render("error", w, ctx)
return
}
ctx.Error = false
ctx.Message = "Successfully added url"
s.render("error", w, ctx)
}
}
// CacheHandler ...
func (s *Server) CacheHandler() httprouter.Handle {
return func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
ctx := NewContext(s.config, s.db, r)
s.render("cache", w, ctx)
}
}
// SearchHandler ...
func (s *Server) SearchHandler() httprouter.Handle {
return func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
ctx := NewContext(s.config, s.db, r)
s.render("search", w, ctx)
}
}