main.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. import os
  2. import subprocess
  3. import shutil
  4. from typing import Optional
  5. from fastapi import FastAPI, UploadFile, HTTPException
  6. from fastapi.responses import JSONResponse, FileResponse
  7. from fastapi.staticfiles import StaticFiles
  8. from obs import ObsClient
  9. from dotenv import load_dotenv
  10. # Load environment variables
  11. load_dotenv()
  12. app = FastAPI()
  13. # Mount static files
  14. app.mount("/static", StaticFiles(directory="static"), name="static")
  15. # OBS configuration
  16. ACCESS_KEY = os.getenv('OBS_ACCESS_KEY')
  17. SECRET_KEY = os.getenv('OBS_SECRET_KEY')
  18. ENDPOINT = os.getenv('OBS_ENDPOINT')
  19. BUCKET = os.getenv('OBS_BUCKET')
  20. # File paths
  21. UPLOAD_DIR = "/app/uploads"
  22. PROCESSED_DIR = "/app/processed"
  23. # Ensure directories exist
  24. os.makedirs(UPLOAD_DIR, exist_ok=True)
  25. os.makedirs(PROCESSED_DIR, exist_ok=True)
  26. def get_obs_client() -> ObsClient:
  27. return ObsClient(
  28. access_key_id=ACCESS_KEY,
  29. secret_access_key=SECRET_KEY,
  30. server=ENDPOINT
  31. )
  32. @app.get("/")
  33. async def root():
  34. return FileResponse("static/index.html")
  35. @app.post("/convert")
  36. async def convert_eps_to_svg(file: UploadFile):
  37. # Check file size (10MB limit)
  38. file_size = 0
  39. content = await file.read()
  40. file_size = len(content)
  41. if file_size > 10 * 1024 * 1024: # 10MB
  42. raise HTTPException(status_code=400, detail="File too large. Maximum size is 10MB")
  43. # Check file extension
  44. if not file.filename.lower().endswith('.eps'):
  45. raise HTTPException(status_code=400, detail="Only EPS files are accepted")
  46. try:
  47. # Ensure directories exist and are writable
  48. for directory in [UPLOAD_DIR, PROCESSED_DIR]:
  49. if not os.path.exists(directory):
  50. os.makedirs(directory, exist_ok=True)
  51. if not os.access(directory, os.W_OK):
  52. raise HTTPException(status_code=500, detail=f"Directory {directory} is not writable")
  53. # Save uploaded file
  54. input_path = os.path.join(UPLOAD_DIR, file.filename)
  55. with open(input_path, "wb") as f:
  56. f.write(content)
  57. # Generate output paths
  58. base_name = os.path.splitext(file.filename)[0]
  59. temp_svg = os.path.join(PROCESSED_DIR, f"{base_name}_temp.svg")
  60. final_svg = os.path.join(PROCESSED_DIR, f"{base_name}.svg")
  61. # Convert EPS to SVG
  62. try:
  63. subprocess.run(['eps2svg', input_path, temp_svg], check=True, capture_output=True, text=True)
  64. except subprocess.CalledProcessError as e:
  65. raise HTTPException(status_code=500, detail=f"eps2svg conversion failed: {e.stderr}")
  66. # Check if temp_svg was created
  67. if not os.path.exists(temp_svg):
  68. raise HTTPException(status_code=500, detail="eps2svg failed to create output file")
  69. # Try to optimize SVG using scour
  70. try:
  71. subprocess.run(['scour', '-i', temp_svg, '-o', final_svg], check=True)
  72. except subprocess.CalledProcessError:
  73. # If scour fails, use the unoptimized SVG
  74. shutil.copy(temp_svg, final_svg)
  75. print("Scour optimization failed, using unoptimized SVG")
  76. # Upload to OBS
  77. obs_client = get_obs_client()
  78. obs_key = f"svg/{base_name}.svg"
  79. with open(final_svg, 'rb') as f:
  80. obs_client.putContent(BUCKET, obs_key, f.read())
  81. # Clean up files
  82. os.remove(input_path)
  83. os.remove(temp_svg)
  84. os.remove(final_svg)
  85. return JSONResponse({
  86. "status": "success",
  87. "message": "File processed successfully",
  88. "obs_key": obs_key
  89. })
  90. except subprocess.CalledProcessError as e:
  91. raise HTTPException(status_code=500, detail=f"Error processing file: {str(e)}")
  92. except Exception as e:
  93. raise HTTPException(status_code=500, detail=f"An error occurred: {str(e)}")
  94. @app.get("/health")
  95. def health_check():
  96. return {"status": "healthy"}