Samples work in ui now
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { getDatasetsRoot } from '@/app/api/datasets/utils';
|
||||
import { getDatasetsRoot } from '@/server/settings';
|
||||
|
||||
export async function GET(request: NextRequest, { params }: { params: { imagePath: string } }) {
|
||||
const { imagePath } = await params;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { getDatasetsRoot } from '@/app/api/datasets/utils';
|
||||
import { getDatasetsRoot } from '@/server/settings';
|
||||
|
||||
export async function POST(request: Request) {
|
||||
try {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { getDatasetsRoot } from '@/app/api/datasets/utils';
|
||||
import { getDatasetsRoot } from '@/server/settings';
|
||||
|
||||
export async function POST(request: Request) {
|
||||
try {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import fs from 'fs';
|
||||
import { getDatasetsRoot } from '@/app/api/datasets/utils';
|
||||
import { getDatasetsRoot } from '@/server/settings';
|
||||
|
||||
export async function GET() {
|
||||
try {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { getDatasetsRoot } from '@/app/api/datasets/utils';
|
||||
import { getDatasetsRoot } from '@/server/settings';
|
||||
|
||||
export async function POST(request: Request) {
|
||||
const datasetsPath = await getDatasetsRoot();
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import { writeFile, mkdir } from 'fs/promises';
|
||||
import { join } from 'path';
|
||||
import { getDatasetsRoot } from '@/app/api/datasets/utils';
|
||||
import { getDatasetsRoot } from '@/server/settings';
|
||||
|
||||
export async function POST(request: NextRequest) {
|
||||
try {
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
import { defaultDatasetsFolder } from '@/paths';
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
export const getDatasetsRoot = async () => {
|
||||
let row = await prisma.settings.findFirst({
|
||||
where: {
|
||||
key: 'DATASETS_FOLDER',
|
||||
},
|
||||
});
|
||||
let datasetsPath = defaultDatasetsFolder;
|
||||
if (row?.value && row.value !== '') {
|
||||
datasetsPath = row.value;
|
||||
}
|
||||
return datasetsPath;
|
||||
};
|
||||
@@ -2,23 +2,25 @@
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { getDatasetsRoot } from '@/app/api/datasets/utils';
|
||||
import { getDatasetsRoot, getTrainingFolder } from '@/server/settings';
|
||||
|
||||
export async function GET(request: NextRequest, { params }: { params: { imagePath: string } }) {
|
||||
const { imagePath } = await params;
|
||||
try {
|
||||
// Decode the path
|
||||
const filepath = decodeURIComponent(imagePath);
|
||||
console.log('Serving image:', filepath);
|
||||
|
||||
// Get allowed directories
|
||||
const allowedDir = await getDatasetsRoot();
|
||||
const datasetRoot = await getDatasetsRoot();
|
||||
const trainingRoot = await getTrainingFolder();
|
||||
|
||||
const allowedDirs = [datasetRoot, trainingRoot];
|
||||
|
||||
// Security check: Ensure path is in allowed directory
|
||||
const isAllowed = filepath.startsWith(allowedDir) && !filepath.includes('..');
|
||||
const isAllowed = allowedDirs.some(allowedDir => filepath.startsWith(allowedDir)) && !filepath.includes('..');
|
||||
|
||||
if (!isAllowed) {
|
||||
console.warn(`Access denied: ${filepath} not in ${allowedDir}`);
|
||||
console.warn(`Access denied: ${filepath} not in ${allowedDirs.join(', ')}`);
|
||||
return new NextResponse('Access denied', { status: 403 });
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import fs from 'fs';
|
||||
import { getDatasetsRoot } from '@/app/api/datasets/utils';
|
||||
import { getDatasetsRoot } from '@/server/settings';
|
||||
|
||||
export async function POST(request: Request) {
|
||||
try {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import fs from 'fs';
|
||||
import { getDatasetsRoot } from '@/app/api/datasets/utils';
|
||||
import { getDatasetsRoot } from '@/server/settings';
|
||||
|
||||
export async function POST(request: Request) {
|
||||
try {
|
||||
|
||||
40
ui/src/app/api/jobs/[jobID]/samples/route.ts
Normal file
40
ui/src/app/api/jobs/[jobID]/samples/route.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
import path from 'path';
|
||||
import fs from 'fs';
|
||||
import { getTrainingFolder } from '@/server/settings';
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
export async function GET(request: NextRequest, { params }: { params: { jobID: string } }) {
|
||||
const { jobID } = await params;
|
||||
|
||||
const job = await prisma.job.findUnique({
|
||||
where: { id: jobID },
|
||||
});
|
||||
|
||||
if (!job) {
|
||||
return NextResponse.json({ error: 'Job not found' }, { status: 404 });
|
||||
}
|
||||
|
||||
// setup the training
|
||||
const trainingFolder = await getTrainingFolder();
|
||||
|
||||
const samplesFolder = path.join(trainingFolder, job.name, 'samples');
|
||||
if (!fs.existsSync(samplesFolder)) {
|
||||
return NextResponse.json({ samples: [] });
|
||||
}
|
||||
|
||||
// find all img (png, jpg, jpeg) files in the samples folder
|
||||
const samples = fs
|
||||
.readdirSync(samplesFolder)
|
||||
.filter(file => {
|
||||
return file.endsWith('.png') || file.endsWith('.jpg') || file.endsWith('.jpeg');
|
||||
})
|
||||
.map(file => {
|
||||
return path.join(samplesFolder, file);
|
||||
})
|
||||
.sort();
|
||||
|
||||
return NextResponse.json({ samples });
|
||||
}
|
||||
@@ -4,7 +4,7 @@ import { TOOLKIT_ROOT, defaultTrainFolder } from '@/paths';
|
||||
import { spawn } from 'child_process';
|
||||
import path from 'path';
|
||||
import fs from 'fs';
|
||||
|
||||
import { getTrainingFolder } from '@/server/settings';
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
@@ -30,18 +30,10 @@ export async function GET(request: NextRequest, { params }: { params: { jobID: s
|
||||
});
|
||||
|
||||
// setup the training
|
||||
const settings = await prisma.settings.findMany();
|
||||
const settingsObject = settings.reduce((acc: any, setting) => {
|
||||
acc[setting.key] = setting.value;
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
// if TRAINING_FOLDER is not set, use default
|
||||
if (!settingsObject.TRAINING_FOLDER || settingsObject.TRAINING_FOLDER === '') {
|
||||
settingsObject.TRAINING_FOLDER = defaultTrainFolder;
|
||||
}
|
||||
const trainingRoot = await getTrainingFolder();
|
||||
|
||||
const trainingFolder = path.join(settingsObject.TRAINING_FOLDER, job.name);
|
||||
const trainingFolder = path.join(trainingRoot, job.name);
|
||||
if (!fs.existsSync(trainingFolder)) {
|
||||
fs.mkdirSync(trainingFolder, { recursive: true });
|
||||
}
|
||||
@@ -53,7 +45,6 @@ export async function GET(request: NextRequest, { params }: { params: { jobID: s
|
||||
const jobConfig = JSON.parse(job.job_config);
|
||||
jobConfig.config.process[0].sqlite_db_path = path.join(TOOLKIT_ROOT, 'aitk_db.db');
|
||||
|
||||
|
||||
// write the config file
|
||||
fs.writeFileSync(configPath, JSON.stringify(jobConfig, null, 2));
|
||||
|
||||
@@ -70,7 +61,10 @@ export async function GET(request: NextRequest, { params }: { params: { jobID: s
|
||||
return NextResponse.json({ error: 'run.py not found' }, { status: 500 });
|
||||
}
|
||||
|
||||
console.log('Spawning command:', `AITK_JOB_ID=${jobID} CUDA_VISIBLE_DEVICES=${job.gpu_ids} ${pythonPath} ${runFilePath} ${configPath}`);
|
||||
console.log(
|
||||
'Spawning command:',
|
||||
`AITK_JOB_ID=${jobID} CUDA_VISIBLE_DEVICES=${job.gpu_ids} ${pythonPath} ${runFilePath} ${configPath}`,
|
||||
);
|
||||
|
||||
// start job
|
||||
const subprocess = spawn(pythonPath, [runFilePath, configPath], {
|
||||
@@ -83,7 +77,7 @@ export async function GET(request: NextRequest, { params }: { params: { jobID: s
|
||||
},
|
||||
cwd: TOOLKIT_ROOT,
|
||||
});
|
||||
|
||||
|
||||
subprocess.unref();
|
||||
|
||||
return NextResponse.json(job);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
import { defaultTrainFolder, defaultDatasetsFolder } from '@/paths';
|
||||
import {flushCache} from '@/server/settings';
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
@@ -49,6 +50,8 @@ export async function POST(request: Request) {
|
||||
}),
|
||||
]);
|
||||
|
||||
flushCache();
|
||||
|
||||
return NextResponse.json({ success: true });
|
||||
} catch (error) {
|
||||
return NextResponse.json({ error: 'Failed to update settings' }, { status: 500 });
|
||||
|
||||
Reference in New Issue
Block a user