diff --git a/app/app.go b/app/app.go
index 889afa8..5a7b9c7 100644
--- a/app/app.go
+++ b/app/app.go
@@ -13,8 +13,7 @@ import (
// App struct
type App struct {
- ctx context.Context
- exDir string
+ ctx context.Context
}
// NewApp creates a new App application struct
diff --git a/app/update.go b/app/update.go
deleted file mode 100644
index 7e2201a..0000000
--- a/app/update.go
+++ /dev/null
@@ -1,102 +0,0 @@
-package app
-
-import (
- "archive/zip"
- "bytes"
- "io"
- "net/http"
- "path/filepath"
- "runtime"
- "strings"
- "time"
-
- "github.com/minio/selfupdate"
- wruntime "github.com/wailsapp/wails/v2/pkg/runtime"
-)
-
-type ProgressReader struct {
- reader io.Reader
- total int64
- err error
-}
-type DownloadStatus struct {
- Name string `json:"name"`
- Path string `json:"path"`
- Url string `json:"url"`
- Transferred int64 `json:"transferred"`
- Size int64 `json:"size"`
- Speed float64 `json:"speed"`
- Progress float64 `json:"progress"`
- Downloading bool `json:"downloading"`
- Done bool `json:"done"`
-}
-
-func (pr *ProgressReader) Read(p []byte) (n int, err error) {
- n, err = pr.reader.Read(p)
- pr.err = err
- pr.total += int64(n)
- return
-}
-func (a *App) UpdateApp(url string) (broken bool, err error) {
- resp, err := http.Get(url)
- if err != nil {
- return false, err
- }
- defer resp.Body.Close()
- pr := &ProgressReader{reader: resp.Body}
-
- ticker := time.NewTicker(250 * time.Millisecond)
- defer ticker.Stop()
-
- // update progress
- go func() {
- for {
- <-ticker.C
- wruntime.EventsEmit(a.ctx, "updateApp", &DownloadStatus{
- Name: filepath.Base(url),
- Path: "",
- Url: url,
- Transferred: pr.total,
- Size: resp.ContentLength,
- Speed: 0,
- Progress: 100 * (float64(pr.total) / float64(resp.ContentLength)),
- Downloading: pr.err == nil && pr.total < resp.ContentLength,
- Done: pr.total == resp.ContentLength,
- })
- if pr.err != nil || pr.total == resp.ContentLength {
- break
- }
- }
- }()
-
- var updateFile io.Reader = pr
- // extract macos binary from zip
- if strings.HasSuffix(url, ".zip") && runtime.GOOS == "darwin" {
- zipBytes, err := io.ReadAll(pr)
- if err != nil {
- return false, err
- }
- archive, err := zip.NewReader(bytes.NewReader(zipBytes), int64(len(zipBytes)))
- if err != nil {
- return false, err
- }
- file, err := archive.Open("godoos.app/Contents/MacOS/godoos")
- if err != nil {
- return false, err
- }
- defer file.Close()
- updateFile = file
- }
-
- // apply update
- err = selfupdate.Apply(updateFile, selfupdate.Options{})
- if err != nil {
- if rerr := selfupdate.RollbackError(err); rerr != nil {
- return true, rerr
- }
- return false, err
- }
- // restart app
- a.RestartApp()
- return false, nil
-}
diff --git a/frontend/src/components/setting/SetSystem.vue b/frontend/src/components/setting/SetSystem.vue
index 7590481..0941012 100644
--- a/frontend/src/components/setting/SetSystem.vue
+++ b/frontend/src/components/setting/SetSystem.vue
@@ -27,7 +27,7 @@
diff --git a/frontend/src/system/config.ts b/frontend/src/system/config.ts
index 48ea9a6..03afc2a 100644
--- a/frontend/src/system/config.ts
+++ b/frontend/src/system/config.ts
@@ -15,6 +15,7 @@ export const getSystemConfig = (ifset = false) => {
// 初始化配置对象的各项属性,若本地存储中已存在则不进行覆盖
if (!config.version) {
config.version = '1.0.0';
+ //config.version = '0.0.9';
}
if (!config.isFirstRun) {
config.isFirstRun = false;
diff --git a/frontend/src/system/index.ts b/frontend/src/system/index.ts
index 7a43897..c3e7d5a 100644
--- a/frontend/src/system/index.ts
+++ b/frontend/src/system/index.ts
@@ -25,7 +25,8 @@ import { Tray, TrayOptions } from './menu/Tary';
import { InitSystemFile, InitUserFile } from './core/SystemFileConfig';
import { createInitFile } from './core/createInitFile';
import { getSystemConfig, getSystemKey, setSystemKey, setSystemConfig, clearSystemConfig } from './config'
-
+import { checkUpdate } from '@/util/update';
+import { RestartApp } from '@/util/goutil';
export type OsPlugin = (system: System) => void;
export type FileOpener = {
@@ -71,8 +72,6 @@ export class System {
this._eventer = this.initEvent();
this.firstRun();
this.initSystem();
-
-
}
/**
@@ -112,11 +111,17 @@ export class System {
this.initBackground(); // 初始化壁纸
this.emit('start');
- // setTimeout(() => {
- // if (this._rootState.magnet?.length < 1) {
- // this.refershAppList()
- // }
- // }, 6000);
+ setTimeout(() => {
+ if (this._rootState.magnet?.length < 1) {
+ this.refershAppList()
+ }
+ checkUpdate();
+ setTimeout(() => {
+ if (this._rootState.magnet?.length < 1) {
+ this.recover()
+ }
+ }, 3000);
+ }, 6000);
}
/**
@@ -382,7 +387,7 @@ export class System {
}
reboot() {
this._rootState.state = SystemStateEnum.close;
- window.location.reload();
+ RestartApp();
}
recover() {
clearSystemConfig()
@@ -390,7 +395,7 @@ export class System {
this.fs.removeFileSystem().then(() => {
window.indexedDB.deleteDatabase("GodoDatabase");
- window.location.reload();
+ RestartApp();
})
}
diff --git a/frontend/src/system/window/Dialog.ts b/frontend/src/system/window/Dialog.ts
index 48eb471..f2c6f28 100644
--- a/frontend/src/system/window/Dialog.ts
+++ b/frontend/src/system/window/Dialog.ts
@@ -49,6 +49,7 @@ class Dialog {
return {
setProgress,
+ dialogwin
};
}
public static showMessageBox(option: {
diff --git a/frontend/src/util/goutil.ts b/frontend/src/util/goutil.ts
index b2a6f5d..c6fc542 100644
--- a/frontend/src/util/goutil.ts
+++ b/frontend/src/util/goutil.ts
@@ -1,8 +1,16 @@
export async function OpenDirDialog(){
if((window as any).go) {
- //(window as any).go.OpenDirDialog();
- return (window as any)['go']['main']['App']['OpenDirDialog']();
+ return (window as any)['go']['app']['App']['OpenDirDialog']();
}else {
return ""
}
-}
\ No newline at end of file
+}
+
+export function RestartApp(){
+ if(!(window as any).go){
+ window.location.reload();
+ }else{
+ return (window as any)['go']['app']['App']['RestartApp']();
+ }
+
+}
diff --git a/frontend/src/util/update.ts b/frontend/src/util/update.ts
index 0fef1c7..bad3665 100644
--- a/frontend/src/util/update.ts
+++ b/frontend/src/util/update.ts
@@ -1,114 +1,62 @@
-//import { EventsOff, EventsOn } from '~/runtime';
-//import manifest from '../../package.json';
-import {isWindowsOS,getSystemConfig} from '@/system/config'
+import { getSystemConfig,setSystemKey,parseJson } from '@/system/config'
+import { RestartApp } from './goutil';
+import { Dialog } from '@/system';
+import { ElMessage } from 'element-plus'
export async function checkUpdate() {
- if(!(window as any).go) return;
- const config = getSystemConfig();
- const updateGiteeUrl = `https://gitee.com/api/v5/repos/ruitao_admin/godoos/releases/`
- const releaseRes = await fetch(updateGiteeUrl)
- if(!releaseRes.ok) return;
- const releaseData = await releaseRes.json()
- const versionTag = releaseData.tag_name;
- if(!versionTag) return;
- if (versionTag.replace('v', '') <= config.version) return;
- const verifyUrl = `${updateGiteeUrl}tags/${versionTag}`;
- const verRes = await fetch(verifyUrl);
- if(!verRes.ok) return;
- const verData = await verRes.json()
- if(!verData.assets || verData.assets.length <= 0) return;
- const appName = "godoos"+ versionTag + (isWindowsOS() ? '.exe' : '');
- const updateUrl = `${updateGiteeUrl}download/${versionTag}/${appName}`;
- console.log(updateUrl)
- // fetch(`${updateGiteeUrl}latest`).then((r) => {
- // if (r.ok) {
- // r.json().then((data) => {
- // if (data.tag_name) {
- // const versionTag = data.tag_name;
- // console.log(versionTag)
- // if (versionTag.replace('v', '') > manifest.version) {
- // const verifyUrl = `${updateGiteeUrl}tags/${versionTag}`;
- // }
- /*
- if (versionTag.replace('v', '') > manifest.version) {
- const verifyUrl = `${updateGiteeUrl}tags/${versionTag}`;
-
- fetch(verifyUrl).then((r) => {
- if (r.ok) {
- r.json().then((data) => {
- if (data.assets && data.assets.length > 0) {
- const asset = data.assets.find((a: any) => a.name.toLowerCase().includes(commonStore.platform.toLowerCase().replace('darwin', 'macos')));
- if (asset) {
- const updateUrl = `${updateGiteeUrl}download/${versionTag}/${asset.name}`;
- toastWithButton(t('New Version Available') + ': ' + versionTag, t('Update'), () => {
- DeleteFile('cache.json');
- const progressId = 'update_app';
- const progressEvent = 'updateApp';
- const updateProgress = (ds: DownloadStatus | null) => {
- const content =
- t('Downloading update, please wait. If it is not completed, please manually download the program from GitHub and replace the original program.')
- + (ds ? ` (${ds.progress.toFixed(2)}% ${bytesToReadable(ds.transferred)}/${bytesToReadable(ds.size)})` : '');
- const options: ToastOptions = {
- type: 'info',
- position: 'bottom-left',
- autoClose: false,
- toastId: progressId,
- hideProgressBar: false,
- progress: ds ? ds.progress / 100 : 0
- };
- if (toast.isActive(progressId))
- toast.update(progressId, {
- render: content,
- ...options
- });
- else
- toast(content, options);
- };
- updateProgress(null);
- EventsOn(progressEvent, updateProgress);
- UpdateApp(updateUrl).then(() => {
- toast(t('Update completed, please restart the program.'), {
- type: 'success',
- position: 'bottom-left',
- autoClose: false
- }
- );
- }).catch((e) => {
- toast(t('Update Error') + ' - ' + (e.message || e), {
- type: 'error',
- position: 'bottom-left',
- autoClose: false
- });
- }).finally(() => {
- toast.dismiss(progressId);
- EventsOff(progressEvent);
- });
- }, {
- autoClose: false,
- position: 'bottom-left'
- });
- }
- }
- });
- } else {
- throw new Error('Verify response was not ok.');
- }
- });
- } else {
- if (notifyEvenLatest) {
- toast(t('This is the latest version'), { type: 'success', position: 'bottom-left', autoClose: 2000 });
- }
- }
- */
- // } else {
- // throw new Error('Invalid response.');
- // }
- // });
- // } else {
- // throw new Error('Network response was not ok.');
- // }
- // }
- // ).catch((e) => {
- // //toast(t('Updates Check Error') + ' - ' + (e.message || e), { type: 'error', position: 'bottom-left' });
- // });
+ const config = getSystemConfig();
+ const updateGiteeUrl = `${config.apiUrl}/system/updateInfo`
+ const releaseRes = await fetch(updateGiteeUrl)
+ if (!releaseRes.ok) return;
+ const releaseData = await releaseRes.json()
+ const versionTag = releaseData.version;
+ if (!versionTag) return;
+ if (versionTag <= config.version) return;
+ const updateUrl = releaseData.url
+ if (!updateUrl || updateUrl == '') return;
+ const dialogRes: any = await Dialog.showMessageBox({
+ title: '更新提示',
+ message: `发现新版本:${versionTag},是否更新?`
+ })
+ //console.log(dialogRes)
+ if (dialogRes.response !== -1) {
+ return;
}
-
\ No newline at end of file
+ const { setProgress,dialogwin } = Dialog.showProcessDialog({
+ message: '正在更新',
+ });
+ const upUrl = `${config.apiUrl}/system/update?url=${updateUrl}`
+ const upRes = await fetch(upUrl)
+ if (!upRes.ok) return;
+ const reader: any = upRes.body?.getReader();
+ if (!reader) {
+ ElMessage({
+ type: 'error',
+ message: "the system has not stream!"
+ })
+ }
+ while (true) {
+ const { done, value } = await reader.read();
+ if (done) {
+ reader.releaseLock();
+ break;
+ }
+ const rawjson = new TextDecoder().decode(value);
+ const json = parseJson(rawjson);
+ console.log(json)
+ if(json){
+ if(json.progress){
+ setProgress(json.progress)
+ }
+ if(json.updateCompleted){
+ dialogwin.close()
+ ElMessage({
+ type: 'success',
+ message: "update completed!"
+ })
+ setSystemKey('version',versionTag)
+ RestartApp()
+ break;
+ }
+ }
+ }
+}
diff --git a/frontend/wailsjs/go/app/App.d.ts b/frontend/wailsjs/go/app/App.d.ts
index 5fb974e..43d4ff9 100644
--- a/frontend/wailsjs/go/app/App.d.ts
+++ b/frontend/wailsjs/go/app/App.d.ts
@@ -4,5 +4,3 @@
export function OpenDirDialog():Promise;
export function RestartApp():Promise;
-
-export function UpdateApp(arg1:string):Promise;
diff --git a/frontend/wailsjs/go/app/App.js b/frontend/wailsjs/go/app/App.js
index 033291d..a5390dd 100644
--- a/frontend/wailsjs/go/app/App.js
+++ b/frontend/wailsjs/go/app/App.js
@@ -9,7 +9,3 @@ export function OpenDirDialog() {
export function RestartApp() {
return window['go']['app']['App']['RestartApp']();
}
-
-export function UpdateApp(arg1) {
- return window['go']['app']['App']['UpdateApp'](arg1);
-}
diff --git a/go.mod b/go.mod
index 5a70697..0cb8459 100644
--- a/go.mod
+++ b/go.mod
@@ -2,15 +2,13 @@ module godoos
go 1.22.5
-require (
- github.com/minio/selfupdate v0.6.0
- github.com/wailsapp/wails/v2 v2.9.1
-)
+require github.com/wailsapp/wails/v2 v2.9.1
require (
aead.dev/minisign v0.2.0 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/gorilla/mux v1.8.1 // indirect
+ github.com/minio/selfupdate v0.6.0 // indirect
github.com/shirou/gopsutil v3.21.11+incompatible // indirect
github.com/tklauser/go-sysconf v0.3.14 // indirect
github.com/tklauser/numcpus v0.8.0 // indirect
diff --git a/godo/.gitignore b/godo/.gitignore
new file mode 100644
index 0000000..1586e95
--- /dev/null
+++ b/godo/.gitignore
@@ -0,0 +1,2 @@
+tmp
+
diff --git a/godo/cmd/main.go b/godo/cmd/main.go
index cba0f4d..7d73d6f 100644
--- a/godo/cmd/main.go
+++ b/godo/cmd/main.go
@@ -6,6 +6,7 @@ import (
"godo/libs"
"godo/localchat"
"godo/progress"
+ "godo/sys"
"log"
"net/http"
"time"
@@ -38,8 +39,11 @@ func OsStart() {
progressRouter.HandleFunc("/app/{name}/{subpath:.*}", progress.ForwardRequest).Methods(http.MethodGet, http.MethodPost)
router.HandleFunc("/ping", progress.Ping).Methods(http.MethodGet)
router.HandleFunc("/", progress.Ping).Methods(http.MethodGet)
- router.HandleFunc("/system/info", files.HandleSystemInfo).Methods(http.MethodGet)
- router.HandleFunc("/system/setting", HandleSetConfig).Methods(http.MethodPost)
+ router.HandleFunc("/system/updateInfo", sys.GetUpdateUrlHandler).Methods(http.MethodGet)
+ router.HandleFunc("/system/update", sys.UpdateAppHandler).Methods(http.MethodGet)
+ router.HandleFunc("/system/storeList", sys.GetStoreInfoHandler).Methods(http.MethodGet)
+ router.HandleFunc("/system/setting", sys.HandleSetConfig).Methods(http.MethodPost)
+ router.HandleFunc("/files/info", files.HandleSystemInfo).Methods(http.MethodGet)
router.HandleFunc("/file/read", files.HandleReadDir).Methods(http.MethodGet)
router.HandleFunc("/file/stat", files.HandleStat).Methods(http.MethodGet)
router.HandleFunc("/file/chmod", files.HandleChmod).Methods(http.MethodPost)
diff --git a/godo/cmd/serve.go b/godo/cmd/serve.go
index d634c79..e3113d6 100644
--- a/godo/cmd/serve.go
+++ b/godo/cmd/serve.go
@@ -73,10 +73,10 @@ func corsMiddleware() mux.MiddlewareFunc {
w.Header().Set("Access-Control-Allow-Headers", allowHeaders)
// 如果是预检请求(OPTIONS),直接返回 200 OK
- // if r.Method == http.MethodOptions {
- // w.WriteHeader(http.StatusOK)
- // return
- // }
+ if r.Method == http.MethodOptions {
+ w.WriteHeader(http.StatusOK)
+ return
+ }
next.ServeHTTP(w, r)
})
diff --git a/godo/go.mod b/godo/go.mod
index 73313a5..029314b 100644
--- a/godo/go.mod
+++ b/godo/go.mod
@@ -3,18 +3,21 @@ module godo
go 1.22.5
require (
+ github.com/cavaliergopher/grab/v3 v3.0.1
github.com/fsnotify/fsnotify v1.7.0
github.com/gorilla/mux v1.8.1
+ github.com/minio/selfupdate v0.6.0
github.com/pkg/errors v0.9.1
github.com/shirou/gopsutil v3.21.11+incompatible
)
require (
- github.com/cavaliergopher/grab/v3 v3.0.1 // indirect
+ aead.dev/minisign v0.2.0 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/stretchr/testify v1.9.0 // indirect
github.com/tklauser/go-sysconf v0.3.14 // indirect
github.com/tklauser/numcpus v0.8.0 // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
+ golang.org/x/crypto v0.0.0-20211209193657-4570a0811e8b // indirect
golang.org/x/sys v0.19.0 // indirect
)
diff --git a/godo/go.sum b/godo/go.sum
index 245f13e..d04d61e 100644
--- a/godo/go.sum
+++ b/godo/go.sum
@@ -1,3 +1,5 @@
+aead.dev/minisign v0.2.0 h1:kAWrq/hBRu4AARY6AlciO83xhNnW9UaC8YipS2uhLPk=
+aead.dev/minisign v0.2.0/go.mod h1:zdq6LdSd9TbuSxchxwhpA9zEb9YXcVGoE8JakuiGaIQ=
github.com/cavaliergopher/grab/v3 v3.0.1 h1:4z7TkBfmPjmLAAmkkAZNX/6QJ1nNFdv3SdIHXju0Fr4=
github.com/cavaliergopher/grab/v3 v3.0.1/go.mod h1:1U/KNnD+Ft6JJiYoYBAimKH2XrYptb8Kl3DFGmsjpq4=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@@ -8,6 +10,8 @@ github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
+github.com/minio/selfupdate v0.6.0 h1:i76PgT0K5xO9+hjzKcacQtO7+MjJ4JKA8Ak8XQ9DDwU=
+github.com/minio/selfupdate v0.6.0/go.mod h1:bO02GTIPCMQFTEvE5h4DjYB58bCoZ35XLeBf0buTDdM=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
@@ -22,8 +26,25 @@ github.com/tklauser/numcpus v0.8.0 h1:Mx4Wwe/FjZLeQsK/6kt2EOepwwSl7SmJrK5bV/dXYg
github.com/tklauser/numcpus v0.8.0/go.mod h1:ZJZlAY+dmR4eut8epnzf0u/VwodKmryxR8txiloSqBE=
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
+golang.org/x/crypto v0.0.0-20211209193657-4570a0811e8b h1:QAqMVf3pSa6eeTsuklijukjXBlj7Es2QQplab+/RbQ4=
+golang.org/x/crypto v0.0.0-20211209193657-4570a0811e8b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210228012217-479acdf4ea46/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/godo/cmd/setting.go b/godo/sys/setting.go
similarity index 98%
rename from godo/cmd/setting.go
rename to godo/sys/setting.go
index d9366ce..5ada378 100644
--- a/godo/cmd/setting.go
+++ b/godo/sys/setting.go
@@ -1,4 +1,4 @@
-package cmd
+package sys
import (
"encoding/json"
diff --git a/godo/sys/store.go b/godo/sys/store.go
new file mode 100644
index 0000000..3529cb2
--- /dev/null
+++ b/godo/sys/store.go
@@ -0,0 +1,41 @@
+package sys
+
+import (
+ "encoding/json"
+ "fmt"
+ "godo/libs"
+ "io"
+ "net/http"
+ "runtime"
+)
+
+func GetStoreInfoHandler(w http.ResponseWriter, r *http.Request) {
+ cate := r.URL.Query().Get("cate")
+ os := runtime.GOOS
+ arch := runtime.GOARCH
+ if cate == "" {
+ libs.ErrorMsg(w, "cate is required")
+ return
+ }
+ pluginUrl := "https://gitee.com/ruitao_admin/godoos-image/raw/master/store/" + os + "/" + arch + "/" + cate + ".json"
+ res, err := http.Get(pluginUrl)
+ if err != nil {
+ libs.ErrorMsg(w, err.Error())
+ }
+ defer res.Body.Close()
+ if res.StatusCode == 200 {
+ body, err := io.ReadAll(res.Body)
+ if err != nil {
+ libs.ErrorMsg(w, err.Error())
+ return
+ }
+ var info interface{}
+ err = json.Unmarshal(body, &info)
+ if err != nil {
+ fmt.Println("Error unmarshalling JSON:", err)
+ return
+ }
+ json.NewEncoder(w).Encode(info)
+
+ }
+}
diff --git a/godo/sys/update.go b/godo/sys/update.go
new file mode 100644
index 0000000..60c6c19
--- /dev/null
+++ b/godo/sys/update.go
@@ -0,0 +1,175 @@
+package sys
+
+import (
+ "encoding/json"
+ "fmt"
+ "godo/libs"
+ "io"
+ "log"
+ "net/http"
+ "path/filepath"
+ "runtime"
+ "time"
+
+ "github.com/minio/selfupdate"
+)
+
+type OSInfo struct {
+ Amd64 string `json:"amd64"`
+ Arm64 string `json:"arm64"`
+}
+
+type VersionInfo struct {
+ Version string `json:"version"`
+ Name string `json:"name"`
+ Description string `json:"description"`
+ Changelog string `json:"changelog"`
+ Windows OSInfo `json:"windows"`
+ Linux OSInfo `json:"linux"`
+ Darwin OSInfo `json:"darwin"`
+}
+
+type ProgressReader struct {
+ reader io.Reader
+ total int64
+ err error
+}
+type DownloadStatus struct {
+ Name string `json:"name"`
+ Path string `json:"path"`
+ Url string `json:"url"`
+ Current int64 `json:"current"`
+ Size int64 `json:"size"`
+ Speed float64 `json:"speed"`
+ Progress float64 `json:"progress"`
+ Downloading bool `json:"downloading"`
+ Done bool `json:"done"`
+}
+
+func (pr *ProgressReader) Read(p []byte) (n int, err error) {
+ n, err = pr.reader.Read(p)
+ pr.err = err
+ pr.total += int64(n)
+ return
+}
+func UpdateAppHandler(w http.ResponseWriter, r *http.Request) {
+ url := r.URL.Query().Get("url")
+ resp, err := http.Get(url)
+ if err != nil {
+ return
+ }
+ defer resp.Body.Close()
+ pr := &ProgressReader{reader: resp.Body}
+
+ ticker := time.NewTicker(250 * time.Millisecond)
+ defer ticker.Stop()
+ flusher, ok := w.(http.Flusher)
+ if !ok {
+ log.Printf("Streaming unsupported")
+ http.Error(w, "Streaming unsupported", http.StatusInternalServerError)
+ return
+ }
+ // update progress
+ go func() {
+ for {
+ <-ticker.C
+ rp := &DownloadStatus{
+ Name: filepath.Base(url),
+ Path: "",
+ Url: url,
+ Current: pr.total,
+ Size: resp.ContentLength,
+ Speed: 0,
+ Progress: 100 * (float64(pr.total) / float64(resp.ContentLength)),
+ Downloading: pr.err == nil && pr.total < resp.ContentLength,
+ Done: pr.total == resp.ContentLength,
+ }
+ if pr.err != nil || pr.total == resp.ContentLength {
+ break
+ }
+ if w != nil {
+ jsonBytes, err := json.Marshal(rp)
+ if err != nil {
+ log.Printf("Error marshaling FileProgress to JSON: %v", err)
+ continue
+ }
+ io.WriteString(w, string(jsonBytes))
+ w.Write([]byte("\n"))
+ flusher.Flush()
+ } else {
+ log.Println("ResponseWriter is nil, cannot send progress")
+ }
+ }
+ }()
+
+ var updateFile io.Reader = pr
+ // apply update
+ err = selfupdate.Apply(updateFile, selfupdate.Options{})
+ if err != nil {
+ if rerr := selfupdate.RollbackError(err); rerr != nil {
+ http.Error(w, "update error:"+rerr.Error(), http.StatusInternalServerError)
+ return
+ }
+ return
+ }
+ // 更新完成后发送响应给前端
+ json.NewEncoder(w).Encode(map[string]bool{"updateCompleted": true})
+}
+
+func GetUpdateUrlHandler(w http.ResponseWriter, r *http.Request) {
+ updateUrl := "https://gitee.com/ruitao_admin/godoos-image/raw/master/version/version.json"
+ res, err := http.Get(updateUrl)
+ if err != nil {
+ libs.ErrorMsg(w, err.Error())
+ }
+ defer res.Body.Close()
+ if res.StatusCode == 200 {
+ body, err := io.ReadAll(res.Body)
+ if err != nil {
+ libs.ErrorMsg(w, err.Error())
+ return
+ }
+ var info VersionInfo
+ err = json.Unmarshal(body, &info)
+ if err != nil {
+ fmt.Println("Error unmarshalling JSON:", err)
+ return
+ }
+ //log.Printf("info: %v", info)
+ // 根据操作系统和架构获取路径
+ path := getPathForOSAndArch(&info)
+ // 将结果以 JSON 格式返回给前端
+ response := map[string]string{"url": path, "version": info.Version}
+ json.NewEncoder(w).Encode(response)
+
+ }
+}
+
+// 根据操作系统和架构获取路径
+func getPathForOSAndArch(info *VersionInfo) string {
+ os := runtime.GOOS
+ arch := runtime.GOARCH
+ switch os {
+ case "windows":
+ if arch == "amd64" {
+ return info.Windows.Amd64
+ } else if arch == "arm64" {
+ return info.Windows.Arm64
+ }
+ case "linux":
+ if arch == "amd64" {
+ return info.Linux.Amd64
+ } else if arch == "arm64" {
+ return info.Linux.Arm64
+ }
+ case "darwin":
+ if arch == "amd64" {
+ return info.Darwin.Amd64
+ } else if arch == "arm64" {
+ return info.Darwin.Arm64
+ }
+ default:
+ return ""
+ }
+ return ""
+}