Samples work in ui now

This commit is contained in:
Jaret Burkett
2025-02-21 20:28:52 -07:00
parent 2b6e66e0cb
commit 710c6de1c9
24 changed files with 408 additions and 68 deletions

View File

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

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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 {

View File

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

View File

@@ -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 {

View File

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

View File

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

View File

@@ -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 {

View File

@@ -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 {

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

View File

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

View File

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