This commit is contained in:
IDONTSUDO 2024-04-26 15:44:09 +03:00
parent e155b4a2a1
commit c4ddb3dc8c
23 changed files with 333 additions and 132 deletions

View file

@ -1,8 +1,17 @@
{ {
"cSpell.words": [ "cSpell.words": [
"введите",
"Ведите", "Ведите",
"Количество",
"может",
"навык", "навык",
"Навыки", "Навыки",
"отрицательное",
"принимать",
"скила",
"число",
"эпох",
"эпоха",
"skils", "skils",
"typedataset" "typedataset"
] ]

View 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));
}
};
}

View file

@ -6,6 +6,7 @@ import { MongoIdValidation } from "../../../core/validations/mongo_id_validation
import { DatasetDBModel } from "../models/dataset_database_model"; import { DatasetDBModel } from "../models/dataset_database_model";
import { IDatasetModel } from "../models/dataset_validation_model"; import { IDatasetModel } from "../models/dataset_validation_model";
import { ProcessWatcherAndDatabaseUpdateService } from "./create_dataset_scenario"; import { ProcessWatcherAndDatabaseUpdateService } from "./create_dataset_scenario";
import { FolderStructure } from "../../projects/domain/upload_file_to_to_project_scenario";
export class ExecDatasetProcessScenario extends CallbackStrategyWithIdQuery { export class ExecDatasetProcessScenario extends CallbackStrategyWithIdQuery {
idValidationExpression = new MongoIdValidation(); 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 ReadByIdDataBaseModelUseCase<IDatasetModel>(DatasetDBModel).call(id)).map(async (model) => {
return (await new IsHaveActiveProcessUseCase().call()).map(async () => { return (await new IsHaveActiveProcessUseCase().call()).map(async () => {
await DatasetDBModel.findById(id).updateOne({ processStatus: "RUN" }); 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( return new ExecProcessUseCase().call(
`${model.project.rootDir}/`, `${model.project.rootDir}/`,
`blenderproc run $PYTHON_BLENDER_PROC --cfg '${JSON.stringify(model)}'`, `blenderproc run $PYTHON_BLENDER_PROC --cfg '${JSON.stringify(model)}'`,

View file

@ -9,6 +9,7 @@ export class FormBuilderValidationModel {
public context: string; public context: string;
@IsArray() @IsArray()
public form: []; public form: [];
output: any;
} }
export enum ProcessStatus { export enum ProcessStatus {
END = "END", END = "END",

View file

@ -6,6 +6,14 @@ import { IProjectInstanceModel } from "../models/project_instance_database_model
import { ReadByIdDataBaseModelUseCase } from "../../../core/usecases/read_by_id_database_model_usecase"; import { ReadByIdDataBaseModelUseCase } from "../../../core/usecases/read_by_id_database_model_usecase";
import { ProjectDBModel } from "../../_projects/models/project_database_model"; import { ProjectDBModel } from "../../_projects/models/project_database_model";
import { ExecProcessUseCase } from "../../../core/usecases/exec_process_usecase"; 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 { export class UploadCadFileToProjectScenario extends CallbackStrategyWithFileUpload {
checkingFileExpression: RegExp = new RegExp(".FCStd"); checkingFileExpression: RegExp = new RegExp(".FCStd");
@ -14,12 +22,17 @@ export class UploadCadFileToProjectScenario extends CallbackStrategyWithFileUplo
async call(file: IFile, id: string): ResponseBase { async call(file: IFile, id: string): ResponseBase {
return (await new ReadByIdDataBaseModelUseCase<IProjectInstanceModel>(ProjectDBModel).call(id)).map( return (await new ReadByIdDataBaseModelUseCase<IProjectInstanceModel>(ProjectDBModel).call(id)).map(
async (databaseModel) => async (databaseModel) =>
(await new CreateFileUseCase().call(`${databaseModel.rootDir}/${file.name}`, file.data)).map( (await new CreateFileUseCase().call(`${databaseModel.rootDir}/${file.name}`, file.data)).map(async () =>
async () => (
await new ExecProcessUseCase().call( await new ExecProcessUseCase().call(
`${databaseModel.rootDir}/`, `${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")
)
) )
) )
); );

View file

@ -13,14 +13,16 @@ export class ExecWeightProcessScenario extends CallbackStrategyWithIdQuery {
return (await new ReadByIdDataBaseModelUseCase<IWeightModel>(WeightDBModel).call(id)).map(async (model) => { return (await new ReadByIdDataBaseModelUseCase<IWeightModel>(WeightDBModel).call(id)).map(async (model) => {
return (await new IsHaveActiveProcessUseCase().call()).map(async () => { return (await new IsHaveActiveProcessUseCase().call()).map(async () => {
await WeightDBModel.findById(id).updateOne({ processStatus: "RUN" }); await WeightDBModel.findById(id).updateOne({ processStatus: "RUN" });
if (typeof model.project === "object" && typeof model.datasetId === "object") { if (typeof model.project === "object" && typeof model.datasetId === "object") {
console.log( if (model.processStatus === "exec") {
`python3 $PYTHON_EDUCATION --path ${model.project.rootDir} --name ${model.name} --datasetName ${model.datasetId.name}` console.log(20);
); }
if (model.processStatus === "new") {
console.log(20);
}
return new ExecProcessUseCase().call( return new ExecProcessUseCase().call(
`${model.project.rootDir}/`, `${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, id,
new ProcessWatcherAndDatabaseUpdateService(id as unknown as ObjectId, WeightDBModel) new ProcessWatcherAndDatabaseUpdateService(id as unknown as ObjectId, WeightDBModel)
); );

View file

@ -1,11 +1,12 @@
import { IsMongoId, IsString } from "class-validator"; import { IsNumber, IsString } from "class-validator";
import { IWeightModel } from "./weights_validation_model"; import { IWeightModel } from "./weights_validation_model";
export class WeightValidationModel implements IWeightModel { export class WeightValidationModel implements IWeightModel {
public processStatus: string;
@IsNumber()
public epoch: number;
@IsString() @IsString()
public name: string; public name: string;
@IsMongoId()
public datasetId: string; public datasetId: string;
@IsMongoId()
public project: string; public project: string;
} }

View file

@ -7,6 +7,8 @@ export interface IWeightModel {
name: string; name: string;
datasetId: string | IDatasetModel; datasetId: string | IDatasetModel;
project: string | IProjectModel; project: string | IProjectModel;
processStatus: string;
epoch: number;
} }
export const WeightSchema = new Schema({ export const WeightSchema = new Schema({
name: { name: {
@ -22,11 +24,15 @@ export const WeightSchema = new Schema({
type: String, type: String,
default: "none", default: "none",
}, },
// the user selects // the user selects
isFinished: { isFinished: {
type: Boolean, type: Boolean,
default: false, default: false,
}, },
epoch:{
type:Number,
},
datasetId: { datasetId: {
type: Schema.Types.ObjectId, type: Schema.Types.ObjectId,
ref: datasetSchema, ref: datasetSchema,

View file

@ -5,6 +5,7 @@ import { extensions } from "./core/extensions/extensions";
import { httpRoutes } from "./core/controllers/routes"; import { httpRoutes } from "./core/controllers/routes";
import { executorProgramService } from "./core/usecases/exec_process_usecase"; import { executorProgramService } from "./core/usecases/exec_process_usecase";
extensions(); extensions();
const socketSubscribers = [new SocketSubscriber(executorProgramService, "realtime")]; const socketSubscribers = [new SocketSubscriber(executorProgramService, "realtime")];

View file

@ -26,7 +26,9 @@ declare global {
toPx(): string; toPx(): string;
unixFromDate(): string; unixFromDate(): string;
isValid(str: string): boolean; isValid(str: string): boolean;
randRange(min:number,max:number):number randRange(min: number, max: number): number;
isPositive(): boolean;
isNegative(): boolean;
} }
interface String { interface String {

View file

@ -28,6 +28,18 @@ export const NumberExtensions = () => {
// eslint-disable-next-line no-extend-native // 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; 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()
} }
} }
}; };

View file

@ -2,9 +2,13 @@ import { NavigateFunction } from "react-router-dom";
import { Result } from "../helper/result"; import { Result } from "../helper/result";
import { UiBaseError } from "../model/ui_base_error"; import { UiBaseError } from "../model/ui_base_error";
import { HttpError } from "../repository/http_repository"; import { HttpError } from "../repository/http_repository";
import { message } from "antd";
export type CoreError = HttpError | Error; export type CoreError = HttpError | Error;
interface IMessage {
successMessage?: string;
errorMessage?: string;
}
export abstract class UiLoader { export abstract class UiLoader {
isLoading = false; isLoading = false;
async httpHelper<T>(callBack: Promise<Result<any, T>>) { 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 { export class SimpleErrorState extends UiLoader {
errorHandingStrategy = () => { errorHandingStrategy = () => {

View file

@ -2,7 +2,6 @@ import makeAutoObservable from "mobx-store-inheritance";
import { ProjectRepository, UUID } from "../data/project_repository"; import { ProjectRepository, UUID } from "../data/project_repository";
import { IProjectModel } from "../model/project_model"; import { IProjectModel } from "../model/project_model";
import { SimpleErrorState } from "../../../core/store/base_store"; import { SimpleErrorState } from "../../../core/store/base_store";
import { ActivePipeline } from "../../../core/model/active_pipeline";
interface IProjectView { interface IProjectView {
isActive: boolean; isActive: boolean;

View file

@ -8,7 +8,7 @@ import type { MenuProps } from "antd";
import { Dropdown } from "antd"; import { Dropdown } from "antd";
import { ProcessStatus } from "./dataset_model"; import { ProcessStatus } from "./dataset_model";
interface IMenuItem { export interface IMenuItem {
onClick: Function; onClick: Function;
name: string; name: string;
} }

View file

@ -6,6 +6,7 @@ export enum ProcessStatus {
ERROR = "ERROR", ERROR = "ERROR",
NEW = "NEW", NEW = "NEW",
RUN = "RUN", RUN = "RUN",
NONE = "none"
} }
export interface IDatasetModel { export interface IDatasetModel {

View file

@ -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>
);
};

View 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>
);
};

View 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);
}
}

View file

@ -2,8 +2,9 @@ import { Result } from "../../core/helper/result";
import { HttpError, HttpMethod, HttpRepository } from "../../core/repository/http_repository"; import { HttpError, HttpMethod, HttpRepository } from "../../core/repository/http_repository";
import { UUID } from "../all_projects/data/project_repository"; import { UUID } from "../all_projects/data/project_repository";
import { IDatasetModel } from "../dataset/dataset_model"; import { IDatasetModel } from "../dataset/dataset_model";
import { SkillModel } from "./skills_store"; import { SkillModel } from "./skill_model";
export interface IEducations {
export interface ISkils {
_id: string; _id: string;
name: string; name: string;
processStatus: string; processStatus: string;
@ -13,13 +14,20 @@ export interface IEducations {
__v: number; __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 () => { getAllSkills = async () => {
return this._jsonRequest<IEducations[]>(HttpMethod.GET, "/weights"); return this._jsonRequest<ISkils[]>(HttpMethod.GET, "/weights");
}; };
deleteSkill = async (id: string) => { deleteSkill = async (id: string) => {
return this._jsonRequest<void>(HttpMethod.DELETE, `/weights?id=${id}`); return this._jsonRequest<void>(HttpMethod.DELETE, `/weights?id=${id}`);
}; };
addNewSkill = async (model: SkillModel) => { addNewSkill = async (model: SkillModel) => {
return this._jsonRequest(HttpMethod.POST, "/weights", model); return this._jsonRequest(HttpMethod.POST, "/weights", model);
}; };

View file

@ -1,10 +1,10 @@
import React from "react"; import React from "react";
import { Drawer } from "antd";
import { observer } from "mobx-react-lite";
import { MainPage } from "../../core/ui/pages/main_page"; import { MainPage } from "../../core/ui/pages/main_page";
import { CoreText, CoreTextType } from "../../core/ui/text/text"; import { CoreText, CoreTextType } from "../../core/ui/text/text";
import { DrawersSkill, SkillStore } from "./skills_store"; import { DrawersSkill, SkillStore } from "./skills_store";
import { observer } from "mobx-react-lite"; import { SkillCard } from "./skill_card";
import { SkillCard } from "./skil_card";
import { Drawer } from "antd";
import { CoreInput } from "../../core/ui/input/input"; import { CoreInput } from "../../core/ui/input/input";
import { CoreButton } from "../../core/ui/button/button"; import { CoreButton } from "../../core/ui/button/button";
import { CoreSwitch } from "../../core/ui/switch/switch"; import { CoreSwitch } from "../../core/ui/switch/switch";
@ -17,6 +17,7 @@ interface IItem {
const skills: IItem[] = [{ name: "ML", isActive: true }]; const skills: IItem[] = [{ name: "ML", isActive: true }];
export const SkillPath = "/skills"; export const SkillPath = "/skills";
export const SkillScreen = observer(() => { export const SkillScreen = observer(() => {
const [store] = React.useState(() => new SkillStore()); const [store] = React.useState(() => new SkillStore());
@ -47,7 +48,7 @@ export const SkillScreen = observer(() => {
}} }}
> >
{store.skils?.map((el) => ( {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)} /> <SkillCard empty={true} emptyOnClick={() => store.edtDrawer(DrawersSkill.NEW_SKILL, true)} />
</div> </div>
@ -61,6 +62,11 @@ export const SkillScreen = observer(() => {
> >
<div style={{ display: "flex", flexDirection: "column", justifyContent: "space-between", height: "100%" }}> <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.name} label={"Имя навыка"} onChange={(e) => store.changeSkillName(e)} />
<CoreInput
value={store.skill.epoch.toString()}
label="Количество эпох"
onChange={(e) => store.changeEpoch(Number(e))}
/>
<div style={{ height: "100%" }}> <div style={{ height: "100%" }}>
{store.datasets?.map((el) => ( {store.datasets?.map((el) => (
<div <div

View file

@ -1,38 +1,18 @@
import makeAutoObservable from "mobx-store-inheritance";
import { NavigateFunction } from "react-router-dom"; import { NavigateFunction } from "react-router-dom";
import { HttpError } from "../../core/repository/http_repository"; import { HttpError } from "../../core/repository/http_repository";
import { UiErrorState } from "../../core/store/base_store"; import { UiErrorState } from "../../core/store/base_store";
import makeAutoObservable from "mobx-store-inheritance"; import { ISkils, SkillsHttpRepository } from "./skills_repository";
import { IEducations as ISkils, SkillsRepository as SkillsHttpRepository } from "./skills_repository";
import { Drawer } from "../dataset/dataset_store"; import { Drawer } from "../dataset/dataset_store";
import { IDatasetModel } from "../dataset/dataset_model"; import { IDatasetModel } from "../dataset/dataset_model";
import { Result } from "../../core/helper/result";
import { message } from "antd"; import { message } from "antd";
import { UUID } from "../all_projects/data/project_repository"; import { UUID } from "../all_projects/data/project_repository";
import { SkillModel } from "./skill_model";
export enum DrawersSkill { export enum DrawersSkill {
NEW_SKILL = "Новый навык", 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> { export class SkillStore extends UiErrorState<HttpError> {
drawers: Drawer[]; drawers: Drawer[];
skillsHttpRepository: SkillsHttpRepository; skillsHttpRepository: SkillsHttpRepository;
@ -54,6 +34,27 @@ export class SkillStore extends UiErrorState<HttpError> {
this.skillsHttpRepository = new SkillsHttpRepository(); this.skillsHttpRepository = new SkillsHttpRepository();
makeAutoObservable(this); 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) => {}; errorHandingStrategy: (error: HttpError) => {};
init = async (navigate?: NavigateFunction | undefined) => { init = async (navigate?: NavigateFunction | undefined) => {
await this.mapOk("skils", this.skillsHttpRepository.getAllSkills()); await this.mapOk("skils", this.skillsHttpRepository.getAllSkills());
@ -63,8 +64,10 @@ export class SkillStore extends UiErrorState<HttpError> {
changeSkillName(name: string): void { changeSkillName(name: string): void {
this.skill.name = name; this.skill.name = name;
} }
changeEpoch(epoch: number) {
this.skill.epoch = epoch;
}
saveSkill() { saveSkill() {
console.log(this.activeProjectId);
this.skill.project = this.activeProjectId?.id ?? ""; this.skill.project = this.activeProjectId?.id ?? "";
this.skill.valid().fold( this.skill.valid().fold(
async (model) => { async (model) => {

View file

@ -8,13 +8,13 @@ args = parser.parse_args()
def copy_and_move_folder(src, dst): def copy_and_move_folder(src, dst):
try: try:
if os.path.exists(dst): if os.path.exists(src):
shutil.rmtree(dst) shutil.rmtree(src)
shutil.copytree(src, dst) shutil.copytree(src, dst)
print(f"Folder {src} successfully copied") print(f"Folder {src} successfully copied")
except shutil.Error as e: except shutil.Error as e:
print(f"Error: {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) copy_and_move_folder(source_folder, args.path)

View file

@ -4,9 +4,13 @@ import os.path
from pathlib import Path from pathlib import Path
parser = argparse.ArgumentParser() 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() args = parser.parse_args()