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:
Hayden
2021-11-23 18:57:24 -09:00
committed by GitHub
parent 7afdd5b577
commit dce84c3937
32 changed files with 657 additions and 563 deletions

View File

@@ -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"])

View File

@@ -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()

View File

@@ -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."}

View File

@@ -60,6 +60,7 @@ class CreateBackup(BaseModel):
class BackupFile(BaseModel):
name: str
date: datetime
size: str
class AllBackups(BaseModel):

View 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
View 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"