mirror of
https://github.com/bunkerity/bunkerweb
synced 2026-05-24 09:28:37 +00:00
build.py working, removing build.js
This commit is contained in:
parent
84b1863bab
commit
373b0d5548
4 changed files with 56 additions and 217 deletions
4
src/ui/client/.gitignore
vendored
4
src/ui/client/.gitignore
vendored
|
|
@ -22,3 +22,7 @@ dist-ssr
|
|||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
# build
|
||||
opt-dashboard
|
||||
opt-setup
|
||||
|
|
@ -17,7 +17,7 @@ For example, you need to execute `npm run dev-dashboard` to run a vite dev serve
|
|||
|
||||
In case you want to run the BunkerWeb UI, try to update front-end and get the modifications on your app, you need to do the following :
|
||||
- go to `misc/dev` path and run `docker compose -f docker-compose.ui.yml up --build` in order to create BunkerWeb with UI looking for local static and templates folder
|
||||
- update front-end in dev mode and run inside `cd/src/ui/client` : `node ./build.js` to rebuild setup and dashboard pages.
|
||||
- update front-end in dev mode and run inside `cd/src/ui/client` : `python build.py` to rebuild setup and dashboard pages.
|
||||
|
||||
# Prod mode
|
||||
|
||||
|
|
|
|||
|
|
@ -1,205 +0,0 @@
|
|||
import { execSync } from "child_process";
|
||||
import { resolve } from "path";
|
||||
import fs from "fs";
|
||||
|
||||
const __dirname = import.meta.dirname;
|
||||
|
||||
const clientBuildDir = "opt-dashboard";
|
||||
const appStaticDir = "../static";
|
||||
const appTempDir = "../templates";
|
||||
|
||||
async function moveFile(src, dest) {
|
||||
fs.renameSync(src, dest, (err) => {
|
||||
if (err) {
|
||||
return console.error(err);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function createDirIfNotExists(dir) {
|
||||
if (!fs.existsSync(dir)) {
|
||||
fs.mkdirSync(dir);
|
||||
}
|
||||
}
|
||||
|
||||
async function delElRecursive(path) {
|
||||
if (!fs.existsSync(path)) return;
|
||||
fs.rmSync(path, { recursive: true }, (err) => {
|
||||
if (err) {
|
||||
console.log(err);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function copyDir(src, dest) {
|
||||
fs.cpSync(src, dest, { recursive: true }, (err) => {
|
||||
if (err) {
|
||||
console.log(err);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Run subprocess command on specific dir
|
||||
async function runCommand(dir, command) {
|
||||
try {
|
||||
execSync(
|
||||
command,
|
||||
{ cwd: resolve(__dirname + dir) },
|
||||
function (err, stdout, stderr) {
|
||||
console.log(stdout);
|
||||
console.log(stderr);
|
||||
if (err !== null) {
|
||||
console.log(`exec error: ${err}`);
|
||||
}
|
||||
}
|
||||
);
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
}
|
||||
}
|
||||
|
||||
// Install deps and build vite (work for client and setup)
|
||||
async function buildVite() {
|
||||
// Install packages
|
||||
await runCommand("", "npm install");
|
||||
await runCommand("", "npm run build-dashboard");
|
||||
}
|
||||
|
||||
// Change dir structure for flask app
|
||||
async function updateClientDir() {
|
||||
const srcDir = resolve(`./${clientBuildDir}/dashboard/pages`);
|
||||
const temporaryTemp = resolve(`./templatestemp`);
|
||||
const baseTemp = resolve(`./${clientBuildDir}/dashboard/`);
|
||||
const staticTemp = resolve(`./${clientBuildDir}/templates`);
|
||||
|
||||
try {
|
||||
createDirIfNotExists(staticTemp);
|
||||
copyDir(srcDir, temporaryTemp);
|
||||
changeOutputTemplates();
|
||||
// Delete templatestemp dir
|
||||
delElRecursive(baseTemp);
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
}
|
||||
}
|
||||
|
||||
async function changeOutputTemplates() {
|
||||
const templateTempDir = resolve(`./templatestemp`);
|
||||
fs.readdir(templateTempDir, (err, subdirs) => {
|
||||
subdirs.forEach((subdir) => {
|
||||
// Get absolute path of current subdir
|
||||
const currPath = resolve(`./templatestemp/${subdir}`);
|
||||
// Rename index.html by subdir name
|
||||
moveFile(
|
||||
`${currPath}/index.html`,
|
||||
`./${clientBuildDir}/templates/${subdir}.html`
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function setBuildTempToUI() {
|
||||
// Run all files in /templates and get data
|
||||
fs.readdir(resolve(`./${clientBuildDir}/templates`), (err, files) => {
|
||||
// Read content
|
||||
files.forEach((file) => {
|
||||
fs.readFile(
|
||||
resolve(`./${clientBuildDir}/templates/${file}`),
|
||||
{
|
||||
encoding: "utf8",
|
||||
flag: "r",
|
||||
},
|
||||
(err, data) => {
|
||||
if (err) {
|
||||
console.log(err);
|
||||
}
|
||||
let updateData = data;
|
||||
// I want to remove the first "/" for href="/css", href="/js", href="/img", href="/favicon", src="/assets" or src="/js"
|
||||
const regexPaths =
|
||||
/href="\/(css|js|img|favicon|assets|js)|src="\/(assets|js)/g;
|
||||
updateData = data.replace(regexPaths, (match) => {
|
||||
return match.replace("/", "");
|
||||
});
|
||||
|
||||
// For each <script> tag, I want to add nonce="{{ script_nonce }}" inside it
|
||||
const regexScript = /<script/g;
|
||||
updateData = updateData.replace(regexScript, (match) => {
|
||||
return match.replace(
|
||||
"<script",
|
||||
'<script nonce="{{ script_nonce }}" '
|
||||
);
|
||||
});
|
||||
|
||||
// remove everything after <body> tag
|
||||
const bodyIndex = updateData.indexOf("<body>");
|
||||
// Add attributs
|
||||
|
||||
const attributs = `
|
||||
<body>
|
||||
{% set data_server_flash = [] %}
|
||||
{% with messages = get_flashed_messages(with_categories=true) %}
|
||||
{% for category, message in messages %}
|
||||
{% if data_server_flash.append({"type": "error" if category == "error" else "success", "title": "dashboard_error" if category == "error" else "dashboard_success", "message": message}) %}{% endif %}
|
||||
{% endfor %}
|
||||
{% endwith %}
|
||||
<div class='hidden' data-csrf-token='{{ csrf_token() }}'></div>
|
||||
<div class='hidden' data-server-global='{{data_server_global if data_server_global else {}}}'></div>
|
||||
<div class='hidden' data-server-flash='{{data_server_flash|tojson}}'></div>
|
||||
<div class='hidden' data-server-builder='{{data_server_builder[1:-1]}}'></div>
|
||||
<div id='app'></div>
|
||||
</body>
|
||||
</html>`;
|
||||
// insert the new content
|
||||
updateData = updateData.substring(0, bodyIndex) + attributs;
|
||||
fs.writeFileSync(
|
||||
`${appTempDir}/${file}`,
|
||||
updateData,
|
||||
"utf8",
|
||||
(err) => {}
|
||||
);
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function moveBuildStaticToUI() {
|
||||
// move build static subdir to app ui static dir
|
||||
const srcDir = resolve(`./${clientBuildDir}`);
|
||||
const destDir = resolve(appStaticDir);
|
||||
fs.readdir(srcDir, (err, dirs) => {
|
||||
dirs.forEach((dir) => {
|
||||
// Avoid try something on dir templates because it's already moved/removed
|
||||
if (dir === "templates") return;
|
||||
// Delete prev existing dir
|
||||
copyDir(`${srcDir}/${dir}`, `${destDir}/${dir}`);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function delPrevDirs() {
|
||||
// Delete prev existing dir
|
||||
delElRecursive(`${appStaticDir}/css`);
|
||||
delElRecursive(`${appStaticDir}/assets`);
|
||||
delElRecursive(`${appStaticDir}/flags`);
|
||||
delElRecursive(`${appStaticDir}/img`);
|
||||
}
|
||||
|
||||
async function buildSetup() {
|
||||
// Build setup
|
||||
await runCommand("/", "npm run build-setup");
|
||||
// Move /setup/output/index.html to ui/templates/setup.html
|
||||
await moveFile("./setup/index.html", "../ui/templates/setup.html");
|
||||
}
|
||||
|
||||
async function build() {
|
||||
// Build client and setup
|
||||
await delPrevDirs();
|
||||
await buildVite();
|
||||
await updateClientDir();
|
||||
await setBuildTempToUI();
|
||||
// await moveBuildStaticToUI();
|
||||
// await buildSetup();
|
||||
}
|
||||
|
||||
build();
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
from subprocess import Popen, PIPE
|
||||
import os
|
||||
import shutil
|
||||
import re
|
||||
|
||||
# get current directory
|
||||
current_directory = os.path.dirname(os.path.realpath(__file__))
|
||||
|
|
@ -38,16 +39,52 @@ def reset():
|
|||
remove_dir(opt_dir)
|
||||
remove_dir(opt_dir_dashboard)
|
||||
remove_dir(opt_dir_setup)
|
||||
|
||||
|
||||
def create_base_dirs():
|
||||
os.makedirs(opt_dir, exist_ok=True)
|
||||
os.makedirs(opt_dir_templates, exist_ok=True)
|
||||
|
||||
|
||||
def move_template(folder, target_folder):
|
||||
base_html = """
|
||||
<body>
|
||||
{% set data_server_flash = [] %}
|
||||
{% with messages = get_flashed_messages(with_categories=true) %}
|
||||
{% for category, message in messages %}
|
||||
{% if data_server_flash.append({"type": "error" if category == "error" else "success", "title": "dashboard_error" if category == "error" else "dashboard_success", "message": message}) %}{% endif %}
|
||||
{% endfor %}
|
||||
{% endwith %}
|
||||
<div class='hidden' data-csrf-token='{{ csrf_token() }}'></div>
|
||||
<div class='hidden' data-server-global='{{data_server_global if data_server_global else {}}}'></div>
|
||||
<div class='hidden' data-server-flash='{{data_server_flash|tojson}}'></div>
|
||||
<div class='hidden' data-server-builder='{{data_server_builder[1:-1]}}'></div>
|
||||
<div id='app'></div>
|
||||
</body>
|
||||
</html>"""
|
||||
|
||||
# I want to get all subfollder of a folder
|
||||
for root, dirs, files in os.walk(folder):
|
||||
for file in files:
|
||||
file_path = os.path.join(root, file)
|
||||
# rename index.html by the name of the folder
|
||||
|
||||
# get file content
|
||||
content = ""
|
||||
with open(file_path, "r") as f:
|
||||
content = f.read()
|
||||
# I want to replace all paths using regex like this : /href="\/(css|js|img|favicon|assets|js)|src="\/(assets|js)/g
|
||||
regex_paths = """/href="\/(css|js|img|favicon|assets|js)|src="\/(assets|js)/g"""
|
||||
content = re.sub(regex_paths, "", content)
|
||||
regex_script = """/<script/g"""
|
||||
content = re.sub(regex_script, '<script nonce="{{ script_nonce }}" ', content)
|
||||
# get index of <body>
|
||||
index = content.index("<body>")
|
||||
# get the content before <body>
|
||||
content = content[:index] + base_html
|
||||
# write the new content
|
||||
with open(file_path, "w") as f:
|
||||
f.write(content)
|
||||
|
||||
# remove previous file if exists
|
||||
if os.path.exists(f"{target_folder}/{os.path.basename(root)}.html"):
|
||||
os.remove(f"{target_folder}/{os.path.basename(root)}.html")
|
||||
|
|
@ -70,21 +107,24 @@ def move_statics(folder, target_folder):
|
|||
shutil.move(dir, f"{target_folder}/{os.path.basename(dir)}")
|
||||
|
||||
|
||||
def move_opt_to_ui():
|
||||
move_statics(opt_dir_dashboard)
|
||||
def set_dashboard():
|
||||
move_template(opt_dir_dashboard_pages, ui_dir_templates)
|
||||
move_statics(opt_dir_dashboard, ui_dir_static)
|
||||
|
||||
|
||||
def set_setup():
|
||||
move_template(opt_dir_setup_page, ui_dir_templates)
|
||||
|
||||
|
||||
def build():
|
||||
reset()
|
||||
create_base_dirs()
|
||||
run_command(["npm", "install"], True)
|
||||
run_command(["npm", "run", "build-dashboard"])
|
||||
run_command(["npm", "run", "build-setup"], True)
|
||||
# format dashboard files
|
||||
move_template(opt_dir_dashboard_pages, ui_dir_templates)
|
||||
move_statics(opt_dir_dashboard, ui_dir_static)
|
||||
# format setup files
|
||||
move_template(opt_dir_setup_page, ui_dir_templates)
|
||||
# now move output files to the ui
|
||||
run_command(["npm", "run", "build-dashboard"], True)
|
||||
# run_command(["npm", "run", "build-dashboard"])
|
||||
# run_command(["npm", "run", "build-setup"], True)
|
||||
set_dashboard()
|
||||
# set_setup()
|
||||
|
||||
|
||||
build()
|
||||
|
|
|
|||
Loading…
Reference in a new issue