progress
This commit is contained in:
parent
e155b4a2a1
commit
c4ddb3dc8c
23 changed files with 333 additions and 132 deletions
9
.vscode/settings.json
vendored
9
.vscode/settings.json
vendored
|
@ -1,8 +1,17 @@
|
|||
{
|
||||
"cSpell.words": [
|
||||
"введите",
|
||||
"Ведите",
|
||||
"Количество",
|
||||
"может",
|
||||
"навык",
|
||||
"Навыки",
|
||||
"отрицательное",
|
||||
"принимать",
|
||||
"скила",
|
||||
"число",
|
||||
"эпох",
|
||||
"эпоха",
|
||||
"skils",
|
||||
"typedataset"
|
||||
]
|
||||
|
|
15
server/src/core/scenarios/create_many_folder_scenario.ts
Normal file
15
server/src/core/scenarios/create_many_folder_scenario.ts
Normal file
|
@ -0,0 +1,15 @@
|
|||
import { Result } from "../helpers/result";
|
||||
import { CreateFolderUseCase } from "../usecases/create_folder_usecase";
|
||||
|
||||
export class CreateManyFolderScenario {
|
||||
call = async (path: string, foldersNames: string[]): Promise<Result<Error, string>> => {
|
||||
try {
|
||||
foldersNames.forEach(async (folder) => {
|
||||
await new CreateFolderUseCase().call(`${path}${folder}`.normalize());
|
||||
});
|
||||
return Result.ok("many folder created");
|
||||
} catch (error) {
|
||||
return Result.error(new Error(error));
|
||||
}
|
||||
};
|
||||
}
|
|
@ -6,6 +6,7 @@ import { MongoIdValidation } from "../../../core/validations/mongo_id_validation
|
|||
import { DatasetDBModel } from "../models/dataset_database_model";
|
||||
import { IDatasetModel } from "../models/dataset_validation_model";
|
||||
import { ProcessWatcherAndDatabaseUpdateService } from "./create_dataset_scenario";
|
||||
import { FolderStructure } from "../../projects/domain/upload_file_to_to_project_scenario";
|
||||
|
||||
export class ExecDatasetProcessScenario extends CallbackStrategyWithIdQuery {
|
||||
idValidationExpression = new MongoIdValidation();
|
||||
|
@ -14,6 +15,8 @@ export class ExecDatasetProcessScenario extends CallbackStrategyWithIdQuery {
|
|||
return (await new ReadByIdDataBaseModelUseCase<IDatasetModel>(DatasetDBModel).call(id)).map(async (model) => {
|
||||
return (await new IsHaveActiveProcessUseCase().call()).map(async () => {
|
||||
await DatasetDBModel.findById(id).updateOne({ processStatus: "RUN" });
|
||||
model.local_path = `${model.local_path}/${FolderStructure.datasets}/`;
|
||||
console.log(`blenderproc run $PYTHON_BLENDER_PROC --cfg '${JSON.stringify(model)}'`);
|
||||
return new ExecProcessUseCase().call(
|
||||
`${model.project.rootDir}/`,
|
||||
`blenderproc run $PYTHON_BLENDER_PROC --cfg '${JSON.stringify(model)}'`,
|
||||
|
@ -23,4 +26,4 @@ export class ExecDatasetProcessScenario extends CallbackStrategyWithIdQuery {
|
|||
});
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ export class FormBuilderValidationModel {
|
|||
public context: string;
|
||||
@IsArray()
|
||||
public form: [];
|
||||
output: any;
|
||||
}
|
||||
export enum ProcessStatus {
|
||||
END = "END",
|
||||
|
@ -16,7 +17,7 @@ export enum ProcessStatus {
|
|||
NEW = "NEW",
|
||||
}
|
||||
export interface IDatasetModel {
|
||||
_id?:string;
|
||||
_id?: string;
|
||||
name: string;
|
||||
local_path: string;
|
||||
dataSetObjects: string[];
|
||||
|
|
|
@ -6,6 +6,14 @@ import { IProjectInstanceModel } from "../models/project_instance_database_model
|
|||
import { ReadByIdDataBaseModelUseCase } from "../../../core/usecases/read_by_id_database_model_usecase";
|
||||
import { ProjectDBModel } from "../../_projects/models/project_database_model";
|
||||
import { ExecProcessUseCase } from "../../../core/usecases/exec_process_usecase";
|
||||
import { Result } from "../../../core/helpers/result";
|
||||
import { CreateManyFolderScenario } from "../../../core/scenarios/create_many_folder_scenario";
|
||||
|
||||
export enum FolderStructure {
|
||||
assets = "assets",
|
||||
weights = "weights",
|
||||
datasets = "datasets",
|
||||
}
|
||||
|
||||
export class UploadCadFileToProjectScenario extends CallbackStrategyWithFileUpload {
|
||||
checkingFileExpression: RegExp = new RegExp(".FCStd");
|
||||
|
@ -14,13 +22,18 @@ export class UploadCadFileToProjectScenario extends CallbackStrategyWithFileUplo
|
|||
async call(file: IFile, id: string): ResponseBase {
|
||||
return (await new ReadByIdDataBaseModelUseCase<IProjectInstanceModel>(ProjectDBModel).call(id)).map(
|
||||
async (databaseModel) =>
|
||||
(await new CreateFileUseCase().call(`${databaseModel.rootDir}/${file.name}`, file.data)).map(
|
||||
async () =>
|
||||
(await new CreateFileUseCase().call(`${databaseModel.rootDir}/${file.name}`, file.data)).map(async () =>
|
||||
(
|
||||
await new ExecProcessUseCase().call(
|
||||
`${databaseModel.rootDir}/`,
|
||||
'',
|
||||
`python3 $PYTHON_BLENDER --path '${databaseModel.rootDir}/assets/'`
|
||||
`python3 $PYTHON_BLENDER --path '${databaseModel.rootDir}/assets/'`,
|
||||
""
|
||||
)
|
||||
).map(async () =>
|
||||
(await new CreateManyFolderScenario().call(databaseModel.rootDir, Object.keys(FolderStructure).map((el) => `/${el}`))).map(() =>
|
||||
Result.ok("file upload and save")
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -13,14 +13,16 @@ export class ExecWeightProcessScenario extends CallbackStrategyWithIdQuery {
|
|||
return (await new ReadByIdDataBaseModelUseCase<IWeightModel>(WeightDBModel).call(id)).map(async (model) => {
|
||||
return (await new IsHaveActiveProcessUseCase().call()).map(async () => {
|
||||
await WeightDBModel.findById(id).updateOne({ processStatus: "RUN" });
|
||||
|
||||
if (typeof model.project === "object" && typeof model.datasetId === "object") {
|
||||
console.log(
|
||||
`python3 $PYTHON_EDUCATION --path ${model.project.rootDir} --name ${model.name} --datasetName ${model.datasetId.name}`
|
||||
);
|
||||
if (model.processStatus === "exec") {
|
||||
console.log(20);
|
||||
}
|
||||
if (model.processStatus === "new") {
|
||||
console.log(20);
|
||||
}
|
||||
return new ExecProcessUseCase().call(
|
||||
`${model.project.rootDir}/`,
|
||||
`python3 $PYTHON_EDUCATION --path ${model.project.rootDir} --name ${model.name} --datasetName ${model.datasetId.name}`,
|
||||
`python3 $PYTHON_EDUCATION --path ${model.project.rootDir} --name ${model.name} --datasetName ${model.datasetId.name} --outpath ${model.project.rootDir} --type ${model.datasetId.formBuilder.output.typedataset} --epoch ${model.epoch} `,
|
||||
id,
|
||||
new ProcessWatcherAndDatabaseUpdateService(id as unknown as ObjectId, WeightDBModel)
|
||||
);
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
import { IsMongoId, IsString } from "class-validator";
|
||||
import { IsNumber, IsString } from "class-validator";
|
||||
import { IWeightModel } from "./weights_validation_model";
|
||||
|
||||
export class WeightValidationModel implements IWeightModel {
|
||||
public processStatus: string;
|
||||
@IsNumber()
|
||||
public epoch: number;
|
||||
@IsString()
|
||||
public name: string;
|
||||
@IsMongoId()
|
||||
public datasetId: string;
|
||||
@IsMongoId()
|
||||
public project: string;
|
||||
}
|
||||
|
|
|
@ -7,6 +7,8 @@ export interface IWeightModel {
|
|||
name: string;
|
||||
datasetId: string | IDatasetModel;
|
||||
project: string | IProjectModel;
|
||||
processStatus: string;
|
||||
epoch: number;
|
||||
}
|
||||
export const WeightSchema = new Schema({
|
||||
name: {
|
||||
|
@ -22,11 +24,15 @@ export const WeightSchema = new Schema({
|
|||
type: String,
|
||||
default: "none",
|
||||
},
|
||||
|
||||
// the user selects
|
||||
isFinished: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
epoch:{
|
||||
type:Number,
|
||||
},
|
||||
datasetId: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: datasetSchema,
|
||||
|
|
|
@ -5,6 +5,7 @@ import { extensions } from "./core/extensions/extensions";
|
|||
import { httpRoutes } from "./core/controllers/routes";
|
||||
import { executorProgramService } from "./core/usecases/exec_process_usecase";
|
||||
|
||||
|
||||
extensions();
|
||||
|
||||
const socketSubscribers = [new SocketSubscriber(executorProgramService, "realtime")];
|
||||
|
|
|
@ -26,7 +26,9 @@ declare global {
|
|||
toPx(): string;
|
||||
unixFromDate(): string;
|
||||
isValid(str: string): boolean;
|
||||
randRange(min:number,max:number):number
|
||||
randRange(min: number, max: number): number;
|
||||
isPositive(): boolean;
|
||||
isNegative(): boolean;
|
||||
}
|
||||
|
||||
interface String {
|
||||
|
|
|
@ -24,10 +24,22 @@ export const NumberExtensions = () => {
|
|||
return !isNaN(Number(str));
|
||||
};
|
||||
}
|
||||
if(Number().randRange === undefined){
|
||||
if (Number().randRange === undefined) {
|
||||
// eslint-disable-next-line no-extend-native
|
||||
Number.prototype.randRange = function (min,max) {
|
||||
Number.prototype.randRange = function (min, max) {
|
||||
return Math.random() * (max - min) + min;
|
||||
};
|
||||
}
|
||||
if (Number().isPositive === undefined) {
|
||||
// eslint-disable-next-line no-extend-native
|
||||
Number.prototype.isPositive = function () {
|
||||
return Math.sign(Number(this)) === 1;
|
||||
};
|
||||
}
|
||||
if(Number().isNegative === undefined){
|
||||
// eslint-disable-next-line no-extend-native
|
||||
Number.prototype.isNegative = function (){
|
||||
return !this.isPositive()
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -2,9 +2,13 @@ import { NavigateFunction } from "react-router-dom";
|
|||
import { Result } from "../helper/result";
|
||||
import { UiBaseError } from "../model/ui_base_error";
|
||||
import { HttpError } from "../repository/http_repository";
|
||||
import { message } from "antd";
|
||||
|
||||
export type CoreError = HttpError | Error;
|
||||
|
||||
interface IMessage {
|
||||
successMessage?: string;
|
||||
errorMessage?: string;
|
||||
}
|
||||
export abstract class UiLoader {
|
||||
isLoading = false;
|
||||
async httpHelper<T>(callBack: Promise<Result<any, T>>) {
|
||||
|
@ -32,6 +36,16 @@ export abstract class UiLoader {
|
|||
})
|
||||
);
|
||||
};
|
||||
messageHttp = async <T>(callBack: Promise<Result<CoreError, T>>, report?: IMessage) => {
|
||||
return (await this.httpHelper(callBack)).fold(
|
||||
(s) => {
|
||||
if (report && report.successMessage) message.success(report.successMessage);
|
||||
},
|
||||
(e) => {
|
||||
if (report && report.errorMessage) message.error(report.errorMessage);
|
||||
}
|
||||
);
|
||||
};
|
||||
}
|
||||
export class SimpleErrorState extends UiLoader {
|
||||
errorHandingStrategy = () => {
|
||||
|
|
|
@ -2,7 +2,6 @@ import makeAutoObservable from "mobx-store-inheritance";
|
|||
import { ProjectRepository, UUID } from "../data/project_repository";
|
||||
import { IProjectModel } from "../model/project_model";
|
||||
import { SimpleErrorState } from "../../../core/store/base_store";
|
||||
import { ActivePipeline } from "../../../core/model/active_pipeline";
|
||||
|
||||
interface IProjectView {
|
||||
isActive: boolean;
|
||||
|
|
|
@ -8,7 +8,7 @@ import type { MenuProps } from "antd";
|
|||
import { Dropdown } from "antd";
|
||||
import { ProcessStatus } from "./dataset_model";
|
||||
|
||||
interface IMenuItem {
|
||||
export interface IMenuItem {
|
||||
onClick: Function;
|
||||
name: string;
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ export enum ProcessStatus {
|
|||
ERROR = "ERROR",
|
||||
NEW = "NEW",
|
||||
RUN = "RUN",
|
||||
NONE = "none"
|
||||
}
|
||||
|
||||
export interface IDatasetModel {
|
||||
|
|
|
@ -1,74 +0,0 @@
|
|||
import { CoreButton } from "../../core/ui/button/button";
|
||||
import { Icon } from "../../core/ui/icons/icons";
|
||||
import { CoreText, CoreTextType } from "../../core/ui/text/text";
|
||||
import { ProcessStatus } from "../dataset/dataset_model";
|
||||
|
||||
export interface ISkillCardProps {
|
||||
processStatus?: string;
|
||||
name?: string;
|
||||
emptyOnClick?: Function;
|
||||
empty: boolean;
|
||||
}
|
||||
|
||||
export const SkillCard = (props: ISkillCardProps) => {
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
margin: 10,
|
||||
backgroundColor: "#f7f2fa",
|
||||
borderRadius: 10,
|
||||
padding: 10,
|
||||
width: 150,
|
||||
height: 100,
|
||||
alignContent: "center",
|
||||
}}
|
||||
>
|
||||
{props.empty ? (
|
||||
<div
|
||||
onClick={() => {
|
||||
if (props.empty && props.emptyOnClick) props.emptyOnClick();
|
||||
}}
|
||||
style={{ display: "flex", justifyContent: "center", alignItems: "center" }}
|
||||
>
|
||||
<Icon type="PlusCircle" />
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
<CoreText text={props.name ?? ""} type={CoreTextType.medium} />
|
||||
{props.processStatus === ProcessStatus.END ? (
|
||||
<CoreButton
|
||||
onClick={() => {
|
||||
// if (props.type.isEqual(CardDataSetType.COMPLETED) && props.onClickButton && props.id) {
|
||||
// props.onClickButton(props.id);
|
||||
// }
|
||||
}}
|
||||
text="Завершен"
|
||||
/>
|
||||
) : null}
|
||||
{props.processStatus === ProcessStatus.RUN ? (
|
||||
<>
|
||||
<CoreButton
|
||||
onClick={() => {
|
||||
// if (props.type.isEqual(CardDataSetType.COMPLETED) && props.onClickButton && props.id) {
|
||||
// props.onClickButton(props.id);
|
||||
}}
|
||||
block={true}
|
||||
text="Стоп"
|
||||
/>
|
||||
</>
|
||||
) : null}
|
||||
{props.processStatus === ProcessStatus.ERROR ? (
|
||||
<CoreButton
|
||||
style={{
|
||||
backgroundColor: "red",
|
||||
}}
|
||||
onClick={() => {}}
|
||||
filled={true}
|
||||
text="Ошибка"
|
||||
/>
|
||||
) : null}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
149
ui/src/features/skils/skill_card.tsx
Normal file
149
ui/src/features/skils/skill_card.tsx
Normal file
|
@ -0,0 +1,149 @@
|
|||
import { CoreButton } from "../../core/ui/button/button";
|
||||
import { Icon } from "../../core/ui/icons/icons";
|
||||
import { Dropdown } from "antd";
|
||||
import { CoreText, CoreTextType } from "../../core/ui/text/text";
|
||||
import { ProcessStatus } from "../dataset/dataset_model";
|
||||
import { IMenuItem } from "../dataset/card_dataset";
|
||||
import type { MenuProps } from "antd";
|
||||
|
||||
export interface ISkillCardProps {
|
||||
processStatus?: string;
|
||||
name?: string;
|
||||
isFinished?: boolean;
|
||||
id?: string;
|
||||
emptyOnClick?: Function;
|
||||
startOnClick?: (id: string) => void;
|
||||
continueOnClick?: (id: string) => void;
|
||||
empty: boolean;
|
||||
onEdit?: (id: string) => void;
|
||||
onDelete?: (id: string) => void;
|
||||
}
|
||||
|
||||
export const SkillCard = (props: ISkillCardProps) => {
|
||||
const menu: IMenuItem[] = [
|
||||
{
|
||||
onClick: () => {
|
||||
if (props.onEdit && props.id) props.onEdit(props.id);
|
||||
},
|
||||
name: "Редактировать",
|
||||
},
|
||||
{
|
||||
onClick: () => {
|
||||
if (props.onDelete && props.id) props.onDelete(props.id);
|
||||
},
|
||||
name: "Удалить",
|
||||
},
|
||||
];
|
||||
|
||||
const items: MenuProps["items"] = menu.map((el, index) => {
|
||||
return {
|
||||
key: String(index),
|
||||
label: <CoreText text={el.name} type={CoreTextType.medium} />,
|
||||
onClick: () => el.onClick(props.id),
|
||||
};
|
||||
});
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
margin: 10,
|
||||
backgroundColor: "#f7f2fa",
|
||||
borderRadius: 10,
|
||||
padding: 10,
|
||||
width: 150,
|
||||
height: "max-content",
|
||||
alignContent: "center",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "stretch",
|
||||
justifyContent: "space-between",
|
||||
}}
|
||||
>
|
||||
{props.empty ? (
|
||||
<div
|
||||
onClick={() => {
|
||||
if (props.empty && props.emptyOnClick) props.emptyOnClick();
|
||||
}}
|
||||
style={{ display: "flex", justifyContent: "center", alignItems: "center" }}
|
||||
>
|
||||
<Icon type="PlusCircle" />
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "space-between",
|
||||
}}
|
||||
>
|
||||
<CoreText text={props.name ?? ""} type={CoreTextType.medium} />
|
||||
<Dropdown overlayStyle={{ backgroundColor: "rgba(243, 237, 247, 1)" }} menu={{ items }}>
|
||||
<div>
|
||||
<Icon type="Settings" />
|
||||
</div>
|
||||
</Dropdown>
|
||||
</div>
|
||||
<div style={{ height: 10 }} />
|
||||
<div>
|
||||
{props.processStatus === ProcessStatus.NONE ? (
|
||||
<>
|
||||
<CoreButton
|
||||
text="старт"
|
||||
onClick={() => {
|
||||
if (props.startOnClick && props.id) props.startOnClick(props.id);
|
||||
}}
|
||||
/>
|
||||
<div style={{ height: 10 }} />
|
||||
<CoreButton
|
||||
text="продолжить"
|
||||
onClick={() => {
|
||||
if (props.continueOnClick && props.id) props.continueOnClick(props.id);
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
) : null}
|
||||
{props.processStatus === ProcessStatus.END ? (
|
||||
<>
|
||||
<CoreButton
|
||||
text="старт"
|
||||
onClick={() => {
|
||||
if (props.startOnClick && props.id) props.startOnClick(props.id);
|
||||
}}
|
||||
/>
|
||||
<div style={{ height: 10 }} />
|
||||
<CoreButton
|
||||
text="продолжить"
|
||||
onClick={() => {
|
||||
if (props.continueOnClick && props.id) props.continueOnClick(props.id);
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
) : null}
|
||||
{props.processStatus === ProcessStatus.RUN ? (
|
||||
<>
|
||||
<CoreButton
|
||||
onClick={() => {
|
||||
// if (props.type.isEqual(CardDataSetType.COMPLETED) && props.onClickButton && props.id) {
|
||||
// props.onClickButton(props.id);
|
||||
}}
|
||||
block={true}
|
||||
text="Стоп"
|
||||
/>
|
||||
</>
|
||||
) : null}
|
||||
{props.processStatus === ProcessStatus.ERROR ? (
|
||||
<CoreButton
|
||||
style={{
|
||||
backgroundColor: "red",
|
||||
}}
|
||||
onClick={() => {}}
|
||||
filled={true}
|
||||
text="Ошибка"
|
||||
/>
|
||||
) : null}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
26
ui/src/features/skils/skill_model.ts
Normal file
26
ui/src/features/skils/skill_model.ts
Normal file
|
@ -0,0 +1,26 @@
|
|||
import makeAutoObservable from "mobx-store-inheritance";
|
||||
import { Result } from "../../core/helper/result";
|
||||
|
||||
export class SkillModel {
|
||||
constructor(public name: string, public datasetId: string, public project: string, public epoch: number) {
|
||||
makeAutoObservable(this);
|
||||
}
|
||||
static empty() {
|
||||
return new SkillModel("", "", "", 0);
|
||||
}
|
||||
valid(): Result<string, SkillModel> {
|
||||
if (this.name.isEmpty()) {
|
||||
return Result.error("введите имя скила");
|
||||
}
|
||||
if (this.datasetId.isEmpty()) {
|
||||
return Result.error("datasetId is empty");
|
||||
}
|
||||
if (this.project.isEmpty()) {
|
||||
return Result.error("project is empty");
|
||||
}
|
||||
if (this.epoch.isNegative()) {
|
||||
return Result.error("эпоха не может принимать отрицательное число");
|
||||
}
|
||||
return Result.ok(this);
|
||||
}
|
||||
}
|
|
@ -2,8 +2,9 @@ import { Result } from "../../core/helper/result";
|
|||
import { HttpError, HttpMethod, HttpRepository } from "../../core/repository/http_repository";
|
||||
import { UUID } from "../all_projects/data/project_repository";
|
||||
import { IDatasetModel } from "../dataset/dataset_model";
|
||||
import { SkillModel } from "./skills_store";
|
||||
export interface IEducations {
|
||||
import { SkillModel } from "./skill_model";
|
||||
|
||||
export interface ISkils {
|
||||
_id: string;
|
||||
name: string;
|
||||
processStatus: string;
|
||||
|
@ -13,13 +14,20 @@ export interface IEducations {
|
|||
__v: number;
|
||||
}
|
||||
|
||||
export class SkillsRepository extends HttpRepository {
|
||||
export class SkillsHttpRepository extends HttpRepository {
|
||||
execSkill(id: string) {
|
||||
return this._jsonRequest(HttpMethod.GET, `/weights/exec?id=${id}`);
|
||||
}
|
||||
editSkill(model: ISkils) {
|
||||
return this._jsonRequest(HttpMethod.PUT, `/weights/`, model);
|
||||
}
|
||||
getAllSkills = async () => {
|
||||
return this._jsonRequest<IEducations[]>(HttpMethod.GET, "/weights");
|
||||
return this._jsonRequest<ISkils[]>(HttpMethod.GET, "/weights");
|
||||
};
|
||||
deleteSkill = async (id: string) => {
|
||||
return this._jsonRequest<void>(HttpMethod.DELETE, `/weights?id=${id}`);
|
||||
};
|
||||
|
||||
addNewSkill = async (model: SkillModel) => {
|
||||
return this._jsonRequest(HttpMethod.POST, "/weights", model);
|
||||
};
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import React from "react";
|
||||
import { Drawer } from "antd";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { MainPage } from "../../core/ui/pages/main_page";
|
||||
import { CoreText, CoreTextType } from "../../core/ui/text/text";
|
||||
import { DrawersSkill, SkillStore } from "./skills_store";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { SkillCard } from "./skil_card";
|
||||
import { Drawer } from "antd";
|
||||
import { SkillCard } from "./skill_card";
|
||||
import { CoreInput } from "../../core/ui/input/input";
|
||||
import { CoreButton } from "../../core/ui/button/button";
|
||||
import { CoreSwitch } from "../../core/ui/switch/switch";
|
||||
|
@ -17,6 +17,7 @@ interface IItem {
|
|||
const skills: IItem[] = [{ name: "ML", isActive: true }];
|
||||
|
||||
export const SkillPath = "/skills";
|
||||
|
||||
export const SkillScreen = observer(() => {
|
||||
const [store] = React.useState(() => new SkillStore());
|
||||
|
||||
|
@ -47,7 +48,7 @@ export const SkillScreen = observer(() => {
|
|||
}}
|
||||
>
|
||||
{store.skils?.map((el) => (
|
||||
<SkillCard name={el.name} processStatus={el.processStatus} empty={false} />
|
||||
<SkillCard id={el._id} isFinished={el.isFinished} name={el.name} processStatus={el.processStatus} empty={false} startOnClick={(id) => store.execSkill(id)} continueOnClick={(id) => store.continueSkill(id)} />
|
||||
))}
|
||||
<SkillCard empty={true} emptyOnClick={() => store.edtDrawer(DrawersSkill.NEW_SKILL, true)} />
|
||||
</div>
|
||||
|
@ -61,6 +62,11 @@ export const SkillScreen = observer(() => {
|
|||
>
|
||||
<div style={{ display: "flex", flexDirection: "column", justifyContent: "space-between", height: "100%" }}>
|
||||
<CoreInput value={store.skill.name} label={"Имя навыка"} onChange={(e) => store.changeSkillName(e)} />
|
||||
<CoreInput
|
||||
value={store.skill.epoch.toString()}
|
||||
label="Количество эпох"
|
||||
onChange={(e) => store.changeEpoch(Number(e))}
|
||||
/>
|
||||
<div style={{ height: "100%" }}>
|
||||
{store.datasets?.map((el) => (
|
||||
<div
|
||||
|
|
|
@ -1,38 +1,18 @@
|
|||
import makeAutoObservable from "mobx-store-inheritance";
|
||||
import { NavigateFunction } from "react-router-dom";
|
||||
import { HttpError } from "../../core/repository/http_repository";
|
||||
import { UiErrorState } from "../../core/store/base_store";
|
||||
import makeAutoObservable from "mobx-store-inheritance";
|
||||
import { IEducations as ISkils, SkillsRepository as SkillsHttpRepository } from "./skills_repository";
|
||||
import { ISkils, SkillsHttpRepository } from "./skills_repository";
|
||||
import { Drawer } from "../dataset/dataset_store";
|
||||
import { IDatasetModel } from "../dataset/dataset_model";
|
||||
import { Result } from "../../core/helper/result";
|
||||
import { message } from "antd";
|
||||
import { UUID } from "../all_projects/data/project_repository";
|
||||
import { SkillModel } from "./skill_model";
|
||||
|
||||
export enum DrawersSkill {
|
||||
NEW_SKILL = "Новый навык",
|
||||
}
|
||||
|
||||
export class SkillModel {
|
||||
constructor(public name: string, public datasetId: string, public project: string) {
|
||||
makeAutoObservable(this);
|
||||
}
|
||||
static empty() {
|
||||
return new SkillModel("", "", "");
|
||||
}
|
||||
valid(): Result<string, SkillModel> {
|
||||
if (this.name.isEmpty()) {
|
||||
return Result.error("name is empty");
|
||||
}
|
||||
if (this.datasetId.isEmpty()) {
|
||||
return Result.error("datasetId is empty");
|
||||
}
|
||||
if (this.project.isEmpty()) {
|
||||
return Result.error("project is empty");
|
||||
}
|
||||
return Result.ok(this);
|
||||
}
|
||||
}
|
||||
export class SkillStore extends UiErrorState<HttpError> {
|
||||
drawers: Drawer[];
|
||||
skillsHttpRepository: SkillsHttpRepository;
|
||||
|
@ -54,6 +34,27 @@ export class SkillStore extends UiErrorState<HttpError> {
|
|||
this.skillsHttpRepository = new SkillsHttpRepository();
|
||||
makeAutoObservable(this);
|
||||
}
|
||||
getSkillById = (id: string) => this.skils?.find((el) => el._id === id);
|
||||
continueSkill = async (id: string) => {
|
||||
const skill = this.getSkillById(id) as ISkils;
|
||||
skill.processStatus = "new";
|
||||
await this.skillsHttpRepository.editSkill(skill);
|
||||
this.messageHttp(this.skillsHttpRepository.execSkill(id), {
|
||||
errorMessage: "Ошибка",
|
||||
successMessage: "Обучение продолжено",
|
||||
});
|
||||
};
|
||||
|
||||
execSkill = async (id: string) => {
|
||||
const skill = this.getSkillById(id) as ISkils;
|
||||
skill.processStatus = "exec";
|
||||
await this.skillsHttpRepository.editSkill(skill);
|
||||
this.messageHttp(this.skillsHttpRepository.execSkill(id), {
|
||||
errorMessage: "Ошибка",
|
||||
successMessage: "Обучение стартовало",
|
||||
});
|
||||
};
|
||||
|
||||
errorHandingStrategy: (error: HttpError) => {};
|
||||
init = async (navigate?: NavigateFunction | undefined) => {
|
||||
await this.mapOk("skils", this.skillsHttpRepository.getAllSkills());
|
||||
|
@ -63,8 +64,10 @@ export class SkillStore extends UiErrorState<HttpError> {
|
|||
changeSkillName(name: string): void {
|
||||
this.skill.name = name;
|
||||
}
|
||||
changeEpoch(epoch: number) {
|
||||
this.skill.epoch = epoch;
|
||||
}
|
||||
saveSkill() {
|
||||
console.log(this.activeProjectId);
|
||||
this.skill.project = this.activeProjectId?.id ?? "";
|
||||
this.skill.valid().fold(
|
||||
async (model) => {
|
||||
|
|
|
@ -8,13 +8,13 @@ args = parser.parse_args()
|
|||
|
||||
def copy_and_move_folder(src, dst):
|
||||
try:
|
||||
if os.path.exists(dst):
|
||||
shutil.rmtree(dst)
|
||||
if os.path.exists(src):
|
||||
shutil.rmtree(src)
|
||||
shutil.copytree(src, dst)
|
||||
print(f"Folder {src} successfully copied")
|
||||
except shutil.Error as e:
|
||||
print(f"Error: {e}")
|
||||
|
||||
source_folder = os.path.dirname(os.path.abspath(__file__)) + "/blender" #"/home/shalenikol/web_p/blender/"
|
||||
source_folder = os.path.dirname(os.path.abspath(__file__)) + "/blender/assets/"
|
||||
|
||||
copy_and_move_folder(source_folder, args.path)
|
|
@ -4,9 +4,13 @@ import os.path
|
|||
from pathlib import Path
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--path")
|
||||
parser.add_argument("--name")
|
||||
|
||||
|
||||
parser.add_argument("--path", required=True, help="Path for dataset")
|
||||
parser.add_argument("--name", required=True, help="String with result weights name")
|
||||
parser.add_argument("--datasetName", required=True, help="String with dataset name")
|
||||
parser.add_argument("--outpath", default="weights", help="Output path for weights")
|
||||
parser.add_argument("--type", default="ObjectDetection", help="Type of implementation")
|
||||
parser.add_argument("--epoch", default=3, help="How many training epochs")
|
||||
args = parser.parse_args()
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue