Merge pull request #1 from lavafroth/autorun-boot-script
- If a script called `boot.dd` exists, it will be run without user confirmation asynchronously while setting up the server - Makes the file list cover the view on smaller screens - Replaces old JS patterns with modern IE10+ patterns - Adds a button to confirm file title without the need to press enter
This commit is contained in:
15
src/code.py
15
src/code.py
@@ -9,11 +9,11 @@ import microcontroller
|
||||
import socketpool
|
||||
import wifi
|
||||
from adafruit_httpserver import POST, FileResponse, Request, Server
|
||||
from ducky import run_boot_script
|
||||
|
||||
from api import handle
|
||||
|
||||
|
||||
async def main():
|
||||
async def setup_server():
|
||||
"""
|
||||
Begin a wifi access point defined by the SSID and PASSWORD environment
|
||||
variables.
|
||||
@@ -44,6 +44,17 @@ async def main():
|
||||
server.serve_forever(str(wifi.radio.ipv4_address_ap))
|
||||
|
||||
|
||||
async def main():
|
||||
"""
|
||||
Asynchronously run the boot script while setting
|
||||
the server up for the web interface.
|
||||
"""
|
||||
await asyncio.gather(
|
||||
run_boot_script(),
|
||||
setup_server()
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
asyncio.run(main())
|
||||
|
||||
12
src/ducky.py
12
src/ducky.py
@@ -118,3 +118,15 @@ def run_script_file(path: str):
|
||||
run_script(handle.read())
|
||||
except OSError as error:
|
||||
warn(f"unable to open file {path}: {error}")
|
||||
|
||||
|
||||
async def run_boot_script():
|
||||
"""
|
||||
If a script with the name 'boot.dd' exists,
|
||||
run it without user interaction on boot.
|
||||
"""
|
||||
try:
|
||||
with open("payloads/boot.dd", "r", encoding="utf-8") as handle:
|
||||
run_script(handle.read())
|
||||
except OSError:
|
||||
info("boot script does not exist, skipping its execution")
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="files">
|
||||
<div class="hide files">
|
||||
</div>
|
||||
<div class="sidebar">
|
||||
<div class="documents icon"></div>
|
||||
@@ -19,7 +19,14 @@
|
||||
<div class="add icon"></div>
|
||||
</div>
|
||||
<div class="editorarea">
|
||||
<input class="title" placeholder="new file"></input>
|
||||
<div class="title-bar">
|
||||
<input class="title" placeholder="new file"></input>
|
||||
<button class="title-btn">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" class="bi bi-check" viewBox="0 0 16 16">
|
||||
<path d="M10.97 4.97a.75.75 0 0 1 1.07 1.05l-3.99 4.99a.75.75 0 0 1-1.08.02L4.324 8.384a.75.75 0 1 1 1.06-1.06l2.094 2.093 3.473-4.425a.267.267 0 0 1 .02-.022z"/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<textarea class="editor"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -13,8 +13,9 @@ body {
|
||||
}
|
||||
|
||||
.container {
|
||||
height: calc(70vh);
|
||||
height: 70vh;
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
@@ -44,8 +45,9 @@ body {
|
||||
background: #111;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 25vw;
|
||||
width: 0;
|
||||
overflow: scroll;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.entry {
|
||||
@@ -90,23 +92,36 @@ body {
|
||||
.editorarea {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.editorarea > .title {
|
||||
padding: 0.5rem 1rem;
|
||||
.editorarea > .title-bar {
|
||||
color: #888;
|
||||
background: #222;
|
||||
outline: none;
|
||||
border: none;
|
||||
border-bottom: #444 solid 0.1rem;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.editorarea > .title-bar > .title {
|
||||
outline: none;
|
||||
border: none;
|
||||
background: #222;
|
||||
flex-grow: 1;
|
||||
padding: 0.5rem 1rem;
|
||||
}
|
||||
|
||||
.editorarea > .title-bar > .title-btn {
|
||||
border: none;
|
||||
background: #222;
|
||||
padding: 0 0.4rem 0 0.4rem;
|
||||
}
|
||||
|
||||
.editor {
|
||||
background: #222;
|
||||
border: none;
|
||||
resize: none;
|
||||
min-width: max-content;
|
||||
height: calc(70vh - 3rem);
|
||||
padding: 0.5rem;
|
||||
}
|
||||
@@ -136,3 +151,9 @@ body {
|
||||
.editor:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
@media screen and (orientation: portrait) {
|
||||
.show {
|
||||
width: calc(100vw - 3rem);
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,8 @@ const logs = document.querySelector('.logs')
|
||||
const documents_icon = document.querySelector('.documents')
|
||||
const run_icon = document.querySelector('.run')
|
||||
const add_icon = document.querySelector('.add')
|
||||
const title = document.querySelector('.editorarea > .title')
|
||||
const title = document.querySelector('.editorarea > .title-bar > .title')
|
||||
const title_button = document.querySelector('.editorarea > .title-bar > .title-btn')
|
||||
let timer
|
||||
|
||||
function doApi(message) {
|
||||
@@ -67,10 +68,15 @@ function reload_listing() {
|
||||
})
|
||||
}
|
||||
|
||||
function create_file() {
|
||||
title.readOnly = true
|
||||
doApi({"action": "create", "filename": title.value})
|
||||
}
|
||||
|
||||
title_button.addEventListener('click', create_file);
|
||||
title.addEventListener('keypress', (e) => {
|
||||
if (e.keyCode==13) {
|
||||
title.readOnly = true
|
||||
doApi({"action": "create", "filename": title.value})
|
||||
create_file()
|
||||
}
|
||||
})
|
||||
|
||||
@@ -82,14 +88,8 @@ add_icon.addEventListener('click', () => {
|
||||
})
|
||||
|
||||
documents_icon.addEventListener('click', () => {
|
||||
const classList = files.classList
|
||||
if (classList.contains("show")) {
|
||||
files.classList.replace('show', 'hide')
|
||||
} else if (classList.contains("hide")) {
|
||||
files.classList.replace('hide', 'show')
|
||||
} else {
|
||||
files.classList.add('hide')
|
||||
}
|
||||
files.classList.toggle("show");
|
||||
files.classList.toggle("hide");
|
||||
});
|
||||
|
||||
run_icon.addEventListener('click', () => {
|
||||
|
||||
Reference in New Issue
Block a user