Spaces:
Running
Running
| from fastapi import APIRouter, File, UploadFile, HTTPException | |
| from fastapi.responses import FileResponse | |
| import os | |
| from .config import Config, load_config | |
| from .main import ComicPanelExtractor | |
| import traceback | |
| from pathlib import Path | |
| import shutil | |
| import time | |
| import mimetypes | |
| config = load_config() | |
| base_output_folder = "api_outputs" | |
| output_folder = os.path.join(config.current_path, base_output_folder) | |
| app = APIRouter() | |
| def delete_folder_if_old_or_empty(parent_folder, age_days=1): | |
| """ | |
| Delete subfolders inside `parent_folder` if they are empty | |
| or older than `age_days`. | |
| Args: | |
| parent_folder (str): Path to the parent directory. | |
| age_days (int): Number of days before a folder is considered old. | |
| """ | |
| try: | |
| current_time = time.time() | |
| age_seconds = age_days * 24 * 60 * 60 | |
| # Loop through all items in the parent folder | |
| for entry in os.scandir(parent_folder): | |
| if entry.is_dir(): | |
| folder_path = entry.path | |
| # Check if folder is empty | |
| if not os.listdir(folder_path): | |
| shutil.rmtree(folder_path) | |
| print(f"Deleted empty folder: {folder_path}") | |
| continue | |
| # Check if folder is older than age_days | |
| folder_mtime = os.path.getmtime(folder_path) | |
| if current_time - folder_mtime > age_seconds: | |
| shutil.rmtree(folder_path) | |
| print(f"Deleted old folder (>{age_days} day): {folder_path}") | |
| except Exception as e: | |
| print(f"Error cleaning subfolders in {parent_folder}: {e}") | |
| async def convert_comic(file: UploadFile = File(...)): | |
| """ | |
| Upload a comic page and extract panels | |
| """ | |
| # Generate unique filename | |
| file_id = os.path.splitext(file.filename)[0] | |
| specific_output_folder = f'{output_folder}/{file_id}' | |
| shutil.rmtree(specific_output_folder, ignore_errors=True) | |
| Path(specific_output_folder).mkdir(parents=True, exist_ok=True) | |
| file_path = f'{specific_output_folder}/{file.filename}' | |
| # Save uploaded file | |
| try: | |
| content = await file.read() | |
| with open(file_path, "wb") as f: | |
| f.write(content) | |
| # π DEBUG: Log file info | |
| print("======== DEBUG: Upload Info ========") | |
| print(f"Working Dir: {os.getcwd()}") | |
| print(f"Saved file path: {file_path}") | |
| print(f"Output folder: {specific_output_folder}") | |
| print(f"List of files in output folder: {os.listdir(specific_output_folder)}") | |
| print("====================================") | |
| # Extract panels | |
| config.input_path = file_path | |
| config.output_folder = specific_output_folder | |
| print(f"[DEBUG] Setting config.input_path to: {config.input_path}") | |
| print(f"[DEBUG] Setting config.output_folder to: {config.output_folder}") | |
| _, _, all_panel_path = ComicPanelExtractor(config, reset=False).extract_panels_from_comic() | |
| all_panel_path = [f'/api/extract/{base_output_folder}/{file_id}/{os.path.basename(path)}' for path in all_panel_path] | |
| return { | |
| "success": True, | |
| "message": f"Extracted {len(all_panel_path)} panels", | |
| "panels": all_panel_path | |
| } | |
| except Exception as e: | |
| print(f"Error processing image: {str(e)} {traceback.format_exc()}") | |
| raise HTTPException(status_code=500, detail=f"Error processing image: {str(e)} {traceback.format_exc()}") | |
| async def get_output_file(folder: str, filename: str): | |
| file_path = f'{output_folder}/{folder}/{filename}' | |
| if not os.path.exists(file_path): | |
| raise HTTPException(status_code=404, detail="File not found") | |
| mime_type, _ = mimetypes.guess_type(file_path) | |
| return FileResponse(file_path, media_type=mime_type, filename=filename) |