chore & auto dep
This commit is contained in:
		
							parent
							
								
									9076ff3fd7
								
							
						
					
					
						commit
						b8f7582513
					
				
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -10,3 +10,6 @@ __pycache__ | |||||||
| /cache.json | /cache.json | ||||||
| /frontend/stats.html | /frontend/stats.html | ||||||
| /frontend/package.json.md5 | /frontend/package.json.md5 | ||||||
|  | /backend-python/get-pip.py | ||||||
|  | /py310 | ||||||
|  | *.zip | ||||||
| @ -5,9 +5,10 @@ import ( | |||||||
| 	"net/http" | 	"net/http" | ||||||
| 	"os" | 	"os" | ||||||
| 	"os/exec" | 	"os/exec" | ||||||
|  | 	"runtime" | ||||||
| 
 | 
 | ||||||
| 	"github.com/minio/selfupdate" | 	"github.com/minio/selfupdate" | ||||||
| 	"github.com/wailsapp/wails/v2/pkg/runtime" | 	wruntime "github.com/wailsapp/wails/v2/pkg/runtime" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // App struct | // App struct | ||||||
| @ -46,6 +47,10 @@ func (a *App) UpdateApp(url string) (broken bool, err error) { | |||||||
| 		return false, err | 		return false, err | ||||||
| 	} | 	} | ||||||
| 	exec.Command(name, os.Args[1:]...).Start() | 	exec.Command(name, os.Args[1:]...).Start() | ||||||
| 	runtime.Quit(a.ctx) | 	wruntime.Quit(a.ctx) | ||||||
| 	return false, nil | 	return false, nil | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | func (a *App) GetPlatform() string { | ||||||
|  | 	return runtime.GOOS | ||||||
|  | } | ||||||
|  | |||||||
| @ -1,28 +1,52 @@ | |||||||
| package backend_golang | package backend_golang | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
|  | 	"errors" | ||||||
| 	"os/exec" | 	"os/exec" | ||||||
| 	"path/filepath" |  | ||||||
| 	"strconv" | 	"strconv" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func cmd(args ...string) (string, error) { |  | ||||||
| 	cmdHelper, err := filepath.Abs("./cmd-helper") |  | ||||||
| 	if err != nil { |  | ||||||
| 		return "", err |  | ||||||
| 	} |  | ||||||
| 	cmd := exec.Command(cmdHelper, args...) |  | ||||||
| 	out, err := cmd.CombinedOutput() |  | ||||||
| 	if err != nil { |  | ||||||
| 		return "", err |  | ||||||
| 	} |  | ||||||
| 	return string(out), nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (a *App) StartServer(port int) (string, error) { | func (a *App) StartServer(port int) (string, error) { | ||||||
| 	return cmd("python", "./backend-python/main.py", strconv.Itoa(port)) | 	python, err := GetPython() | ||||||
|  | 	if err != nil { | ||||||
|  | 		return "", err | ||||||
|  | 	} | ||||||
|  | 	return Cmd(python, "./backend-python/main.py", strconv.Itoa(port)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (a *App) ConvertModel(modelPath string, strategy string, outPath string) (string, error) { | func (a *App) ConvertModel(modelPath string, strategy string, outPath string) (string, error) { | ||||||
| 	return cmd("python", "./backend-python/convert_model.py", "--in", modelPath, "--out", outPath, "--strategy", strategy) | 	python, err := GetPython() | ||||||
|  | 	if err != nil { | ||||||
|  | 		return "", err | ||||||
|  | 	} | ||||||
|  | 	return Cmd(python, "./backend-python/convert_model.py", "--in", modelPath, "--out", outPath, "--strategy", strategy) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (a *App) DepCheck() error { | ||||||
|  | 	python, err := GetPython() | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	out, err := exec.Command(python, "./backend-python/dep_check.py").CombinedOutput() | ||||||
|  | 	if err != nil { | ||||||
|  | 		return errors.New("DepCheck Error: " + string(out)) | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (a *App) InstallPyDep() (string, error) { | ||||||
|  | 	python, err := GetPython() | ||||||
|  | 	if err != nil { | ||||||
|  | 		return "", err | ||||||
|  | 	} | ||||||
|  | 	_, err = Cmd(python, "./backend-python/get-pip.py") | ||||||
|  | 	if err != nil { | ||||||
|  | 		return "", err | ||||||
|  | 	} | ||||||
|  | 	ChangeFileLine("./py310/python310._pth", 3, "Lib\\site-packages") | ||||||
|  | 	_, err = Cmd(python, "-m", "pip", "install", "torch", "torchvision", "torchaudio", "--index-url", "https://download.pytorch.org/whl/cu117") | ||||||
|  | 	if err != nil { | ||||||
|  | 		return "", err | ||||||
|  | 	} | ||||||
|  | 	return Cmd(python, "-m", "pip", "install", "-r", "./backend-python/requirements_versions.txt") | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										130
									
								
								backend-golang/utils.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										130
									
								
								backend-golang/utils.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,130 @@ | |||||||
|  | package backend_golang | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"archive/zip" | ||||||
|  | 	"bufio" | ||||||
|  | 	"errors" | ||||||
|  | 	"io" | ||||||
|  | 	"os" | ||||||
|  | 	"os/exec" | ||||||
|  | 	"path/filepath" | ||||||
|  | 	"runtime" | ||||||
|  | 	"strings" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func Cmd(args ...string) (string, error) { | ||||||
|  | 	cmdHelper, err := filepath.Abs("./cmd-helper") | ||||||
|  | 	if err != nil { | ||||||
|  | 		return "", err | ||||||
|  | 	} | ||||||
|  | 	cmd := exec.Command(cmdHelper, args...) | ||||||
|  | 	out, err := cmd.CombinedOutput() | ||||||
|  | 	if err != nil { | ||||||
|  | 		return "", err | ||||||
|  | 	} | ||||||
|  | 	return string(out), nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func GetPython() (string, error) { | ||||||
|  | 	switch platform := runtime.GOOS; platform { | ||||||
|  | 	case "windows": | ||||||
|  | 		_, err := os.Stat("py310/python.exe") | ||||||
|  | 		if err != nil { | ||||||
|  | 			_, err := os.Stat("python-3.10.11-embed-amd64.zip") | ||||||
|  | 			if err != nil { | ||||||
|  | 				return "", errors.New("python zip not found") | ||||||
|  | 			} else { | ||||||
|  | 				err := Unzip("python-3.10.11-embed-amd64.zip", "py310") | ||||||
|  | 				if err != nil { | ||||||
|  | 					return "", errors.New("failed to unzip python") | ||||||
|  | 				} else { | ||||||
|  | 					return "py310/python.exe", nil | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} else { | ||||||
|  | 			return "py310/python.exe", nil | ||||||
|  | 		} | ||||||
|  | 	case "darwin": | ||||||
|  | 		return "python3", nil | ||||||
|  | 	case "linux": | ||||||
|  | 		return "python3", nil | ||||||
|  | 	} | ||||||
|  | 	return "", errors.New("unsupported OS") | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func ChangeFileLine(filePath string, lineNumber int, newText string) error { | ||||||
|  | 	file, err := os.OpenFile(filePath, os.O_RDWR, 0644) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	defer file.Close() | ||||||
|  | 
 | ||||||
|  | 	scanner := bufio.NewScanner(file) | ||||||
|  | 	content := make([]string, 0) | ||||||
|  | 	for scanner.Scan() { | ||||||
|  | 		content = append(content, scanner.Text()) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	content[lineNumber-1] = newText | ||||||
|  | 
 | ||||||
|  | 	newContent := strings.Join(content, "\n") | ||||||
|  | 
 | ||||||
|  | 	err = file.Truncate(0) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	_, err = file.Seek(0, io.SeekStart) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	_, err = file.WriteString(newContent) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // https://gist.github.com/paulerickson/6d8650947ee4e3f3dbcc28fde10eaae7 | ||||||
|  | func Unzip(source, destination string) error { | ||||||
|  | 	archive, err := zip.OpenReader(source) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	defer archive.Close() | ||||||
|  | 	for _, file := range archive.Reader.File { | ||||||
|  | 		reader, err := file.Open() | ||||||
|  | 		if err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 		defer reader.Close() | ||||||
|  | 		path := filepath.Join(destination, file.Name) | ||||||
|  | 		// Remove file if it already exists; no problem if it doesn't; other cases can error out below | ||||||
|  | 		_ = os.Remove(path) | ||||||
|  | 		// Create a directory at path, including parents | ||||||
|  | 		err = os.MkdirAll(path, os.ModePerm) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 		// If file is _supposed_ to be a directory, we're done | ||||||
|  | 		if file.FileInfo().IsDir() { | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  | 		// otherwise, remove that directory (_not_ including parents) | ||||||
|  | 		err = os.Remove(path) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 		// and create the actual file.  This ensures that the parent directories exist! | ||||||
|  | 		// An archive may have a single file with a nested path, rather than a file for each parent dir | ||||||
|  | 		writer, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, file.Mode()) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 		defer writer.Close() | ||||||
|  | 		_, err = io.Copy(writer, reader) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
| @ -1,7 +1,9 @@ | |||||||
| import os | import os | ||||||
| import psutil |  | ||||||
| import sys | import sys | ||||||
| 
 | 
 | ||||||
|  | sys.path.append(os.path.dirname(os.path.realpath(__file__))) | ||||||
|  | 
 | ||||||
|  | import psutil | ||||||
| from fastapi import FastAPI | from fastapi import FastAPI | ||||||
| from fastapi.middleware.cors import CORSMiddleware | from fastapi.middleware.cors import CORSMiddleware | ||||||
| import uvicorn | import uvicorn | ||||||
|  | |||||||
| @ -90,5 +90,8 @@ | |||||||
|   "Continue": "继续", |   "Continue": "继续", | ||||||
|   "Check": "查看", |   "Check": "查看", | ||||||
|   "Model file not found": "模型文件不存在", |   "Model file not found": "模型文件不存在", | ||||||
|   "Can not find download url": "找不到下载地址" |   "Can not find download url": "找不到下载地址", | ||||||
|  |   "Python target not found, would you like to download it?": "没有找到目标Python, 是否下载?", | ||||||
|  |   "Python dependencies are incomplete, would you like to install them?": "Python依赖缺失, 是否安装?", | ||||||
|  |   "Install": "安装" | ||||||
| } | } | ||||||
| @ -1,12 +1,12 @@ | |||||||
| import React, {FC, MouseEventHandler, ReactElement} from 'react'; | import React, {FC, MouseEventHandler, ReactElement} from 'react'; | ||||||
| import commonStore, {ModelStatus} from '../stores/commonStore'; | import commonStore, {ModelStatus} from '../stores/commonStore'; | ||||||
| import {AddToDownloadList, FileExists, StartServer} from '../../wailsjs/go/backend_golang/App'; | import {AddToDownloadList, DepCheck, FileExists, InstallPyDep, StartServer} from '../../wailsjs/go/backend_golang/App'; | ||||||
| import {Button} from '@fluentui/react-components'; | import {Button} from '@fluentui/react-components'; | ||||||
| import {observer} from 'mobx-react-lite'; | import {observer} from 'mobx-react-lite'; | ||||||
| import {exit, readRoot, switchModel, updateConfig} from '../apis'; | import {exit, readRoot, switchModel, updateConfig} from '../apis'; | ||||||
| import {toast} from 'react-toastify'; | import {toast} from 'react-toastify'; | ||||||
| import manifest from '../../../manifest.json'; | import manifest from '../../../manifest.json'; | ||||||
| import {getStrategy, toastWithButton} from '../utils'; | import {getStrategy, saveCache, toastWithButton} from '../utils'; | ||||||
| import {useTranslation} from 'react-i18next'; | import {useTranslation} from 'react-i18next'; | ||||||
| import {ToolTipButton} from './ToolTipButton'; | import {ToolTipButton} from './ToolTipButton'; | ||||||
| import {Play16Regular, Stop16Regular} from '@fluentui/react-icons'; | import {Play16Regular, Stop16Regular} from '@fluentui/react-icons'; | ||||||
| @ -39,6 +39,32 @@ export const RunButton: FC<{ onClickRun?: MouseEventHandler, iconMode?: boolean | |||||||
|     const modelName = modelConfig.modelParameters.modelName; |     const modelName = modelConfig.modelParameters.modelName; | ||||||
|     const modelPath = `./${manifest.localModelDir}/${modelName}`; |     const modelPath = `./${manifest.localModelDir}/${modelName}`; | ||||||
| 
 | 
 | ||||||
|  |     if (!commonStore.depComplete) { | ||||||
|  |       let depErrorMsg = ''; | ||||||
|  |       await DepCheck().catch((e) => { | ||||||
|  |         depErrorMsg = e.message || e; | ||||||
|  |         if (depErrorMsg === 'python zip not found') { | ||||||
|  |           toastWithButton(t('Python target not found, would you like to download it?'), t('Download'), () => { | ||||||
|  |             toastWithButton(`${t('Downloading')} Python`, t('Check'), () => { | ||||||
|  |               navigate({pathname: '/downloads'}); | ||||||
|  |             }, {autoClose: 3000}); | ||||||
|  |             AddToDownloadList('python-3.10.11-embed-amd64.zip', 'https://www.python.org/ftp/python/3.10.11/python-3.10.11-embed-amd64.zip'); | ||||||
|  |           }); | ||||||
|  |         } else if (depErrorMsg.includes('DepCheck Error')) { | ||||||
|  |           toastWithButton(t('Python dependencies are incomplete, would you like to install them?'), t('Install'), () => { | ||||||
|  |             InstallPyDep(); | ||||||
|  |           }); | ||||||
|  |         } else { | ||||||
|  |           toast(depErrorMsg, {type: 'error'}); | ||||||
|  |         } | ||||||
|  |       }); | ||||||
|  |       if (depErrorMsg) { | ||||||
|  |         return; | ||||||
|  |       } | ||||||
|  |       commonStore.setDepComplete(true); | ||||||
|  |       saveCache(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     if (!await FileExists(modelPath)) { |     if (!await FileExists(modelPath)) { | ||||||
|       toastWithButton(t('Model file not found'), t('Download'), () => { |       toastWithButton(t('Model file not found'), t('Download'), () => { | ||||||
|         const downloadUrl = commonStore.modelSourceList.find(item => item.name === modelName)?.downloadUrl; |         const downloadUrl = commonStore.modelSourceList.find(item => item.name === modelName)?.downloadUrl; | ||||||
|  | |||||||
| @ -256,7 +256,7 @@ export const Configs: FC = observer(() => { | |||||||
|                       toast(`${t('Convert Success')} - ${newModelPath}`, {type: 'success'}); |                       toast(`${t('Convert Success')} - ${newModelPath}`, {type: 'success'}); | ||||||
|                       refreshLocalModels({models: commonStore.modelSourceList}, false); |                       refreshLocalModels({models: commonStore.modelSourceList}, false); | ||||||
|                     }).catch(e => { |                     }).catch(e => { | ||||||
|                       toast(`${t('Convert Failed')} - ${e}`, {type: 'error'}); |                       toast(`${t('Convert Failed')} - ${e.message || e}`, {type: 'error'}); | ||||||
|                     }); |                     }); | ||||||
|                   } else { |                   } else { | ||||||
|                     toast(`${t('Model Not Found')} - ${modelPath}`, {type: 'error'}); |                     toast(`${t('Model Not Found')} - ${modelPath}`, {type: 'error'}); | ||||||
|  | |||||||
| @ -4,7 +4,7 @@ import {Page} from '../components/Page'; | |||||||
| import {observer} from 'mobx-react-lite'; | import {observer} from 'mobx-react-lite'; | ||||||
| import commonStore from '../stores/commonStore'; | import commonStore from '../stores/commonStore'; | ||||||
| import {Divider, Field, ProgressBar} from '@fluentui/react-components'; | import {Divider, Field, ProgressBar} from '@fluentui/react-components'; | ||||||
| import {bytesToGb, bytesToMb, refreshLocalModels} from '../utils'; | import {bytesToGb, bytesToKb, bytesToMb, refreshLocalModels} from '../utils'; | ||||||
| import {ToolTipButton} from '../components/ToolTipButton'; | import {ToolTipButton} from '../components/ToolTipButton'; | ||||||
| import {Folder20Regular, Pause20Regular, Play20Regular} from '@fluentui/react-icons'; | import {Folder20Regular, Pause20Regular, Play20Regular} from '@fluentui/react-icons'; | ||||||
| import {ContinueDownload, OpenFileFolder, PauseDownload} from '../../wailsjs/go/backend_golang/App'; | import {ContinueDownload, OpenFileFolder, PauseDownload} from '../../wailsjs/go/backend_golang/App'; | ||||||
| @ -23,21 +23,31 @@ export type DownloadStatus = { | |||||||
| 
 | 
 | ||||||
| export const Downloads: FC = observer(() => { | export const Downloads: FC = observer(() => { | ||||||
|   const {t} = useTranslation(); |   const {t} = useTranslation(); | ||||||
|   const finishedDownloads = commonStore.downloadList.filter((status) => status.done).length; |   const finishedModelsLen = commonStore.downloadList.filter((status) => status.done && status.name.endsWith('.pth')).length; | ||||||
|   useEffect(() => { |   useEffect(() => { | ||||||
|     if (finishedDownloads > 0) |     if (finishedModelsLen > 0) | ||||||
|       refreshLocalModels({models: commonStore.modelSourceList}, false); |       refreshLocalModels({models: commonStore.modelSourceList}, false); | ||||||
|     console.log('finishedDownloads:', finishedDownloads); |     console.log('finishedModelsLen:', finishedModelsLen); | ||||||
|   }, [finishedDownloads]); |   }, [finishedModelsLen]); | ||||||
| 
 | 
 | ||||||
|   return ( |   return ( | ||||||
|     <Page title={t('Downloads')} content={ |     <Page title={t('Downloads')} content={ | ||||||
|       <div className="flex flex-col gap-2 overflow-y-auto overflow-x-hidden p-1"> |       <div className="flex flex-col gap-2 overflow-y-auto overflow-x-hidden p-1"> | ||||||
|         {commonStore.downloadList.map((status, index) => ( |         {commonStore.downloadList.slice().reverse().map((status, index) => { | ||||||
|           <div className="flex flex-col gap-1" key={index}> |           const downloadProgress = `${status.progress.toFixed(2)}%`; | ||||||
|  |           const downloadSpeed = `${status.downloading ? bytesToMb(status.speed) : '0'}MB/s`; | ||||||
|  |           let downloadDetails: string; | ||||||
|  |           if (status.size < 1024 * 1024) | ||||||
|  |             downloadDetails = `${bytesToKb(status.transferred) + 'KB'}/${bytesToKb(status.size) + 'KB'}`; | ||||||
|  |           else if (status.size < 1024 * 1024 * 1024) | ||||||
|  |             downloadDetails = `${bytesToMb(status.transferred) + 'MB'}/${bytesToMb(status.size) + 'MB'}`; | ||||||
|  |           else | ||||||
|  |             downloadDetails = `${bytesToGb(status.transferred) + 'GB'}/${bytesToGb(status.size) + 'GB'}`; | ||||||
|  | 
 | ||||||
|  |           return <div className="flex flex-col gap-1" key={index}> | ||||||
|             <Field |             <Field | ||||||
|               label={`${status.downloading ? (t('Downloading') + ': ') : ''}${status.name}`} |               label={`${status.downloading ? (t('Downloading') + ': ') : ''}${status.name}`} | ||||||
|               validationMessage={`${status.progress.toFixed(2)}% - ${bytesToGb(status.transferred) + 'GB'}/${bytesToGb(status.size) + 'GB'} - ${status.downloading ? bytesToMb(status.speed) : 0}MB/s - ${status.url}`} |               validationMessage={`${downloadProgress} - ${downloadDetails} - ${downloadSpeed} - ${status.url}`} | ||||||
|               validationState={status.done ? 'success' : 'none'} |               validationState={status.done ? 'success' : 'none'} | ||||||
|             > |             > | ||||||
|               <div className="flex items-center gap-2"> |               <div className="flex items-center gap-2"> | ||||||
| @ -57,8 +67,8 @@ export const Downloads: FC = observer(() => { | |||||||
|               </div> |               </div> | ||||||
|             </Field> |             </Field> | ||||||
|             <Divider style={{flexGrow: 0}}/> |             <Divider style={{flexGrow: 0}}/> | ||||||
|           </div> |           </div>; | ||||||
|         )) |         }) | ||||||
|         } |         } | ||||||
|       </div> |       </div> | ||||||
|     }/> |     }/> | ||||||
|  | |||||||
| @ -1,29 +1,28 @@ | |||||||
| import commonStore from './stores/commonStore'; | import commonStore from './stores/commonStore'; | ||||||
| import {ReadJson} from '../wailsjs/go/backend_golang/App'; | import {ReadJson} from '../wailsjs/go/backend_golang/App'; | ||||||
| import {Cache, checkUpdate, downloadProgramFiles, LocalConfig, refreshModels} from './utils'; | import {Cache, checkUpdate, downloadProgramFiles, LocalConfig, refreshModels, saveCache} from './utils'; | ||||||
| import {getStatus} from './apis'; | import {getStatus} from './apis'; | ||||||
| import {EventsOn} from '../wailsjs/runtime'; | import {EventsOn} from '../wailsjs/runtime'; | ||||||
| import {defaultModelConfigs} from './pages/Configs'; | import {defaultModelConfigs} from './pages/Configs'; | ||||||
| 
 | 
 | ||||||
| export async function startup() { | export async function startup() { | ||||||
|   downloadProgramFiles(); |   downloadProgramFiles(); | ||||||
| 
 |  | ||||||
|   initRemoteText(); |  | ||||||
|   initCache(); |  | ||||||
|   await initConfig(); |  | ||||||
| 
 |  | ||||||
|   if (commonStore.settings.autoUpdatesCheck) |  | ||||||
|     checkUpdate(); |  | ||||||
| 
 |  | ||||||
|   getStatus(500).then(status => { |  | ||||||
|     if (status) |  | ||||||
|       commonStore.setModelStatus(status); |  | ||||||
|   }); |  | ||||||
| 
 |  | ||||||
|   EventsOn('downloadList', (data) => { |   EventsOn('downloadList', (data) => { | ||||||
|     if (data) |     if (data) | ||||||
|       commonStore.setDownloadList(data); |       commonStore.setDownloadList(data); | ||||||
|   }); |   }); | ||||||
|  | 
 | ||||||
|  |   initCache().then(initRemoteText); | ||||||
|  | 
 | ||||||
|  |   await initConfig(); | ||||||
|  | 
 | ||||||
|  |   if (commonStore.settings.autoUpdatesCheck) // depends on config settings
 | ||||||
|  |     checkUpdate(); | ||||||
|  | 
 | ||||||
|  |   getStatus(500).then(status => { // depends on config api port
 | ||||||
|  |     if (status) | ||||||
|  |       commonStore.setModelStatus(status); | ||||||
|  |   }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| async function initRemoteText() { | async function initRemoteText() { | ||||||
| @ -33,7 +32,7 @@ async function initRemoteText() { | |||||||
|         commonStore.setIntroduction(data.introduction); |         commonStore.setIntroduction(data.introduction); | ||||||
|       if (data.about) |       if (data.about) | ||||||
|         commonStore.setAbout(data.about); |         commonStore.setAbout(data.about); | ||||||
|     }); |     }).then(saveCache); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| async function initConfig() { | async function initConfig() { | ||||||
| @ -61,6 +60,8 @@ async function initCache() { | |||||||
|       commonStore.setIntroduction(cacheData.introduction); |       commonStore.setIntroduction(cacheData.introduction); | ||||||
|     if (cacheData.about) |     if (cacheData.about) | ||||||
|       commonStore.setAbout(cacheData.about); |       commonStore.setAbout(cacheData.about); | ||||||
|  |     if (cacheData.depComplete) | ||||||
|  |       commonStore.setDepComplete(cacheData.depComplete); | ||||||
|   }).catch(() => { |   }).catch(() => { | ||||||
|   }); |   }); | ||||||
|   await refreshModels(false); |   await refreshModels(false); | ||||||
|  | |||||||
| @ -24,6 +24,7 @@ class CommonStore { | |||||||
| 
 | 
 | ||||||
|   // global
 |   // global
 | ||||||
|   modelStatus: ModelStatus = ModelStatus.Offline; |   modelStatus: ModelStatus = ModelStatus.Offline; | ||||||
|  |   depComplete: boolean = false; | ||||||
| 
 | 
 | ||||||
|   // home
 |   // home
 | ||||||
|   introduction: IntroductionContent = manifest.introduction; |   introduction: IntroductionContent = manifest.introduction; | ||||||
| @ -130,6 +131,10 @@ class CommonStore { | |||||||
|     this.about = value; |     this.about = value; | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|  |   setDepComplete = (value: boolean) => { | ||||||
|  |     this.depComplete = value; | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|   setDownloadList = (value: DownloadStatus[]) => { |   setDownloadList = (value: DownloadStatus[]) => { | ||||||
|     this.downloadList = value; |     this.downloadList = value; | ||||||
|   }; |   }; | ||||||
|  | |||||||
| @ -1,4 +1,5 @@ | |||||||
| import { | import { | ||||||
|  |   AddToDownloadList, | ||||||
|   DeleteFile, |   DeleteFile, | ||||||
|   DownloadFile, |   DownloadFile, | ||||||
|   FileExists, |   FileExists, | ||||||
| @ -23,6 +24,7 @@ export type Cache = { | |||||||
|   models: ModelSourceItem[] |   models: ModelSourceItem[] | ||||||
|   introduction: IntroductionContent, |   introduction: IntroductionContent, | ||||||
|   about: AboutContent |   about: AboutContent | ||||||
|  |   depComplete: boolean | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export type LocalConfig = { | export type LocalConfig = { | ||||||
| @ -153,7 +155,8 @@ export const saveCache = async () => { | |||||||
|   const data: Cache = { |   const data: Cache = { | ||||||
|     models: commonStore.modelSourceList, |     models: commonStore.modelSourceList, | ||||||
|     introduction: commonStore.introduction, |     introduction: commonStore.introduction, | ||||||
|     about: commonStore.about |     about: commonStore.about, | ||||||
|  |     depComplete: commonStore.depComplete | ||||||
|   }; |   }; | ||||||
|   return SaveJson('cache.json', data); |   return SaveJson('cache.json', data); | ||||||
| }; | }; | ||||||
| @ -175,7 +178,7 @@ export function downloadProgramFiles() { | |||||||
|   manifest.programFiles.forEach(({url, path}) => { |   manifest.programFiles.forEach(({url, path}) => { | ||||||
|     FileExists(path).then(exists => { |     FileExists(path).then(exists => { | ||||||
|       if (!exists) |       if (!exists) | ||||||
|         DownloadFile(path, url); |         AddToDownloadList(path, url); | ||||||
|     }); |     }); | ||||||
|   }); |   }); | ||||||
| } | } | ||||||
| @ -188,7 +191,7 @@ export function forceDownloadProgramFiles() { | |||||||
| 
 | 
 | ||||||
| export function deletePythonProgramFiles() { | export function deletePythonProgramFiles() { | ||||||
|   manifest.programFiles.forEach(({path}) => { |   manifest.programFiles.forEach(({path}) => { | ||||||
|     if (path.endsWith('.py')) |     if (path.endsWith('.py') && !path.includes('get-pip.py')) | ||||||
|       DeleteFile(path); |       DeleteFile(path); | ||||||
|   }); |   }); | ||||||
| } | } | ||||||
| @ -201,6 +204,10 @@ export function bytesToMb(size: number) { | |||||||
|   return (size / 1024 / 1024).toFixed(2); |   return (size / 1024 / 1024).toFixed(2); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | export function bytesToKb(size: number) { | ||||||
|  |   return (size / 1024).toFixed(2); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| export async function checkUpdate() { | export async function checkUpdate() { | ||||||
|   let updateUrl = ''; |   let updateUrl = ''; | ||||||
|   await fetch('https://api.github.com/repos/josstorer/RWKV-Runner/releases/latest').then((r) => { |   await fetch('https://api.github.com/repos/josstorer/RWKV-Runner/releases/latest').then((r) => { | ||||||
| @ -214,7 +221,7 @@ export async function checkUpdate() { | |||||||
|                 deletePythonProgramFiles(); |                 deletePythonProgramFiles(); | ||||||
|                 setTimeout(() => { |                 setTimeout(() => { | ||||||
|                   UpdateApp(updateUrl).catch((e) => { |                   UpdateApp(updateUrl).catch((e) => { | ||||||
|                     toast(t('Update Error, Please restart this program') + ' - ' + e.message, { |                     toast(t('Update Error, Please restart this program') + ' - ' + e.message || e, { | ||||||
|                       type: 'error', |                       type: 'error', | ||||||
|                       position: 'bottom-left', |                       position: 'bottom-left', | ||||||
|                       autoClose: false |                       autoClose: false | ||||||
| @ -235,7 +242,7 @@ export async function checkUpdate() { | |||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   ).catch((e) => { |   ).catch((e) => { | ||||||
|     toast(t('Updates Check Error') + ' - ' + e.message, {type: 'error', position: 'bottom-left'}); |     toast(t('Updates Check Error') + ' - ' + e.message || e, {type: 'error', position: 'bottom-left'}); | ||||||
|   }); |   }); | ||||||
|   return updateUrl; |   return updateUrl; | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										6
									
								
								frontend/wailsjs/go/backend_golang/App.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								frontend/wailsjs/go/backend_golang/App.d.ts
									
									
									
									
										vendored
									
									
								
							| @ -10,10 +10,16 @@ export function ConvertModel(arg1:string,arg2:string,arg3:string):Promise<string | |||||||
| 
 | 
 | ||||||
| export function DeleteFile(arg1:string):Promise<void>; | export function DeleteFile(arg1:string):Promise<void>; | ||||||
| 
 | 
 | ||||||
|  | export function DepCheck():Promise<void>; | ||||||
|  | 
 | ||||||
| export function DownloadFile(arg1:string,arg2:string):Promise<void>; | export function DownloadFile(arg1:string,arg2:string):Promise<void>; | ||||||
| 
 | 
 | ||||||
| export function FileExists(arg1:string):Promise<boolean>; | export function FileExists(arg1:string):Promise<boolean>; | ||||||
| 
 | 
 | ||||||
|  | export function GetPlatform():Promise<string>; | ||||||
|  | 
 | ||||||
|  | export function InstallPyDep():Promise<string>; | ||||||
|  | 
 | ||||||
| export function ListDirFiles(arg1:string):Promise<Array<backend_golang.FileInfo>>; | export function ListDirFiles(arg1:string):Promise<Array<backend_golang.FileInfo>>; | ||||||
| 
 | 
 | ||||||
| export function OpenFileFolder(arg1:string):Promise<void>; | export function OpenFileFolder(arg1:string):Promise<void>; | ||||||
|  | |||||||
| @ -18,6 +18,10 @@ export function DeleteFile(arg1) { | |||||||
|   return window['go']['backend_golang']['App']['DeleteFile'](arg1); |   return window['go']['backend_golang']['App']['DeleteFile'](arg1); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | export function DepCheck() { | ||||||
|  |   return window['go']['backend_golang']['App']['DepCheck'](); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| export function DownloadFile(arg1, arg2) { | export function DownloadFile(arg1, arg2) { | ||||||
|   return window['go']['backend_golang']['App']['DownloadFile'](arg1, arg2); |   return window['go']['backend_golang']['App']['DownloadFile'](arg1, arg2); | ||||||
| } | } | ||||||
| @ -26,6 +30,14 @@ export function FileExists(arg1) { | |||||||
|   return window['go']['backend_golang']['App']['FileExists'](arg1); |   return window['go']['backend_golang']['App']['FileExists'](arg1); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | export function GetPlatform() { | ||||||
|  |   return window['go']['backend_golang']['App']['GetPlatform'](); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export function InstallPyDep() { | ||||||
|  |   return window['go']['backend_golang']['App']['InstallPyDep'](); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| export function ListDirFiles(arg1) { | export function ListDirFiles(arg1) { | ||||||
|   return window['go']['backend_golang']['App']['ListDirFiles'](arg1); |   return window['go']['backend_golang']['App']['ListDirFiles'](arg1); | ||||||
| } | } | ||||||
|  | |||||||
| @ -61,6 +61,10 @@ | |||||||
|     { |     { | ||||||
|       "url": "https://cdn.jsdelivr.net/gh/josstorer/RWKV-Runner/backend-python/20B_tokenizer.json", |       "url": "https://cdn.jsdelivr.net/gh/josstorer/RWKV-Runner/backend-python/20B_tokenizer.json", | ||||||
|       "path": "backend-python/20B_tokenizer.json" |       "path": "backend-python/20B_tokenizer.json" | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "url": "https://raw.githubusercontent.com/pypa/get-pip/main/public/get-pip.py", | ||||||
|  |       "path": "backend-python/get-pip.py" | ||||||
|     } |     } | ||||||
|   ], |   ], | ||||||
|   "models": [ |   "models": [ | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user