From 4cb2542a4171fbf9f7d19dd1054c8f78311855d7 Mon Sep 17 00:00:00 2001 From: Donkie Date: Sat, 12 Aug 2023 21:32:20 +0200 Subject: [PATCH] Added support for color_hex alpha channel --- migrations/README.md | 2 +- ...08_12_2121-92793c8a937c_color_hex_alpha.py | 24 ++++++++++++++++++ spoolman/api/v1/filament.py | 25 ++++++++++++++++--- spoolman/api/v1/models.py | 4 +-- spoolman/database/models.py | 2 +- tests_integration/tests/test_filament.py | 20 +++++++++++++++ 6 files changed, 69 insertions(+), 8 deletions(-) create mode 100644 migrations/versions/2023_08_12_2121-92793c8a937c_color_hex_alpha.py diff --git a/migrations/README.md b/migrations/README.md index 0ae2b6c..cb1b35b 100644 --- a/migrations/README.md +++ b/migrations/README.md @@ -2,6 +2,6 @@ Creating a new version: ```bash -python -m spoolman.main +pdm run python -m spoolman.main pdm run alembic revision -m "some title" --autogenerate ``` diff --git a/migrations/versions/2023_08_12_2121-92793c8a937c_color_hex_alpha.py b/migrations/versions/2023_08_12_2121-92793c8a937c_color_hex_alpha.py new file mode 100644 index 0000000..ba7abd0 --- /dev/null +++ b/migrations/versions/2023_08_12_2121-92793c8a937c_color_hex_alpha.py @@ -0,0 +1,24 @@ +"""color_hex alpha. + +Revision ID: 92793c8a937c +Revises: 92186a5f7b0f +Create Date: 2023-08-12 21:21:08.536216 +""" +import sqlalchemy as sa +from alembic import op + +# revision identifiers, used by Alembic. +revision = "92793c8a937c" +down_revision = "92186a5f7b0f" +branch_labels = None +depends_on = None + + +def upgrade() -> None: + """Perform the upgrade.""" + op.alter_column("filament", "color_hex", type_=sa.String(length=8), existing_nullable=True) + + +def downgrade() -> None: + """Perform the downgrade.""" + op.alter_column("filament", "color_hex", type_=sa.String(length=6), existing_nullable=True) diff --git a/spoolman/api/v1/filament.py b/spoolman/api/v1/filament.py index e83df22..6d94d74 100644 --- a/spoolman/api/v1/filament.py +++ b/spoolman/api/v1/filament.py @@ -6,7 +6,7 @@ from typing import Annotated, Optional from fastapi import APIRouter, Depends, Query from fastapi.exceptions import RequestValidationError from fastapi.responses import JSONResponse -from pydantic import BaseModel, Field +from pydantic import BaseModel, Field, validator from pydantic.error_wrappers import ErrorWrapper from sqlalchemy.ext.asyncio import AsyncSession @@ -74,12 +74,29 @@ class FilamentParameters(BaseModel): example=60, ) color_hex: Optional[str] = Field( - min_length=6, - max_length=6, - description="Hexadecimal color code of the filament, e.g. FF0000 for red. (no leading #)", + description="Hexadecimal color code of the filament, e.g. FF0000 for red. Supports alpha channel at the end.", example="FF0000", ) + @validator("color_hex") + @classmethod + def color_hex_validator(cls, v: Optional[str]) -> Optional[str]: # noqa: ANN102 + """Validate the color_hex field.""" + if not v: + return None + if v.startswith("#"): + v = v[1:] + v = v.upper() + + for c in v: + if c not in "0123456789ABCDEF": + raise ValueError("Invalid character in color code.") + + if len(v) not in (6, 8): + raise ValueError("Color code must be 6 or 8 characters long.") + + return v + class FilamentUpdateParameters(FilamentParameters): density: Optional[float] = Field(gt=0, description="The density of this filament in g/cm3.", example=1.24) diff --git a/spoolman/api/v1/models.py b/spoolman/api/v1/models.py index a27f8f0..b3c437d 100644 --- a/spoolman/api/v1/models.py +++ b/spoolman/api/v1/models.py @@ -82,8 +82,8 @@ class Filament(BaseModel): ) color_hex: Optional[str] = Field( min_length=6, - max_length=6, - description="Hexadecimal color code of the filament, e.g. FF0000 for red. (no leading #)", + max_length=8, + description="Hexadecimal color code of the filament, e.g. FF0000 for red. Supports alpha channel at the end.", example="FF0000", ) diff --git a/spoolman/database/models.py b/spoolman/database/models.py index c6c5bdb..f78bfa5 100644 --- a/spoolman/database/models.py +++ b/spoolman/database/models.py @@ -41,7 +41,7 @@ class Filament(Base): comment: Mapped[Optional[str]] = mapped_column(String(1024)) settings_extruder_temp: Mapped[Optional[int]] = mapped_column(comment="Overridden extruder temperature.") settings_bed_temp: Mapped[Optional[int]] = mapped_column(comment="Overridden bed temperature.") - color_hex: Mapped[Optional[str]] = mapped_column(String(6)) + color_hex: Mapped[Optional[str]] = mapped_column(String(8)) class Spool(Base): diff --git a/tests_integration/tests/test_filament.py b/tests_integration/tests/test_filament.py index 01dc3f3..eebb7f6 100644 --- a/tests_integration/tests/test_filament.py +++ b/tests_integration/tests/test_filament.py @@ -438,3 +438,23 @@ def test_update_filament_not_found(): assert "filament" in message assert "id" in message assert "123456789" in message + + +def test_add_filament_color_hex_alpha(): + """Test adding a filament with an alpha channel in the color hex.""" + color_hex = "FF000088" + + # Execute + result = httpx.post( + f"{URL}/api/v1/filament", + json={ + "density": 1.25, + "diameter": 1.75, + "color_hex": color_hex, + }, + ) + result.raise_for_status() + + # Verify + filament = result.json() + assert filament["color_hex"] == color_hex