Initialize project
This commit is contained in:
52
backend/app/core/cleanup.py
Normal file
52
backend/app/core/cleanup.py
Normal file
@@ -0,0 +1,52 @@
|
||||
import shutil
|
||||
import time
|
||||
import os
|
||||
from pathlib import Path
|
||||
from apscheduler.schedulers.background import BackgroundScheduler
|
||||
|
||||
TEMP_DIR = Path("backend/temp_uploads")
|
||||
|
||||
def init_temp_dir():
|
||||
"""임시 디렉토리 생성 (없으면 생성)"""
|
||||
if not TEMP_DIR.exists():
|
||||
TEMP_DIR.mkdir(parents=True, exist_ok=True)
|
||||
print(f"Created temp directory at: {TEMP_DIR.absolute()}")
|
||||
|
||||
def cleanup_old_files(max_age_seconds: int = 600):
|
||||
"""지정된 시간(기본 10분)보다 오래된 파일/폴더 삭제"""
|
||||
if not TEMP_DIR.exists():
|
||||
return
|
||||
|
||||
now = time.time()
|
||||
deleted_count = 0
|
||||
|
||||
for item in TEMP_DIR.iterdir():
|
||||
try:
|
||||
# 최종 수정 시간 확인
|
||||
item_mtime = item.stat().st_mtime
|
||||
if now - item_mtime > max_age_seconds:
|
||||
if item.is_dir():
|
||||
shutil.rmtree(item)
|
||||
else:
|
||||
item.unlink()
|
||||
deleted_count += 1
|
||||
except Exception as e:
|
||||
print(f"Error deleting {item}: {e}")
|
||||
|
||||
if deleted_count > 0:
|
||||
print(f"Cleaned up {deleted_count} old items from temp directory.")
|
||||
|
||||
def cleanup_all():
|
||||
"""서버 시작 시 모든 임시 파일 삭제"""
|
||||
if TEMP_DIR.exists():
|
||||
shutil.rmtree(TEMP_DIR)
|
||||
init_temp_dir()
|
||||
print("Cleaned up all temporary files on startup.")
|
||||
|
||||
def start_scheduler():
|
||||
"""백그라운드 스케줄러 시작 (1분마다 정리 작업 실행)"""
|
||||
scheduler = BackgroundScheduler()
|
||||
# 10분(600초) 지난 파일 삭제 작업을 1분마다 수행
|
||||
scheduler.add_job(cleanup_old_files, 'interval', minutes=1, args=[600])
|
||||
scheduler.start()
|
||||
return scheduler
|
||||
164
backend/app/core/registry.py
Normal file
164
backend/app/core/registry.py
Normal file
@@ -0,0 +1,164 @@
|
||||
from typing import List, Optional
|
||||
from pydantic import BaseModel
|
||||
|
||||
class ToolMetadata(BaseModel):
|
||||
id: str
|
||||
name: str
|
||||
description: str
|
||||
category: str
|
||||
tags: List[str]
|
||||
type: str # 'client' or 'server'
|
||||
endpoint: Optional[str] = None # Only for server type
|
||||
|
||||
# === 도구 등록소 ===
|
||||
# 새로운 기능을 추가할 때 여기만 수정하면 검색/메뉴에 자동 반영되도록 구성합니다.
|
||||
TOOLS_REGISTRY = [
|
||||
ToolMetadata(
|
||||
id="url-parser",
|
||||
name="URL Encoder/Decoder",
|
||||
description="Encodes or decodes a URL string.",
|
||||
category="Web",
|
||||
tags=["url", "encode", "decode", "percent-encoding"],
|
||||
type="client"
|
||||
),
|
||||
ToolMetadata(
|
||||
id="json-formatter",
|
||||
name="JSON Formatter",
|
||||
description="Prettify or minify JSON data.",
|
||||
category="Data",
|
||||
tags=["json", "pretty", "minify", "format"],
|
||||
type="client"
|
||||
),
|
||||
ToolMetadata(
|
||||
id="py-uuid",
|
||||
name="UUID Generator",
|
||||
description="Generates UUIDs locally (v1/v4).",
|
||||
category="Development",
|
||||
tags=["uuid", "guid", "random", "client-side"],
|
||||
type="client"
|
||||
),
|
||||
ToolMetadata(
|
||||
id="png-compressor",
|
||||
name="PNG Compressor",
|
||||
description="Compress PNG images using pngquant (Lossy, 60-80% reduction).",
|
||||
category="Image",
|
||||
tags=["image", "png", "compress", "pngquant", "optimize"],
|
||||
type="server",
|
||||
endpoint="/api/tools/png-compress"
|
||||
),
|
||||
ToolMetadata(
|
||||
id="password-generator",
|
||||
name="Password Generator",
|
||||
description="Generate secure random passwords locally (Client-side).",
|
||||
category="Security",
|
||||
tags=["password", "random", "secure", "generator", "client-side"],
|
||||
type="client"
|
||||
),
|
||||
ToolMetadata(
|
||||
id="jwt-debugger",
|
||||
name="JWT Debugger",
|
||||
description="Decode and inspect JSON Web Tokens.",
|
||||
category="Security",
|
||||
tags=["jwt", "token", "decode", "security"],
|
||||
type="client"
|
||||
),
|
||||
ToolMetadata(
|
||||
id="cron-generator",
|
||||
name="Cron Schedule Generator",
|
||||
description="Generate and explain cron expressions.",
|
||||
category="Utility",
|
||||
tags=["cron", "schedule", "time", "generator"],
|
||||
type="client"
|
||||
),
|
||||
ToolMetadata(
|
||||
id="sql-formatter",
|
||||
name="SQL Formatter",
|
||||
description="Beautify and format SQL queries.",
|
||||
category="Formatters",
|
||||
tags=["sql", "format", "database", "query"],
|
||||
type="client"
|
||||
),
|
||||
ToolMetadata(
|
||||
id="diff-viewer",
|
||||
name="Diff Viewer",
|
||||
description="Compare text and see differences side-by-side.",
|
||||
category="Text",
|
||||
tags=["diff", "compare", "text", "code"],
|
||||
type="client"
|
||||
),
|
||||
ToolMetadata(
|
||||
id="qr-generator",
|
||||
name="QR Code Generator",
|
||||
description="Generate QR codes from text or URLs.",
|
||||
category="Generators",
|
||||
tags=["qr", "code", "generator", "image"],
|
||||
type="client"
|
||||
),
|
||||
ToolMetadata(
|
||||
id="base64-encoder",
|
||||
name="Base64 File Encoder",
|
||||
description="Convert files to Base64 strings.",
|
||||
category="Encoders",
|
||||
tags=["base64", "encode", "file", "image"],
|
||||
type="client"
|
||||
),
|
||||
ToolMetadata(
|
||||
id="json-converter",
|
||||
name="JSON Converter",
|
||||
description="Convert between JSON, CSV, and YAML.",
|
||||
category="Converters",
|
||||
tags=["json", "csv", "yaml", "convert"],
|
||||
type="client"
|
||||
),
|
||||
ToolMetadata(
|
||||
id="regex-tester",
|
||||
name="Regex Tester",
|
||||
description="Test regular expressions in real-time.",
|
||||
category="Text",
|
||||
tags=["regex", "test", "pattern", "match"],
|
||||
type="client"
|
||||
),
|
||||
ToolMetadata(
|
||||
id="docker-converter",
|
||||
name="Docker Converter",
|
||||
description="Convert between Docker Run and Docker Compose.",
|
||||
category="DevOps",
|
||||
tags=["docker", "compose", "convert", "devops"],
|
||||
type="client"
|
||||
),
|
||||
ToolMetadata(
|
||||
id="mock-data-generator",
|
||||
name="Mock Data Generator",
|
||||
description="Generate random user data for testing.",
|
||||
category="Generators",
|
||||
tags=["mock", "data", "fake", "generator"],
|
||||
type="client"
|
||||
),
|
||||
ToolMetadata(
|
||||
id="svg-optimizer",
|
||||
name="SVG Optimizer",
|
||||
description="Optimize and minify SVG code.",
|
||||
category="Image",
|
||||
tags=["svg", "optimize", "minify", "image"],
|
||||
type="client"
|
||||
),
|
||||
ToolMetadata(
|
||||
id="video-to-gif",
|
||||
name="Video to GIF",
|
||||
description="Convert video clips to GIF format.",
|
||||
category="Video",
|
||||
tags=["video", "gif", "convert", "ffmpeg"],
|
||||
type="server",
|
||||
endpoint="/api/tools/video/gif"
|
||||
)
|
||||
]
|
||||
|
||||
def search_tools(query: str = "") -> List[ToolMetadata]:
|
||||
if not query:
|
||||
return TOOLS_REGISTRY
|
||||
|
||||
q = query.lower()
|
||||
return [
|
||||
t for t in TOOLS_REGISTRY
|
||||
if q in t.name.lower() or q in t.description.lower() or any(q in tag for tag in t.tags)
|
||||
]
|
||||
Reference in New Issue
Block a user