GoBlog/postsDb.go

187 lines
4.0 KiB
Go

package main
import (
"bytes"
"errors"
"fmt"
"strings"
"text/template"
"time"
"github.com/araddon/dateparse"
)
func (p *post) checkPost() error {
if p == nil {
return errors.New("no post")
}
now := time.Now()
// Fix content
p.Content = strings.TrimSuffix(strings.TrimPrefix(p.Content, "\n"), "\n")
// Fix date strings
if p.Published != "" {
d, err := dateparse.ParseIn(p.Published, time.Local)
if err != nil {
return err
}
p.Published = d.String()
}
if p.Updated != "" {
d, err := dateparse.ParseIn(p.Updated, time.Local)
if err != nil {
return err
}
p.Updated = d.String()
}
// Cleanup params
for key, value := range p.Parameters {
if value == nil {
delete(p.Parameters, key)
continue
}
allValues := []string{}
for _, v := range value {
if v != "" {
allValues = append(allValues, v)
}
}
if len(allValues) >= 1 {
p.Parameters[key] = allValues
} else {
delete(p.Parameters, key)
}
}
// Check blog
if p.Blog == "" {
p.Blog = appConfig.DefaultBlog
}
// Check path
p.Path = strings.TrimSuffix(p.Path, "/")
if p.Path == "" {
if p.Section == "" {
p.Section = appConfig.Blogs[p.Blog].DefaultSection
}
if p.Slug == "" {
random := generateRandomString(5)
p.Slug = fmt.Sprintf("%v-%02d-%02d-%v", now.Year(), int(now.Month()), now.Day(), random)
}
published, _ := dateparse.ParseIn(p.Published, time.Local)
pathTmplString := appConfig.Blogs[p.Blog].Sections[p.Section].PathTemplate
if pathTmplString == "" {
return errors.New("path template empty")
}
pathTmpl, err := template.New("location").Parse(pathTmplString)
if err != nil {
return errors.New("failed to parse location template")
}
var pathBuffer bytes.Buffer
err = pathTmpl.Execute(&pathBuffer, map[string]interface{}{
"BlogPath": appConfig.Blogs[p.Blog].Path,
"Year": published.Year(),
"Month": int(published.Month()),
"Day": published.Day(),
"Slug": p.Slug,
"Section": p.Section,
})
if err != nil {
return errors.New("failed to execute location template")
}
p.Path = pathBuffer.String()
}
if p.Path != "" && !strings.HasPrefix(p.Path, "/") {
return errors.New("wrong path")
}
return nil
}
func (p *post) create() error {
return p.createOrReplace(true)
}
func (p *post) replace() error {
return p.createOrReplace(false)
}
func (p *post) createOrReplace(new bool) error {
err := p.checkPost()
if err != nil {
return err
}
startWritingToDb()
tx, err := appDb.Begin()
if err != nil {
finishWritingToDb()
return err
}
sqlCommand := "insert"
if !new {
sqlCommand = "insert or replace"
}
_, err = tx.Exec(sqlCommand+" into posts (path, content, published, updated, blog, section) values (?, ?, ?, ?, ?, ?)", p.Path, p.Content, p.Published, p.Updated, p.Blog, p.Section)
if err != nil {
_ = tx.Rollback()
finishWritingToDb()
return err
}
_, err = tx.Exec("delete from post_parameters where path=?", p.Path)
if err != nil {
_ = tx.Rollback()
finishWritingToDb()
return err
}
for param, value := range p.Parameters {
for _, value := range value {
if value != "" {
_, err = tx.Exec("insert into post_parameters (path, parameter, value) values (?, ?, ?)", p.Path, param, value)
if err != nil {
_ = tx.Rollback()
finishWritingToDb()
return err
}
}
}
}
err = tx.Commit()
if err != nil {
finishWritingToDb()
return err
}
finishWritingToDb()
go purgeCache()
defer postPostHooks(p.Path)
return reloadRouter()
}
func deletePost(path string) error {
if path == "" {
return nil
}
startWritingToDb()
tx, err := appDb.Begin()
if err != nil {
finishWritingToDb()
return err
}
_, err = tx.Exec("delete from posts where path=?", path)
if err != nil {
_ = tx.Rollback()
finishWritingToDb()
return err
}
_, err = tx.Exec("delete from post_parameters where path=?", path)
if err != nil {
_ = tx.Rollback()
finishWritingToDb()
return err
}
err = tx.Commit()
if err != nil {
finishWritingToDb()
return err
}
finishWritingToDb()
go purgeCache()
defer postDeleteHooks(path)
return reloadRouter()
}