Feature/misc tasks (#864)

* feat(backend): 🌐 make foods/ingredients translatable

* feat(backend):  add remember me support for login - 14 days

* feat(frontend): 💄 add persistent darkmode for user sessions

* capture #859

* feat(frontend): 💄 add basic open-graph data for site links
This commit is contained in:
Hayden
2021-12-04 16:06:24 -09:00
committed by GitHub
parent c32d7d7486
commit ba4107348f
11 changed files with 323 additions and 1054 deletions

View File

@@ -3,6 +3,7 @@ from pathlib import Path
from mealie.core.root_logger import get_logger
from mealie.db.data_access_layer.access_model_factory import Database
from mealie.schema.recipe import CreateIngredientFood, CreateIngredientUnit
CWD = Path(__file__).parent
logger = get_logger(__name__)
@@ -14,21 +15,26 @@ def get_default_foods():
return foods
def get_default_units():
def get_default_units() -> dict[str, str]:
with open(CWD.joinpath("resources", "units", "en-us.json"), "r") as f:
units = json.loads(f.read())
return units
def default_recipe_unit_init(db: Database) -> None:
for unit in get_default_units():
for unit in get_default_units().values():
try:
db.ingredient_units.create(unit)
db.ingredient_units.create(
CreateIngredientUnit(
name=unit["name"], description=unit["description"], abbreviation=unit["abbreviation"]
)
)
except Exception as e:
logger.error(e)
for food in get_default_foods():
try:
db.ingredient_foods.create(food)
db.ingredient_foods.create(CreateIngredientFood(name=food, description=""))
except Exception as e:
logger.error(e)

File diff suppressed because it is too large Load Diff

View File

@@ -1,122 +1,102 @@
[
{
{
"teaspoon": {
"name": "teaspoon",
"description": "",
"fraction": true,
"abbreviation": "tsp"
},
{
"tablespoon": {
"name": "tablespoon",
"description": "",
"fraction": true,
"abbreviation": "tbsp"
},
{
"cup": {
"name": "cup",
"description": "",
"fraction": true,
"abbreviation": "cup"
},
{
"fluid-ounce": {
"name": "fluid ounce",
"description": "",
"fraction": true,
"abbreviation": "fl oz"
},
{
"pint": {
"name": "pint",
"description": "",
"fraction": true,
"abbreviation": "pt"
},
{
"quart": {
"name": "quart",
"description": "",
"fraction": true,
"abbreviation": "qt"
},
{
"gallon": {
"name": "gallon",
"description": "",
"fraction": true,
"abbreviation": "gal"
},
{
"milliliter": {
"name": "milliliter",
"description": "",
"fraction": true,
"abbreviation": "ml"
},
{
"liter": {
"name": "liter",
"description": "",
"fraction": true,
"abbreviation": "l"
},
{
"pound": {
"name": "pound",
"description": "",
"fraction": true,
"abbreviation": "lb"
},
{
"ounce": {
"name": "ounce",
"description": "",
"fraction": true,
"abbreviation": "oz"
},
{
"gram": {
"name": "gram",
"description": "",
"fraction": true,
"abbreviation": "g"
},
{
"kilogram": {
"name": "kilogram",
"description": "",
"fraction": true,
"abbreviation": "kg"
},
{
"milligram": {
"name": "milligram",
"description": "",
"fraction": true,
"abbreviation": "mg"
},
{
"splash": {
"name": "splash",
"description": "",
"fraction": true,
"abbreviation": ""
},
{
"dash": {
"name": "dash",
"description": "",
"fraction": true,
"abbreviation": ""
},
{
"serving": {
"name": "serving",
"description": "",
"fraction": true,
"abbreviation": ""
},
{
"head": {
"name": "head",
"description": "",
"fraction": true,
"abbreviation": ""
},
{
"clove": {
"name": "clove",
"description": "",
"fraction": true,
"abbreviation": ""
},
{
"can": {
"name": "can",
"description": "",
"fraction": true,
"abbreviation": ""
}
]
}

View File

@@ -1,4 +1,7 @@
from fastapi import APIRouter, BackgroundTasks, Depends, Request, status
from datetime import timedelta
from typing import Optional
from fastapi import APIRouter, BackgroundTasks, Depends, Form, Request, status
from fastapi.exceptions import HTTPException
from fastapi.security import OAuth2PasswordRequestForm
from sqlalchemy.orm.session import Session
@@ -15,12 +18,31 @@ public_router = APIRouter(tags=["Users: Authentication"])
user_router = UserAPIRouter(tags=["Users: Authentication"])
@public_router.post("/token/long")
class CustomOAuth2Form(OAuth2PasswordRequestForm):
def __init__(
self,
grant_type: str = Form(None, regex="password"),
username: str = Form(...),
password: str = Form(...),
remember_me: bool = Form(False),
scope: str = Form(""),
client_id: Optional[str] = Form(None),
client_secret: Optional[str] = Form(None),
):
self.grant_type = grant_type
self.username = username
self.password = password
self.remember_me = remember_me
self.scopes = scope.split()
self.client_id = client_id
self.client_secret = client_secret
@public_router.post("/token")
def get_token(
background_tasks: BackgroundTasks,
request: Request,
data: OAuth2PasswordRequestForm = Depends(),
data: CustomOAuth2Form = Depends(),
session: Session = Depends(generate_session),
):
email = data.username
@@ -37,7 +59,8 @@ def get_token(
headers={"WWW-Authenticate": "Bearer"},
)
access_token = security.create_access_token(dict(sub=user.email))
duration = timedelta(days=14) if data.remember_me else None
access_token = security.create_access_token(dict(sub=user.email), duration)
return {"access_token": access_token, "token_type": "bearer"}

View File

@@ -55,6 +55,8 @@ def scrape_image(image_url: str, slug: str) -> Path:
all_image_requests = []
for url in image_url:
if isinstance(url, dict):
url = url.get("url", "")
try:
r = requests.get(url, stream=True, headers={"User-Agent": _FIREFOX_UA})
except Exception: