Files
Matheus Sampaio Queiroga cc50a88525
All checks were successful
Find and Upload Minecraft Server versions / build (push) Successful in 1m28s
Fix fetch
Signed-off-by: Matheus Sampaio Queiroga <srherobrine20@gmail.com>
2024-04-29 21:22:37 -03:00

228 lines
6.3 KiB
Go

package tea
import (
"bytes"
"encoding/json"
"fmt"
"io"
"mime/multipart"
"net/http"
"os"
"strings"
"time"
"sirherobrine23.org/minecraft-server/bedrockfetch/internal/request"
)
var Token string = (func() string {
if ghToken := os.Getenv("GH_TOKEN"); len(ghToken) > 0 {
return ghToken
} else if githubToken := os.Getenv("GITHUB_TOKEN"); len(githubToken) > 0 {
return githubToken
} else if giteaToken := os.Getenv("GITEA_TOKEN"); len(giteaToken) > 0 {
return giteaToken
}
return ""
})() // global token to auth to sirherobrine23.org
const (
GiteaReleaseAPI string = "https://sirherobrine23.org/api/v1/repos/Minecraft-Server/BedrockFetch/releases"
)
type GiteaAsset struct {
Id int64 `json:"id"`
FileSize int64 `json:"size"`
Downloads int64 `json:"download_count"`
Uuid string `json:"uuid"`
FileUrl string `json:"browser_download_url"`
FileName string `json:"name"`
Create time.Time `json:"created_at"`
}
type GiteaRelease struct {
ReleaseId int64 `json:"id"` // Release id
TagName string `json:"tag_name"` // Release tag name
Name string `json:"name,omitempty"` // Release name
IsPrerelease bool `json:"prerelease"` // Set Pre-release
IsDraft bool `json:"draft"` // Set release to draft
FileAssets []GiteaAsset `json:"assets,omitempty"` // Files in release
}
// Create release if exist return current release
func CreateReleasee(TagName, Name string, IsPrerelease, Draft, Force bool) (*GiteaRelease, error) {
// Check token
if len(Token) == 0 {
return nil, fmt.Errorf("set Gitea token in Env (GH_TOKEN || GITHUB_TOKEN || GITEA_TOKEN)")
}
// Check to tag is valid string
if TagName = strings.TrimSpace(TagName); len(TagName) == 0 {
return nil, fmt.Errorf("set valid tag to create release")
}
// Copy name from tag
if Name = strings.TrimSpace(Name); len(Name) == 0 {
Name = TagName
}
// Request base
req := request.RequestOptions{
HttpError: false,
Method: "GET",
Url: fmt.Sprintf("%s/tags/%s", GiteaReleaseAPI, TagName),
Headers: http.Header{
"Authorization": {fmt.Sprintf("token %s", Token)},
},
}
// Release body
var ReleaseContent GiteaRelease
res, err := req.Do(&ReleaseContent)
if err != nil {
return nil, err
} else if res.StatusCode == 200 && !Force {
return &ReleaseContent, nil
} else if res.StatusCode == 200 && Force {
req.Method = "DELETE"
res, err = req.Request()
if err != nil {
return nil, err
} else if !(res.StatusCode == 200 || res.StatusCode == 204) {
return nil, fmt.Errorf("cannot delete %q", TagName)
}
}
// Encode body
body, err := json.Marshal(&GiteaRelease{TagName: TagName, Name: Name, IsPrerelease: IsPrerelease, IsDraft: Draft})
if err != nil {
return nil, err
}
// Create relase
req.Method = "POST"
req.Headers.Set("Content-Type", "application/json")
req.Url = GiteaReleaseAPI
req.Body = bytes.NewReader(body)
if res, err = req.Do(&ReleaseContent); err != nil {
return nil, err
} else if res.StatusCode != 201 {
return nil, fmt.Errorf("cannot create release, code %d (%s)", res.StatusCode, res.Status)
}
// Return body
return &ReleaseContent, nil
}
// Sync local release to Remote release
// no sync files
func (release *GiteaRelease) Update() error {
// Encode body
body, err := json.Marshal(release)
if err != nil {
return err
}
// Create relase
req := request.RequestOptions{
HttpError: false,
Method: "PATCH",
Url: fmt.Sprintf("%s/%d", GiteaReleaseAPI, release.ReleaseId),
Body: bytes.NewReader(body),
Headers: http.Header{
"Authorization": {fmt.Sprintf("token %s", Token)},
"Content-Type": {"application/json"},
},
}
// Release body
var ReleaseContent GiteaRelease
res, err := req.Do(&ReleaseContent)
if err != nil {
return err
} else if res.StatusCode != 200 {
return fmt.Errorf("cannot get release body")
}
// Copy new struct
copy(release.FileAssets, ReleaseContent.FileAssets) // Update files
release.IsDraft = ReleaseContent.IsDraft // Update Draft status
release.IsPrerelease = ReleaseContent.IsPrerelease // Update prerelease status
release.Name = ReleaseContent.Name // Update release name
return nil
}
// Update Release info
func (release *GiteaRelease) UpdateLocal() error {
// Request base
req := request.RequestOptions{
HttpError: false,
Method: "GET",
Url: fmt.Sprintf("%s/tags/%s", GiteaReleaseAPI, release.TagName),
Headers: http.Header{
"Authorization": {fmt.Sprintf("token %s", Token)},
},
}
// Release body
var ReleaseContent GiteaRelease
res, err := req.Do(&ReleaseContent)
if err != nil {
return err
} else if res.StatusCode != 200 {
return fmt.Errorf("cannot get release body")
}
// Copy new struct
copy(release.FileAssets, ReleaseContent.FileAssets) // Update files
release.IsDraft = ReleaseContent.IsDraft // Update Draft status
release.IsPrerelease = ReleaseContent.IsPrerelease // Update prerelease status
release.Name = ReleaseContent.Name // Update release name
return nil
}
// Get file from release assets if not exists return nil
func (release *GiteaRelease) GetFile(filename string) *GiteaAsset {
for _, file := range release.FileAssets {
if file.FileName == filename {
return &file
}
}
return nil
}
func (release *GiteaRelease) Upload(filename string, file io.Reader) (*GiteaAsset, error) {
body := new(bytes.Buffer)
writer := multipart.NewWriter(body)
part, err := writer.CreateFormFile("attachment", filename)
if err != nil {
return nil, err
} else if _, err = io.Copy(part, file); err != nil {
return nil, err
} else if err = writer.Close(); err != nil {
return nil, err
}
req := request.RequestOptions{
Url: fmt.Sprintf("%s/%d/assets", GiteaReleaseAPI, release.ReleaseId),
HttpError: false,
Method: "POST",
Body: body,
Headers: http.Header{
"Authorization": {fmt.Sprintf("token %s", Token)},
"Content-Type": {writer.FormDataContentType()},
},
}
var asset GiteaAsset
res, err := req.Do(&asset)
if err != nil {
return nil, err
} else if res.StatusCode != 201 {
return nil, fmt.Errorf("cannot upload %q to release, code: %d (%s)", filename, res.StatusCode, res.Status)
}
release.FileAssets = append(release.FileAssets, asset)
return &asset, nil
}