Add voice profile import functionality with file size validation

- Implemented a new endpoint to import voice profiles from ZIP archives.
- Added file size validation to ensure uploads do not exceed 100MB.
- Enhanced error handling for various exceptions during the import process.
- Cleaned up the import function by removing the previous implementation.
This commit is contained in:
Jamie Pine
2026-01-26 00:08:27 -08:00
parent 04bc1aded4
commit 333cb262e0
4 changed files with 35 additions and 35 deletions
+27 -27
View File
@@ -143,6 +143,33 @@ async def list_profiles(db: Session = Depends(get_db)):
return await profiles.list_profiles(db)
@app.post("/profiles/import", response_model=models.VoiceProfileResponse)
async def import_profile(
file: UploadFile = File(...),
db: Session = Depends(get_db),
):
"""Import a voice profile from a ZIP archive."""
# Validate file size (max 100MB)
MAX_FILE_SIZE = 100 * 1024 * 1024 # 100MB
# Read file content
content = await file.read()
if len(content) > MAX_FILE_SIZE:
raise HTTPException(
status_code=400,
detail=f"File too large. Maximum size is {MAX_FILE_SIZE / (1024 * 1024)}MB"
)
try:
profile = await export_import.import_profile_from_zip(content, db)
return profile
except ValueError as e:
raise HTTPException(status_code=400, detail=str(e))
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@app.get("/profiles/{profile_id}", response_model=models.VoiceProfileResponse)
async def get_profile(
profile_id: str,
@@ -265,33 +292,6 @@ async def export_profile(
raise HTTPException(status_code=500, detail=str(e))
@app.post("/profiles/import", response_model=models.VoiceProfileResponse)
async def import_profile(
file: UploadFile = File(...),
db: Session = Depends(get_db),
):
"""Import a voice profile from a ZIP archive."""
# Validate file size (max 100MB)
MAX_FILE_SIZE = 100 * 1024 * 1024 # 100MB
# Read file content
content = await file.read()
if len(content) > MAX_FILE_SIZE:
raise HTTPException(
status_code=400,
detail=f"File too large. Maximum size is {MAX_FILE_SIZE / (1024 * 1024)}MB"
)
try:
profile = await export_import.import_profile_from_zip(content, db)
return profile
except ValueError as e:
raise HTTPException(status_code=400, detail=str(e))
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
# ============================================
# GENERATION ENDPOINTS
# ============================================
+1 -4
View File
@@ -10,9 +10,6 @@ export async function GET() {
return NextResponse.json(releaseInfo);
} catch (error) {
console.error('Error fetching release info:', error);
return NextResponse.json(
{ error: 'Failed to fetch release information' },
{ status: 500 }
);
return NextResponse.json({ error: 'Failed to fetch release information' }, { status: 500 });
}
}
+7 -4
View File
@@ -65,13 +65,16 @@ export async function getLatestRelease(): Promise<ReleaseInfo> {
// Fallback: construct URLs if not found in assets
const baseUrl = `https://github.com/${GITHUB_REPO}/releases/download/${version}`;
const releaseInfo: ReleaseInfo = {
version,
downloadLinks: {
macArm: downloadLinks.macArm || `${baseUrl}/voicebox_${version.replace('v', '')}_aarch64.dmg`,
macIntel: downloadLinks.macIntel || `${baseUrl}/voicebox_${version.replace('v', '')}_x64.dmg`,
windows: downloadLinks.windows || `${baseUrl}/voicebox_${version.replace('v', '')}_x64_en-US.msi`,
macArm:
downloadLinks.macArm || `${baseUrl}/voicebox_${version.replace('v', '')}_aarch64.dmg`,
macIntel:
downloadLinks.macIntel || `${baseUrl}/voicebox_${version.replace('v', '')}_x64.dmg`,
windows:
downloadLinks.windows || `${baseUrl}/voicebox_${version.replace('v', '')}_x64_en-US.msi`,
linux: downloadLinks.linux || `${baseUrl}/voicebox_x86_64-unknown-linux-gnu.AppImage`,
},
};
Binary file not shown.