se agregaron nuevas caracteristicas
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy import select
|
||||
from app.models.models import SystemSetting
|
||||
from app.core.config import settings
|
||||
from pathlib import Path
|
||||
import os
|
||||
|
||||
DEFAULT_SETTINGS = {
|
||||
"storage_root": settings.STORAGE_ROOT,
|
||||
"global_quota_gb": "1000",
|
||||
"default_client_quota_gb": "100",
|
||||
"default_keep_daily": str(settings.DEFAULT_RETENTION_DAILY),
|
||||
"default_keep_weekly": str(settings.DEFAULT_RETENTION_WEEKLY),
|
||||
"default_keep_monthly": str(settings.DEFAULT_RETENTION_MONTHLY),
|
||||
}
|
||||
|
||||
async def get_setting(db: AsyncSession, key: str) -> str:
|
||||
result = await db.execute(select(SystemSetting).where(SystemSetting.key == key))
|
||||
setting = result.scalar_one_or_none()
|
||||
if setting:
|
||||
return setting.value
|
||||
return DEFAULT_SETTINGS.get(key, "")
|
||||
|
||||
async def get_all_settings(db: AsyncSession) -> dict:
|
||||
result = await db.execute(select(SystemSetting))
|
||||
db_settings = {s.key: s.value for s in result.scalars().all()}
|
||||
|
||||
# Merge defaults and add them if not present in db
|
||||
updated = False
|
||||
for k, v in DEFAULT_SETTINGS.items():
|
||||
if k not in db_settings:
|
||||
db_settings[k] = v
|
||||
db.add(SystemSetting(key=k, value=v))
|
||||
updated = True
|
||||
if updated:
|
||||
await db.commit()
|
||||
return db_settings
|
||||
|
||||
async def update_settings_service(db: AsyncSession, new_settings: dict) -> dict:
|
||||
from app.storage.local import storage_provider
|
||||
|
||||
for k, v in new_settings.items():
|
||||
if k in DEFAULT_SETTINGS and v is not None:
|
||||
# If changing storage root, validate and apply
|
||||
if k == "storage_root":
|
||||
path = Path(v).resolve()
|
||||
try:
|
||||
os.makedirs(path, exist_ok=True)
|
||||
# Test write access
|
||||
test_file = path / ".write_test"
|
||||
test_file.touch()
|
||||
test_file.unlink()
|
||||
except Exception as e:
|
||||
raise ValueError(f"Invalid or unwritable storage root path: {str(e)}")
|
||||
|
||||
# Apply to in-memory storage provider
|
||||
storage_provider.root_dir = path
|
||||
|
||||
result = await db.execute(select(SystemSetting).where(SystemSetting.key == k))
|
||||
setting = result.scalar_one_or_none()
|
||||
if setting:
|
||||
setting.value = str(v)
|
||||
else:
|
||||
db.add(SystemSetting(key=k, value=str(v)))
|
||||
|
||||
await db.commit()
|
||||
return await get_all_settings(db)
|
||||
@@ -24,6 +24,28 @@ async def create_or_resume_session(
|
||||
"""
|
||||
total_chunks = max(1, math.ceil(file_size / chunk_size))
|
||||
|
||||
# 1. Check client quota
|
||||
if client.storage_used_bytes + file_size > client.storage_quota_bytes:
|
||||
raise ValueError(
|
||||
f"Client storage quota exceeded. Limit: {client.storage_quota_bytes} bytes. Attempted to upload: {file_size} bytes."
|
||||
)
|
||||
|
||||
# 2. Check global quota
|
||||
from app.services.settings_service import get_setting
|
||||
from sqlalchemy import func
|
||||
global_quota_gb_str = await get_setting(db, "global_quota_gb")
|
||||
if global_quota_gb_str:
|
||||
try:
|
||||
global_quota_bytes = int(global_quota_gb_str) * 1024 * 1024 * 1024
|
||||
used_res = await db.execute(select(func.sum(Client.storage_used_bytes)))
|
||||
total_used_bytes = used_res.scalar() or 0
|
||||
if total_used_bytes + file_size > global_quota_bytes:
|
||||
raise ValueError(
|
||||
f"Global storage quota exceeded. Limit: {global_quota_bytes} bytes. Current used: {total_used_bytes} bytes."
|
||||
)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
# Check for existing incomplete session for this client and file hash
|
||||
query = (
|
||||
select(BackupSession)
|
||||
@@ -193,6 +215,8 @@ async def complete_session(
|
||||
job = job_res.scalar_one_or_none()
|
||||
if job:
|
||||
job_code = job.job_code
|
||||
job.status = "RUNNING"
|
||||
job.last_run_at = datetime.now(timezone.utc)
|
||||
|
||||
session.status = "ASSEMBLING"
|
||||
await db.commit()
|
||||
@@ -230,6 +254,12 @@ async def complete_session(
|
||||
client.storage_used_bytes += total_bytes
|
||||
client.last_backup_at = datetime.now(timezone.utc)
|
||||
|
||||
if session.job_id:
|
||||
job_res = await db.execute(select(BackupJob).where(BackupJob.id == session.job_id))
|
||||
job = job_res.scalar_one_or_none()
|
||||
if job:
|
||||
job.status = "SUCCESS"
|
||||
|
||||
await db.commit()
|
||||
await db.refresh(backup_file)
|
||||
|
||||
@@ -263,6 +293,16 @@ async def complete_session(
|
||||
except Exception as ex:
|
||||
session.status = "FAILED"
|
||||
session.error_message = str(ex)
|
||||
|
||||
if session.job_id:
|
||||
try:
|
||||
job_res = await db.execute(select(BackupJob).where(BackupJob.id == session.job_id))
|
||||
job = job_res.scalar_one_or_none()
|
||||
if job:
|
||||
job.status = "FAILED"
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
await db.commit()
|
||||
|
||||
await log_event(
|
||||
|
||||
Reference in New Issue
Block a user