mirror of
https://github.com/mealie-recipes/mealie.git
synced 2025-12-12 13:25:14 -05:00
refactor: ♻️ rewrite admin CRUD interface for admins (#825)
* docs: 📝 general documentation + add FAQ page * fix(frontend): 🐛 readd missing upload button to backups. * feat(backend): ✨ add support for backup sizes to be displayed on frontend * feat(backend): ✨ add backend for administrator CRUD of users * add admin support for user * refactor(frontend): ♻️ rewrite admin CRUD interface for admins * fix build errors Co-authored-by: hay-kot <hay-kot@pm.me>
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
from fastapi import APIRouter
|
||||
|
||||
from mealie.routes.routers import AdminAPIRouter
|
||||
from mealie.services._base_http_service.router_factory import RouterFactory
|
||||
from mealie.services.admin.admin_user_service import AdminUserService
|
||||
|
||||
from . import admin_about, admin_email, admin_group, admin_log, admin_server_tasks
|
||||
|
||||
@@ -9,5 +11,6 @@ router = AdminAPIRouter(prefix="/admin")
|
||||
router.include_router(admin_about.router, tags=["Admin: About"])
|
||||
router.include_router(admin_log.router, tags=["Admin: Log"])
|
||||
router.include_router(admin_group.router, tags=["Admin: Group"])
|
||||
router.include_router(RouterFactory(AdminUserService, prefix="/users", tags=["Admin: Users"]))
|
||||
router.include_router(admin_email.router, tags=["Admin: Email"])
|
||||
router.include_router(admin_server_tasks.router, tags=["Admin: Server Tasks"])
|
||||
|
||||
@@ -15,7 +15,6 @@ router = AdminAPIRouter(prefix="/groups")
|
||||
async def get_all_groups(session: Session = Depends(generate_session)):
|
||||
"""Returns a list of all groups in the database"""
|
||||
db = get_database(session)
|
||||
|
||||
return db.groups.get_all()
|
||||
|
||||
|
||||
|
||||
@@ -6,8 +6,6 @@ from fastapi import BackgroundTasks, Depends, File, HTTPException, UploadFile, s
|
||||
from sqlalchemy.orm.session import Session
|
||||
|
||||
from mealie.core.config import get_app_dirs
|
||||
|
||||
app_dirs = get_app_dirs()
|
||||
from mealie.core.dependencies import get_current_user
|
||||
from mealie.core.root_logger import get_logger
|
||||
from mealie.core.security import create_file_token
|
||||
@@ -18,9 +16,11 @@ from mealie.schema.user.user import PrivateUser
|
||||
from mealie.services.backups import imports
|
||||
from mealie.services.backups.exports import backup_all
|
||||
from mealie.services.events import create_backup_event
|
||||
from mealie.utils.fs_stats import pretty_size
|
||||
|
||||
router = AdminAPIRouter(prefix="/api/backups", tags=["Backups"])
|
||||
logger = get_logger()
|
||||
app_dirs = get_app_dirs()
|
||||
|
||||
|
||||
@router.get("/available", response_model=AllBackups)
|
||||
@@ -28,7 +28,7 @@ def available_imports():
|
||||
"""Returns a list of avaiable .zip files for import into Mealie."""
|
||||
imports = []
|
||||
for archive in app_dirs.BACKUP_DIR.glob("*.zip"):
|
||||
backup = BackupFile(name=archive.name, date=archive.stat().st_ctime)
|
||||
backup = BackupFile(name=archive.name, date=archive.stat().st_ctime, size=pretty_size(archive.stat().st_size))
|
||||
imports.append(backup)
|
||||
|
||||
templates = [template.name for template in app_dirs.TEMPLATE_DIR.glob("*.*")]
|
||||
@@ -118,3 +118,5 @@ def delete_backup(file_name: str):
|
||||
file_path.unlink()
|
||||
except Exception:
|
||||
raise HTTPException(status.HTTP_500_INTERNAL_SERVER_ERROR)
|
||||
|
||||
return {"message": f"{file_name} has been deleted."}
|
||||
|
||||
@@ -60,6 +60,7 @@ class CreateBackup(BaseModel):
|
||||
class BackupFile(BaseModel):
|
||||
name: str
|
||||
date: datetime
|
||||
size: str
|
||||
|
||||
|
||||
class AllBackups(BaseModel):
|
||||
|
||||
36
mealie/services/admin/admin_user_service.py
Normal file
36
mealie/services/admin/admin_user_service.py
Normal file
@@ -0,0 +1,36 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from functools import cached_property
|
||||
|
||||
from mealie.schema.user.user import UserIn, UserOut
|
||||
from mealie.services._base_http_service.crud_http_mixins import CrudHttpMixins
|
||||
from mealie.services._base_http_service.http_services import AdminHttpService
|
||||
from mealie.services.events import create_recipe_event
|
||||
|
||||
|
||||
class AdminUserService(
|
||||
CrudHttpMixins[UserOut, UserIn, UserIn],
|
||||
AdminHttpService[int, UserOut],
|
||||
):
|
||||
event_func = create_recipe_event
|
||||
_schema = UserOut
|
||||
|
||||
@cached_property
|
||||
def dal(self):
|
||||
return self.db.users
|
||||
|
||||
def populate_item(self, id: int) -> UserOut:
|
||||
self.item = self.dal.get_one(id)
|
||||
return self.item
|
||||
|
||||
def get_all(self) -> list[UserOut]:
|
||||
return self.dal.get_all()
|
||||
|
||||
def create_one(self, data: UserIn) -> UserOut:
|
||||
return self._create_one(data)
|
||||
|
||||
def update_one(self, data: UserOut, item_id: int = None) -> UserOut:
|
||||
return self._update_one(data, item_id)
|
||||
|
||||
def delete_one(self, id: int = None) -> UserOut:
|
||||
return self._delete_one(id)
|
||||
15
mealie/utils/fs_stats.py
Normal file
15
mealie/utils/fs_stats.py
Normal file
@@ -0,0 +1,15 @@
|
||||
def pretty_size(size: int) -> str:
|
||||
"""
|
||||
Pretty size takes in a integer value of a file size and returns the most applicable
|
||||
file unit and the size.
|
||||
"""
|
||||
if size < 1024:
|
||||
return f"{size} bytes"
|
||||
elif size < 1024 ** 2:
|
||||
return f"{round(size / 1024, 2)} KB"
|
||||
elif size < 1024 ** 2 * 1024:
|
||||
return f"{round(size / 1024 / 1024, 2)} MB"
|
||||
elif size < 1024 ** 2 * 1024 * 1024:
|
||||
return f"{round(size / 1024 / 1024 / 1024, 2)} GB"
|
||||
else:
|
||||
return f"{round(size / 1024 / 1024 / 1024 / 1024, 2)} TB"
|
||||
Reference in New Issue
Block a user