dedc3b4183
- Full FastAPI backend with JWT auth, file management, processing pipeline, memory CRUD, barcode mappings, config management, cloud sync - Vue 3 + Element Plus frontend with dashboard, task history, HTTP logs, memory editor, barcode editor, config editor, sync page - HTTP request logging middleware with SQLite persistence - Task history tracking with progress and retry support - File metadata recording for upload/download operations - WebAuth section in config.ini for bcrypt password storage - Bug fix: logs.py count query returns tuple not dict Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
94 lines
2.9 KiB
Python
94 lines
2.9 KiB
Python
"""Cloud sync endpoints (Gitea-based)."""
|
|
|
|
from pathlib import Path
|
|
|
|
from fastapi import APIRouter, HTTPException, Depends, Request
|
|
from pydantic import BaseModel
|
|
|
|
from ..auth.dependencies import get_current_user
|
|
from ..services.task_manager import TaskManager
|
|
|
|
router = APIRouter(prefix="/api/sync", tags=["sync"])
|
|
|
|
_project_root = Path(__file__).resolve().parent.parent.parent.parent
|
|
|
|
|
|
class SyncResponse(BaseModel):
|
|
task_id: str
|
|
status: str
|
|
message: str
|
|
|
|
|
|
def _get_sync():
|
|
from app.core.utils.cloud_sync import GiteaSync
|
|
from app.config.settings import ConfigManager
|
|
cfg = ConfigManager()
|
|
return GiteaSync(cfg)
|
|
|
|
|
|
@router.post("/push", response_model=SyncResponse)
|
|
async def sync_push(
|
|
request: Request,
|
|
current_user: dict = Depends(get_current_user),
|
|
):
|
|
tm = request.state.task_manager
|
|
task = tm.create_task("推送到云端")
|
|
|
|
async def _run():
|
|
try:
|
|
tm.update_progress(task.id, 10, "正在初始化同步...")
|
|
sync = _get_sync()
|
|
tm.update_progress(task.id, 30, "正在推送文件...")
|
|
tm.add_log(task.id, "[Push] 开始推送")
|
|
result = sync.push()
|
|
tm.add_log(task.id, f"[Push] 完成: {result}")
|
|
tm.set_completed(task.id, message="推送完成")
|
|
except Exception as e:
|
|
tm.set_failed(task.id, str(e))
|
|
|
|
import asyncio
|
|
asyncio.create_task(_run())
|
|
return SyncResponse(task_id=task.id, status="accepted", message="推送任务已创建")
|
|
|
|
|
|
@router.post("/pull", response_model=SyncResponse)
|
|
async def sync_pull(
|
|
request: Request,
|
|
current_user: dict = Depends(get_current_user),
|
|
):
|
|
tm = request.state.task_manager
|
|
task = tm.create_task("从云端拉取")
|
|
|
|
async def _run():
|
|
try:
|
|
tm.update_progress(task.id, 10, "正在初始化同步...")
|
|
sync = _get_sync()
|
|
tm.update_progress(task.id, 30, "正在拉取文件...")
|
|
tm.add_log(task.id, "[Pull] 开始拉取")
|
|
result = sync.pull()
|
|
tm.add_log(task.id, f"[Pull] 完成: {result}")
|
|
tm.set_completed(task.id, message="拉取完成")
|
|
except Exception as e:
|
|
tm.set_failed(task.id, str(e))
|
|
|
|
import asyncio
|
|
asyncio.create_task(_run())
|
|
return SyncResponse(task_id=task.id, status="accepted", message="拉取任务已创建")
|
|
|
|
|
|
@router.get("/status")
|
|
async def sync_status(
|
|
current_user: dict = Depends(get_current_user),
|
|
):
|
|
try:
|
|
from app.config.settings import ConfigManager
|
|
cfg = ConfigManager()
|
|
base_url = cfg.get("Gitea", "base_url", fallback="")
|
|
owner = cfg.get("Gitea", "owner", fallback="")
|
|
repo = cfg.get("Gitea", "repo", fallback="")
|
|
enabled = bool(base_url and owner and repo)
|
|
repo_url = f"{base_url}/{owner}/{repo}" if enabled else ""
|
|
return {"enabled": enabled, "repo_url": repo_url}
|
|
except Exception:
|
|
return {"enabled": False, "repo_url": ""}
|