Added theme download script. Added front page info and save to file, as well as extra sort options

This commit is contained in:
FrederikBaerentsen 2024-04-14 15:56:08 +02:00
parent 3883c67d96
commit 2b9448fd35
3 changed files with 198 additions and 30 deletions

46
app.py
View File

@ -2,22 +2,54 @@ from flask import Flask, request, redirect, jsonify, render_template, Response
import json import json
from pprint import pprint as pp from pprint import pprint as pp
from pathlib import Path from pathlib import Path
import numpy as np
import re import re
app = Flask(__name__) app = Flask(__name__)
#tmp = '71386-10' #tmp = '71386-10'
@app.route('/favicon.ico') @app.route('/favicon.ico')
@app.route('/') @app.route('/', methods=['GET', 'POST'])
def index(): def index():
pathlist = Path('./info/').rglob('*.json') pathlist = Path('./info/').rglob('*.json')
set_list = [] set_list = []
for path in pathlist: json_file = {}
set_num = re.findall(r"\b\d+(?:-\d+)?\b",str(path))[0] theme_file = np.loadtxt("themes.csv", delimiter=",",dtype="str")
with open('./static/sets/'+set_num+'/info.json') as info: if request.method == 'GET':
info_file = json.loads(info.read()) for path in pathlist:
set_list.append(info_file) set_num = re.findall(r"\b\d+(?:-\d+)?\b",str(path))[0]
return render_template('frontpage.html',set_list=set_list) with open('./static/sets/'+set_num+'/info.json') as info:
info_file = json.loads(info.read())
try:
info_file['theme_id'] = theme_file[theme_file[:, 0] == str(info_file['theme_id'])][0][1]
except Exception as e:
print(e)
with open('./info/'+set_num+'.json') as info:
json_file[set_num] = json.loads(info.read())
set_list.append(info_file)
return render_template('frontpage.html',set_list=set_list,themes_list=theme_file,json_file=json_file)
if request.method == 'POST':
set_num = request.form.get('set_num')
minif = request.form.get('minif')
scheck = request.form.get('scheck')
scol = request.form.get('scol')
with open('./info/'+set_num+'.json') as info:
json_file = json.loads(info.read())
if minif != None:
json_file['Minifigs Collected'] = minif
if scheck != None:
json_file['Set Checked'] = scheck
if scol != None:
json_file['Set Collected'] = scol
with open('./info/'+set_num+'.json', 'w') as dump_file:
json.dump(json_file,dump_file)
return ('', 204)
@app.route('/<tmp>', methods=['GET', 'POST']) @app.route('/<tmp>', methods=['GET', 'POST'])
def sets(tmp): def sets(tmp):

4
lego.sh Normal file
View File

@ -0,0 +1,4 @@
#!/bin/bash
wget https://cdn.rebrickable.com/media/downloads/themes.csv.gz
gzip -d themes.csv.gz

View File

