diff --git a/CHANGELOG.md b/CHANGELOG.md index 54b0fa8..40b4f17 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ - Minifigure - Deduplicate + - Compute number of parts Parts - Damaged parts @@ -57,6 +58,9 @@ Parts - Add a clear button for dynamic text inputs - Add error message in a tooltip for dynamic inputs +- Minifigure + - Display number of parts + - Parts - Use Rebrickable URL if stored (+ color code) - Display color and transparency diff --git a/bricktracker/minifigure.py b/bricktracker/minifigure.py index 1ad6aa6..c09589e 100644 --- a/bricktracker/minifigure.py +++ b/bricktracker/minifigure.py @@ -37,9 +37,6 @@ class BrickMinifigure(RebrickableMinifigure): # Insert into database self.insert(commit=False) - # Insert the rebrickable set into database - self.insert_rebrickable() - # Load the inventory if not BrickPartList.download( socket, @@ -49,6 +46,9 @@ class BrickMinifigure(RebrickableMinifigure): ): return False + # Insert the rebrickable set into database (after counting parts) + self.insert_rebrickable() + except Exception as e: socket.fail( message='Error while importing minifigure {figure} from {set}: {error}'.format( # noqa: E501 diff --git a/bricktracker/part_list.py b/bricktracker/part_list.py index d0e7138..eb3f58d 100644 --- a/bricktracker/part_list.py +++ b/bricktracker/part_list.py @@ -239,10 +239,18 @@ class BrickPartList(BrickRecordList[BrickPart]): ).list() # Process each part + number_of_parts: int = 0 for part in inventory: + # Count the number of parts for minifigures + if minifigure is not None: + number_of_parts += part.fields.quantity + if not part.download(socket, refresh=refresh): return False + if minifigure is not None: + minifigure.fields.number_of_parts = number_of_parts + except Exception as e: socket.fail( message='Error while importing {kind} {identifier} parts list: {error}'.format( # noqa: E501 diff --git a/bricktracker/sql/migrations/0015.sql b/bricktracker/sql/migrations/0015.sql new file mode 100644 index 0000000..de2d6ec --- /dev/null +++ b/bricktracker/sql/migrations/0015.sql @@ -0,0 +1,32 @@ +-- description: Add number of parts for minifigures + +BEGIN TRANSACTION; + +-- Add the number_of_parts column to the minifigures +ALTER TABLE "rebrickable_minifigures" +ADD COLUMN "number_of_parts" INTEGER NOT NULL DEFAULT 0; + +-- Update the number of parts for each minifigure +UPDATE "rebrickable_minifigures" +SET "number_of_parts" = "parts_sum"."number_of_parts" +FROM ( + SELECT + "parts"."figure", + SUM("parts"."quantity") as "number_of_parts" + FROM ( + SELECT + "bricktracker_parts"."figure", + "bricktracker_parts"."quantity" + FROM "bricktracker_parts" + WHERE "bricktracker_parts"."figure" IS NOT NULL + GROUP BY + "bricktracker_parts"."figure", + "bricktracker_parts"."part", + "bricktracker_parts"."color", + "bricktracker_parts"."spare" + ) "parts" + GROUP BY "parts"."figure" +) "parts_sum" +WHERE "rebrickable_minifigures"."figure" = "parts_sum"."figure"; + +COMMIT; diff --git a/bricktracker/sql/minifigure/base/base.sql b/bricktracker/sql/minifigure/base/base.sql index d651bf0..a3a30a7 100644 --- a/bricktracker/sql/minifigure/base/base.sql +++ b/bricktracker/sql/minifigure/base/base.sql @@ -2,6 +2,7 @@ SELECT "bricktracker_minifigures"."quantity", "rebrickable_minifigures"."figure", "rebrickable_minifigures"."number", + "rebrickable_minifigures"."number_of_parts", "rebrickable_minifigures"."name", "rebrickable_minifigures"."image", {% block total_missing %} diff --git a/bricktracker/sql/rebrickable/minifigure/insert.sql b/bricktracker/sql/rebrickable/minifigure/insert.sql index 6c0ac8e..3db1680 100644 --- a/bricktracker/sql/rebrickable/minifigure/insert.sql +++ b/bricktracker/sql/rebrickable/minifigure/insert.sql @@ -2,16 +2,19 @@ INSERT OR IGNORE INTO "rebrickable_minifigures" ( "figure", "number", "name", - "image" + "image", + "number_of_parts" ) VALUES ( :figure, :number, :name, - :image + :image, + :number_of_parts ) ON CONFLICT("figure") DO UPDATE SET "number" = :number, "name" = :name, -"image" = :image +"image" = :image, +"number_of_parts" = :number_of_parts WHERE "rebrickable_minifigures"."figure" IS NOT DISTINCT FROM :figure diff --git a/bricktracker/version.py b/bricktracker/version.py index 767fad5..4efb1e6 100644 --- a/bricktracker/version.py +++ b/bricktracker/version.py @@ -1,4 +1,4 @@ from typing import Final __version__: Final[str] = '1.2.0' -__database_version__: Final[int] = 14 +__database_version__: Final[int] = 15 diff --git a/templates/macro/table.html b/templates/macro/table.html index d31e1c2..ebf1ded 100644 --- a/templates/macro/table.html +++ b/templates/macro/table.html @@ -1,4 +1,4 @@ -{% macro header(color=false, quantity=false, missing_parts=false, damaged_parts=false, sets=false, minifigures=false) %} +{% macro header(color=false, parts=false, quantity=false, missing_parts=false, damaged_parts=false, sets=false, minifigures=false) %} Image @@ -6,6 +6,9 @@ {% if color %} Color {% endif %} + {% if parts %} + Parts + {% endif %} {% if quantity %} Quantity {% endif %} diff --git a/templates/minifigure/card.html b/templates/minifigure/card.html index 80459e3..2cba9b4 100644 --- a/templates/minifigure/card.html +++ b/templates/minifigure/card.html @@ -6,6 +6,7 @@ {{ card.header(item, item.fields.name, solo=solo, identifier=item.fields.figure, icon='user-line') }} {{ card.image(item, solo=solo, last=last, caption=item.fields.name, alt=item.fields.figure, medium=true) }}
+ {{ badge.parts(item.fields.number_of_parts, solo=solo, last=last) }} {% if last %} {{ badge.set(item.fields.set, solo=solo, last=last, id=item.fields.rebrickable_set_id) }} {{ badge.quantity(item.fields.quantity, solo=solo, last=last) }} diff --git a/templates/minifigure/table.html b/templates/minifigure/table.html index aeb0bb7..c91ab58 100644 --- a/templates/minifigure/table.html +++ b/templates/minifigure/table.html @@ -2,7 +2,7 @@
- {{ table.header(quantity=true, missing_parts=true, damaged_parts=true, sets=true) }} + {{ table.header(parts=true, quantity=true, missing_parts=true, damaged_parts=true, sets=true) }} {% for item in table_collection %} @@ -13,6 +13,7 @@ {{ table.rebrickable(item) }} {% endif %} +
{{ item.fields.number_of_parts }} {{ item.fields.total_quantity }} {{ item.fields.total_missing }} {{ item.fields.total_damaged }}