cleanup and gzip web files

- clean up unnecessary files
- fix ota update, maybe preventing timeouts
- new 'wwwroot' folder for the web source files, and python script to gzip the files to the /data/www folder
- run gzip_wwwfiles.py to compress the files in wwwroot into /data/www
This commit is contained in:
Nic Limper
2023-07-29 20:47:12 +02:00
parent a78f2e3af5
commit f9b4d163bc
30 changed files with 91 additions and 106 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

View File

@@ -1,64 +0,0 @@
import requests
from PIL import Image, ImageDraw, ImageFont
mac = "00000197E5CB3B38" # destination mac address
dither = 0 # set dither to 1 is you're sending photos etc
apip = "192.168.178.192" # ip address of your access point
# Create a new paletted image with indexed colors
image = Image.new('P', (296, 128))
# Define the color palette (white, black, red)
palette = [
255, 255, 255, # white
0, 0, 0, # black
255, 0, 0 # red
]
# Assign the color palette to the image
image.putpalette(palette)
# Initialize the drawing context
draw = ImageDraw.Draw(image)
# Define the text lines
line1 = 'OpenEPaperLink'
line2 = 'Demo image'
# Define the fonts and sizes
font_line1 = ImageFont.truetype('arial.ttf', size=36) # Change the font file and size as per your preference
font_line2 = ImageFont.truetype('arial.ttf', size=16) # Change the font file and size as per your preference
# Calculate the text bounding boxes to get the text widths and heights
text_bbox_line1 = draw.textbbox((0, 0), line1, font=font_line1)
text_bbox_line2 = draw.textbbox((0, 0), line2, font=font_line2)
# Calculate the text positions to center the lines horizontally
text_position_line1 = ((image.width - (text_bbox_line1[2] - text_bbox_line1[0])) // 2, 20)
text_position_line2 = ((image.width - (text_bbox_line2[2] - text_bbox_line2[0])) // 2, 80)
# Write the text on the image
draw.text(text_position_line1, line1, fill=2, font=font_line1) # Use palette index 1 for black color
draw.text(text_position_line2, line2, fill=1, font=font_line2) # Use palette index 2 for red color
# Convert the image to 24-bit RGB
rgb_image = image.convert('RGB')
# Save the image as JPEG with maximum quality
image_path = 'output.jpg'
rgb_image.save(image_path, 'JPEG', quality="maximum")
# Prepare the HTTP POST request
url = "http://" + apip + "/imgupload"
payload = {"dither": dither, "mac": mac} # Additional POST parameter
files = {"file": open(image_path, "rb")} # File to be uploaded
# Send the HTTP POST request
response = requests.post(url, data=payload, files=files)
# Check the response status
if response.status_code == 200:
print("Image uploaded successfully!")
else:
print("Failed to upload the image.")

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

View File

@@ -10,6 +10,20 @@
"/fonts/numbers3-1.vlw",
"/fonts/numbers3-2.vlw",
"/fonts/tw20.vlw",
"/fonts/twbold20.vlw"
"/fonts/twbold20.vlw",
"/alignment.jpg",
"/gradient.jpg",
"/demo_image_generator.py",
"/www/content_cards.json",
"/www/favicon.ico",
"/www/index.html",
"/www/jsontemplate-demo.html",
"/www/main.css",
"/www/main.js",
"/www/ota.js",
"/www/painter.js",
"/www/setup.html",
"/www/setup.js",
"/www/upload-demo.html"
]
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,27 @@
import os
import gzip
import shutil
def gzip_files(source_folder, destination_folder):
# Create the destination folder if it doesn't exist
if not os.path.exists(destination_folder):
os.makedirs(destination_folder)
# Get a list of all files in the source folder
files = os.listdir(source_folder)
for file in files:
source_file_path = os.path.join(source_folder, file)
destination_file_path = os.path.join(destination_folder, file + ".gz")
print(f"Gzipping: {file}")
with open(source_file_path, 'rb') as f_in, gzip.open(destination_file_path, 'wb') as f_out:
shutil.copyfileobj(f_in, f_out)
if __name__ == "__main__":
source_folder = "wwwroot" # Replace with the path of the source folder
destination_folder = "data/www" # Replace with the path of the destination folder
gzip_files(source_folder, destination_folder)

View File

@@ -1,8 +1,8 @@
/*
Read truetype(.ttf) and generate bitmap.
TrueType™ Reference Manual
https://developer.apple.com/fonts/TrueType-Reference-Manual/
TrueType™ Reference Manual: https://developer.apple.com/fonts/TrueType-Reference-Manual/
get info on a ttf file: https://fontdrop.info/
MIT licencse
original source by https://github.com/garretlab/truetype

View File

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

View File

@@ -62,16 +62,17 @@ export async function initUpdate() {
const releaseDetails = data.map(release => {
const assets = release.assets;
let fileUrl = null;
const filesJsonAsset = assets.find(asset => asset.name === 'files.json');
if (filesJsonAsset) {
fileUrl = filesJsonAsset.browser_download_url;
const filesJsonAsset = assets.find(asset => asset.name === 'filesystem.json');
const binariesJsonAsset = assets.find(asset => asset.name === 'binaries.json');
if (filesJsonAsset && binariesJsonAsset) {
return {
html_url: release.html_url,
tag_name: release.tag_name,
name: release.name,
date: formatDateTime(release.published_at),
author: release.author.login,
file_url: fileUrl
file_url: filesJsonAsset.browser_download_url,
bin_url: binariesJsonAsset.browser_download_url
}
};
});
@@ -87,7 +88,7 @@ export async function initUpdate() {
} else if (release.date < formatEpoch(currentBuildtime)) {
easyupdate.innerHTML = `Your version is newer than the latest release date.<br>Are you the developer? :-)`;
} else {
easyupdate.innerHTML = `An update from version ${currentVer} to version ${release.tag_name} is available.<button onclick="otamodule.updateAll('${release.file_url}','${release.tag_name}')">Update now!</button>`;
easyupdate.innerHTML = `An update from version ${currentVer} to version ${release.tag_name} is available.<button onclick="otamodule.updateAll('${release.bin_url}','${release.file_url}','${release.tag_name}')">Update now!</button>`;
}
}
}
@@ -101,7 +102,7 @@ export async function initUpdate() {
releaseDetails.forEach(release => {
if (release && release.html_url) {
const tableRow = document.createElement('tr');
let tablerow = `<td><a href="${release.html_url}" target="_new">${release.tag_name}</a></td><td>${release.date}</td><td>${release.name}</td><td><button onclick="otamodule.updateESP('${release.file_url}', true)">ESP32</button></td><td><button onclick="otamodule.updateWebpage('${release.file_url}','${release.tag_name}', true)">Filesystem</button></td>`;
let tablerow = `<td><a href="${release.html_url}" target="_new">${release.tag_name}</a></td><td>${release.date}</td><td>${release.name}</td><td><button onclick="otamodule.updateESP('${release.bin_url}', true)">ESP32</button></td><td><button onclick="otamodule.updateWebpage('${release.file_url}','${release.tag_name}', true)">Filesystem</button></td>`;
if (release.tag_name == currentVer) {
tablerow += "<td>current version</td>";
} else if (release.date < formatEpoch(currentBuildtime)) {
@@ -123,10 +124,10 @@ export async function initUpdate() {
});
}
export function updateAll(fileUrl, tagname) {
export function updateAll(binUrl, fileUrl, tagname) {
updateWebpage(fileUrl, tagname, false)
.then(() => {
updateESP(fileUrl, false);
updateESP(binUrl, false);
})
.catch(error => {
console.error(error);
@@ -152,48 +153,55 @@ export async function updateWebpage(fileUrl, tagname, showReload) {
print("Updating littleFS partition...");
try {
const response = await fetch("/update_actions", {
method: "POST",
body: ''
});
if (response.ok) {
const data = await response.text();
} else {
print(`error performing update actions: ${response.status}`, "red");
errors++;
}
} catch (error) {
console.error(`error calling update actions:` + error, "red");
errors++;
}
fetch("/getexturl?url=" + fileUrl)
.then(response => response.json())
.then(data => {
checkfiles(data.files);
checkfiles(data);
})
.catch(error => {
print('Error fetching data:' + error, "red");
});
const checkfiles = async (files) => {
const updateactions = files.find(files => files.name === "update_actions.json");
if (updateactions) {
await fetchAndPost(updateactions.url, updateactions.name, updateactions.path);
try {
const response = await fetch("/update_actions", {
method: "POST",
body: ''
});
if (response.ok) {
const data = await response.text();
} else {
print(`error performing update actions: ${response.status}`, "red");
errors++;
}
} catch (error) {
console.error(`error calling update actions:` + error, "red");
errors++;
}
}
for (const file of files) {
try {
const url = "/check_file?path=" + encodeURIComponent(file.path);
const response = await fetch(url);
if (response.ok) {
const data = await response.json();
if (data.filesize == file.size && data.md5 == file.md5) {
print(`file ${file.path} is up to date`, "green");
} else if (data.filesize == 0) {
await fetchAndPost(file.url, file.name, file.path);
if (file.name != "update_actions.json") {
const url = "/check_file?path=" + encodeURIComponent(file.path);
const response = await fetch(url);
if (response.ok) {
const data = await response.json();
if (data.filesize == file.size && data.md5 == file.md5) {
print(`file ${file.path} is up to date`, "green");
} else if (data.filesize == 0) {
await fetchAndPost(file.url, file.name, file.path);
} else {
await fetchAndPost(file.url, file.name, file.path);
}
} else {
await fetchAndPost(file.url, file.name, file.path);
print(`error checking file ${file.path}: ${response.status}`, "red");
errors++;
}
} else {
print(`error checking file ${file.path}: ${response.status}`, "red");
errors++;
}
} catch (error) {
console.error(`error checking file ${file.path}:` + error, "red");
@@ -257,12 +265,12 @@ export async function updateESP(fileUrl, showConfirm) {
}
const responseBody = await response.text();
if (responseBody.trim()[0] !== "{") {
if (responseBody.trim()[0] !== "[") {
throw new Error("Failed to fetch the release info file");
}
const data = JSON.parse(responseBody);
const file = data.binaries?.find((entry) => entry.name == env + '.bin');
const file = data.find((entry) => entry.name == env + '.bin');
if (file) {
binurl = file.url;
binmd5 = file.md5;