Signed-off-by: Matheus Sampaio Queiroga <srherobrine20@gmail.com>
234 lines
5.6 KiB
Go
234 lines
5.6 KiB
Go
package bds
|
|
|
|
import (
|
|
"archive/tar"
|
|
"archive/zip"
|
|
"compress/gzip"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"time"
|
|
|
|
"sirherobrine23.org/minecraft-server/bedrockfetch/internal/convert"
|
|
"sirherobrine23.org/minecraft-server/bedrockfetch/internal/request"
|
|
gitea "sirherobrine23.org/minecraft-server/bedrockfetch/internal/tea"
|
|
)
|
|
|
|
type BedrockVersionsTarget struct {
|
|
NodePlatform string `json:"Platform"` // Nodejs Platform string
|
|
NodeArch string `json:"Arch"` // Nodejs Archs
|
|
ZipFile string `json:"zip"` // Local file and http to remote
|
|
ZipSHA1 string `json:"zipSHA1"` // File SHA1
|
|
TarFile string `json:"tar"` // Local file and http to remote
|
|
TarSHA1 string `json:"tarSHA1"` // File SHA1
|
|
}
|
|
|
|
type BedrockVersions struct {
|
|
Version string `json:"version"`
|
|
DateRelease time.Time `json:"releaseDate"`
|
|
ReleaseType string `json:"type"`
|
|
Targets []BedrockVersionsTarget `json:"targets"`
|
|
}
|
|
|
|
var (
|
|
VersionsPathFile, _ = filepath.Abs("./versions.json")
|
|
Versions = make(map[string]BedrockVersions)
|
|
)
|
|
|
|
func init() {
|
|
LoadLocalVersions()
|
|
}
|
|
|
|
func AddNewVersion(v BedrockVersions) {
|
|
Versions[v.Version] = v
|
|
}
|
|
|
|
func LoadLocalVersions() error {
|
|
file, err := os.Open(VersionsPathFile)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
defer file.Close()
|
|
|
|
localEnv := []BedrockVersions{}
|
|
err = json.NewDecoder(file).Decode(&localEnv)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, ver := range localEnv {
|
|
Versions[ver.Version] = ver
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func SaveLocalVersions() error {
|
|
doArray := []BedrockVersions{}
|
|
for _, ver := range Versions {
|
|
doArray = append(doArray, ver)
|
|
}
|
|
|
|
data, err := json.MarshalIndent(&doArray, "", " ")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return os.WriteFile(VersionsPathFile, data, os.FileMode(0o666))
|
|
}
|
|
|
|
func (bdsRelease *BedrockVersions) UploadRelease() error {
|
|
tea, err := gitea.CreateRelease(gitea.GiteaRelease{
|
|
AuthToken: gitea.Token,
|
|
TagName: bdsRelease.Version,
|
|
Name: bdsRelease.Version,
|
|
IsPrerelease: bdsRelease.ReleaseType != "release",
|
|
IsDraft: true,
|
|
FileAssets: []gitea.GiteaAsset{},
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
fmt.Printf("Uploading %s\n", bdsRelease.Version)
|
|
for targetIndex, target := range bdsRelease.Targets {
|
|
// Zip upload
|
|
zipStr, err := os.Open(target.ZipFile)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
filename := fmt.Sprintf("%s-%s.zip", target.NodeArch, target.NodePlatform)
|
|
fmt.Printf("Uploading %s: %s\n", bdsRelease.Version, filename)
|
|
infoZip, err := tea.UploadAsset(filename, zipStr)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
bdsRelease.Targets[targetIndex].ZipFile = infoZip.FileUrl
|
|
|
|
// Tar upload
|
|
tarStr, err := os.Open(target.TarFile)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
filename = fmt.Sprintf("%s-%s.tgz", target.NodeArch, target.NodePlatform)
|
|
fmt.Printf("Uploading %s: %s\n", bdsRelease.Version, filename)
|
|
infoTar, err := tea.UploadAsset(filename, tarStr)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
bdsRelease.Targets[targetIndex].TarFile = infoTar.FileUrl
|
|
}
|
|
|
|
tea.IsDraft = false
|
|
err = tea.UpdateRelease()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Download zip file and convert to .tgz and set file path to ZipFile and TarFile
|
|
func (assert *BedrockVersionsTarget) Download() error {
|
|
zipSplited := strings.Split(assert.ZipFile, "/")[len(strings.Split(assert.ZipFile, "/"))-2:]
|
|
zipFile := filepath.Join(os.TempDir(), "bdsfetch", filepath.Join(zipSplited...))
|
|
tarFile := strings.Replace(zipFile, ".zip", ".tgz", 1)
|
|
os.MkdirAll(filepath.Dir(zipFile), os.FileMode(0o666))
|
|
|
|
// Get file stream
|
|
_, res, err := request.Request(request.RequestOptions{
|
|
Url: assert.ZipFile,
|
|
HttpError: true,
|
|
Method: "GET",
|
|
})
|
|
|
|
defer res.Body.Close()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
fmt.Printf("Downloading %s, size %s\n", assert.ZipFile, convert.ByteCountSI(res.ContentLength))
|
|
// Create zip file
|
|
zipFileStream, err := os.Create(zipFile)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Copy to file
|
|
_, err = io.Copy(zipFileStream, res.Body)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
fmt.Printf("Download %q complete\n", assert.ZipFile)
|
|
// Create zip file
|
|
tarFileStream, err := os.Create(tarFile)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
gzStr := gzip.NewWriter(tarFileStream)
|
|
tarStr := tar.NewWriter(gzStr)
|
|
defer (func() {
|
|
tarStr.Close()
|
|
gzStr.Close()
|
|
tarFileStream.Close()
|
|
})()
|
|
|
|
zipStats, _ := zipFileStream.Stat()
|
|
zipStr, err := zip.NewReader(zipFileStream, zipStats.Size())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
fmt.Printf("zip (%q) to tgz (%q)\n", filepath.Base(zipFile), filepath.Base(tarFile))
|
|
for _, fileEntry := range zipStr.File {
|
|
fileInfo := fileEntry.FileInfo()
|
|
tarhead := tar.Header{
|
|
Name: fileEntry.Name,
|
|
ChangeTime: fileEntry.Modified,
|
|
ModTime: fileEntry.Modified,
|
|
Size: fileInfo.Size(),
|
|
Mode: int64(fileInfo.Mode()),
|
|
}
|
|
|
|
if fileInfo.IsDir() {
|
|
tarhead.Size = 0
|
|
}
|
|
|
|
if err = tarStr.WriteHeader(&tarhead); err != nil {
|
|
return fmt.Errorf("unable to get entry content: %s", err)
|
|
}
|
|
|
|
// fmt.Printf("zip (%q) to tgz (%q): %s, size: %s\n", filepath.Base(zipFile), filepath.Base(tarFile), fileEntry.Name, convert.ByteCountSI(fileInfo.Size()))
|
|
if !fileInfo.IsDir() {
|
|
fileContent, _err := fileEntry.Open()
|
|
if _err != nil {
|
|
return fmt.Errorf("unable to get entry content: %s", _err)
|
|
}
|
|
|
|
_, err = io.Copy(tarStr, fileContent)
|
|
if !(err == nil || err == io.EOF) {
|
|
return fmt.Errorf("cannot copy file (%s) content: %s", fileEntry.Name, err)
|
|
}
|
|
fileContent.Close()
|
|
}
|
|
}
|
|
|
|
// Save zip info
|
|
assert.ZipFile = zipFile
|
|
assert.ZipSHA1, _ = convert.FileSHA1(zipFile)
|
|
|
|
// Save tgz info
|
|
assert.TarFile = tarFile
|
|
assert.TarSHA1, _ = convert.FileSHA1(tarFile)
|
|
|
|
return nil
|
|
}
|