hugo-micropub/storage.go

134 lines
3.6 KiB
Go
Raw Normal View History

2019-11-07 10:00:24 +00:00
package main
import (
"bytes"
"encoding/base64"
"encoding/json"
"errors"
2019-11-14 17:46:49 +00:00
"io/ioutil"
2019-11-07 10:00:24 +00:00
"net/http"
"net/url"
2019-12-12 15:29:26 +00:00
"strings"
2019-11-07 10:00:24 +00:00
)
2019-12-22 20:17:11 +00:00
type Storage interface {
CreateFile(path string, file string, message string) (err error)
UpdateFile(path string, file string, message string) (err error)
ReadFile(path string) (content string, sha string, exists bool, err error)
}
// Gitea
type Gitea struct {
endpoint string
token string
}
type giteaCommitRequest struct {
2019-12-12 15:29:26 +00:00
Content string `json:"content"`
Message string `json:"message"`
SHA string `json:"sha,omitempty"`
}
2019-12-22 20:17:11 +00:00
type giteaReadResponse struct {
2019-12-12 15:29:26 +00:00
Type string `json:"type"`
Content string `json:"content"`
SHA string `json:"sha"`
}
2019-12-22 20:17:11 +00:00
type giteaErrorResponse struct {
2019-12-12 15:29:26 +00:00
Message string `json:"message"`
}
2019-12-22 20:17:11 +00:00
func (gitea *Gitea) CreateFile(path string, file string, message string) (err error) {
request := &giteaCommitRequest{
2019-12-12 15:29:26 +00:00
Content: base64.StdEncoding.EncodeToString([]byte(file)),
Message: message,
2019-11-07 10:00:24 +00:00
}
2019-12-12 15:29:26 +00:00
bytesRepresentation, err := json.Marshal(request)
2019-11-07 10:00:24 +00:00
if err != nil {
return errors.New("failed to marshal json before committing")
}
2019-12-22 20:17:11 +00:00
resp, err := http.Post(gitea.endpoint+url.QueryEscape(path)+"?access_token="+gitea.token, "application/json", bytes.NewBuffer(bytesRepresentation))
2019-11-07 10:00:24 +00:00
if err != nil || resp.StatusCode != 201 {
return errors.New("failed to create file in repo")
}
return nil
}
2019-11-14 17:46:49 +00:00
2019-12-22 20:17:11 +00:00
func (gitea *Gitea) UpdateFile(path string, file string, message string) (err error) {
_, sha, exists, err := gitea.ReadFile(path)
2019-12-12 15:29:26 +00:00
if err != nil {
return err
}
if !exists {
// File doesn't exist, create it
2019-12-22 20:17:11 +00:00
return gitea.CreateFile(path, file, message)
2019-12-12 15:29:26 +00:00
}
2019-12-22 20:17:11 +00:00
request := &giteaCommitRequest{
2019-12-12 15:29:26 +00:00
Content: base64.StdEncoding.EncodeToString([]byte(file)),
Message: message,
2019-12-22 20:17:11 +00:00
SHA: sha,
2019-12-12 15:29:26 +00:00
}
bytesRepresentation, err := json.Marshal(request)
if err != nil {
return errors.New("failed to marshal json before committing")
}
2019-12-22 20:17:11 +00:00
req, err := http.NewRequest(http.MethodPut, gitea.endpoint+url.QueryEscape(path)+"?access_token="+gitea.token, bytes.NewBuffer(bytesRepresentation))
2019-12-12 15:29:26 +00:00
if err != nil {
return errors.New("error making update request")
}
req.Header.Set("Content-type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil || resp.StatusCode != 200 {
return errors.New("failed to update file in repo")
}
return nil
}
2019-12-22 20:17:11 +00:00
func (gitea *Gitea) ReadFile(path string) (content string, sha string, exists bool, err error) {
2019-12-12 15:29:26 +00:00
exists = false
2019-12-22 20:17:11 +00:00
resp, err := http.Get(gitea.endpoint + url.QueryEscape(path) + "?access_token=" + gitea.token)
2019-11-14 17:46:49 +00:00
if err != nil || resp.StatusCode != 200 {
2019-12-12 15:29:26 +00:00
if resp != nil {
defer resp.Body.Close()
body, readErr := ioutil.ReadAll(resp.Body)
if readErr != nil {
err = errors.New("failed reading Gitea error response")
return
}
2019-12-22 20:17:11 +00:00
errorResponse := &giteaErrorResponse{}
2019-12-12 15:29:26 +00:00
marshalErr := json.Unmarshal(body, &errorResponse)
if marshalErr != nil {
err = errors.New("failed parsing Gitea error response")
return
}
exists = !strings.Contains(errorResponse.Message, "does not exist")
if !exists {
return
}
}
2019-11-14 17:46:49 +00:00
err = errors.New("failed to read file in repo")
return
}
2019-12-12 15:29:26 +00:00
exists = true
2019-11-14 17:46:49 +00:00
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
err = errors.New("failed reading file in repo")
return
}
2019-12-22 20:17:11 +00:00
readResponse := &giteaReadResponse{}
err = json.Unmarshal(body, &readResponse)
2019-11-14 17:46:49 +00:00
if err != nil {
err = errors.New("failed parsing Gitea response")
return
}
2019-12-22 20:17:11 +00:00
decodedContentBytes, err := base64.StdEncoding.DecodeString(readResponse.Content)
2019-11-14 17:46:49 +00:00
if err != nil {
err = errors.New("failed decoding file content")
}
2019-12-22 20:17:11 +00:00
content = string(decodedContentBytes)
sha = readResponse.SHA
2019-11-14 17:46:49 +00:00
return
}