@ -7,14 +7,22 @@
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css">
<!-- CSS Reset --> <!-- CSS Reset -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/normalize.css"> <!-- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/normalize.css"> --->
<!-- Milligram CSS --> <!-- Milligram CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/milligram/1.4.1/milligram.css">
<!---
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/milligram/1.4.1/milligram.css">
<link <link
rel="stylesheet" rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css" href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css"
/> />
--->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js" integrity="sha512-v2CJ7UaYy4JwqLDIrZUI/4hqeoQieOmAZNXBeQyjo21dadnwR+8ZaIJVT8EE2iyI61OV8e6M8PP2/4hpQINQ/g==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<style> <style>
body { body {
@ -98,8 +106,12 @@
<button class="button button-outline" onclick="dynamicSort('set_year')">Sort by Year</button> <button class="button button-outline" onclick="dynamicSort('set_year')">Sort by Year</button>
<button class="button button-outline" onclick="dynamicSort('set_parts')">Sort by Parts</button> <button class="button button-outline" onclick="dynamicSort('set_parts')">Sort by Parts</button>
<button class="button button-outline" onclick="dynamicSort('set_name')">Sort by Name</button> <button class="button button-outline" onclick="dynamicSort('set_name')">Sort by Name</button>
<button class="button button-outline" onclick="dynamicSort('s_col')">Sort by Collected</button>
<button class="button button-outline" onclick="dynamicSort('s_check')">Sort by Checked</button>
</center> </center>
<button id="toggleButton">Toggle Visibility</button>
<!-- Add more buttons for other text values if needed --> <!-- Add more buttons for other text values if needed -->
</div> </div>
@ -107,8 +119,9 @@
{% for i in set_list %} {% for i in set_list %}
<div class="grid-item"> <div class="grid-item">
<div class="card"> <div class="card" style="display: flex;flex-direction: column;">
<div class="card-image"> <div class="card-image">
<figure class="image is-4by3"> <figure class="image is-4by3">
<a href="/{{ i['set_num'] }}"> <a href="/{{ i['set_num'] }}">
@ -116,37 +129,77 @@
</a> </a>
</figure> </figure>
</div> </div>
<div class="wrapper" style="min-height: 120px;display:flex;flex-direction:column;"> <div class="card-content" style="padding:0;margin: 0 auto;height:100%; max-height:inherit;display: flex;flex-direction: column;">
<div class="card-content" style="display: flex;flex-direction: column;flex: 1;">
<p class="title">
<span class="set_id">{{ i['set_num'] }}</span> <span class="set_name">{{ i['name'] }}</span>
</p>
<p class="subtitle"style="margin-bottom:auto;">
Theme - <span class='set_year'>{{ i['year'] }}</span>
</p>
<div style="margin:auto auto 0 0;">
<b>Parts:</b>
<span class='set_parts'>{{ i['num_parts'] }}</span>
</div>
</div>
<footer class="card-footer"> <div style="">
<b class="is-size-5" style="width: 100%;">
<span class="set_id">{{ i['set_num'] }}</span> <span class="set_name">{{ i['name'] }}</span>
</b>
<p class="is-size-7">
{{ i['theme_id'] }} (<span class='set_year'>{{ i['year'] }}</span>)
</p>
</div>
<span style="display:block; height: 10px;"></span>
<div style="display: flex;flex-direction: column;margin-top:auto;">
<div class="is-size-6" style="margin:auto auto 0 0;">
<b>Parts:</b>
<span class='set_parts'>{{ i['num_parts'] }}</span>
</div>
<span style="display:block; height: 10px;"></span>
<div class="is-size-7" >
<label class="checkbox" >
<input type="hidden" id="set_num" value="{{ i['set_num'] }}">
{% if json_file[i['set_num']]['Minifigs Collected'] == 'true' %}
<input class="s_fig" id="s_fig" type="checkbox" checked />
{% else %}
<input id="s_fig" type="checkbox" />
{% endif %}
Minifigs Collected
</label>
<label class="checkbox" >
<input type="hidden" id="set_num" value="{{ i['set_num'] }}">
{% if json_file[i['set_num']]['Set Checked'] == 'true' %}
<input class="s_check" id="s_check" type="checkbox" checked />
{% else %}
<input class="s_check" id="s_check" type="checkbox" />
{% endif %}
Set is checked
</label>
<label class="checkbox" >
<input type="hidden" id="set_num" value="{{ i['set_num'] }}">
{% if json_file[i['set_num']]['Set Collected'] == 'true' %}
<input class="s_col" id="s_col" type="checkbox" checked />
{% else %}
<input class="s_col" id="s_col" type="checkbox" />
{% endif %}
Set is collected
</label>
</div>
</div>
</div>
<footer class="card-footer" style="">
<p class="card-footer-item"> <p class="card-footer-item">
<span> <span>
<a style="color: #363636;" href="/{{ i['set_num'] }}">Inventory</a> <a class="is-size-7" style="color: #363636;" href="/{{ i['set_num'] }}">Inventory</a>
</span> </span>
</p> </p>
<p class="card-footer-item"> <p class="card-footer-item">
<span> <span>
<a style="color: #363636;" href="/{{ i['set_num'] }}">Instructions</a> <a class="is-size-7" style="color: #363636;" href="/{{ i['set_num'] }}">Instructions</a>
</span> </span>
</p> </p>
</footer> </footer>
</div> </div>
</div> </div>
</div>
{% endfor %} {% endfor %}
@ -211,7 +264,15 @@ function dynamicSort(className) {
sortedItems.sort(function(a, b) { sortedItems.sort(function(a, b) {
var textA = a.getElementsByClassName(className)[0].textContent.trim(); var textA = a.getElementsByClassName(className)[0].textContent.trim();
var textB = b.getElementsByClassName(className)[0].textContent.trim(); var textB = b.getElementsByClassName(className)[0].textContent.trim();
// Check if the className corresponds to a checkbox
if (className == 's_col' || className == 's_check') {
var checkedA = a.getElementsByClassName(className)[0].checked;
var checkedB = b.getElementsByClassName(className)[0].checked;
// Sort by checked checkboxes (true first, false last)
return (checkedA === checkedB) ? 0 : checkedA ? -1 : 1;
}
// Remove digits after hyphen if present // Remove digits after hyphen if present
textA = textA.replace(/-\d+$/, '').trim(); textA = textA.replace(/-\d+$/, '').trim();
textB = textB.replace(/-\d+$/, '').trim(); textB = textB.replace(/-\d+$/, '').trim();
@ -244,6 +305,77 @@ function dynamicSort(className) {
gridContainer.appendChild(sortedItems[i]); gridContainer.appendChild(sortedItems[i]);
} }
} }
$("body").on("change", "#s_fig", function (event) {
minif = $(this).prop('checked');
set_num = $(this).siblings().val()
$.ajax({
url: '/',
type: 'POST',
data: {
'set_num': set_num,
'minif': minif
}
});
});
$("body").on("change", "#s_check", function (event) {
scheck = $(this).prop('checked');
set_num = $(this).siblings().val()
$.ajax({
url: '/',
type: 'POST',
data: {
'set_num': set_num,
'scheck': scheck
}
});
});
$("body").on("change", "#s_col", function (event) {
scol = $(this).prop('checked');
set_num = $(this).siblings().val()
$.ajax({
url: '/',
type: 'POST',
data: {
'set_num': set_num,
'scol': scol
}
});
});
document.addEventListener('DOMContentLoaded', function () {
const toggleButton = document.getElementById('toggleButton');
let isHidden = true; // Initially, only show checked grid items
toggleButton.addEventListener('click', function() {
// Get all grid items
const gridItems = document.querySelectorAll('.grid-item');
// Iterate over each grid item
gridItems.forEach(function(item) {
// Check if the corresponding checkbox is checked
const checkbox = item.querySelector('.s_col');
if (isHidden || (checkbox && checkbox.checked)) {
// Show the grid item if it's hidden or the checkbox is checked
item.style.display = 'block';
} else {
// Hide the grid item if the checkbox is not checked
item.style.display = 'none';
}
});
// Invert the visibility state for the next click
isHidden = !isHidden;
});
});
</script> </script>
</body> </body>
</html> </html>