diff --git a/blog.go b/blog.go index ed75b42..4673c18 100644 --- a/blog.go +++ b/blog.go @@ -16,13 +16,10 @@ package main import ( "bytes" - "encoding/json" "flag" "fmt" - "io" "io/fs" "log" - "net/http" "net/url" "os" "path/filepath" @@ -35,7 +32,6 @@ import ( "github.com/yuin/goldmark" ) -const mataroaApiUrl = "https://capivaras.dev/api/" const rssBaseUrl = "https://github.com/thiagokokada/blog/blob/main" const readmeTemplate = `# Blog @@ -48,8 +44,6 @@ Mirror of my blog in https://kokada.capivaras.dev/. %s ` -var mataroaToken = os.Getenv("MATAROA_TOKEN") - type post struct { title string file string @@ -58,28 +52,6 @@ type post struct { date time.Time } -// https://capivaras.dev/api/docs/ -type mataroaResponse struct { - Ok bool `json:"ok"` - Title string `json:"title"` - Url string `json:"url"` - Slug string `json:"slug"` - // Error string `json:"error"` -} - -type mataroaPostRequest struct { - Title string `json:"title"` - Body string `json:"body"` - PublishedAt string `json:"published_at"` -} - -type mataroaPatchRequest struct { - Title string `json:"title"` - Slug string `json:"slug"` - Body string `json:"body"` - PublishedAt string `json:"published_at"` -} - func must1[T any](v T, err error) T { must(err) return v @@ -208,69 +180,6 @@ func genReadme(posts []post) string { return fmt.Sprintf(readmeTemplate, strings.Join(titles, "\n")) } -func mustMataroaReq(method string, elem []string, body []byte) (p mataroaResponse, r *http.Response) { - // generate a Mataroa URL, ensure '/' at the end - reqUrl := must1(url.JoinPath(mataroaApiUrl, elem...)) - reqUrl = must1(url.JoinPath(reqUrl, "/")) - - // Prepare request payload if non-nil - var reqBuf io.Reader - if body != nil { - reqBuf = bytes.NewBuffer(body) - } - req := must1(http.NewRequest(method, reqUrl, reqBuf)) - req.Header.Add("Accept", "application/json") - req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", mataroaToken)) - - // Do request and return response - resp := must1(http.DefaultClient.Do(req)) - respBody := must1(io.ReadAll(resp.Body)) - json.Unmarshal(respBody, &p) - return p, resp -} - -func mustGetMataroaPost(post post) (p mataroaResponse, r *http.Response) { - return mustMataroaReq("GET", []string{"posts", post.slug}, nil) -} - -func mustPatchMataroaPost(post post) (p mataroaResponse, r *http.Response) { - reqBody := must1(json.Marshal(mataroaPatchRequest{ - Title: post.title, - Body: string(post.contents), - Slug: post.slug, - PublishedAt: post.date.Format(time.DateOnly), - })) - return mustMataroaReq("PATCH", []string{"posts", post.slug}, reqBody) -} - -func mustPostMataroaPost(post post) (p mataroaResponse, r *http.Response) { - reqBody := must1(json.Marshal(mataroaPostRequest{ - Title: post.title, - Body: string(post.contents), - PublishedAt: post.date.Format(time.DateOnly), - })) - return mustMataroaReq("POST", []string{"posts"}, reqBody) -} - -func publishToMataroa(posts []post) { - for _, post := range posts { - p, resp := mustGetMataroaPost(post) - if p.Ok { - p, resp = mustPatchMataroaPost(post) - log.Printf("[UPDATED] (code=%d): %+v\n", resp.StatusCode, p) - } else if resp.StatusCode == 404 { - p, resp = mustPostMataroaPost(post) - log.Printf("[NEW] (code=%d): %+v\n", resp.StatusCode, p) - } else { - log.Printf("[ERROR] %s: %+v\n", post.slug, resp) - } - - if resp.StatusCode != 200 { - panic(fmt.Sprintf("non-200 response for post: %s", post.slug)) - } - } -} - func main() { rss := flag.Bool("rss", false, "Generate RSS (XML) instead of README.md") publish := flag.Bool("publish", false, "Publish updates to Maratoa instance") diff --git a/mataroa.go b/mataroa.go new file mode 100644 index 0000000..62fad65 --- /dev/null +++ b/mataroa.go @@ -0,0 +1,116 @@ +package main + +// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE +// Version 2, December 2004 +// +// Copyright (C) 2024 Thiago Kenji Okada +// +// Everyone is permitted to copy and distribute verbatim or modified +// copies of this license document, and changing it is allowed as long +// as the name is changed. +// +// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE +// TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION +// +// 0. You just DO WHAT THE FUCK YOU WANT TO. + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "log" + "net/http" + "net/url" + "os" + "time" +) + +const mataroaApiUrl = "https://capivaras.dev/api/" + +var mataroaToken = os.Getenv("MATAROA_TOKEN") + +// https://capivaras.dev/api/docs/ +type mataroaResponse struct { + Ok bool `json:"ok"` + Title string `json:"title"` + Url string `json:"url"` + Slug string `json:"slug"` + // Error string `json:"error"` +} + +type mataroaPostRequest struct { + Title string `json:"title"` + Body string `json:"body"` + PublishedAt string `json:"published_at"` +} + +type mataroaPatchRequest struct { + Title string `json:"title"` + Slug string `json:"slug"` + Body string `json:"body"` + PublishedAt string `json:"published_at"` +} + +func mustMataroaReq(method string, elem []string, body []byte) (p mataroaResponse, r *http.Response) { + // generate a Mataroa URL, ensure '/' at the end + reqUrl := must1(url.JoinPath(mataroaApiUrl, elem...)) + reqUrl = must1(url.JoinPath(reqUrl, "/")) + + // Prepare request payload if non-nil + var reqBuf io.Reader + if body != nil { + reqBuf = bytes.NewBuffer(body) + } + req := must1(http.NewRequest(method, reqUrl, reqBuf)) + req.Header.Add("Accept", "application/json") + req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", mataroaToken)) + + // Do request and return response + resp := must1(http.DefaultClient.Do(req)) + respBody := must1(io.ReadAll(resp.Body)) + json.Unmarshal(respBody, &p) + return p, resp +} + +func mustGetMataroaPost(post post) (p mataroaResponse, r *http.Response) { + return mustMataroaReq("GET", []string{"posts", post.slug}, nil) +} + +func mustPatchMataroaPost(post post) (p mataroaResponse, r *http.Response) { + reqBody := must1(json.Marshal(mataroaPatchRequest{ + Title: post.title, + Body: string(post.contents), + Slug: post.slug, + PublishedAt: post.date.Format(time.DateOnly), + })) + return mustMataroaReq("PATCH", []string{"posts", post.slug}, reqBody) +} + +func mustPostMataroaPost(post post) (p mataroaResponse, r *http.Response) { + reqBody := must1(json.Marshal(mataroaPostRequest{ + Title: post.title, + Body: string(post.contents), + PublishedAt: post.date.Format(time.DateOnly), + })) + return mustMataroaReq("POST", []string{"posts"}, reqBody) +} + +func publishToMataroa(posts []post) { + for _, post := range posts { + p, resp := mustGetMataroaPost(post) + if p.Ok { + p, resp = mustPatchMataroaPost(post) + log.Printf("[UPDATED] (code=%d): %+v\n", resp.StatusCode, p) + } else if resp.StatusCode == 404 { + p, resp = mustPostMataroaPost(post) + log.Printf("[NEW] (code=%d): %+v\n", resp.StatusCode, p) + } else { + log.Printf("[ERROR] %s: %+v\n", post.slug, resp) + } + + if resp.StatusCode != 200 { + panic(fmt.Sprintf("non-200 response for post: %s", post.slug)) + } + } +}