DweebUI/controllers/apps.js
2024-03-17 19:32:02 -07:00

386 lines
No EOL
13 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { readFileSync } from 'fs';
let templatesJSON = readFileSync('./templates/templates.json');
let templates = JSON.parse(templatesJSON).templates;
templates = templates.sort((a, b) => {
if (a.name < b.name) {
return -1;
}
});
export const Apps = (req, res) => {
let page = Number(req.params.page) || 1;
let list_start = (page-1)*28;
let list_end = (page*28);
let last_page = Math.ceil(templates.length/28);
let prev = '/apps/' + (page-1);
let next = '/apps/' + (page+1);
if (page == 1) {
prev = '/apps/' + (page);
}
if (page == last_page) {
next = '/apps/' + (page);
}
let apps_list = '';
for (let i = list_start; i < list_end && i < templates.length; i++) {
let appCard = readFileSync('./views/partials/appCard.html', 'utf8');
let name = templates[i].name || templates[i].title.toLowerCase();
let desc = templates[i].description.slice(0, 60) + "...";
let description = templates[i].description.replaceAll(". ", ".\n") || "no description available";
let note = templates[i].note ? templates[i].note.replaceAll(". ", ".\n") : "no notes available";
let image = templates[i].image;
let logo = templates[i].logo;
let categories = '';
// set data.catagories to 'other' if data.catagories is empty or undefined
if (templates[i].categories == null || templates[i].categories == undefined || templates[i].categories == '') {
templates[i].categories = ['Other'];
}
for (let c = 0; c < templates[i].categories.length; c++) {
categories += CatagoryColor(templates[i].categories[c]);
}
appCard = appCard.replace(/AppName/g, name);
appCard = appCard.replace(/AppShortName/g, name);
appCard = appCard.replace(/AppDesc/g, desc);
appCard = appCard.replace(/AppLogo/g, logo);
appCard = appCard.replace(/AppCategories/g, categories);
apps_list += appCard;
}
res.render("apps", {
name: req.session.user,
role: req.session.role,
avatar: req.session.avatar,
list_start: list_start + 1,
list_end: list_end,
app_count: templates.length,
prev: prev,
next: next,
apps_list: apps_list
});
}
export const appSearch = async (req, res) => {
let search = req.body.search.split(' ');
let apps_list = '';
let results = [];
let page = Number(req.query.page) || 1;
let list_start = (page - 1) * 28;
let list_end = (page * 28);
let last_page = Math.ceil(templates.length / 28);
let prev = '/apps?page=' + (page - 1);
let next = '/apps?page=' + (page + 1);
if (page == 1) {
prev = '/apps?page=' + (page);
}
if (page == last_page) {
next = '/apps?page=' + (page);
}
function searchTemplates(word) {
for (let i = 0; i < templates.length; i++) {
if ((templates[i].description.includes(word)) || (templates[i].name.includes(word)) || (templates[i].title.includes(word))) {
results.push(templates[i]);
}
}
}
searchTemplates(search);
for (let i = 0; i < results.length; i++) {
let appCard = readFileSync('./views/partials/appCard.html', 'utf8');
let name = results[i].name || results[i].title.toLowerCase();
let desc = results[i].description.slice(0, 60) + "...";
let description = results[i].description.replaceAll(". ", ".\n") || "no description available";
let note = results[i].note ? results[i].note.replaceAll(". ", ".\n") : "no notes available";
let image = results[i].image;
let logo = results[i].logo;
let categories = '';
// set data.catagories to 'other' if data.catagories is empty or undefined
if (results[i].categories == null || results[i].categories == undefined || results[i].categories == '') {
results[i].categories = ['Other'];
}
for (let c = 0; c < results[i].categories.length; c++) {
categories += CatagoryColor(results[i].categories[c]);
}
appCard = appCard.replace(/AppName/g, name);
appCard = appCard.replace(/AppShortName/g, name);
appCard = appCard.replace(/AppDesc/g, desc);
appCard = appCard.replace(/AppLogo/g, logo);
appCard = appCard.replace(/AppCategories/g, categories);
apps_list += appCard;
}
res.render("apps", {
name: req.session.user,
role: req.session.role,
avatar: req.session.avatar,
list_start: list_start + 1,
list_end: list_end,
app_count: results.length,
prev: prev,
next: next,
apps_list: apps_list
});
}
function CatagoryColor(category) {
switch (category) {
case 'Other':
return '<span class="badge bg-blue-lt">Other</span> ';
case 'Productivity':
return '<span class="badge bg-blue-lt">Productivity</span> ';
case 'Tools':
return '<span class="badge bg-blue-lt">Tools</span> ';
case 'Dashboard':
return '<span class="badge bg-blue-lt">Dashboard</span> ';
case 'Communication':
return '<span class="badge bg-azure-lt">Communication</span> ';
case 'Media':
return '<span class="badge bg-azure-lt">Media</span> ';
case 'CMS':
return '<span class="badge bg-azure-lt">CMS</span> ';
case 'Monitoring':
return '<span class="badge bg-indigo-lt">Monitoring</span> ';
case 'LDAP':
return '<span class="badge bg-purple-lt">LDAP</span> ';
case 'Arr':
return '<span class="badge bg-purple-lt">Arr</span> ';
case 'Database':
return '<span class="badge bg-red-lt">Database</span> ';
case 'Paid':
return '<span class="badge bg-red-lt" title="This is a paid product or contains paid features.">Paid</span> ';
case 'Gaming':
return '<span class="badge bg-pink-lt">Gaming</span> ';
case 'Finance':
return '<span class="badge bg-orange-lt">Finance</span> ';
case 'Networking':
return '<span class="badge bg-yellow-lt">Networking</span> ';
case 'Authentication':
return '<span class="badge bg-lime-lt">Authentication</span> ';
case 'Development':
return '<span class="badge bg-green-lt">Development</span> ';
case 'Media Server':
return '<span class="badge bg-teal-lt">Media Server</span> ';
case 'Downloaders':
return '<span class="badge bg-cyan-lt">Downloaders</span> ';
default:
return ''; // default to other if the category is not recognized
}
}
export const InstallModal = async (req, res) => {
let input = req.header('hx-trigger-name');
let result = templates.find(t => t.name == input);
let name = result.name || result.title.toLowerCase();
let short_name = name.slice(0, 25) + "...";
let desc = result.description.replaceAll(". ", ".\n") || "no description available";
let short_desc = desc.slice(0, 60) + "...";
let modal_name = name.replaceAll(" ", "-");
let form_id = name.replaceAll("-", "_");
let note = result.note ? result.note.replaceAll(". ", ".\n") : "no notes available";
let command = result.command ? result.command : "";
let command_check = command ? "checked" : "";
let privileged = result.privileged || "";
let privileged_check = privileged ? "checked" : "";
let repository = result.repository || "";
let image = result.image || "";
let net_host, net_bridge, net_docker = '';
let net_name = 'AppBridge';
let restart_policy = result.restart_policy || 'unless-stopped';
switch (result.network) {
case 'host':
net_host = 'checked';
break;
case 'bridge':
net_bridge = 'checked';
net_name = result.network;
break;
default:
net_docker = 'checked';
}
if (repository != "") {
image = (`${repository.url}/raw/master/${repository.stackfile}`);
}
let [ports_data, volumes_data, env_data, label_data] = [[], [], [], []];
for (let i = 0; i < 12; i++) {
// Get port details
try {
let ports = result.ports[i];
let port_check = ports ? "checked" : "";
let port_external = ports.split(":")[0] ? ports.split(":")[0] : ports.split("/")[0];
let port_internal = ports.split(":")[1] ? ports.split(":")[1].split("/")[0] : ports.split("/")[0];
let port_protocol = ports.split("/")[1] ? ports.split("/")[1] : "";
// remove /tcp or /udp from port_external if it exists
if (port_external.includes("/")) {
port_external = port_external.split("/")[0];
}
ports_data.push({
check: port_check,
external: port_external,
internal: port_internal,
protocol: port_protocol
});
} catch {
ports_data.push({
check: "",
external: "",
internal: "",
protocol: ""
});
}
// Get volume details
try {
let volumes = result.volumes[i];
let volume_check = volumes ? "checked" : "";
let volume_bind = volumes.bind ? volumes.bind : "";
let volume_container = volumes.container ? volumes.container.split(":")[0] : "";
let volume_readwrite = "rw";
if (volumes.readonly == true) {
volume_readwrite = "ro";
}
volumes_data.push({
check: volume_check,
bind: volume_bind,
container: volume_container,
readwrite: volume_readwrite
});
} catch {
volumes_data.push({
check: "",
bind: "",
container: "",
readwrite: ""
});
}
// Get environment details
try {
let env = result.env[i];
let env_check = "";
let env_default = env.default ? env.default : "";
if (env.set) { env_default = env.set;}
let env_description = env.description ? env.description : "";
let env_label = env.label ? env.label : "";
let env_name = env.name ? env.name : "";
env_data.push({
check: env_check,
default: env_default,
description: env_description,
label: env_label,
name: env_name
});
} catch {
env_data.push({
check: "",
default: "",
description: "",
label: "",
name: ""
});
}
// Get label details
try {
let label = result.labels[i];
let label_check = "";
let label_name = label.name ? label.name : "";
let label_value = label.value ? label.value : "";
label_data.push({
check: label_check,
name: label_name,
value: label_value
});
} catch {
label_data.push({
check: "",
name: "",
value: ""
});
}
}
let modal = readFileSync('./views/modals/install.html', 'utf8');
modal = modal.replace(/AppName/g, name);
modal = modal.replace(/AppNote/g, note);
modal = modal.replace(/AppImage/g, image);
modal = modal.replace(/RestartPolicy/g, restart_policy);
modal = modal.replace(/NetHost/g, net_host);
modal = modal.replace(/NetBridge/g, net_bridge);
modal = modal.replace(/NetDocker/g, net_docker);
modal = modal.replace(/NetName/g, net_name);
modal = modal.replace(/ModalName/g, modal_name);
modal = modal.replace(/FormId/g, form_id);
modal = modal.replace(/CommandCheck/g, command_check);
modal = modal.replace(/CommandValue/g, command);
modal = modal.replace(/PrivilegedCheck/g, privileged_check);
for (let i = 0; i < 12; i++) {
modal = modal.replaceAll(`Port${i}Check`, ports_data[i].check);
modal = modal.replaceAll(`Port${i}External`, ports_data[i].external);
modal = modal.replaceAll(`Port${i}Internal`, ports_data[i].internal);
modal = modal.replaceAll(`Port${i}Protocol`, ports_data[i].protocol);
modal = modal.replaceAll(`Volume${i}Check`, volumes_data[i].check);
modal = modal.replaceAll(`Volume${i}Bind`, volumes_data[i].bind);
modal = modal.replaceAll(`Volume${i}Container`, volumes_data[i].container);
modal = modal.replaceAll(`Volume${i}RW`, volumes_data[i].readwrite);
modal = modal.replaceAll(`Env${i}Check`, env_data[i].check);
modal = modal.replaceAll(`Env${i}Default`, env_data[i].default);
modal = modal.replaceAll(`Env${i}Description`, env_data[i].description);
modal = modal.replaceAll(`Env${i}Label`, env_data[i].label);
modal = modal.replaceAll(`Env${i}Name`, env_data[i].name);
modal = modal.replaceAll(`Label${i}Check`, label_data[i].check);
modal = modal.replaceAll(`Label${i}Name`, label_data[i].name);
modal = modal.replaceAll(`Label${i}Value`, label_data[i].value);
}
res.send(modal);
}
export const LearnMore = async (req, res) => {
let name = req.header('hx-trigger-name');
let id = req.header('hx-trigger');
let modal = readFileSync('./views/modals/learnmore.html', 'utf8');
res.send(modal);
}