feature/debug-info (#286)

* rename 'ENV' to 'PRODUCTION' and default to true

* set env PRODUCTION

* refactor file download process

* add last_recipe.json and log downloads

* changelog + version bump

* set env on workflows

* bump version

Co-authored-by: hay-kot <hay-kot@pm.me>
This commit is contained in:
Hayden
2021-04-10 21:42:04 -08:00
committed by GitHub
parent b3b1778890
commit 2a158ab290
18 changed files with 191 additions and 53 deletions

View File

@@ -1,10 +1,12 @@
import operator
import shutil
from typing import Optional
from fastapi import APIRouter, Depends, File, HTTPException, UploadFile
from mealie.core.config import app_dirs
from mealie.core.security import create_file_token
from mealie.db.db_setup import generate_session
from mealie.routes.deps import get_current_user
from mealie.routes.deps import get_current_user, validate_file_token
from mealie.schema.backup import BackupJob, ImportJob, Imports, LocalBackup
from mealie.schema.snackbar import SnackResponse
from mealie.services.backups import imports
@@ -68,13 +70,10 @@ def upload_backup_file(archive: UploadFile = File(...)):
@router.get("/{file_name}/download")
async def download_backup_file(file_name: str):
""" Upload a .zip File to later be imported into Mealie """
""" Returns a token to download a file """
file = app_dirs.BACKUP_DIR.joinpath(file_name)
if file.is_file:
return FileResponse(file, media_type="application/octet-stream", filename=file_name)
else:
return SnackResponse.error("No File Found")
return {"fileToken": create_file_token(file)}
@router.post("/{file_name}/import", status_code=200)

View File

@@ -3,6 +3,7 @@ import json
from fastapi import APIRouter, Depends
from mealie.core.config import APP_VERSION, app_dirs, settings
from mealie.core.root_logger import LOGGER_FILE
from mealie.core.security import create_file_token
from mealie.routes.deps import get_current_user
from mealie.schema.debug import AppInfo, DebugInfo
@@ -37,10 +38,8 @@ async def get_mealie_version():
@router.get("/last-recipe-json")
async def get_last_recipe_json(current_user=Depends(get_current_user)):
""" Doc Str """
with open(app_dirs.DEBUG_DIR.joinpath("last_recipe.json"), "r") as f:
return json.loads(f.read())
""" Returns a token to download a file """
return {"fileToken": create_file_token(app_dirs.DEBUG_DIR.joinpath("last_recipe.json"))}
@router.get("/log/{num}")
@@ -51,6 +50,12 @@ async def get_log(num: int, current_user=Depends(get_current_user)):
return log_text
@router.get("/log")
async def get_log_file():
""" Returns a token to download a file """
return {"fileToken": create_file_token(LOGGER_FILE)}
def tail(f, lines=20):
total_lines_wanted = lines

View File

@@ -1,3 +1,6 @@
from pathlib import Path
from typing import Optional
from fastapi import Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer
from jose import JWTError, jwt
@@ -25,7 +28,25 @@ async def get_current_user(token: str = Depends(oauth2_scheme), session=Depends(
token_data = TokenData(username=username)
except JWTError:
raise credentials_exception
user = db.users.get(session, token_data.username, "email")
if user is None:
raise credentials_exception
return user
async def validate_file_token(token: Optional[str] = None) -> Path:
credentials_exception = HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="could not validate file token",
)
if not token:
return None
try:
payload = jwt.decode(token, settings.SECRET, algorithms=[ALGORITHM])
file_path = Path(payload.get("file"))
except JWTError:
raise credentials_exception
return file_path

View File

@@ -0,0 +1,20 @@
from pathlib import Path
from typing import Optional
from fastapi import APIRouter, Depends
from mealie.routes.deps import validate_file_token
from mealie.schema.snackbar import SnackResponse
from starlette.responses import FileResponse
router = APIRouter(prefix="/api/utils", tags=["Utils"], include_in_schema=True)
@router.get("/download")
async def download_file(file_path: Optional[Path] = Depends(validate_file_token)):
""" Uses a file token obtained by an active user to retrieve a file from the operating
system. """
print("File Name:", file_path)
if file_path.is_file():
return FileResponse(file_path, media_type="application/octet-stream", filename=file_path.name)
else:
return SnackResponse.error("No File Found")