Added basic console site generator and web server

This commit is contained in:
Mark Qvist 2023-01-07 23:32:07 +01:00
parent f932c43411
commit 0d59b6b672
20 changed files with 249 additions and 80 deletions

1
.gitignore vendored
View File

@ -5,4 +5,5 @@ TODO
Release/*.hex Release/*.hex
Release/*.zip Release/*.zip
Release/*.json Release/*.json
Console/build
build/* build/*

View File

@ -15,10 +15,6 @@
#error Target CONFIG_IDF_TARGET is not supported #error Target CONFIG_IDF_TARGET is not supported
#endif #endif
// Replace with your network credentials
const char* ssid = "RNode Test";
const char* password = "somepass";
WebServer server(80); WebServer server(80);
void console_dbg(String msg) { void console_dbg(String msg) {
@ -63,6 +59,8 @@ String console_get_content_type(String filename) {
return "application/x-zip"; return "application/x-zip";
} else if (filename.endsWith(".gz")) { } else if (filename.endsWith(".gz")) {
return "application/x-gzip"; return "application/x-gzip";
} else if (filename.endsWith(".whl")) {
return "application/octet-stream";
} }
return "text/plain"; return "text/plain";
} }
@ -83,6 +81,7 @@ bool console_serve_file(String path) {
File file = SPIFFS.open(path, "r"); File file = SPIFFS.open(path, "r");
console_dbg("Serving file to client"); console_dbg("Serving file to client");
server.streamFile(file, content_type); server.streamFile(file, content_type);
console_dbg("Closing file");
file.close(); file.close();
console_dbg("File serving done"); console_dbg("File serving done");
@ -104,8 +103,7 @@ void console_register_pages() {
void console_start() { void console_start() {
Serial.println(""); Serial.println("");
console_dbg("Starting Access Point..."); console_dbg("Starting Access Point...");
// WiFi.softAP(ssid, password); WiFi.softAP(bt_devname);
WiFi.softAP(bt_devname, password);
delay(150); delay(150);
IPAddress ip(10, 0, 0, 1); IPAddress ip(10, 0, 0, 1);
IPAddress nm(255, 255, 255, 0); IPAddress nm(255, 255, 255, 0);
@ -125,10 +123,9 @@ void console_start() {
void console_loop(){ void console_loop(){
server.handleClient(); server.handleClient();
// Internally, this yields the thread and allows // Internally, this yields the thread and allows
// other tasks to run. // other tasks to run.
delay(5); delay(2);
} }
// void listDir(fs::FS &fs, const char * dirname, uint8_t levels){ // void listDir(fs::FS &fs, const char * dirname, uint8_t levels){

View File

@ -7,10 +7,11 @@ site:
@mkdir -p ./build/css @mkdir -p ./build/css
@mkdir -p ./build/gfx @mkdir -p ./build/gfx
@mkdir -p ./build/images @mkdir -p ./build/images
# @mkdir -p ./build/pkgs
python ./build.py python ./build.py
cp assets/css/* build/css/ @cp assets/css/* build/css/
cp assets/gfx/* build/gfx/ @cp assets/gfx/* build/gfx/
cp assets/images/* build/images/ # @cp assets/images/* build/images/
cp assets/scripts/* build/scripts/ # @cp assets/scripts/* build/scripts/
# @cp -r ../../Reticulum/docs/manual/* build/reticulum_manual/ # @cp -r ../../Reticulum/docs/manual/* build/reticulum_manual/
# @cp -r ../../Reticulum/docs/Reticulum\ Manual.pdf build/reticulum_manual/ # @cp -r ../../Reticulum/docs/Reticulum\ Manual.pdf build/reticulum_manual/

BIN
Console/assets/gfx/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
Console/assets/gfx/nn.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View File

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

View File

@ -1,9 +1,17 @@
import markdown import markdown
import os import os
import shutil
packages = {
"rns": "rns-0.4.6-py3-none-any.whl",
"nomadnet": "nomadnet-0.3.1-py3-none-any.whl",
"lxmf": "lxmf-0.2.8-py3-none-any.whl",
}
DEFAULT_TITLE = "RNode Bootstrap Console" DEFAULT_TITLE = "RNode Bootstrap Console"
SOURCES_PATH="./source" SOURCES_PATH="./source"
BUILD_PATH="./build" BUILD_PATH="./build"
PACKAGES_PATH = "../../dist_archive"
INPUT_ENCODING="utf-8" INPUT_ENCODING="utf-8"
OUTPUT_ENCODING="utf-8" OUTPUT_ENCODING="utf-8"
@ -13,7 +21,7 @@ document_start = """
<!doctype html> <!doctype html>
<html> <html>
<head> <head>
<link rel="stylesheet" href="water.css?v=5"> <link rel="stylesheet" href="{ASSET_PATH}css/water.css">
<link rel="shortcut icon" type="image/x-icon" href="{ASSET_PATH}gfx/icon.png"> <link rel="shortcut icon" type="image/x-icon" href="{ASSET_PATH}gfx/icon.png">
<meta charset="utf-8"/> <meta charset="utf-8"/>
<title>{PAGE_TITLE}</title> <title>{PAGE_TITLE}</title>
@ -26,7 +34,7 @@ document_start = """
document_end = """</body></html>""" document_end = """</body></html>"""
menu_md = """<center><span class="menu">[Start]({CONTENT_PATH}index.html) | [Replicate]({CONTENT_PATH}replicate.html) | [Guides]({CONTENT_PATH}guides.html) | [Software]({CONTENT_PATH}software/index.html)| [Help](help.html) | [Contribute]({CONTENT_PATH}contribute.html)</span></center>""" menu_md = """<center><span class="menu">[Start]({CONTENT_PATH}index.html) | [Replicate]({CONTENT_PATH}replicate.html) | [Guides]({CONTENT_PATH}guides.html) | [Software]({CONTENT_PATH}software.html) | [Help](help.html) | [Contribute]({CONTENT_PATH}contribute.html)</span></center>"""
url_maps = [ url_maps = [
# { "path": "", "target": "/.md"}, # { "path": "", "target": "/.md"},
@ -125,6 +133,10 @@ def generate_html(f, root_path):
menu_html = markdown.markdown(menu_md.replace("{CONTENT_PATH}", root_path), extensions=["markdown.extensions.fenced_code"]).replace("<p></p>", "") menu_html = markdown.markdown(menu_md.replace("{CONTENT_PATH}", root_path), extensions=["markdown.extensions.fenced_code"]).replace("<p></p>", "")
page_html = markdown.markdown(md, extensions=["markdown.extensions.fenced_code"]).replace("{ASSET_PATH}", root_path) page_html = markdown.markdown(md, extensions=["markdown.extensions.fenced_code"]).replace("{ASSET_PATH}", root_path)
page_html = page_html.replace("{LXMF_ADDRESS}", LXMF_ADDRESS) page_html = page_html.replace("{LXMF_ADDRESS}", LXMF_ADDRESS)
for pkg_name in packages:
page_html = page_html.replace("{PKG_"+pkg_name+"}", pkg_name+".zip")
page_html = page_html.replace("{PKG_NAME_"+pkg_name+"}", packages[pkg_name])
page_date = get_prop(md, "date") page_date = get_prop(md, "date")
if page_date != None: if page_date != None:
page_html = page_html.replace("{DATE}", page_date) page_html = page_html.replace("{DATE}", page_date)
@ -133,6 +145,39 @@ def generate_html(f, root_path):
source_files = scan_pages(SOURCES_PATH) source_files = scan_pages(SOURCES_PATH)
def fetch_reticulum_site():
r_site_path = BUILD_PATH+"/r"
shutil.copytree(PACKAGES_PATH+"/reticulum.network", r_site_path)
shutil.rmtree(r_site_path+"/manual")
def gz_all():
import gzip
for root, dirs, files in os.walk(BUILD_PATH):
for file in files:
fpath = root+"/"+file
print("Gzipping "+fpath+"...")
f = open(fpath, "rb")
g = gzip.open(fpath+".gz", "wb")
g.writelines(f)
g.close()
f.close()
os.unlink(fpath)
from zipfile import ZipFile
for pkg_name in packages:
pkg_file = packages[pkg_name]
pkg_full_path = PACKAGES_PATH+"/"+pkg_file
if os.path.isfile(pkg_full_path):
print("Including "+pkg_file)
z = ZipFile(BUILD_PATH+"/"+pkg_name+".zip", "w")
z.write(pkg_full_path, pkg_full_path[len(PACKAGES_PATH+"/"):])
z.close()
# shutil.copy(pkg_full_path, BUILD_PATH+"/"+pkg_name)
else:
print("Could not find "+pkg_full_path)
exit(1)
for um in url_maps: for um in url_maps:
with open(SOURCES_PATH+"/"+um["target"], "rb") as f: with open(SOURCES_PATH+"/"+um["target"], "rb") as f:
of = BUILD_PATH+um["target"].replace(SOURCES_PATH, "").replace(".md", ".html") of = BUILD_PATH+um["target"].replace(SOURCES_PATH, "").replace(".md", ".html")
@ -160,3 +205,6 @@ for mdf in source_files:
with open(of, "wb") as wf: with open(of, "wb") as wf:
wf.write(html.encode(OUTPUT_ENCODING)) wf.write(html.encode(OUTPUT_ENCODING))
fetch_reticulum_site()
gz_all()

View File

@ -1,18 +0,0 @@
<div id="load_overlay" style="background-color:#2a2a2f; position:absolute; top:0px; left:0px; width:100%; height:100%; z-index:2000;"></div>
<span class="logo">unsigned.io</span>
<p></p><center><span class="menu"><a href="index.html">Home</a> | <a href="guides.html">Guides</a> | <a href="software/index.html">Software</a> | <a href="hardware/index.html">Hardware</a> | <a href="https://github.com/markqvist/Reticulum/discussions">Discussions</a> | <a href="https://unsigned.io/shop">Shop</a> | <a href="contact.html">Contact Me</a> | <a href="donate.html">Donate</a></span></center><p></p><hr><h2>Support My Work</h2>
<p>You can help support the continued development of open, free and private communications systems by donating via one of the following channels:</p>
<ul>
<li>Monero<br>
<code>84FpY1QbxHcgdseePYNmhTHcrgMX4nFfBYtz2GKYToqHVVhJp8Eaw1Z1EedRnKD19b3B8NiLCGVxzKV17UMmmeEsCrPyA5w</code>
<br><br></li>
<li>Ethereum<br>
<code>0x81F7B979fEa6134bA9FD5c701b3501A2e61E897a</code>
<br><br></li>
<li>Bitcoin<br>
<code>3CPmacGm34qYvR6XWLVEJmi2aNe3PZqUuq</code>
<br><br></li>
<li>Ko-Fi<br>
<a href="https://ko-fi.com/markqvist"><code>https://ko-fi.com/markqvist</code></a></li>
</ul>

View File

@ -1,36 +0,0 @@
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="water.css?v=5">
<link rel="shortcut icon" type="image/x-icon" href="{ASSET_PATH}gfx/icon.png">
<meta charset="utf-8"/>
<title>RNode Bootstrap Console</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div id="load_overlay" style="background-color:#2a2a2f; position:absolute; top:0px; left:0px; width:100%; height:100%; z-index:2000;"></div>
<span class="logo">RNode Console</span>
<br/>
<center><span class="menu"><a href="index.html">Start</a> | <a href="replicate.html">Replicate</a> | <a href="guides.html">Guides</a> | <a href="software.html">Software</a> | <a href="help.html">Help & Support</a> | <a href="donate.html">Donate</a></span></center>
<br/>
<hr>
<p>Welcome to the <b>RNode Bootstrap Console</b>. This repository contains all the tools, software and information necessary to bootstrap networks and communications systems based on Reticulum.</p>
<p>The tools and information contained in this RNode will also allow you to replicate the design, build more RNodes and grow your communications ecosystems.</p>
<br/>
<br/>
<center><img src="test.png" width="50%"/></center>
<br/>
<center>
<h3>What would you like to do?</h3>
<p>This repository contains resources for a variety of different tasks. You can browse this repository freely, or jump straight into a task-oriented workflow by selecting one of the starting points below.</p>
<br/>
<button type="button" id="task-rns">Create RNodes</button>
<button type="button" id="task-rns">Download Programs</button>
<button type="button" id="task-rns">Install Reticulum</button>
<button type="button" id="task-rns">Build A Network</button>
<button type="button" id="task-rns">Learn About Reticulum</button>
<button type="button" id="task-rns">Contribute</button>
<button type="button" id="task-rns">Get Help</button>
</center>
</body></html>

View File

@ -0,0 +1,37 @@
[title]: <> (Donate)
## Keep Communications Free and Open
Please take part in keeping the continued development, maintenance and distribution of the RNode ecosystem possible by donating via one of the following channels:
Donating to the project directly helps improve the entire system.
- Monero<br/>
```
84FpY1QbxHcgdseePYNmhTHcrgMX4nFfBYtz2GKYToqHVVhJp8Eaw1Z1EedRnKD19b3B8NiLCGVxzKV17UMmmeEsCrPyA5w
```
<br/><br/>
- Ethereum<br/>
```
0x81F7B979fEa6134bA9FD5c701b3501A2e61E897a
```
<br/><br/>
- Bitcoin<br/>
```
3CPmacGm34qYvR6XWLVEJmi2aNe3PZqUuq
```
<br/><br/>
- Ko-Fi<br/>
<a href="https://ko-fi.com/markqvist">`https://ko-fi.com/markqvist`</a>
## Spread Knowledge and Awareness
Another great way to contribute, is to spread awareness about the RNode project. Here's some ideas:
- Introduce the concepts of Free & Open Communications Systems to your community
- Teach others to build and use RNodes, and how to set up resilient and private communications systems
- Learn about using Reticulum to set up resilient communications networks, and teach these skills to people in your area that need them
## Contribute Code & Ideas
If you like to build and design, there is plenty of oppertunities to take part in the community around RNode, and the wider Reticulum community as well. There's always plenty of work to do, from writing code, to translating guides and information, to designing parts, devices and integrations. You can find us the following places:
- The [Reticulum Matrix Channel](element://room/!TRaVWNnQhAbvuiSnEK%3Amatrix.org?via=matrix.org) at `#reticulum:matrix.org`
- The [discussion forum](https://github.com/markqvist/Reticulum/discussions) on GitHub
- The [Reticulum subreddit](https://reddit.com/r/reticulum)

14
Console/source/help.md Normal file
View File

@ -0,0 +1,14 @@
[title]: <> (Get Help)
## Get Help
If you are having trouble, or if something is not working, these resources may be useful:
- The [Questions & Answers](qa.html) section
- The [No-Grid Communications Handbook](nghb.html)
- The [Reticulum Manual](manual/index.html)
## Community & Support
If things still aren't working as expected here are some great places to ask for help:
- The [discussion forum](https://github.com/markqvist/Reticulum/discussions) on GitHub
- The [Reticulum Matrix Channel](element://room/!TRaVWNnQhAbvuiSnEK%3Amatrix.org?via=matrix.org) at `#reticulum:matrix.org`
- The [Reticulum subreddit](https://reddit.com/r/reticulum)

21
Console/source/index.md Normal file
View File

@ -0,0 +1,21 @@
**Hello!** You have connected to the **RNode Bootstrap Console**.
This repository contains all the tools, software and information necessary to bootstrap networks and communications systems based on Reticulum. The tools and information contained in this RNode will also allow you to replicate the design, build more RNodes and grow your communications ecosystems.
<br/>
<center><img src="{ASSET_PATH}gfx/rnode_iso.png" width="50%"/></center>
<br/>
<center>
### What would you like to do?
This repository contains resources for a variety of different tasks. You can browse this repository freely, or jump straight into a task-oriented workflow by selecting one of the starting points below.
<br/>
<br/>
<button type="button" id="task-rns">Install Reticulum</button>
<button type="button" id="task-rns">Download Programs</button>
<button type="button" id="task-rns">Create RNodes</button>
<button type="button" id="task-rns">Build A Network</button>
<button type="button" id="task-rns">Learn More</button>
<button type="button" id="task-rns">Get Help</button>
<button type="button" id="task-rns">Contribute</button>
</center>

3
Console/source/qa.md Normal file
View File

@ -0,0 +1,3 @@
[title]: <> (Get Help)
## Questions & Answers
This section contains a list of common questions, and associated answers.

View File

@ -0,0 +1,3 @@
[title]: <> (Replicate)
# Create RNodes
This section contains the tools and guides necessary to create more RNodes.

View File

@ -0,0 +1,92 @@
[title]: <> (Software)
# Software
This RNode contains a repository of downloadable software and utilities, that are useful for bootstrapping communications networks, and for replicating RNodes.
**Please Note!** Whenever you install software onto your computer, there is a risk that someone modified this software to include malicious code. Be extra careful installing anything from this RNode, if you did not get it from a source you trust, or if there is a risk it was modified in transit.
If possible, you can check that the `SHA-256` hashes of any downloaded files correspond to the list of release hashes published on the [Reticulum Release page](https://github.com/markqvist/Reticulum/releases).
**You Have The Source!** Due to the size limitations of shipping all this software within an RNode, we don't include separate source-code archives for the below programs, but *all the source code is included within the Python .whl files*! You can simply unzip any of them with any program that understands `zip` files, and you will find the source code inside the unzipped directory (for some zip programs, you may need to change the file ending to `.zip`).
## Reticulum
-------------
The cryptographic networking stack for building resilient networks anywhere. This packages requires you have `python` and `pip` installed on your computer. This should come as standard on most operating systems released since 2020.
**Local Installation**
If you do not have access to the Internet, or would prefer to install Reticulum directly from this RNode, you can use the following instructions.
- Download the [{PKG_rns}]({ASSET_PATH}{PKG_rns}) package from this RNode and unzip it
- Install it with the command `pip install {PKG_NAME_rns}`
- Verify the installed Reticulum version by running `rnstatus --version`
**Online Installation**
If you are connected to the Internet, you can try to install the latest version of Reticulum via the `pip` package manager.
- Install Reticulum by running the command `pip install rns`
- Verify the installed Reticulum version by running `rnstatus --version`
If the installation has problems resolving dependencies, you can try to install the `python-cryptography`, `python-netifaces` and `python-pyserial` packages from your systems package manager, if they are locally available. If this is not possible, you please read the [Getting Started section of the Reticulum Manual]({ASSET_PATH}manual/gettingstartedfast.html) for more detailed information.
## LXMF
-------------
LXMF is a simple and flexible messaging format and delivery protocol that allows a wide variety of implementations, while using as little bandwidth as possible. It is built on top of [Reticulum](https://reticulum.network) and offers zero-conf message routing, end-to-end encryption and Forward Secrecy, and can be transported over any kind of medium that Reticulum supports.
LXMF is efficient enough that it can deliver messages over extremely low-bandwidth systems such as packet radio or LoRa. Encrypted LXMF messages can also be encoded as QR-codes or text-based URIs, allowing completely analog *paper message* transport.
Installing this LXMF library allows other programs on your system, like Nomad Network, to use the LXMF messaging system. It also includes the `lxmd` program that you can use to run LXMF propagation nodes on your network.
**Local Installation**
If you do not have access to the Internet, or would prefer to install LXMF directly from this RNode, you can use the following instructions.
- Download the [{PKG_lxmf}]({ASSET_PATH}{PKG_lxmf}) package from this RNode and unzip it
- Install it with the command `pip install {PKG_NAME_lxmf}`
- Verify the installed Reticulum version by running `lxmd --version`
**Online Installation**
If you are connected to the Internet, you can try to install the latest version of LXMF via the `pip` package manager.
- Install Nomad Network by running the command `pip install lxmf`
- Verify the installed Reticulum version by running `lxmd --version`
## Nomad Network
-------------
Off-grid, resilient mesh communication with strong encryption, forward secrecy and extreme privacy.
Nomad Network Allows you to build private and resilient communications platforms that are in complete control and ownership of the people that use them. No signups, no agreements, no handover of any data, no permissions and gatekeepers.
![Screenshot]({ASSET_PATH}gfx/nn.webp)
Nomad Network is build on [LXMF](lxmf.html) and [Reticulum]({ASSET_PATH}r/), which together provides the cryptographic mesh functionality and peer-to-peer message routing that Nomad Network relies on. This foundation also makes it possible to use the program over a very wide variety of communication mediums, from packet radio to fiber optics.
Nomad Network does not need any connections to the public internet to work. In fact, it doesn't even need an IP or Ethernet network. You can use it entirely over packet radio, LoRa or even serial lines. But if you wish, you can bridge islanded networks over the Internet or private ethernet networks, or you can build networks running completely over the Internet. The choice is yours.
**Local Installation**
If you do not have access to the Internet, or would prefer to install Nomad Network directly from this RNode, you can use the following instructions.
- Download the [{PKG_nomadnet}]({ASSET_PATH}{PKG_nomadnet}) package from this RNode and unzip it
- Install it with the command `pip install {PKG_NAME_nomadnet}`
- Verify the installed Reticulum version by running `nomadnet --version`
**Online Installation**
If you are connected to the Internet, you can try to install the latest version of Nomad Network via the `pip` package manager.
- Install Nomad Network by running the command `pip install nomadnet`
- Verify the installed Reticulum version by running `nomadnet --version`
## Sideband
-------------
Sideband is an LXMF client for Android, Linux and macOS. It allows you to communicate with other people or LXMF-compatible systems over Reticulum networks using LoRa, Packet Radio, WiFi, I2P, or anything else Reticulum supports. Sideband also supports exchanging messages through encrypted QR-codes on paper, or through messages embedded directly in lxm:// links.
![Screenshot]({ASSET_PATH}gfx/sideband.webp)
The Sideband program is to large to be included on this RNode, but downloads for Linux, Android and macOS can be obtained from following sources:
- The [Sideband page](https://unsigned.io/sideband/) on [unsigned.io](https://unsigned.io/)
- The [GitHub release page for Sideband](https://github.com/markqvist/Sideband/releases/latest)
- The [IzzyOnDroid repository for F-Droid](https://android.izzysoft.de/repo/apk/io.unsigned.sideband)

View File

@ -22,10 +22,16 @@ prep-samd:
arduino-cli core update-index --config-file arduino-cli.yaml arduino-cli core update-index --config-file arduino-cli.yaml
arduino-cli core install adafruit:samd arduino-cli core install adafruit:samd
spiffs-image: console-site:
python Release/esptool/spiffsgen.py 2031616 ./Console Release/spiffs.bin make -C Console clean site
spiffs-deploy: spiffs: console-site spiffs-image
spiffs-image:
python Release/esptool/spiffsgen.py 2031616 ./Console/build Release/spiffs.bin
# python Release/esptool/spiffsgen.py --obj-name-len 64 2031616 ./Console/build Release/spiffs.bin
upload-spiffs:
@echo Deploying SPIFFS image... @echo Deploying SPIFFS image...
python ./Release/esptool/esptool.py --chip esp32 --port /dev/ttyACM1 --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 80m --flash_size 4MB 0x210000 ./Release/spiffs.bin python ./Release/esptool/esptool.py --chip esp32 --port /dev/ttyACM1 --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 80m --flash_size 4MB 0x210000 ./Release/spiffs.bin

Binary file not shown.