Compare commits

...

5 Commits

Author SHA1 Message Date
4a6a2cf057 Implement frontend api 2025-01-11 20:38:48 +01:00
75d92a2542 Save settings when quitting
Idk if this is necessary... Maybe it won't be
2025-01-11 20:33:45 +01:00
84617ede5d Refaator service from *Addon to Addon 2025-01-11 20:31:25 +01:00
994a5a86f4 Refactor shit to settings 2025-01-11 20:25:04 +01:00
4c816e6309 Use string for url 2025-01-11 20:19:26 +01:00
8 changed files with 244 additions and 47 deletions

View File

@@ -7,7 +7,6 @@ import (
"io"
"log"
"net/http"
"net/url"
"os"
"path/filepath"
"regexp"
@@ -16,30 +15,20 @@ import (
type Addon struct {
Name string `json:"name"`
URL *url.URL `json:"url"`
URL string `json:"url"`
}
var versionRegex = regexp.MustCompile(`(\d+\.\d+\.\d+)`)
func NewAddon(name, aurl string) *Addon {
a := &Addon{Name: name}
var err error
a.URL, err = url.Parse(aurl)
if err != nil {
Error.Printf("invalid url: %s", aurl)
return nil
}
return a
func (a *Addon) GetRemoteTocURL() string {
return fmt.Sprintf("%s/raw/branch/master/%s.toc", a.URL, a.Name)
}
func (a *Addon) GetRemoteTocURL() *url.URL {
return a.URL.JoinPath("raw", "branch", "master", a.Name+".toc")
}
func (a *Addon) GetRemoteReleaseURL() *url.URL {
return a.URL.JoinPath("media", "branch", "master", a.Name+".zip")
func (a *Addon) GetRemoteReleaseURL() string {
return fmt.Sprintf("%s/media/branch/master/%s.zip", a.URL, a.Name)
}
func (a *Addon) GetRemoteRelease() (body []byte, err error) {
url := a.GetRemoteReleaseURL()
response, err := http.Get(url.String())
response, err := http.Get(url)
if err != nil {
return nil, fmt.Errorf("error getting remote release: %w", err)
}
@@ -139,8 +128,8 @@ func (a *Addon) GetLocalTocPath() string {
}
func (a *Addon) GetRemoteVersion() (version string, err error) {
url := a.GetRemoteTocURL()
log.Printf("Fetching remote version from %s", url.String())
response, err := http.Get(url.String())
log.Printf("Fetching remote version from %s", url)
response, err := http.Get(url)
if err != nil {
return "", fmt.Errorf("error getting remote version: %w", err)
}

View File

@@ -3,27 +3,22 @@ package main
import "fmt"
type AddonService struct {
Addons map[string]*Addon
Addons map[string]Addon
}
var addons = map[string]*Addon{
"Channeler": NewAddon("Channeler", "https://git.site.quack-lab.dev/dave/wow_channeler"),
"Heimdall": NewAddon("Heimdall", "https://git.site.quack-lab.dev/dave/wow-Heimdall"),
"Dechickenator": NewAddon("Dechickenator", "https://git.site.quack-lab.dev/dave/wow_dechickenator"),
}
//var addons = map[string]*Addon{
// "Channeler": NewAddon("Channeler", "https://git.site.quack-lab.dev/dave/wow_channeler"),
// "Heimdall": NewAddon("Heimdall", "https://git.site.quack-lab.dev/dave/wow-Heimdall"),
// "Dechickenator": NewAddon("Dechickenator", "https://git.site.quack-lab.dev/dave/wow_dechickenator"),
//}
func NewAddonService() *AddonService {
return &AddonService{
Addons: addons,
}
}
func (a *AddonService) GetAddon(name string) (*Addon, error) {
addon, ok := a.Addons[name]
func (a *AddonService) GetAddon(name string) (addon Addon, err error) {
var ok bool
addon, ok = a.Addons[name]
if !ok {
return nil, fmt.Errorf("addon with name %s not found", name)
return addon, fmt.Errorf("addon with name %s not found", name)
}
return addon, nil
return
}
func (a *AddonService) GetRemoteVersion(name string) (string, error) {
@@ -41,18 +36,18 @@ func (a *AddonService) GetLocalVersion(name string) (string, error) {
return addon.GetLocalVersion()
}
func (a *AddonService) UpdateAddon(name string) (*Addon, error) {
addon, err := a.GetAddon(name)
func (a *AddonService) UpdateAddon(name string) (addon Addon, err error) {
addon, err = a.GetAddon(name)
if err != nil {
return nil, err
return
}
release, err := addon.GetRemoteRelease()
if err != nil {
return nil, err
return
}
err = addon.Update(release)
if err != nil {
return nil, err
return
}
return addon, nil
}

52
app.go
View File

@@ -24,3 +24,55 @@ func (a *App) startup(ctx context.Context) {
func (a *App) Close() {
runtime.Quit(a.ctx)
}
type AddonResponse struct {
Data Addon `json:"data"`
Error string `json:"error,omitempty"`
}
type AddonsResponse struct {
Data map[string]Addon `json:"data"`
Error string `json:"error,omitempty"`
}
type StringResponse struct {
Data string `json:"data"`
Error string `json:"error,omitempty"`
}
func (a *App) GetAddons() AddonsResponse {
return AddonsResponse{
Data: addonService.Addons,
Error: "",
}
}
func (a *App) GetAddon(name string) AddonResponse {
addon, err := addonService.GetAddon(name)
return AddonResponse{
Data: addon,
Error: err.Error(),
}
}
func (a *App) GetAddonRemoteVersion(name string) StringResponse {
version, err := addonService.GetRemoteVersion(name)
return StringResponse{
Data: version,
Error: err.Error(),
}
}
func (a *App) GetAddonLocalVersion(name string) StringResponse {
version, err := addonService.GetLocalVersion(name)
return StringResponse{
Data: version,
Error: err.Error(),
}
}
func (a *App) UpdateAddon(name string) AddonResponse {
addon, err := addonService.UpdateAddon(name)
return AddonResponse{
Data: addon,
Error: err.Error(),
}
}

View File

@@ -1,4 +1,15 @@
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
import {main} from '../models';
export function Close():Promise<void>;
export function GetAddon(arg1:string):Promise<main.AddonResponse>;
export function GetAddonLocalVersion(arg1:string):Promise<main.StringResponse>;
export function GetAddonRemoteVersion(arg1:string):Promise<main.StringResponse>;
export function GetAddons():Promise<main.AddonsResponse>;
export function UpdateAddon(arg1:string):Promise<main.AddonResponse>;

View File

@@ -5,3 +5,23 @@
export function Close() {
return window['go']['main']['App']['Close']();
}
export function GetAddon(arg1) {
return window['go']['main']['App']['GetAddon'](arg1);
}
export function GetAddonLocalVersion(arg1) {
return window['go']['main']['App']['GetAddonLocalVersion'](arg1);
}
export function GetAddonRemoteVersion(arg1) {
return window['go']['main']['App']['GetAddonRemoteVersion'](arg1);
}
export function GetAddons() {
return window['go']['main']['App']['GetAddons']();
}
export function UpdateAddon(arg1) {
return window['go']['main']['App']['UpdateAddon'](arg1);
}

View File

@@ -0,0 +1,97 @@
export namespace main {
export class Addon {
name: string;
url: string;
static createFrom(source: any = {}) {
return new Addon(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.name = source["name"];
this.url = source["url"];
}
}
export class AddonResponse {
data: Addon;
error?: string;
static createFrom(source: any = {}) {
return new AddonResponse(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.data = this.convertValues(source["data"], Addon);
this.error = source["error"];
}
convertValues(a: any, classs: any, asMap: boolean = false): any {
if (!a) {
return a;
}
if (a.slice && a.map) {
return (a as any[]).map(elem => this.convertValues(elem, classs));
} else if ("object" === typeof a) {
if (asMap) {
for (const key of Object.keys(a)) {
a[key] = new classs(a[key]);
}
return a;
}
return new classs(a);
}
return a;
}
}
export class AddonsResponse {
data: {[key: string]: Addon};
error?: string;
static createFrom(source: any = {}) {
return new AddonsResponse(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.data = this.convertValues(source["data"], Addon, true);
this.error = source["error"];
}
convertValues(a: any, classs: any, asMap: boolean = false): any {
if (!a) {
return a;
}
if (a.slice && a.map) {
return (a as any[]).map(elem => this.convertValues(elem, classs));
} else if ("object" === typeof a) {
if (asMap) {
for (const key of Object.keys(a)) {
a[key] = new classs(a[key]);
}
return a;
}
return new classs(a);
}
return a;
}
}
export class StringResponse {
data: string;
error?: string;
static createFrom(source: any = {}) {
return new StringResponse(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.data = source["data"];
this.error = source["error"];
}
}
}

40
main.go
View File

@@ -7,7 +7,6 @@ import (
"io"
"log"
"os"
"path/filepath"
"github.com/wailsapp/wails/v2"
"github.com/wailsapp/wails/v2/pkg/options"
@@ -30,15 +29,47 @@ func init() {
//go:embed all:frontend/dist
var assets embed.FS
var settingsFilePath = "settings.json"
var gamePath string
var addonService *AddonService
type Settings struct {
GamePath string `json:"gamePath"`
Addons map[string]Addon `json:"addons"`
}
func SaveSettings(settings Settings) error {
log.Printf("Saving settings: %+v", settings)
settingsFile, err := os.OpenFile(settingsFilePath, os.O_RDWR|os.O_CREATE, 0644)
if err != nil {
Error.Printf("error opening settings file: %s", err)
return err
}
defer settingsFile.Close()
return json.NewEncoder(settingsFile).Encode(settings)
}
func main() {
addonService = NewAddonService()
gamePath = filepath.Join("C:\\", "Games", "WoWRuski")
settingsFile, err := os.OpenFile(settingsFilePath, os.O_RDWR|os.O_CREATE, 0644)
if err != nil {
Error.Printf("error opening settings file: %s", err)
return
}
settings := Settings{}
err = json.NewDecoder(settingsFile).Decode(&settings)
if err != nil {
Warning.Printf("error decoding settings: %s", err)
settings = Settings{}
}
settingsFile.Close()
log.Printf("Loaded settings: %+v", settings)
addonService = &AddonService{}
addonService.Addons = settings.Addons
app := NewApp()
err := wails.Run(&options.App{
err = wails.Run(&options.App{
Title: "wails-template",
Width: 1024,
Height: 768,
@@ -55,4 +86,5 @@ func main() {
if err != nil {
println("Error:", err.Error())
}
SaveSettings(settings)
}

1
settings.json Normal file
View File

@@ -0,0 +1 @@
{"gamePath":"","addons":{"Channeler":{"name":"","url":"https://git.site.quack-lab.dev/dave/wow_channeler"},"Dechickenator":{"name":"","url":"https://git.site.quack-lab.dev/dave/wow_dechickenator"},"Heimdall":{"name":"","url":"https://git.site.quack-lab.dev/dave/wow-Heimdall"}}}