Added theme download script. Added front page info and save to file, as well as extra sort options
This commit is contained in:
parent
3883c67d96
commit
2b9448fd35
46
app.py
46
app.py
@ -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
4
lego.sh
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
wget https://cdn.rebrickable.com/media/downloads/themes.csv.gz
|
||||||
|
gzip -d themes.csv.gz
|
@ -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>
|
||||||
|
Loading…
Reference in New Issue
Block a user