Created
April 25, 2020 09:24
-
-
Save ariejan/d169bafab4229bca8d3d4cd66a6b0fa9 to your computer and use it in GitHub Desktop.
LEGO Checklist script
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// Taken from https://chkno.net/lego-pieces/index.phps | |
// Working at https://chkno.net/lego-pieces/?set=42009-1 | |
if (isset($_GET['set'])) { | |
$set = urlencode($_GET['set']); | |
} else { | |
$set = "1682-1"; | |
} | |
?><!DOCTYPE HTML><html> | |
<head> | |
<style> | |
body { font-size: 66% } | |
.checkbox { font-size: 120% } | |
.piece { float: left; border: solid 1px; padding: .3em; margin: .1em; page-break-inside: avoid; } | |
.hiding { opacity: 0; -webkit-transform: rotate(180deg); transform: rotate(180deg); | |
transition: opacity .6s, -webkit-transform 1s, transform 1s; } | |
.hidden { display: none; } | |
.reset { clear: left; margin-top: 10em; } | |
.clearfix { content: ""; clear: both; display: table; } | |
img { max-height: 7em; } | |
@media print { | |
.checkbox input { display: none } | |
.checkbox:after { content: '☐' } | |
.reset { display: none; } | |
} | |
</style> | |
<script> | |
const set = <?php echo json_encode($set); ?>; | |
function restore_checkbox_values() { | |
const checkboxes = document.getElementsByTagName('input'); | |
for (var i = 0; i < checkboxes.length; i++) { | |
const key = 'brick-' + checkboxes[i].id; | |
if (key in localStorage && localStorage[key] === 'true') { | |
checkboxes[i].checked = localStorage[key]; | |
} | |
} | |
} | |
function save_checkbox_value(checkbox) { | |
localStorage['brick-' + checkbox.id] = checkbox.checked; | |
} | |
function is_done(piece) { | |
return (Array.from(piece.childNodes) | |
.filter(e => e.hasChildNodes() && | |
e.firstChild.nodeType == e.firstChild.ELEMENT_NODE && | |
e.firstChild.getAttribute("type") == "checkbox") | |
.map(e => e.firstChild.checked) | |
.reduce((a, b) => a && b)); | |
} | |
function hide_piece(piece) { | |
piece.classList.add("hiding"); | |
setTimeout(function() { piece.classList.add("hidden"); }, 350) | |
} | |
function hide_if_done(piece) { | |
<?php if (isset($_GET['completed']) && $_GET['completed'] === 'hide') { ?> | |
if (is_done(piece)) { | |
hide_piece(piece); | |
} | |
<?php } ?> | |
} | |
function respond_to_change(checkbox) { | |
save_checkbox_value(checkbox); | |
hide_if_done(checkbox.parentElement.parentElement); | |
} | |
function hide_any_that_are_done() { | |
Array.from(document.getElementsByClassName("piece")).forEach(hide_if_done); | |
} | |
function start() { | |
restore_checkbox_values(); | |
hide_any_that_are_done(); | |
} | |
function reset() { | |
(Array.from(document.getElementsByTagName("input")) | |
.filter(e => e.getAttribute("type") == "checkbox") | |
.forEach(function(e) { | |
e.checked = false; | |
save_checkbox_value(e); | |
})); | |
(Array.from(document.getElementsByClassName("piece")) | |
.forEach(e => e.classList.remove("hiding", "hidden"))); | |
} | |
</script> | |
<title><?php echo htmlspecialchars($set)?></title> | |
</head> | |
<body onload='start()'> | |
<div class="pieces clearfix"> | |
<?php | |
function make_id($str) { | |
# Per https://www.w3.org/TR/html401/types.html#type-name | |
$safe_chars = preg_replace('/[^[:alnum:]_:.-]/', '_', $str); | |
return preg_match('/^[[:alpha:]]/', $safe_chars) ? $safe_chars : ('a' . $safe_chars); | |
} | |
$ch = curl_init("https://rebrickable.com/api/v3/lego/sets/" . $set . "/parts/?page_size=1000"); | |
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); | |
curl_setopt($ch, CURLOPT_HTTPHEADER, array( | |
'Accept: application/json', | |
'Authorization: key 123456789abcdef0123456789abcdef0' # (PUT YOUR OWN AUTH KEY HERE!) | |
)); | |
$parts_json = curl_exec($ch); | |
curl_close($ch); | |
$parts = json_decode($parts_json, true); | |
if (isset($_GET['sort']) && $_GET['sort'] === 'part') { | |
usort($parts['results'], | |
function($a, $b) { | |
$cmp = strnatcmp($a['part']['name'], $b['part']['name']); | |
return $cmp !== 0 ? $cmp : strnatcmp($a['color']['name'], $b['color']['name']); | |
}); | |
} | |
foreach($parts['results'] as $result) { | |
if (!$result['is_spare']) { | |
?> | |
<div class="piece"><img src="<?php echo htmlspecialchars($result['part']['part_img_url']) ?>"> | |
<div><?php echo htmlspecialchars($result['color']['name'] . " " . $result['part']['name']) ?></div> | |
<?php | |
echo htmlspecialchars($result['quantity']); | |
for ($i = 0; $i < $result['quantity']; $i++) { | |
$part_name = make_id('s' . $set . | |
'p' . $result['part']['part_num'] . | |
'c' . $result['color']['id'] . | |
'n' . $i); | |
?> <span class="checkbox"><input type="checkbox" id="<?php echo htmlspecialchars($part_name)?>" onchange='respond_to_change(this)'></input></span><?php | |
} | |
?></div> | |
<?php | |
} | |
} | |
?> | |
</div> | |
<input class="reset" type="reset" onclick="reset()" value="Reset (clear all checkboxes on this page!)"></input> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment