hugo-micropub/gitea.go

134 lines
3.5 KiB
Go

package main
import (
"bytes"
"encoding/base64"
"encoding/json"
"errors"
"io/ioutil"
"net/http"
"net/url"
"strings"
)
type GiteaCommitRequest struct {
Content string `json:"content"`
Message string `json:"message"`
SHA string `json:"sha,omitempty"`
}
type GiteaReadRequest struct {
Type string `json:"type"`
Content string `json:"content"`
SHA string `json:"sha"`
}
type GiteaErrorResponse struct {
Message string `json:"message"`
}
func CreateFile(path string, file string, message string) error {
request := &GiteaCommitRequest{
Content: base64.StdEncoding.EncodeToString([]byte(file)),
Message: message,
}
bytesRepresentation, err := json.Marshal(request)
if err != nil {
return errors.New("failed to marshal json before committing")
}
resp, err := http.Post(GiteaEndpoint+url.QueryEscape(path)+"?access_token="+GiteaToken, "application/json", bytes.NewBuffer(bytesRepresentation))
if err != nil || resp.StatusCode != 201 {
return errors.New("failed to create file in repo")
}
return nil
}
func UpdateFile(path string, file string, message string) error {
existingFile, exists, err := ReadFile(path)
if err != nil {
return err
}
if !exists {
// File doesn't exist, create it
return CreateFile(path, file, message)
}
request := &GiteaCommitRequest{
Content: base64.StdEncoding.EncodeToString([]byte(file)),
Message: message,
SHA: existingFile.SHA,
}
bytesRepresentation, err := json.Marshal(request)
if err != nil {
return errors.New("failed to marshal json before committing")
}
req, err := http.NewRequest(http.MethodPut, GiteaEndpoint+url.QueryEscape(path)+"?access_token="+GiteaToken, bytes.NewBuffer(bytesRepresentation))
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
}
func ReadFile(path string) (response *GiteaReadRequest, exists bool, err error) {
exists = false
resp, err := http.Get(GiteaEndpoint + url.QueryEscape(path) + "?access_token=" + GiteaToken)
if err != nil || resp.StatusCode != 200 {
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
}
errorResponse := &GiteaErrorResponse{}
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
}
}
err = errors.New("failed to read file in repo")
return
}
exists = true
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
err = errors.New("failed reading file in repo")
return
}
response = &GiteaReadRequest{}
err = json.Unmarshal(body, &response)
if err != nil {
err = errors.New("failed parsing Gitea response")
return
}
return
}
func ReadFileContent(path string) (fileContent string, err error) {
giteaResponseBody, exists, err := ReadFile(path)
if err != nil {
return
}
if !exists {
// File doesn't exist, nothing to read
err = errors.New("file does not exist")
return
}
decodedBytes, err := base64.StdEncoding.DecodeString(giteaResponseBody.Content)
if err != nil {
err = errors.New("failed decoding file content")
}
fileContent = string(decodedBytes)
return
}