forked from FrederikBaerentsen/BrickTracker
bricktracker
migrations
sql
views
__init__.py
app.py
config.py
configuration.py
configuration_list.py
exceptions.py
fields.py
instructions.py
instructions_list.py
login.py
minifigure.py
minifigure_list.py
navbar.py
parser.py
part.py
part_list.py
rebrickable.py
rebrickable_image.py
rebrickable_minifigure.py
rebrickable_part.py
rebrickable_set.py
rebrickable_set_list.py
record.py
record_list.py
reload.py
retired.py
retired_list.py
set.py
set_checkbox.py
set_checkbox_list.py
set_list.py
socket.py
socket_decorator.py
sql.py
sql_counter.py
sql_migration.py
sql_migration_list.py
sql_stats.py
theme.py
theme_list.py
version.py
wish.py
wish_list.py
docs
static
templates
.dockerignore
.env.sample
.gitignore
CHANGELOG.md
Dockerfile
LICENSE
README.md
__init__.py
app.py
compose.legacy.yml
compose.local.yaml
compose.yaml
entrypoint.sh
requirements.txt
test-server.sh
107 lines
3.9 KiB
Python
107 lines
3.9 KiB
Python
import logging
|
|
import os
|
|
from typing import Generator, TYPE_CHECKING
|
|
|
|
from flask import current_app
|
|
|
|
from .exceptions import NotFoundException
|
|
from .instructions import BrickInstructions
|
|
from .rebrickable_set_list import RebrickableSetList
|
|
if TYPE_CHECKING:
|
|
from .rebrickable_set import RebrickableSet
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
# Lego sets instruction list
|
|
class BrickInstructionsList(object):
|
|
all: dict[str, BrickInstructions]
|
|
rejected_total: int
|
|
sets: dict[str, list[BrickInstructions]]
|
|
sets_total: int
|
|
unknown_total: int
|
|
|
|
def __init__(self, /, *, force=False):
|
|
# Load instructions only if there is none already loaded
|
|
all = getattr(self, 'all', None)
|
|
|
|
if all is None or force:
|
|
logger.info('Loading instructions file list')
|
|
|
|
BrickInstructionsList.all = {}
|
|
BrickInstructionsList.rejected_total = 0
|
|
BrickInstructionsList.sets = {}
|
|
BrickInstructionsList.sets_total = 0
|
|
BrickInstructionsList.unknown_total = 0
|
|
|
|
# Try to list the files in the instruction folder
|
|
try:
|
|
# Make a folder relative to static
|
|
folder: str = os.path.join(
|
|
current_app.static_folder, # type: ignore
|
|
current_app.config['INSTRUCTIONS_FOLDER'],
|
|
)
|
|
|
|
for file in os.scandir(folder):
|
|
instruction = BrickInstructions(file)
|
|
|
|
# Unconditionnally add to the list
|
|
BrickInstructionsList.all[instruction.filename] = instruction # noqa: E501
|
|
|
|
if instruction.allowed:
|
|
if instruction.set:
|
|
# Instantiate the list if not existing yet
|
|
if instruction.set not in BrickInstructionsList.sets: # noqa: E501
|
|
BrickInstructionsList.sets[instruction.set] = [] # noqa: E501
|
|
|
|
BrickInstructionsList.sets[instruction.set].append(instruction) # noqa: E501
|
|
BrickInstructionsList.sets_total += 1
|
|
else:
|
|
BrickInstructionsList.unknown_total += 1
|
|
else:
|
|
BrickInstructionsList.rejected_total += 1
|
|
|
|
# List of Rebrickable sets
|
|
rebrickable_sets: dict[str, RebrickableSet] = {}
|
|
for rebrickable_set in RebrickableSetList().all():
|
|
rebrickable_sets[rebrickable_set.fields.set] = rebrickable_set # noqa: E501
|
|
|
|
# Inject the brickset if it exists
|
|
for instruction in self.all.values():
|
|
if (
|
|
instruction.allowed and
|
|
instruction.set is not None and
|
|
instruction.rebrickable is None and
|
|
instruction.set in rebrickable_sets
|
|
):
|
|
instruction.rebrickable = rebrickable_sets[instruction.set] # noqa: E501
|
|
# Ignore errors
|
|
except Exception:
|
|
pass
|
|
|
|
# Grab instructions for a set
|
|
def get(self, set: str) -> list[BrickInstructions]:
|
|
if set in self.sets:
|
|
return self.sets[set]
|
|
else:
|
|
return []
|
|
|
|
# Grab instructions for a file
|
|
def get_file(self, name: str) -> BrickInstructions:
|
|
if name not in self.all:
|
|
raise NotFoundException('Instruction file {name} does not exist'.format( # noqa: E501
|
|
name=name
|
|
))
|
|
|
|
return self.all[name]
|
|
|
|
# List of all instruction files
|
|
def list(self, /) -> Generator[BrickInstructions, None, None]:
|
|
# Get the filenames and sort them
|
|
filenames = list(self.all.keys())
|
|
filenames.sort()
|
|
|
|
# Return the files
|
|
for filename in filenames:
|
|
yield self.all[filename]
|