This commit is contained in:
2025-07-29 17:34:27 +02:00
parent 68e13938b7
commit 7b3b91c998
6 changed files with 271 additions and 2 deletions

View File

@@ -68,6 +68,29 @@ func Add(name, path string) (Metadata, error) {
return m, nil
}
func Register(m Metadata, path string) error {
m.Path = path
err := os.MkdirAll(filepath.Join(datastorepath, m.ID), 0740)
if err != nil {
panic("cannot make directory for the game:" + err.Error())
}
f, err := os.OpenFile(filepath.Join(datastorepath, m.ID, "metadata.json"), os.O_CREATE|os.O_WRONLY, 0740)
if err != nil {
return fmt.Errorf("cannot open the metadata file in the datastore: %w", err)
}
defer f.Close()
e := json.NewEncoder(f)
err = e.Encode(m)
if err != nil {
return fmt.Errorf("cannot write into the metadata file in the datastore: %w", err)
}
return nil
}
func All() ([]Metadata, error) {
ds, err := os.ReadDir(datastorepath)
if err != nil {

View File

@@ -25,6 +25,14 @@ type (
username string
password string
}
Information struct {
Version string `json:"version"`
APIVersion int `json:"api_version"`
GoVersion string `json:"go_version"`
OSName string `json:"os_name"`
OSArchitecture string `json:"os_architecture"`
}
)
func New(baseURL, username, password string) *Client {
@@ -66,6 +74,31 @@ func (c *Client) Exists(gameID string) (bool, error) {
return false, fmt.Errorf("an error occured: server response: %s", r.Status)
}
func (c *Client) Version() (Information, error) {
u, err := url.JoinPath(c.baseURL, "api", "v1", "version")
if err != nil {
return Information{}, err
}
o, err := c.get(u)
if err != nil {
return Information{}, err
}
if info, ok := (o.Data).(map[string]any); ok {
i := Information{
Version: info["version"].(string),
APIVersion: int(info["api_version"].(float64)),
GoVersion: info["go_version"].(string),
OSName: info["os_name"].(string),
OSArchitecture: info["os_architecture"].(string),
}
return i, nil
}
return Information{}, errors.New("invalid payload sent by the server")
}
func (c *Client) Hash(gameID string) (string, error) {
u, err := url.JoinPath(c.baseURL, "api", "v1", "games", gameID, "hash")
if err != nil {

View File

@@ -0,0 +1,73 @@
package archive
import (
"archive/tar"
"compress/gzip"
"io"
"os"
"path/filepath"
)
func Untar(file io.Reader, path string) error {
gzr, err := gzip.NewReader(file)
if err != nil {
return err
}
defer gzr.Close()
tr := tar.NewReader(gzr)
for {
header, err := tr.Next()
switch {
// if no more files are found return
case err == io.EOF:
return nil
// return any other error
case err != nil:
return err
// if the header is nil, just skip it (not sure how this happens)
case header == nil:
continue
}
// the target location where the dir/file should be created
target := filepath.Join(path, header.Name)
// the following switch could also be done using fi.Mode(), not sure if there
// a benefit of using one vs. the other.
// fi := header.FileInfo()
// check the file type
switch header.Typeflag {
// if its a dir and it doesn't exist create it
case tar.TypeDir:
if _, err := os.Stat(target); err != nil {
if err := os.MkdirAll(target, 0755); err != nil {
return err
}
}
// if it's a file create it
case tar.TypeReg:
f, err := os.OpenFile(target, os.O_CREATE|os.O_RDWR, os.FileMode(header.Mode))
if err != nil {
return err
}
// copy over contents
if _, err := io.Copy(f, tr); err != nil {
return err
}
// manually close here after each file operation; defering would cause each file close
// to wait until all operations have completed.
f.Close()
}
}
}