little website
This commit is contained in:
parent
4d14982e38
commit
2e6f697a69
8 changed files with 201 additions and 0 deletions
19
little_website/package.json
Normal file
19
little_website/package.json
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
{
|
||||||
|
"name": "little_website_phone",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"main": "server.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
|
"start": "node server.js"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"description": "",
|
||||||
|
"dependencies": {
|
||||||
|
"body-parser": "^2.2.0",
|
||||||
|
"cors": "^2.8.5",
|
||||||
|
"express": "^5.1.0",
|
||||||
|
"express-rate-limit": "^8.0.1"
|
||||||
|
}
|
||||||
|
}
|
23
little_website/public/index.html
Normal file
23
little_website/public/index.html
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
<!DOCTYPE <html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<title>Hosted on my phone btw</title>
|
||||||
|
<link rel="stylesheet" href="style.css" />
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<h1>Hosted on a phone from 2016 btw</h1>
|
||||||
|
<div id="battery-status">Loading battery status...</div>
|
||||||
|
<h1>Leave an anonymous message</h1>
|
||||||
|
<form id="msgForm">
|
||||||
|
<textarea id="message" rows="4" cols="40" maxlength="1000" placeholder="Your message..."></textarea><br>
|
||||||
|
<button type="submit">Send</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<h2>Recent Messages</h2>
|
||||||
|
<ul id="messages"></ul>
|
||||||
|
<script type="text/javascript" src="script.js"></script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
53
little_website/public/script.js
Normal file
53
little_website/public/script.js
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
async function loadBattery() {
|
||||||
|
const res = await fetch('/api/battery');
|
||||||
|
const data = await res.json();
|
||||||
|
console.log(data);
|
||||||
|
const battery_json = JSON.parse(data.battery);
|
||||||
|
const health = battery_json.health;
|
||||||
|
const status = battery_json.status;
|
||||||
|
const percentage = battery_json.percentage;
|
||||||
|
const voltage = battery_json.voltage;
|
||||||
|
const current = battery_json.current;
|
||||||
|
const temperature = battery_json.temperature;
|
||||||
|
let power = parseInt(voltage) * parseInt(current) / 1000000000;
|
||||||
|
power = String(power).substring(0, 5);
|
||||||
|
document.getElementById("battery-status").innerText = `Battery infos 🔋\n\nstatus : ${status}\nLevel : ${percentage}%\nPower : ${power}W (${current}µA x ${voltage}mV)\nTemperature : ${temperature}°C\nHealth : ${health}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadMessages() {
|
||||||
|
const res = await fetch('/api/messages');
|
||||||
|
const data = await res.json();
|
||||||
|
const list = document.getElementById("messages");
|
||||||
|
list.innerHTML = "";
|
||||||
|
data.forEach(msg => {
|
||||||
|
const li = document.createElement("li");
|
||||||
|
li.textContent = `[${new Date(msg.time).toLocaleTimeString()}] ${msg.message}`;
|
||||||
|
list.appendChild(li);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById("msgForm").addEventListener("submit", async (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
const message = document.getElementById("message").value.trim().substring(0, 1000);
|
||||||
|
const captcha = {};
|
||||||
|
const captchaAnswer = {};
|
||||||
|
const res = await fetch("/api/message", {
|
||||||
|
method: "POST",
|
||||||
|
headers: { "Content-Type": "application/json" },
|
||||||
|
body: JSON.stringify({ message, captchaAnswer, captcha })
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await res.json();
|
||||||
|
if (result.success) {
|
||||||
|
alert("Message sent!");
|
||||||
|
document.getElementById("message").value = "";
|
||||||
|
loadMessages();
|
||||||
|
} else {
|
||||||
|
alert(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
loadMessages();
|
||||||
|
loadBattery();
|
||||||
|
setInterval(loadBattery, 30000);
|
BIN
little_website/public/shrek.png
Normal file
BIN
little_website/public/shrek.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 150 KiB |
34
little_website/public/style.css
Normal file
34
little_website/public/style.css
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
body {
|
||||||
|
font-family: sans-serif;
|
||||||
|
padding: 20px;
|
||||||
|
max-width: 600px;
|
||||||
|
margin: auto;
|
||||||
|
background-image: url("shrek.png");
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
#battery-status {
|
||||||
|
font-size: 1.2em;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
color: green;
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea {
|
||||||
|
width: 100%;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style: none;
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
border-bottom: 1px solid #ccc;
|
||||||
|
padding: 5px 0;
|
||||||
|
word-wrap: break-word;
|
||||||
|
overflow-wrap: break-word;
|
||||||
|
white-space: normal;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
57
little_website/server.js
Normal file
57
little_website/server.js
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
const express = require("express");
|
||||||
|
const fs = require("fs");
|
||||||
|
const path = require("path");
|
||||||
|
const { exec } = require("child_process");
|
||||||
|
const bodyParser = require("body-parser");
|
||||||
|
const rateLimit = require("express-rate-limit");
|
||||||
|
const app = express();
|
||||||
|
const PORT = 3000;
|
||||||
|
|
||||||
|
const limiter = rateLimit({
|
||||||
|
windowMs: 10000,
|
||||||
|
max: 5,
|
||||||
|
message: "Try harder to make my battery boom lol",
|
||||||
|
})
|
||||||
|
|
||||||
|
app.use(express.static("public"));
|
||||||
|
app.use(bodyParser.json());
|
||||||
|
app.use(limiter)
|
||||||
|
|
||||||
|
// app.use("/api/message", limiter);
|
||||||
|
// app.use("/api/messages", limiter);
|
||||||
|
// app.use("/api/battery", limiter);
|
||||||
|
|
||||||
|
const MESSAGES_FILES = "messages.json";
|
||||||
|
|
||||||
|
let messages = [];
|
||||||
|
if (fs.existsSync(MESSAGES_FILES)) {
|
||||||
|
messages = JSON.parse(fs.readFileSync((MESSAGES_FILES)));
|
||||||
|
}
|
||||||
|
|
||||||
|
app.get("/api/messages", (req, res) => {
|
||||||
|
res.json(messages.slice(-20).reverse());
|
||||||
|
})
|
||||||
|
|
||||||
|
app.post("/api/message", (req, res) => {
|
||||||
|
let { message, captchaAnswer, captcha } = req.body;
|
||||||
|
if (!message || !captchaAnswer || !captcha) return res.status(400).send("Missing fields");
|
||||||
|
|
||||||
|
//maybe some captcha verif here
|
||||||
|
|
||||||
|
if (messages.length > 20) messages.shift();
|
||||||
|
message = message.substring(0, 1000);
|
||||||
|
messages.push({ message, time: new Date().toISOString() });
|
||||||
|
fs.writeFileSync(MESSAGES_FILES, JSON.stringify(messages, null, 2));
|
||||||
|
res.json({ success: true });
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get("/api/battery", (req, res) => {
|
||||||
|
exec("./test_cmd", (err, stdout) => {
|
||||||
|
if (err) return res.status(500).send("termux-battery-status error");
|
||||||
|
res.json({ battery: stdout.trim() });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
app.listen(PORT, () => console.log(`Server running on http://localhost:${PORT}`));
|
||||||
|
|
||||||
|
|
1
little_website/test_cmd
Executable file
1
little_website/test_cmd
Executable file
|
@ -0,0 +1 @@
|
||||||
|
termux-battery-status
|
14
n8n_hosting_android/README.md
Normal file
14
n8n_hosting_android/README.md
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
# Intro & Prerequisite
|
||||||
|
n8n is a cool automation tool like zappier to automate your workflows.
|
||||||
|
But n8n source code is available and you can host it on your hardware !
|
||||||
|
And in this guide I'll show you how to host n8n on an old android phone (And you do not need root) !
|
||||||
|
|
||||||
|
I assume you have read
|
||||||
|
https://github.com/Crizomb/android_hosting_tutorials/tree/main
|
||||||
|
Or already have Termux and ssh set-up.
|
||||||
|
|
||||||
|
# Difficulties
|
||||||
|
The recommended way of running n8n is via docker.
|
||||||
|
But docker doesn't run natively on tmux, even with proot I didn't manage to get it working.
|
||||||
|
If your bootloader is unlocked it can be maybe better to install a custom OS to get docker working, but this tutorial is made for devices that are noot rooted.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue