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:
@@ -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 |
@@ -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/
|
@@ -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();
|
||||
});
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user