Renamed to Spoolman

Spoolson just didn't sound that good after all
This commit is contained in:
Donkie
2023-04-02 19:19:15 +02:00
parent c31c3dea42
commit 6fd9662c42
19 changed files with 24 additions and 24 deletions

120
spoolman/database/spool.py Normal file
View File

@@ -0,0 +1,120 @@
"""Helper functions for interacting with spool database objects."""
from datetime import datetime
from typing import Optional
from sqlalchemy.ext.asyncio import AsyncSession
from spoolman.database import filament, models
from spoolman.exceptions import ItemCreateError, ItemNotFoundError
from spoolman.math import weight_from_length
async def create(
*,
db: AsyncSession,
filament_id: int,
weight: Optional[float] = None,
first_used: Optional[datetime] = None,
last_used: Optional[datetime] = None,
location: Optional[str] = None,
lot_nr: Optional[str] = None,
comment: Optional[str] = None,
) -> models.Spool:
"""Add a new spool to the database. Leave weight empty to assume full spool."""
filament_item = await filament.get_by_id(db, filament_id)
if weight is None:
if filament_item.weight is None:
raise ItemCreateError("The weight for neither the spool nor its filament type is set.")
weight = filament_item.weight
db_item = models.Spool(
filament=filament_item,
weight=weight,
first_used=first_used,
last_used=last_used,
location=location,
lot_nr=lot_nr,
comment=comment,
)
db.add(db_item)
await db.flush()
return db_item
async def get_by_id(db: AsyncSession, spool_id: int, with_for_update: Optional[bool] = None) -> models.Spool:
"""Get a spool object from the database by the unique ID."""
spool = await db.get(models.Spool, spool_id, with_for_update=with_for_update) # type: ignore # noqa: PGH003
if spool is None:
raise ItemNotFoundError(f"No spool with ID {spool_id} found.")
return spool
async def update(
*,
db: AsyncSession,
spool_id: int,
data: dict,
) -> models.Spool:
"""Update the fields of a spool object."""
spool = await get_by_id(db, spool_id)
for k, v in data.items():
if k == "filament_id":
spool.filament = await filament.get_by_id(db, v)
else:
setattr(spool, k, v)
await db.flush()
return spool
async def delete(db: AsyncSession, spool_id: int) -> None:
"""Delete a spool object."""
spool = await get_by_id(db, spool_id)
await db.delete(spool)
# TODO: Make unit tests for race conditions on these
async def use_weight(db: AsyncSession, spool_id: int, weight: float) -> models.Spool:
"""Reduce the weight of a spool.
Does nothing if the spool is empty.
Args:
db (AsyncSession): Database session
spool_id (int): Spool ID
weight (float): Weight loss in grams
Returns:
models.Spool: Updated spool object
"""
spool = await get_by_id(db, spool_id, with_for_update=True)
spool.weight -= min(spool.weight, weight)
await db.flush()
return spool
async def use_length(db: AsyncSession, spool_id: int, length: float) -> models.Spool:
"""Reduce the weight of a spool by using a length of filament.
Does nothing if the spool is empty.
Args:
db (AsyncSession): Database session
spool_id (int): Spool ID
length (float): Length of filament to reduce by
Returns:
models.Spool: Updated spool object
"""
spool = await get_by_id(db, spool_id, with_for_update=True)
filament = spool.filament
weight = weight_from_length(
length=length,
radius=filament.diameter / 2,
density=filament.density,
)
spool.weight -= min(spool.weight, weight)
await db.flush()
return spool