214 lines
5.0 KiB
Go
214 lines
5.0 KiB
Go
package action
|
|
|
|
import (
|
|
"html/template"
|
|
"net/http"
|
|
"net/url"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"golang.org/x/text/unicode/norm"
|
|
|
|
"tea.kareha.org/pot/himewiki/internal/config"
|
|
"tea.kareha.org/pot/himewiki/internal/data"
|
|
"tea.kareha.org/pot/himewiki/internal/filter"
|
|
"tea.kareha.org/pot/himewiki/internal/format"
|
|
"tea.kareha.org/pot/himewiki/internal/templates"
|
|
"tea.kareha.org/pot/himewiki/internal/util"
|
|
)
|
|
|
|
func View(cfg *config.Config, w http.ResponseWriter, r *http.Request, params *Params) {
|
|
_, content, err := data.Load(params.DbName)
|
|
if err != nil {
|
|
http.Redirect(w, r, "/"+url.PathEscape(params.Name)+"?a=edit", http.StatusFound)
|
|
return
|
|
}
|
|
|
|
title, _, plain, rendered := format.Apply(cfg, params.DbName, content)
|
|
summary := format.TrimForSummary(plain, 144)
|
|
|
|
subAction := r.URL.Query().Get("b")
|
|
diffText := ""
|
|
if subAction == "diff" {
|
|
_, prev, _ := data.LoadPrev(params.DbName)
|
|
diffText = util.Diff(prev, content)
|
|
}
|
|
|
|
searchName := params.Name
|
|
if strings.HasSuffix(searchName, ".wiki") {
|
|
searchName = searchName[:len(searchName)-5]
|
|
}
|
|
|
|
data := struct {
|
|
Base string
|
|
SiteName string
|
|
Card string
|
|
Name string
|
|
Summary string
|
|
Title string
|
|
SearchName string
|
|
Rendered template.HTML
|
|
Diff string
|
|
}{
|
|
Base: cfg.Site.Base,
|
|
SiteName: cfg.Site.Name,
|
|
Card: cfg.Site.Card,
|
|
Name: params.Name,
|
|
Summary: summary,
|
|
Title: title,
|
|
SearchName: searchName,
|
|
Rendered: template.HTML(rendered),
|
|
Diff: diffText,
|
|
}
|
|
templates.Render(w, "view", data)
|
|
}
|
|
|
|
func Edit(cfg *config.Config, w http.ResponseWriter, r *http.Request, params *Params) {
|
|
var previewed bool
|
|
var revisionID int
|
|
var content string
|
|
var preview string
|
|
var save string
|
|
if r.Method != http.MethodPost {
|
|
previewed = false
|
|
revisionID, content, _ = data.Load(params.DbName)
|
|
preview = ""
|
|
save = ""
|
|
} else {
|
|
previewed = r.FormValue("previewed") == "true"
|
|
var err error
|
|
revisionID, err = strconv.Atoi(r.FormValue("revision_id"))
|
|
if err != nil || revisionID < 0 {
|
|
http.Error(w, "Invalid revision ID", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
rawContent := r.FormValue("content")
|
|
content = norm.NFC.String(rawContent)
|
|
preview = r.FormValue("preview")
|
|
save = r.FormValue("save")
|
|
}
|
|
|
|
var filtered string
|
|
var err error
|
|
if previewed && save != "" {
|
|
filtered, err = filter.Apply(cfg, params.DbName, content)
|
|
} else {
|
|
filtered, err = content, nil
|
|
}
|
|
if err != nil {
|
|
http.Error(w, "Failed to filter content", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
title, normalized, _, rendered := format.Apply(cfg, params.DbName, filtered)
|
|
|
|
diffText := ""
|
|
if previewed && save != "" {
|
|
pageCount, err := data.Save(cfg, params.DbName, normalized, revisionID)
|
|
if err != nil {
|
|
http.Error(w, "Failed to save", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
if cfg.Gnome.Agent != "nil" {
|
|
if pageCount%int64(cfg.Gnome.Ratio) == 0 {
|
|
targetRecent := (pageCount / int64(cfg.Gnome.Ratio)) % int64(cfg.Gnome.Recent)
|
|
go func() {
|
|
runGnome(cfg, int(targetRecent))
|
|
}()
|
|
}
|
|
}
|
|
|
|
http.Redirect(w, r, "/"+url.PathEscape(params.Name)+"?b=diff", http.StatusFound)
|
|
return
|
|
} else if preview != "" {
|
|
previewed = true
|
|
_, current, _ := data.Load(params.DbName)
|
|
diffText = util.Diff(current, normalized)
|
|
}
|
|
|
|
searchName := params.Name
|
|
if strings.HasSuffix(searchName, ".wiki") {
|
|
searchName = searchName[:len(searchName)-5]
|
|
}
|
|
|
|
w.Header().Set("Cache-Control", "no-store")
|
|
w.Header().Set("Pragma", "no-cache")
|
|
|
|
data := struct {
|
|
SiteName string
|
|
Name string
|
|
Previewed bool
|
|
RevisionID int
|
|
Text string
|
|
Title string
|
|
SearchName string
|
|
Rendered template.HTML
|
|
Diff string
|
|
}{
|
|
SiteName: cfg.Site.Name,
|
|
Name: params.Name,
|
|
Previewed: previewed,
|
|
RevisionID: revisionID,
|
|
Text: normalized,
|
|
Title: title,
|
|
SearchName: searchName,
|
|
Rendered: template.HTML(rendered),
|
|
Diff: diffText,
|
|
}
|
|
templates.Render(w, "edit", data)
|
|
}
|
|
|
|
const perBigPage = 500
|
|
|
|
func All(cfg *config.Config, w http.ResponseWriter, r *http.Request, params *Params) {
|
|
pageStr := r.URL.Query().Get("p")
|
|
page, err := strconv.Atoi(pageStr)
|
|
if err != nil {
|
|
page = 1
|
|
}
|
|
|
|
pages, err := data.LoadAll(page, perBigPage)
|
|
if err != nil {
|
|
http.Error(w, "Failed to load pages", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
data := struct {
|
|
SiteName string
|
|
Pages []string
|
|
NextPage int
|
|
}{
|
|
SiteName: cfg.Site.Name,
|
|
Pages: pages,
|
|
NextPage: page + 1,
|
|
}
|
|
templates.Render(w, "all", data)
|
|
}
|
|
|
|
const perPage = 50
|
|
|
|
func Recent(cfg *config.Config, w http.ResponseWriter, r *http.Request, params *Params) {
|
|
pageStr := r.URL.Query().Get("p")
|
|
page, err := strconv.Atoi(pageStr)
|
|
if err != nil {
|
|
page = 1
|
|
}
|
|
|
|
records, err := data.Recent(page, perPage)
|
|
if err != nil {
|
|
http.Error(w, "Failed to load pages", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
data := struct {
|
|
SiteName string
|
|
Records []data.RecentRecord
|
|
NextPage int
|
|
}{
|
|
SiteName: cfg.Site.Name,
|
|
Records: records,
|
|
NextPage: page + 1,
|
|
}
|
|
templates.Render(w, "recent", data)
|
|
}
|