Implemented tools as applets, Added Docker CCTV page, Fixed small issues

Update app.py, uuid-generator.yml, and 47 more files...
This commit is contained in:
2025-02-20 17:24:05 +01:00
parent bd96d85699
commit 0e91b5ed96
43 changed files with 889 additions and 337 deletions

View File

@@ -0,0 +1,134 @@
/**
* Generates a random UUID4 and returns its string representation
* @returns {`${string}-${string}-${string}-${string}-${string}`}
*/
export function generateUUID4(addHyphens, addGuidBrackets) {
let uuid4 = crypto.randomUUID();
if(!addHyphens) {
uuid4 = uuid4.replace(/-/g, "");
}
if(addGuidBrackets) {
uuid4 = "{" + uuid4 + "}";
}
return uuid4;
}
// Tool-centric stuff
{
/** @type {HTMLSelectElement} */
const eOptionTypeSelect = document.querySelector("select#uuid-generator-option-type");
/** @type {HTMLInputElement} */
const eOptionCountInput = document.querySelector("input#uuid-generator-option-count");
/** @type {HTMLInputElement} */
const eOptionHyphenInput = document.querySelector("input#uuid-generator-option-hyphens");
/** @type {HTMLInputElement} */
const eOptionGuidBracketsInput = document.querySelector("input#uuid-generator-option-guid-brackets");
/** @type {HTMLElement} */
const eGenerateButton = document.querySelector("#uuid-generator-generate");
/** @type {HTMLElement} */
const eDownloadRawButton = document.querySelector("#uuid-generator-download-raw");
/** @type {HTMLElement} */
const eDownloadJsonButton = document.querySelector("#uuid-generator-download-json");
/** @type {HTMLElement} */
const eDownloadYamlButton = document.querySelector("#uuid-generator-download-yaml");
/** @type {HTMLTextAreaElement} */
const ePreviewTextArea = document.querySelector("textarea#uuid-generator-preview");
let lastUUIDs = [];
/** @returns {number} */
function getDesiredCount() {
let desiredCount = null;
try {
desiredCount = parseInt(eOptionCountInput.value);
} catch (e) {
console.error(e);
}
if(desiredCount === null) {
desiredCount = 1;
}
if(desiredCount < 1) {
desiredCount = 1;
}
if(desiredCount > 1000) {
desiredCount = 1000;
}
return desiredCount;
}
function changeDesiredCount(difference = 0) {
if(difference !== 0) {
eOptionCountInput.value = getDesiredCount() + difference;
}
eOptionCountInput.value = getDesiredCount();
}
function downloadStringAsFile(content, filename, contentType) {
const blob = new Blob([content], { type: contentType });
const link = document.createElement('a');
const url = URL.createObjectURL(blob);
link.href = url;
link.download = filename;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
URL.revokeObjectURL(url);
}
window.onload = function () {
eGenerateButton.addEventListener("click", function() {
ePreviewTextArea.value = "";
let desiredCount = getDesiredCount();
let uuidGenerator = generateUUID4;
let addHyphens = eOptionHyphenInput.checked;
let addGuidBrackets = eOptionGuidBracketsInput.checked;
lastUUIDs = [];
for(let i= 0; i < desiredCount; i++) {
lastUUIDs.push(uuidGenerator(addHyphens, addGuidBrackets));
ePreviewTextArea.value += uuidGenerator(addHyphens, addGuidBrackets) + "\n";
}
ePreviewTextArea.value = lastUUIDs.join("\n");
});
eOptionCountInput.addEventListener("change", function() {
changeDesiredCount(0);
});
eOptionCountInput.addEventListener("mousewheel", function(e) {
// Handling wheel scroll on count field.
if(e.wheelDelta < 0) {
changeDesiredCount(-1);
} else {
changeDesiredCount(1);
}
});
eDownloadRawButton.addEventListener("click", function() {
if (lastUUIDs.length <= 0) {
return;
}
downloadStringAsFile(lastUUIDs.join("\n"), "uuids.txt", "text/plain");
});
eDownloadJsonButton.addEventListener("click", function() {
if (lastUUIDs.length <= 0) {
return;
}
downloadStringAsFile(JSON.stringify(lastUUIDs, null, 4), "uuids.json", "application/json");
});
eDownloadYamlButton.addEventListener("click", function() {
if (lastUUIDs.length <= 0) {
return;
}
downloadStringAsFile("- \"" + lastUUIDs.join("\"\n- \"") + "\"", "uuids.yaml", "text/yaml");
});
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -0,0 +1,38 @@
# CircuitPython - Custom File Systems
The goal of this experiment was to try and give people a strong, clear, and documented starting point for
future experiments that may require virtual file systems and block-level devices on CircuitPython devices.
For example, by using the blank examples, you can easily create a bootstrapping code and file system that connects
securely to a remote server and pulls code directly from it without ever having to touch the MCU's flash storage. \
The second main advantage is that this project can serve as a robust educational tool. \
Due to the permissive nature of Python and CircuitPython's APIs, it lets people easily test out different designs and
mechanisms for their file systems without running the risk of corrupting unrelated data or bricking their device. \
Additionally, it is possible to manipulate and add logging to many of the methods which allows you to see and understand
the inner workings of CircuitPython, filesystems and BLD devices themselves.
Le but de cette expérience était de fournir un point de départ solide, clair et documenté pour
de futures expériences nécessitant des systèmes de fichiers virtuels, ou des périphériques de bloc sur
des appareils utilisant CircuitPython.
Par exemple, en utilisant les exemples modèles, il est possible de créer facilement un code de démarrage et
un système de fichiers qui vont connecter de manière sécurisée à un serveur distant, et y récupérer directement du
code sans jamais avoir à toucher à la mémoire flash du MCU.
Le deuxième avantage majeur est que ce projet peut servir d'outil éducatif.
En effet, les APIs extrêmement permissives de Python et CircuitPython permettent à leurs utilisateurs de tester
facilement différents designs et mécanismes pour leurs systèmes de fichiers sans risquer de corrompre des
données ou de rendre leur appareil inutilisable. \
De plus, vous pouvez très facilement ajouter des messages de débogage et manipuler plusieurs méthodes, ce
qui permet de voir et de comprendre le fonctionnement interne de CircuitPython, des systèmes de fichiers et
des périphériques de bloc en eux-mêmes.
## ???
## Media coverage
https://blog.adafruit.com/2023/02/22/icymi-python-on-microcontrollers-newsletter-new-raspberry-pi-debug-probe-circuitpython-8-0-2-and-much-more-circuitpython-python-micropython-icymi-raspberry_pi/

View File

@@ -1,61 +0,0 @@
/**
* Generates a random UUID4 and returns its string representation
* @returns {`${string}-${string}-${string}-${string}-${string}`}
*/
export function generateUUID4() {
return crypto.randomUUID();
}
// Tool-centric stuff
{
/** @type {HTMLSelectElement} */
const eOptionTypeSelect = document.querySelector("select#uuid-generator-option-type");
/** @type {HTMLInputElement} */
const eOptionCountInput = document.querySelector("input#uuid-generator-option-count");
/** @type {HTMLInputElement} */
const eOptionHyphenInput = document.querySelector("input#uuid-generator-option-hyphens");
/** @type {HTMLElement} */
const eGenerateButton = document.querySelector("#uuid-generator-generate");
/** @type {HTMLElement} */
const eDownloadButton = document.querySelector("#uuid-generator-download");
/** @type {HTMLTextAreaElement} */
const ePreviewTextArea = document.querySelector("textarea#uuid-generator-preview");
/** @returns {number} */
function getDesiredCount() {
let desiredCount = null;
try {
desiredCount = parseInt(eOptionCountInput.value);
} catch (e) {
console.error(e);
}
if(desiredCount === null) {
desiredCount = 1;
}
if(desiredCount < 1) {
desiredCount = 1;
}
if(desiredCount > 1000) {
desiredCount = 1000;
}
return desiredCount;
}
window.onload = function () {
eGenerateButton.addEventListener("click", function() {
ePreviewTextArea.value = "";
let desiredCount = getDesiredCount();
let uuidGenerator = generateUUID4;
for(let i= 0; i < desiredCount; i++) {
ePreviewTextArea.value += uuidGenerator() + "\n";
}
});
eDownloadButton.addEventListener("click", function() {
//eFileDropInput.click();
});
}
}