feat: adds efficiency calculation for rigs and back pack (WIP). UX cleaned up, graphic added to landing page.
This commit is contained in:
77
app.py
77
app.py
@@ -1,7 +1,7 @@
|
||||
from flask import Flask, render_template, request, redirect, url_for, jsonify
|
||||
import sqlite3
|
||||
|
||||
app = Flask(__name__)
|
||||
app = Flask(__name__, static_folder="assets", static_url_path="/assets")
|
||||
DB_PATH = "tarkov.db"
|
||||
|
||||
|
||||
@@ -436,24 +436,62 @@ LOADOUT_SLOT_FILTERS = [
|
||||
|
||||
def _sort_col(sort):
|
||||
return {
|
||||
"weight_asc": "weight_kg ASC NULLS LAST",
|
||||
"weight_desc": "weight_kg DESC NULLS LAST",
|
||||
"name_asc": "name ASC",
|
||||
"name_desc": "name DESC",
|
||||
"class_desc": "armor_class DESC NULLS LAST, weight_kg ASC NULLS LAST",
|
||||
"class_asc": "armor_class ASC NULLS LAST, weight_kg ASC NULLS LAST",
|
||||
"capacity_desc": "capacity DESC NULLS LAST, weight_kg ASC NULLS LAST",
|
||||
"capacity_asc": "capacity ASC NULLS LAST, weight_kg ASC NULLS LAST",
|
||||
"weight_asc": "weight_kg ASC NULLS LAST",
|
||||
"weight_desc": "weight_kg DESC NULLS LAST",
|
||||
"name_asc": "name ASC",
|
||||
"name_desc": "name DESC",
|
||||
"class_desc": "armor_class DESC NULLS LAST, weight_kg ASC NULLS LAST",
|
||||
"class_asc": "armor_class ASC NULLS LAST, weight_kg ASC NULLS LAST",
|
||||
"capacity_desc": "capacity DESC NULLS LAST, weight_kg ASC NULLS LAST",
|
||||
"capacity_asc": "capacity ASC NULLS LAST, weight_kg ASC NULLS LAST",
|
||||
# carry_efficiency sorts are handled in Python after query; fall back to weight
|
||||
"efficiency_desc": "weight_kg ASC NULLS LAST",
|
||||
"efficiency_asc": "weight_kg ASC NULLS LAST",
|
||||
}.get(sort, "weight_kg ASC NULLS LAST")
|
||||
|
||||
|
||||
def _carry_efficiency(weight_kg, slot_count):
|
||||
"""Return (slots_per_kg, kg_per_slot) or (None, None) if inputs are invalid."""
|
||||
if not weight_kg or not slot_count:
|
||||
return None, None
|
||||
try:
|
||||
w = float(weight_kg)
|
||||
s = int(slot_count)
|
||||
except (TypeError, ValueError):
|
||||
return None, None
|
||||
if w <= 0 or s <= 0:
|
||||
return None, None
|
||||
return round(s / w, 2), round(w / s, 3)
|
||||
|
||||
|
||||
def _enrich_with_efficiency(rows):
|
||||
"""Attach slots_per_kg and kg_per_slot to each sqlite3.Row (returns plain dicts)."""
|
||||
enriched = []
|
||||
for row in rows:
|
||||
d = dict(row)
|
||||
d["slots_per_kg"], d["kg_per_slot"] = _carry_efficiency(
|
||||
d.get("weight_kg"), d.get("capacity")
|
||||
)
|
||||
enriched.append(d)
|
||||
return enriched
|
||||
|
||||
|
||||
def _sort_enriched(rows, sort):
|
||||
"""Sort a list of enriched dicts by carry efficiency when requested."""
|
||||
if sort == "efficiency_desc":
|
||||
return sorted(rows, key=lambda r: (r["slots_per_kg"] is None, -(r["slots_per_kg"] or 0)))
|
||||
if sort == "efficiency_asc":
|
||||
return sorted(rows, key=lambda r: (r["slots_per_kg"] is None, r["slots_per_kg"] or 0))
|
||||
return rows
|
||||
|
||||
|
||||
@app.route("/loadout")
|
||||
def loadout():
|
||||
conn = get_db()
|
||||
tab = request.args.get("tab", "guns")
|
||||
sort = request.args.get("sort", "weight_asc")
|
||||
|
||||
guns = armor = helmets = headwear = backpacks = rigs = plates = []
|
||||
guns = armor = helmets = headwear = backpacks = rigs = armored_rigs = plates = []
|
||||
builder_guns = builder_armor = builder_helmets = builder_rigs = builder_backpacks = []
|
||||
requires = request.args.getlist("requires") # list of slot_nameids that must exist
|
||||
min_class = request.args.get("min_class", 0, type=int)
|
||||
@@ -523,21 +561,34 @@ def loadout():
|
||||
""", (min_class, min_class)).fetchall()
|
||||
|
||||
elif tab == "backpacks":
|
||||
backpacks = conn.execute(f"""
|
||||
rows = conn.execute(f"""
|
||||
SELECT * FROM gear_items
|
||||
WHERE category = 'backpack'
|
||||
AND (? = 0 OR capacity >= ?)
|
||||
ORDER BY {sort_frag}
|
||||
""", (min_capacity, min_capacity)).fetchall()
|
||||
backpacks = _sort_enriched(_enrich_with_efficiency(rows), sort)
|
||||
|
||||
elif tab == "rigs":
|
||||
rigs = conn.execute(f"""
|
||||
rows = conn.execute(f"""
|
||||
SELECT * FROM gear_items
|
||||
WHERE category = 'rig'
|
||||
AND armor_class IS NULL
|
||||
AND (? = 0 OR capacity >= ?)
|
||||
ORDER BY {sort_frag}
|
||||
""", (min_capacity, min_capacity)).fetchall()
|
||||
rigs = _sort_enriched(_enrich_with_efficiency(rows), sort)
|
||||
|
||||
elif tab == "armored_rigs":
|
||||
rows = conn.execute(f"""
|
||||
SELECT * FROM gear_items
|
||||
WHERE category = 'rig'
|
||||
AND armor_class IS NOT NULL
|
||||
AND (? = 0 OR capacity >= ?)
|
||||
AND (? = 0 OR armor_class >= ?)
|
||||
ORDER BY {sort_frag}
|
||||
""", (min_capacity, min_capacity, min_class, min_class)).fetchall()
|
||||
armored_rigs = _sort_enriched(_enrich_with_efficiency(rows), sort)
|
||||
|
||||
elif tab == "plates":
|
||||
plates = conn.execute(f"""
|
||||
@@ -563,7 +614,7 @@ def loadout():
|
||||
"loadout.html",
|
||||
tab=tab, sort=sort,
|
||||
guns=guns, armor=armor, helmets=helmets, headwear=headwear,
|
||||
backpacks=backpacks, rigs=rigs, plates=plates,
|
||||
backpacks=backpacks, rigs=rigs, armored_rigs=armored_rigs, plates=plates,
|
||||
slot_filters=LOADOUT_SLOT_FILTERS,
|
||||
requires=requires,
|
||||
min_class=min_class, min_capacity=min_capacity,
|
||||
|
||||
Reference in New Issue
Block a user