|
|
package model
import ( "fmt" "net/url" "time"
"git.aiterp.net/AiteRP/aitestory/formparser" "git.aiterp.net/gisle/wrouter/generate" "github.com/microcosm-cc/bluemonday" "github.com/russross/blackfriday" )
// PageCategories are used by the view model and page to enforce
// a limited selection of categories. I may move it to a configuration
var PageCategories = []string{ "OoC", "Story", "Background", "Document", "News", "Item", "Info", }
// PageTypes describes how the source is rendered. For now it's only markdown,
// but who knows what the future holds.
var PageTypes = []string{ "Markdown", }
// PageMinDate is the earliest date possible. Stories from Matriarch Eriana's childhood
// are thus not going to happen.
var PageMinDate, _ = time.Parse(time.RFC3339, "1753-01-01T00:00:00Z")
// Page is the model describing the individual articles posted
// by users.
type Page struct { ID string `json:"id"` Name string `json:"name"` Author string `json:"author"` Category string `json:"category"` FictionalDate time.Time `json:"fictionalDate"` PublishDate time.Time `json:"publishDate"` EditDate time.Time `json:"editDate"` Dated bool `json:"dated"` Published bool `json:"published"` Unlisted bool `json:"unlisted"` Specific bool `json:"specific"` Indexed bool `json:"indexed"` BackgroundURL string `json:"backgroundUrl"` Type string `json:"type"` Source string `json:"source"`
cachedOutput string }
// Defaults fills in the default details for a page, suited for populating a form
func (page *Page) Defaults() { page.Category = PageCategories[0]
page.Dated = true page.Published = true page.Unlisted = false page.Specific = false page.Indexed = true
page.BackgroundURL = "" page.Type = PageTypes[0] page.Source = "" }
// Insert adds the page to the database
func (page *Page) Insert() error { page.generateID()
return nil }
// Content parses the content of the page
func (page *Page) Content() (string, error) { if page.cachedOutput != "" { return page.cachedOutput, nil }
if page.Type == "Markdown" { // TODO: Convert [[Ehanis Tioran]] to [Ehanis Tioran](https://wiki.aiterp.net/index.php?title=Ehanis%20Tioran)
unsafe := blackfriday.MarkdownCommon([]byte(page.Source)) page.cachedOutput = string(bluemonday.UGCPolicy().SanitizeBytes(unsafe))
return page.cachedOutput, nil }
return "", fmt.Errorf("Page type '%s' is not supported", page.Type) }
// ParseForm validates the values in a form and sets the page's values whenever possible regardless
// so that it can be pushed to the viewmodel to allow the user to correct their mistakes without fear
// of losing their hard work
func (page *Page) ParseForm(form url.Values) []error { errors := make([]error, 0, 4) page.cachedOutput = ""
err := formparser.Select(form.Get("category"), &page.Category, PageCategories, page.Category != "") if err != nil { errors = append(errors, fmt.Errorf("Category: %s", err)) }
err = formparser.Date(form.Get("fictionalDate"), &page.FictionalDate, !page.FictionalDate.IsZero()) if err != nil { errors = append(errors, fmt.Errorf("Fictonal Date: %s", err)) }
page.Dated = form.Get("dated") != "" page.Published = form.Get("published") != "" page.Unlisted = form.Get("unlisted") != "" page.Specific = form.Get("specific") != "" page.Indexed = form.Get("indexed") != ""
err = formparser.String(form.Get("backgroundUrl"), &page.BackgroundURL, 0, 255) if err != nil { errors = append(errors, fmt.Errorf("Background URL: %s", err)) }
err = formparser.Select(form.Get("type"), &page.Type, PageTypes, page.Type != "") if err != nil { errors = append(errors, fmt.Errorf("Category: %s", err)) }
err = formparser.String(form.Get("source"), &page.Source, 0, 102400) if err != nil { errors = append(errors, fmt.Errorf("Content is too long, max: 100 KB (~17,000 words)")) }
if len(errors) > 0 { errors = nil }
return errors }
// Standardize page ID generation
func (page *Page) generateID() { page.ID = generate.FriendlyID(16) }
|