Metadata list
This commit is contained in:
parent
7d16e491c8
commit
344d4fb575
77
bricktracker/metadata_list.py
Normal file
77
bricktracker/metadata_list.py
Normal file
@ -0,0 +1,77 @@
|
||||
import logging
|
||||
from typing import Type
|
||||
|
||||
from .exceptions import NotFoundException
|
||||
from .fields import BrickRecordFields
|
||||
from .record_list import BrickRecordList
|
||||
from .set_status import BrickSetStatus
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
T = BrickSetStatus
|
||||
|
||||
|
||||
# Lego sets metadata list
|
||||
class BrickMetadataList(BrickRecordList[T]):
|
||||
kind: str
|
||||
mapping: dict[str, T]
|
||||
model: Type[T]
|
||||
|
||||
# Database table
|
||||
table: str
|
||||
|
||||
# Queries
|
||||
select_query: str
|
||||
|
||||
def __init__(self, model: Type[T], /, *, force: bool = False):
|
||||
# Load statuses only if there is none already loaded
|
||||
records = getattr(self, 'records', None)
|
||||
|
||||
if records is None or force:
|
||||
# Don't use super()__init__ as it would mask class variables
|
||||
self.fields = BrickRecordFields()
|
||||
|
||||
logger.info('Loading {kind} list'.format(
|
||||
kind=self.kind
|
||||
))
|
||||
|
||||
self.__class__.records = []
|
||||
self.__class__.mapping = {}
|
||||
|
||||
# Load the statuses from the database
|
||||
for record in self.select():
|
||||
status = model(record=record)
|
||||
|
||||
self.__class__.records.append(status)
|
||||
self.__class__.mapping[status.fields.id] = status
|
||||
|
||||
# Return the items as columns for a select
|
||||
def as_columns(self, /, **kwargs) -> str:
|
||||
return ', '.join([
|
||||
'"{table}"."{column}"'.format(
|
||||
table=self.table,
|
||||
column=record.as_column(),
|
||||
)
|
||||
for record
|
||||
in self.filter(**kwargs)
|
||||
])
|
||||
|
||||
# Filter the list of records (this one does nothing)
|
||||
def filter(self) -> list[T]:
|
||||
return self.records
|
||||
|
||||
# Grab a specific status
|
||||
def get(self, id: str, /) -> T:
|
||||
if id not in self.mapping:
|
||||
raise NotFoundException(
|
||||
'{kind} with ID {id} was not found in the database'.format(
|
||||
kind=self.kind.capitalize(),
|
||||
id=id,
|
||||
),
|
||||
)
|
||||
|
||||
return self.mapping[id]
|
||||
|
||||
# Get the list of statuses depending on the context
|
||||
def list(self, /, **kwargs) -> list[T]:
|
||||
return self.filter(**kwargs)
|
@ -1,5 +1,6 @@
|
||||
from .instructions_list import BrickInstructionsList
|
||||
from .retired_list import BrickRetiredList
|
||||
from .set_status import BrickSetStatus
|
||||
from .set_status_list import BrickSetStatusList
|
||||
from .theme_list import BrickThemeList
|
||||
|
||||
@ -12,7 +13,7 @@ def reload() -> None:
|
||||
BrickInstructionsList(force=True)
|
||||
|
||||
# Reload the set statuses
|
||||
BrickSetStatusList(force=True)
|
||||
BrickSetStatusList(BrickSetStatus, force=True)
|
||||
|
||||
# Reload retired sets
|
||||
BrickRetiredList(force=True)
|
||||
|
@ -9,6 +9,7 @@ from .exceptions import NotFoundException
|
||||
from .minifigure_list import BrickMinifigureList
|
||||
from .part_list import BrickPartList
|
||||
from .rebrickable_set import RebrickableSet
|
||||
from .set_status import BrickSetStatus
|
||||
from .set_status_list import BrickSetStatusList
|
||||
from .sql import BrickSQL
|
||||
if TYPE_CHECKING:
|
||||
@ -161,7 +162,7 @@ class BrickSet(RebrickableSet):
|
||||
|
||||
# Load from database
|
||||
if not self.select(
|
||||
statuses=BrickSetStatusList().as_columns(solo=True)
|
||||
statuses=BrickSetStatusList(BrickSetStatus).as_columns(all=True)
|
||||
):
|
||||
raise NotFoundException(
|
||||
'Set with ID {id} was not found in the database'.format(
|
||||
|
@ -3,6 +3,7 @@ from typing import Self
|
||||
from flask import current_app
|
||||
|
||||
from .record_list import BrickRecordList
|
||||
from .set_status import BrickSetStatus
|
||||
from .set_status_list import BrickSetStatusList
|
||||
from .set import BrickSet
|
||||
|
||||
@ -37,7 +38,7 @@ class BrickSetList(BrickRecordList[BrickSet]):
|
||||
# Load the sets from the database
|
||||
for record in self.select(
|
||||
order=self.order,
|
||||
statuses=BrickSetStatusList().as_columns()
|
||||
statuses=BrickSetStatusList(BrickSetStatus).as_columns()
|
||||
):
|
||||
brickset = BrickSet(record=record)
|
||||
|
||||
@ -73,7 +74,7 @@ class BrickSetList(BrickRecordList[BrickSet]):
|
||||
for record in self.select(
|
||||
order=order,
|
||||
limit=limit,
|
||||
statuses=BrickSetStatusList().as_columns()
|
||||
statuses=BrickSetStatusList(BrickSetStatus).as_columns()
|
||||
):
|
||||
brickset = BrickSet(record=record)
|
||||
|
||||
|
@ -1,71 +1,23 @@
|
||||
import logging
|
||||
|
||||
from .exceptions import NotFoundException
|
||||
from .fields import BrickRecordFields
|
||||
from .record_list import BrickRecordList
|
||||
from .metadata_list import BrickMetadataList
|
||||
from .set_status import BrickSetStatus
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# Lego sets status list
|
||||
class BrickSetStatusList(BrickRecordList[BrickSetStatus]):
|
||||
statuses: dict[str, BrickSetStatus]
|
||||
class BrickSetStatusList(BrickMetadataList):
|
||||
kind: str = 'set statuses'
|
||||
|
||||
# Database table
|
||||
table: str = 'bricktracker_set_statuses'
|
||||
|
||||
# Queries
|
||||
select_query = 'set/metadata/status/list'
|
||||
|
||||
def __init__(self, /, *, force: bool = False):
|
||||
# Load statuses only if there is none already loaded
|
||||
records = getattr(self, 'records', None)
|
||||
|
||||
if records is None or force:
|
||||
# Don't use super()__init__ as it would mask class variables
|
||||
self.fields = BrickRecordFields()
|
||||
|
||||
logger.info('Loading set statuses list')
|
||||
|
||||
BrickSetStatusList.records = []
|
||||
BrickSetStatusList.statuses = {}
|
||||
|
||||
# Load the statuses from the database
|
||||
for record in self.select():
|
||||
status = BrickSetStatus(record=record)
|
||||
|
||||
BrickSetStatusList.records.append(status)
|
||||
BrickSetStatusList.statuses[status.fields.id] = status
|
||||
|
||||
# Return the statuses as columns for a select
|
||||
def as_columns(
|
||||
self,
|
||||
/,
|
||||
*,
|
||||
solo: bool = False,
|
||||
table: str = 'bricktracker_set_statuses'
|
||||
) -> str:
|
||||
return ', '.join([
|
||||
'"{table}"."{column}"'.format(
|
||||
table=table,
|
||||
column=record.as_column(),
|
||||
)
|
||||
for record
|
||||
in self.records
|
||||
if solo or record.fields.displayed_on_grid
|
||||
])
|
||||
|
||||
# Grab a specific status
|
||||
def get(self, id: str, /) -> BrickSetStatus:
|
||||
if id not in self.statuses:
|
||||
raise NotFoundException(
|
||||
'Status with ID {id} was not found in the database'.format(
|
||||
id=id,
|
||||
),
|
||||
)
|
||||
|
||||
return self.statuses[id]
|
||||
|
||||
# Get the list of statuses depending on the context
|
||||
def list(self, /, *, all: bool = False) -> list[BrickSetStatus]:
|
||||
# Filter the list of set status
|
||||
def filter(self, all: bool = False) -> list[BrickSetStatus]:
|
||||
return [
|
||||
record
|
||||
for record
|
||||
|
@ -41,7 +41,7 @@ def admin() -> str:
|
||||
database_version = database.version
|
||||
database_counters = BrickSQL().count_records()
|
||||
|
||||
metadata_statuses = BrickSetStatusList().list(all=True)
|
||||
metadata_statuses = BrickSetStatusList(BrickSetStatus).list(all=True)
|
||||
except Exception as e:
|
||||
database_exception = e
|
||||
|
||||
|
@ -2,6 +2,7 @@ from flask import Blueprint, render_template
|
||||
|
||||
from .exceptions import exception_handler
|
||||
from ..minifigure_list import BrickMinifigureList
|
||||
from ..set_status import BrickSetStatus
|
||||
from ..set_status_list import BrickSetStatusList
|
||||
from ..set_list import BrickSetList
|
||||
|
||||
@ -16,5 +17,5 @@ def index() -> str:
|
||||
'index.html',
|
||||
brickset_collection=BrickSetList().last(),
|
||||
minifigure_collection=BrickMinifigureList().last(),
|
||||
brickset_statuses=BrickSetStatusList().list(),
|
||||
brickset_statuses=BrickSetStatusList(BrickSetStatus).list(),
|
||||
)
|
||||
|
@ -16,6 +16,7 @@ from .exceptions import exception_handler
|
||||
from ..minifigure import BrickMinifigure
|
||||
from ..part import BrickPart
|
||||
from ..set import BrickSet
|
||||
from ..set_status import BrickSetStatus
|
||||
from ..set_status_list import BrickSetStatusList
|
||||
from ..set_list import BrickSetList
|
||||
from ..socket import MESSAGES
|
||||
@ -32,7 +33,7 @@ def list() -> str:
|
||||
return render_template(
|
||||
'sets.html',
|
||||
collection=BrickSetList().all(),
|
||||
brickset_statuses=BrickSetStatusList().list(),
|
||||
brickset_statuses=BrickSetStatusList(BrickSetStatus).list(),
|
||||
)
|
||||
|
||||
|
||||
@ -42,7 +43,7 @@ def list() -> str:
|
||||
@exception_handler(__file__, json=True)
|
||||
def update_status(*, id: str, metadata_id: str) -> Response:
|
||||
brickset = BrickSet().select_light(id)
|
||||
status = BrickSetStatusList().get(metadata_id)
|
||||
status = BrickSetStatusList(BrickSetStatus).get(metadata_id)
|
||||
|
||||
state = status.update_set_state(brickset, request.json)
|
||||
|
||||
@ -97,7 +98,7 @@ def details(*, id: str) -> str:
|
||||
'set.html',
|
||||
item=BrickSet().select_specific(id),
|
||||
open_instructions=request.args.get('open_instructions'),
|
||||
brickset_statuses=BrickSetStatusList().list(all=True),
|
||||
brickset_statuses=BrickSetStatusList(BrickSetStatus).list(all=True),
|
||||
)
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user