2025-01-17 11:03:00 +01:00
|
|
|
from typing import Any, Self, TYPE_CHECKING
|
|
|
|
|
|
|
|
from flask import current_app
|
|
|
|
|
|
|
|
from .part import BrickPart
|
|
|
|
from .record_list import BrickRecordList
|
|
|
|
if TYPE_CHECKING:
|
|
|
|
from .minifigure import BrickMinifigure
|
|
|
|
from .set import BrickSet
|
|
|
|
|
|
|
|
|
|
|
|
# Lego set or minifig parts
|
|
|
|
class BrickPartList(BrickRecordList[BrickPart]):
|
|
|
|
brickset: 'BrickSet | None'
|
|
|
|
minifigure: 'BrickMinifigure | None'
|
2025-01-18 23:13:36 +01:00
|
|
|
order: str
|
2025-01-17 11:03:00 +01:00
|
|
|
|
|
|
|
# Queries
|
|
|
|
all_query: str = 'part/list/all'
|
|
|
|
last_query: str = 'part/list/last'
|
|
|
|
minifigure_query: str = 'part/list/from_minifigure'
|
|
|
|
missing_query: str = 'part/list/missing'
|
|
|
|
select_query: str = 'part/list/from_set'
|
|
|
|
|
|
|
|
def __init__(self, /):
|
|
|
|
super().__init__()
|
|
|
|
|
|
|
|
# Placeholders
|
|
|
|
self.brickset = None
|
|
|
|
self.minifigure = None
|
|
|
|
|
2025-01-18 23:13:36 +01:00
|
|
|
# Store the order for this list
|
|
|
|
self.order = current_app.config['PARTS_DEFAULT_ORDER'].value
|
|
|
|
|
2025-01-17 11:03:00 +01:00
|
|
|
# Load all parts
|
|
|
|
def all(self, /) -> Self:
|
|
|
|
for record in self.select(
|
|
|
|
override_query=self.all_query,
|
2025-01-18 23:13:36 +01:00
|
|
|
order=self.order
|
2025-01-17 11:03:00 +01:00
|
|
|
):
|
|
|
|
part = BrickPart(record=record)
|
|
|
|
|
|
|
|
self.records.append(part)
|
|
|
|
|
|
|
|
return self
|
|
|
|
|
|
|
|
# Load parts from a brickset or minifigure
|
|
|
|
def load(
|
|
|
|
self,
|
|
|
|
brickset: 'BrickSet',
|
|
|
|
/,
|
|
|
|
minifigure: 'BrickMinifigure | None' = None,
|
|
|
|
) -> Self:
|
|
|
|
# Save the brickset and minifigure
|
|
|
|
self.brickset = brickset
|
|
|
|
self.minifigure = minifigure
|
|
|
|
|
|
|
|
# Load the parts from the database
|
2025-01-18 23:13:36 +01:00
|
|
|
for record in self.select(order=self.order):
|
2025-01-17 11:03:00 +01:00
|
|
|
part = BrickPart(
|
|
|
|
brickset=self.brickset,
|
|
|
|
minifigure=minifigure,
|
|
|
|
record=record,
|
|
|
|
)
|
|
|
|
|
|
|
|
if (
|
|
|
|
current_app.config['SKIP_SPARE_PARTS'].value and
|
|
|
|
part.fields.is_spare
|
|
|
|
):
|
|
|
|
continue
|
|
|
|
|
|
|
|
self.records.append(part)
|
|
|
|
|
|
|
|
return self
|
|
|
|
|
|
|
|
# Load generic parts from a minifigure
|
|
|
|
def from_minifigure(
|
|
|
|
self,
|
|
|
|
minifigure: 'BrickMinifigure',
|
|
|
|
/,
|
|
|
|
) -> Self:
|
|
|
|
# Save the minifigure
|
|
|
|
self.minifigure = minifigure
|
|
|
|
|
|
|
|
# Load the parts from the database
|
|
|
|
for record in self.select(
|
|
|
|
override_query=self.minifigure_query,
|
2025-01-18 23:13:36 +01:00
|
|
|
order=self.order
|
2025-01-17 11:03:00 +01:00
|
|
|
):
|
|
|
|
part = BrickPart(
|
|
|
|
minifigure=minifigure,
|
|
|
|
record=record,
|
|
|
|
)
|
|
|
|
|
|
|
|
if (
|
|
|
|
current_app.config['SKIP_SPARE_PARTS'].value and
|
|
|
|
part.fields.is_spare
|
|
|
|
):
|
|
|
|
continue
|
|
|
|
|
|
|
|
self.records.append(part)
|
|
|
|
|
|
|
|
return self
|
|
|
|
|
|
|
|
# Load missing parts
|
|
|
|
def missing(self, /) -> Self:
|
|
|
|
for record in self.select(
|
|
|
|
override_query=self.missing_query,
|
2025-01-18 23:13:36 +01:00
|
|
|
order=self.order
|
2025-01-17 11:03:00 +01:00
|
|
|
):
|
|
|
|
part = BrickPart(record=record)
|
|
|
|
|
|
|
|
self.records.append(part)
|
|
|
|
|
|
|
|
return self
|
|
|
|
|
|
|
|
# Return a dict with common SQL parameters for a parts list
|
|
|
|
def sql_parameters(self, /) -> dict[str, Any]:
|
|
|
|
parameters: dict[str, Any] = {}
|
|
|
|
|
|
|
|
# Set id
|
|
|
|
if self.brickset is not None:
|
|
|
|
parameters['u_id'] = self.brickset.fields.u_id
|
|
|
|
|
|
|
|
# Use the minifigure number if present,
|
|
|
|
# otherwise use the set number
|
|
|
|
if self.minifigure is not None:
|
|
|
|
parameters['set_num'] = self.minifigure.fields.fig_num
|
|
|
|
elif self.brickset is not None:
|
|
|
|
parameters['set_num'] = self.brickset.fields.set_num
|
|
|
|
|
|
|
|
return parameters
|