chore & auto dep

This commit is contained in:
josc146
2023-05-20 23:34:33 +08:00
parent 9076ff3fd7
commit b8f7582513
15 changed files with 291 additions and 53 deletions

View File

@@ -90,5 +90,8 @@
"Continue": "继续",
"Check": "查看",
"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": "安装"
}

View File

@@ -1,12 +1,12 @@
import React, {FC, MouseEventHandler, ReactElement} from 'react';
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 {observer} from 'mobx-react-lite';
import {exit, readRoot, switchModel, updateConfig} from '../apis';
import {toast} from 'react-toastify';
import manifest from '../../../manifest.json';
import {getStrategy, toastWithButton} from '../utils';
import {getStrategy, saveCache, toastWithButton} from '../utils';
import {useTranslation} from 'react-i18next';
import {ToolTipButton} from './ToolTipButton';
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 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)) {
toastWithButton(t('Model file not found'), t('Download'), () => {
const downloadUrl = commonStore.modelSourceList.find(item => item.name === modelName)?.downloadUrl;

View File

@@ -256,7 +256,7 @@ export const Configs: FC = observer(() => {
toast(`${t('Convert Success')} - ${newModelPath}`, {type: 'success'});
refreshLocalModels({models: commonStore.modelSourceList}, false);
}).catch(e => {
toast(`${t('Convert Failed')} - ${e}`, {type: 'error'});
toast(`${t('Convert Failed')} - ${e.message || e}`, {type: 'error'});
});
} else {
toast(`${t('Model Not Found')} - ${modelPath}`, {type: 'error'});

View File

@@ -4,7 +4,7 @@ import {Page} from '../components/Page';
import {observer} from 'mobx-react-lite';
import commonStore from '../stores/commonStore';
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 {Folder20Regular, Pause20Regular, Play20Regular} from '@fluentui/react-icons';
import {ContinueDownload, OpenFileFolder, PauseDownload} from '../../wailsjs/go/backend_golang/App';
@@ -23,21 +23,31 @@ export type DownloadStatus = {
export const Downloads: FC = observer(() => {
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(() => {
if (finishedDownloads > 0)
if (finishedModelsLen > 0)
refreshLocalModels({models: commonStore.modelSourceList}, false);
console.log('finishedDownloads:', finishedDownloads);
}, [finishedDownloads]);
console.log('finishedModelsLen:', finishedModelsLen);
}, [finishedModelsLen]);
return (
<Page title={t('Downloads')} content={
<div className="flex flex-col gap-2 overflow-y-auto overflow-x-hidden p-1">
{commonStore.downloadList.map((status, index) => (
<div className="flex flex-col gap-1" key={index}>
{commonStore.downloadList.slice().reverse().map((status, 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
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'}
>
<div className="flex items-center gap-2">
@@ -57,8 +67,8 @@ export const Downloads: FC = observer(() => {
</div>
</Field>
<Divider style={{flexGrow: 0}}/>
</div>
))
</div>;
})
}
</div>
}/>

View File

@@ -1,29 +1,28 @@
import commonStore from './stores/commonStore';
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 {EventsOn} from '../wailsjs/runtime';
import {defaultModelConfigs} from './pages/Configs';
export async function startup() {
downloadProgramFiles();
initRemoteText();
initCache();
await initConfig();
if (commonStore.settings.autoUpdatesCheck)
checkUpdate();
getStatus(500).then(status => {
if (status)
commonStore.setModelStatus(status);
});
EventsOn('downloadList', (data) => {
if (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() {
@@ -33,7 +32,7 @@ async function initRemoteText() {
commonStore.setIntroduction(data.introduction);
if (data.about)
commonStore.setAbout(data.about);
});
}).then(saveCache);
}
async function initConfig() {
@@ -61,6 +60,8 @@ async function initCache() {
commonStore.setIntroduction(cacheData.introduction);
if (cacheData.about)
commonStore.setAbout(cacheData.about);
if (cacheData.depComplete)
commonStore.setDepComplete(cacheData.depComplete);
}).catch(() => {
});
await refreshModels(false);

View File

@@ -24,6 +24,7 @@ class CommonStore {
// global
modelStatus: ModelStatus = ModelStatus.Offline;
depComplete: boolean = false;
// home
introduction: IntroductionContent = manifest.introduction;
@@ -130,6 +131,10 @@ class CommonStore {
this.about = value;
};
setDepComplete = (value: boolean) => {
this.depComplete = value;
};
setDownloadList = (value: DownloadStatus[]) => {
this.downloadList = value;
};

View File

@@ -1,4 +1,5 @@
import {
AddToDownloadList,
DeleteFile,
DownloadFile,
FileExists,
@@ -23,6 +24,7 @@ export type Cache = {
models: ModelSourceItem[]
introduction: IntroductionContent,
about: AboutContent
depComplete: boolean
}
export type LocalConfig = {
@@ -153,7 +155,8 @@ export const saveCache = async () => {
const data: Cache = {
models: commonStore.modelSourceList,
introduction: commonStore.introduction,
about: commonStore.about
about: commonStore.about,
depComplete: commonStore.depComplete
};
return SaveJson('cache.json', data);
};
@@ -175,7 +178,7 @@ export function downloadProgramFiles() {
manifest.programFiles.forEach(({url, path}) => {
FileExists(path).then(exists => {
if (!exists)
DownloadFile(path, url);
AddToDownloadList(path, url);
});
});
}
@@ -188,7 +191,7 @@ export function forceDownloadProgramFiles() {
export function deletePythonProgramFiles() {
manifest.programFiles.forEach(({path}) => {
if (path.endsWith('.py'))
if (path.endsWith('.py') && !path.includes('get-pip.py'))
DeleteFile(path);
});
}
@@ -201,6 +204,10 @@ export function bytesToMb(size: number) {
return (size / 1024 / 1024).toFixed(2);
}
export function bytesToKb(size: number) {
return (size / 1024).toFixed(2);
}
export async function checkUpdate() {
let updateUrl = '';
await fetch('https://api.github.com/repos/josstorer/RWKV-Runner/releases/latest').then((r) => {
@@ -214,7 +221,7 @@ export async function checkUpdate() {
deletePythonProgramFiles();
setTimeout(() => {
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',
position: 'bottom-left',
autoClose: false
@@ -235,7 +242,7 @@ export async function checkUpdate() {
}
}
).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;
}