aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Chris Lovering <[email protected]>2024-08-25 00:16:18 +0100
committerGravatar Chris Lovering <[email protected]>2024-08-25 00:16:18 +0100
commit9ffe5f25bdaa5f251ddd6d253af75c1c588af526 (patch)
treeff18b525106815f39b5c604cfadff5412d8d4262
parentAdd an admin endpoint for syncing templates & variants from printful (diff)
Add a new route to fetch templates and variants
-rw-r--r--thallium-backend/src/auth.py5
-rw-r--r--thallium-backend/src/dto/__init__.py13
-rw-r--r--thallium-backend/src/dto/templates.py32
-rw-r--r--thallium-backend/src/dto/users.py4
-rw-r--r--thallium-backend/src/routes/templates.py29
5 files changed, 72 insertions, 11 deletions
diff --git a/thallium-backend/src/auth.py b/thallium-backend/src/auth.py
index 7b9a0fa..56987a8 100644
--- a/thallium-backend/src/auth.py
+++ b/thallium-backend/src/auth.py
@@ -138,10 +138,13 @@ class HasPermission:
Raises MissingPermissions if not.
"""
- def __init__(self, required_permissions: UserPermission) -> None:
+ def __init__(self, required_permissions: UserPermission, *, allow_vouchers: bool = False) -> None:
self.required_permissions = required_permissions
+ self.allow_vouchers = allow_vouchers
async def __call__(self, request: Request) -> None:
"""Check the requesting user has all specified permissions."""
+ if hasattr(request.state, "voucher") and self.allow_vouchers:
+ return
if not request.state.user.permissions & self.required_permissions == self.required_permissions:
raise MissingPermissionsError
diff --git a/thallium-backend/src/dto/__init__.py b/thallium-backend/src/dto/__init__.py
index 2a53355..1392017 100644
--- a/thallium-backend/src/dto/__init__.py
+++ b/thallium-backend/src/dto/__init__.py
@@ -1,5 +1,16 @@
from .login import VoucherClaim, VoucherLogin
+from .templates import Template, TemplateWithVariant, Variant
from .users import User, UserPermission
from .vouchers import Voucher
-__all__ = ("LoginData", "User", "UserPermission", "Voucher", "VoucherClaim", "VoucherLogin")
+__all__ = (
+ "LoginData",
+ "User",
+ "UserPermission",
+ "Voucher",
+ "VoucherClaim",
+ "VoucherLogin",
+ "Template",
+ "TemplateWithVariant",
+ "Variant",
+)
diff --git a/thallium-backend/src/dto/templates.py b/thallium-backend/src/dto/templates.py
new file mode 100644
index 0000000..48ab685
--- /dev/null
+++ b/thallium-backend/src/dto/templates.py
@@ -0,0 +1,32 @@
+from datetime import datetime
+from decimal import Decimal
+
+from pydantic import BaseModel
+
+
+class Template(BaseModel):
+ """Base model for a template."""
+
+ template_id: int
+ title: str
+ product_id: int
+ mockup_file_url: str
+ last_synced: datetime
+
+
+class Variant(BaseModel):
+ """Base model for a template."""
+
+ variant_id: int
+ name: str
+ size: str
+ colour: str
+ colour_code: str
+ price: Decimal
+ last_synced: datetime
+
+
+class TemplateWithVariant(Template):
+ """A voucher as stored in the database."""
+
+ variants: list[Variant]
diff --git a/thallium-backend/src/dto/users.py b/thallium-backend/src/dto/users.py
index 35eadec..8faf4e7 100644
--- a/thallium-backend/src/dto/users.py
+++ b/thallium-backend/src/dto/users.py
@@ -10,8 +10,8 @@ class UserPermission(IntFlag):
VIEW_VOUCHERS = 2**0
ISSUE_VOUCHERS = 2**1
REVOKE_VOUCHERS = 2**1
- VIEW_PRODUCTS = 2**2
- MANAGE_USERS = 2**3
+ MANAGE_USERS = 2**2
+ VIEW_TEMPLATES = 2**3
UPDATE_TEMPLATES = 2**4
diff --git a/thallium-backend/src/routes/templates.py b/thallium-backend/src/routes/templates.py
index 7dad7f7..e928745 100644
--- a/thallium-backend/src/routes/templates.py
+++ b/thallium-backend/src/routes/templates.py
@@ -1,16 +1,31 @@
import logging
from fastapi import APIRouter, Depends
+from sqlalchemy import select
+from sqlalchemy.orm import joinedload
-from src.auth import TokenAuth
-from src.settings import PrintfulClient
+from src.auth import HasPermission, TokenAuth, UserPermission
+from src.dto import Template, TemplateWithVariant
+from src.orm import Template as DBTemplate
+from src.settings import DBSession
-router = APIRouter(tags=["Printful"], prefix="/printful", dependencies=[Depends(TokenAuth(allow_regular_users=True))])
+router = APIRouter(
+ tags=["Templates"],
+ prefix="/templates",
+ dependencies=[Depends(TokenAuth(allow_regular_users=True, allow_vouchers=True))],
+)
log = logging.getLogger(__name__)
[email protected]("/templates")
-async def get_templates(client: PrintfulClient) -> dict:
[email protected]("/", dependencies=[Depends(HasPermission(UserPermission.VIEW_TEMPLATES, allow_vouchers=True))])
+async def get_templates(db: DBSession, *, with_variants: bool = False) -> list[Template] | list[TemplateWithVariant]:
"""Return all templates in printful."""
- resp = await client.get("/product-templates")
- return resp.json()
+ stmt = select(DBTemplate)
+ if with_variants:
+ stmt = stmt.options(joinedload(DBTemplate.variants))
+ res = await db.scalars(stmt)
+
+ if with_variants:
+ return res.unique().all()
+
+ return res.all()