From 9aab54619ac99fa073591e2f4f01db13d8c826dd Mon Sep 17 00:00:00 2001 From: Jan-Lukas Else Date: Sun, 22 Dec 2019 08:26:38 +0100 Subject: [PATCH] Refactoring, small fix, added creating posts using JSON --- entry.go | 64 ++++++++++++++++++++++++++++++++++++++++---------- go.sum | 1 + microformat.go | 18 ++++++++++++++ post.go | 36 ++++++++++++++-------------- query.go | 22 ++++------------- 5 files changed, 93 insertions(+), 48 deletions(-) create mode 100644 microformat.go diff --git a/entry.go b/entry.go index 15fd2d9..b55fbfc 100644 --- a/entry.go +++ b/entry.go @@ -5,6 +5,7 @@ import ( "bytes" "errors" "fmt" + "gopkg.in/yaml.v2" "io/ioutil" "math/rand" "net/http" @@ -49,7 +50,16 @@ func CreateEntry(contentType ContentType, r *http.Request) (*Entry, error) { } return createEntryFromValueMap(r.MultipartForm.Value) } else if contentType == Json { - return nil, errors.New("json content-type is not implemented yet") + bodyString, err := parseRequestBody(r) + if err != nil { + return nil, err + } + parsedMfItem := &MicroformatItem{} + err = yaml.Unmarshal([]byte(bodyString), &parsedMfItem) + if err != nil { + return nil, errors.New("failed to parse Json") + } + return createEntryFromMicroformat(parsedMfItem) } else { return nil, errors.New("unsupported content-type") } @@ -65,13 +75,14 @@ func parseRequestBody(r *http.Request) (string, error) { } func createEntryFromValueMap(values map[string][]string) (*Entry, error) { - if h, ok := values["h"]; ok && len(h) == 1 && h[0] != "entry" { + if h, ok := values["h"]; ok && (len(h) != 1 || h[0] != "entry") { return nil, errors.New("only entry type is supported so far") } if _, ok := values["content"]; ok { - entry := new(Entry) - entry.content = values["content"][0] - if name, ok := values["title"]; ok { + entry := &Entry{ + content: values["content"][0], + } + if name, ok := values["name"]; ok { entry.title = name[0] } if category, ok := values["category"]; ok { @@ -102,6 +113,38 @@ func createEntryFromValueMap(values map[string][]string) (*Entry, error) { return nil, errors.New("error parsing the entry") } +func createEntryFromMicroformat(mfEntry *MicroformatItem) (*Entry, error) { + if len(mfEntry.Type) != 1 || mfEntry.Type[0] != "h-entry" { + return nil, errors.New("only entry type is supported so far") + } + if mfEntry.Properties != nil && len(mfEntry.Properties.Content) == 1 && len(mfEntry.Properties.Content[0]) > 0 { + entry := &Entry{ + content: mfEntry.Properties.Content[0], + } + if len(mfEntry.Properties.Name) == 1 { + entry.title = mfEntry.Properties.Name[0] + } + if len(mfEntry.Properties.Category) > 0 { + entry.tags = mfEntry.Properties.Category + } + if len(mfEntry.Properties.MpSlug) == 1 && len(mfEntry.Properties.MpSlug[0]) > 0 { + entry.slug = mfEntry.Properties.MpSlug[0] + } + if len(mfEntry.Properties.InReplyTo) == 1 { + entry.replyLink = mfEntry.Properties.InReplyTo[0] + } + if len(mfEntry.Properties.LikeOf) == 1 { + entry.likeLink = mfEntry.Properties.LikeOf[0] + } + err := computeExtraSettings(entry) + if err != nil { + return nil, err + } + return entry, nil + } + return nil, errors.New("error parsing the entry") +} + func computeExtraSettings(entry *Entry) error { now := time.Now() // Set date @@ -153,15 +196,12 @@ func computeExtraSettings(entry *Entry) error { entry.section = "micro" } entry.section = strings.ToLower(entry.section) - if entry.section == "posts" { - entry.filename = "content/" + entry.section + "/" + entry.slug + ".md" - entry.location = BlogUrl + entry.section + "/" + entry.slug - } else if entry.section == "thoughts" || entry.section == "links" || entry.section == "micro" { + if entry.section == "thoughts" || entry.section == "links" || entry.section == "micro" { entry.filename = fmt.Sprintf("content/%v/%02d/%02d/%v.md", entry.section, now.Year(), int(now.Month()), entry.slug) - entry.location = fmt.Sprintf("%v%v/%02d/%02d/%v", BlogUrl, entry.section, now.Year(), int(now.Month()), entry.slug) + entry.location = fmt.Sprintf("%v%v/%02d/%02d/%v/", BlogUrl, entry.section, now.Year(), int(now.Month()), entry.slug) } else { - entry.filename = "content/" + entry.section + "/" + entry.slug + ".md" - entry.location = BlogUrl + entry.section + "/" + entry.slug + entry.filename = fmt.Sprintf("content/%v/%v.md", entry.section, entry.slug) + entry.location = fmt.Sprintf("%v%v/%v/", BlogUrl, entry.section, entry.slug) } return nil } diff --git a/go.sum b/go.sum index 8875ab7..9970286 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,6 @@ github.com/andybalholm/cascadia v1.0.0 h1:hOCXnnZ5A+3eVDX8pvgl4kofXv2ELss0bKcqRySc45o= github.com/andybalholm/cascadia v1.0.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y= +github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/wsxiaoys/terminal v0.0.0-20160513160801-0940f3fc43a0/go.mod h1:IXCdmsXIht47RaVFLEdVnh1t+pgYtTAhQGj73kz+2DM= golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= diff --git a/microformat.go b/microformat.go new file mode 100644 index 0000000..2993565 --- /dev/null +++ b/microformat.go @@ -0,0 +1,18 @@ +package main + +type MicroformatItem struct { + Type []string `json:"type"` + Properties *MicroformatProperties `json:"properties"` +} + +type MicroformatProperties struct { + Name []string `json:"name,omitempty"` + Published []string `json:"published,omitempty"` + Updated []string `json:"updated,omitempty"` + Category []string `json:"category,omitempty"` + Content []string `json:"content,omitempty"` + Url []string `json:"url,omitempty"` + InReplyTo []string `json:"in-reply-to,omitempty"` + LikeOf []string `json:"like-of,omitempty"` + MpSlug []string `json:"mp-slug,omitempty"` +} diff --git a/post.go b/post.go index 1054e67..5155be1 100644 --- a/post.go +++ b/post.go @@ -7,44 +7,44 @@ import ( "strings" ) -type Frontmatter struct { - Title string `yaml:"title,omitempty"` - Date string `yaml:"date,omitempty"` - Lastmod string `yaml:"lastmod,omitempty"` - Tags []string `yaml:"tags,omitempty"` - ExternalURL string `yaml:"externalURL,omitempty"` - Indieweb Indieweb `yaml:"indieweb,omitempty"` +type HugoFrontmatter struct { + Title string `yaml:"title,omitempty"` + Date string `yaml:"date,omitempty"` + Lastmod string `yaml:"lastmod,omitempty"` + Tags []string `yaml:"tags,omitempty"` + ExternalURL string `yaml:"externalURL,omitempty"` + Indieweb HugoFrontmatterIndieweb `yaml:"indieweb,omitempty"` } -type Indieweb struct { - Reply Reply `yaml:"reply,omitempty"` - Like Like `yaml:"like,omitempty"` +type HugoFrontmatterIndieweb struct { + Reply HugoFrontmatterReply `yaml:"reply,omitempty"` + Like HugoFrontmatterLike `yaml:"like,omitempty"` } -type Reply struct { +type HugoFrontmatterReply struct { Link string `yaml:"link,omitempty"` Title string `yaml:"title,omitempty"` } -type Like struct { +type HugoFrontmatterLike struct { Link string `yaml:"link,omitempty"` Title string `yaml:"title,omitempty"` } func writeFrontMatter(entry *Entry) (frontmatter string, err error) { var buff bytes.Buffer - writeFrontmatter := &Frontmatter{ + writeFrontmatter := &HugoFrontmatter{ Title: entry.title, Date: entry.date, Lastmod: entry.lastmod, Tags: entry.tags, ExternalURL: entry.link, - Indieweb: Indieweb{ - Reply: Reply{ + Indieweb: HugoFrontmatterIndieweb{ + Reply: HugoFrontmatterReply{ Link: entry.replyLink, Title: entry.replyTitle, }, - Like: Like{ + Like: HugoFrontmatterLike{ Link: entry.likeLink, Title: entry.likeTitle, }, @@ -76,7 +76,7 @@ func WriteHugoPost(entry *Entry) (string, error) { } func readFrontMatter(frontmatter string, entry *Entry) (err error) { - parsedFrontmatter := &Frontmatter{} + parsedFrontmatter := &HugoFrontmatter{} err = yaml.Unmarshal([]byte(frontmatter), &parsedFrontmatter) if err != nil { err = errors.New("failed parsing frontmatter") @@ -124,4 +124,4 @@ func ReadHugoPost(fileContent string) (entry *Entry, err error) { } entry.content = strings.TrimSuffix(parts[2], "\n") return -} \ No newline at end of file +} diff --git a/query.go b/query.go index 7f21aa1..a19869b 100644 --- a/query.go +++ b/query.go @@ -8,21 +8,7 @@ import ( ) type ItemList struct { - Items []*Item `json:"items"` -} - -type Item struct { - Type []string `json:"type"` - Properties *Properties `json:"properties"` -} - -type Properties struct { - Name []string `json:"name"` - Published []string `json:"published"` - Updated []string `json:"updated"` - Category []string `json:"category"` - Content []string `json:"content"` - Url []string `json:"url"` + Items []*MicroformatItem `json:"items"` } func QueryURL(url string, limit int) ([]byte, error) { @@ -62,14 +48,14 @@ func QueryURL(url string, limit int) ([]byte, error) { } } -func getItem(url string) (item *Item, err error) { +func getItem(url string) (item *MicroformatItem, err error) { entry, err := ReadEntry(url) if err != nil { return } - item = &Item{ + item = &MicroformatItem{ Type: []string{"h-entry"}, - Properties: &Properties{ + Properties: &MicroformatProperties{ Name: []string{entry.title}, Published: []string{entry.date}, Updated: []string{entry.lastmod},