mirror of
https://github.com/DI0IK/homepage-plus.git
synced 2025-07-10 15:28:47 +00:00
first public source commit
This commit is contained in:
parent
1a4fbb9d42
commit
3914fee775
65 changed files with 4697 additions and 312 deletions
13
src/utils/cached-fetch.js
Normal file
13
src/utils/cached-fetch.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
import cache from "memory-cache";
|
||||
|
||||
export default async function cachedFetch(url, duration) {
|
||||
const cached = cache.get(url);
|
||||
|
||||
if (cached) {
|
||||
return cached;
|
||||
} else {
|
||||
const data = await fetch(url).then((res) => res.json());
|
||||
cache.put(url, data, duration * 1000 * 60);
|
||||
return data;
|
||||
}
|
||||
}
|
356
src/utils/condition-map.js
Normal file
356
src/utils/condition-map.js
Normal file
|
@ -0,0 +1,356 @@
|
|||
import * as Icons from "react-icons/wi";
|
||||
|
||||
const conditions = [
|
||||
{
|
||||
code: 1000,
|
||||
icon: {
|
||||
day: Icons.WiDaySunny,
|
||||
night: Icons.WiNightClear,
|
||||
},
|
||||
},
|
||||
{
|
||||
code: 1003,
|
||||
icon: {
|
||||
day: Icons.WiDayCloudy,
|
||||
night: Icons.WiNightPartlyCloudy,
|
||||
},
|
||||
},
|
||||
{
|
||||
code: 1006,
|
||||
icon: {
|
||||
day: Icons.WiDayCloudy,
|
||||
night: Icons.WiNightCloudy,
|
||||
},
|
||||
},
|
||||
{
|
||||
code: 1009,
|
||||
icon: {
|
||||
day: Icons.WiDayCloudy,
|
||||
night: Icons.WiNightCloudy,
|
||||
},
|
||||
},
|
||||
{
|
||||
code: 1030,
|
||||
icon: {
|
||||
day: Icons.WiDayFog,
|
||||
night: Icons.WiNightFog,
|
||||
},
|
||||
},
|
||||
{
|
||||
code: 1063,
|
||||
icon: {
|
||||
day: Icons.WiDayRain,
|
||||
night: Icons.WiNightRain,
|
||||
},
|
||||
},
|
||||
{
|
||||
code: 1066,
|
||||
icon: {
|
||||
day: Icons.WiDaySnow,
|
||||
night: Icons.WiNightSnow,
|
||||
},
|
||||
},
|
||||
{
|
||||
code: 1069,
|
||||
icon: {
|
||||
day: Icons.WiDayRainMix,
|
||||
night: Icons.WiNightRainMix,
|
||||
},
|
||||
},
|
||||
{
|
||||
code: 1072,
|
||||
icon: {
|
||||
day: Icons.WiDaySleet,
|
||||
night: Icons.WiNightSleet,
|
||||
},
|
||||
},
|
||||
{
|
||||
code: 1087,
|
||||
icon: {
|
||||
day: Icons.WiDayThunderstorm,
|
||||
night: Icons.WiNightThunderstorm,
|
||||
},
|
||||
},
|
||||
{
|
||||
code: 1114,
|
||||
icon: {
|
||||
day: Icons.WiDaySnow,
|
||||
night: Icons.WiNightSnow,
|
||||
},
|
||||
},
|
||||
{
|
||||
code: 1117,
|
||||
icon: {
|
||||
day: Icons.WiDaySnow,
|
||||
night: Icons.WiNightSnow,
|
||||
},
|
||||
},
|
||||
{
|
||||
code: 1135,
|
||||
icon: {
|
||||
day: Icons.WiDayFog,
|
||||
night: Icons.WiNightFog,
|
||||
},
|
||||
},
|
||||
{
|
||||
code: 1147,
|
||||
icon: {
|
||||
day: Icons.WiDayFog,
|
||||
night: Icons.WiNightFog,
|
||||
},
|
||||
},
|
||||
{
|
||||
code: 1150,
|
||||
icon: {
|
||||
day: Icons.WiDayRain,
|
||||
night: Icons.WiNightRain,
|
||||
},
|
||||
},
|
||||
{
|
||||
code: 1153,
|
||||
icon: {
|
||||
day: Icons.WiDayRain,
|
||||
night: Icons.WiNightRain,
|
||||
},
|
||||
},
|
||||
{
|
||||
code: 1168,
|
||||
icon: {
|
||||
day: Icons.WiDaySleet,
|
||||
night: Icons.WiNightSleet,
|
||||
},
|
||||
},
|
||||
{
|
||||
code: 1171,
|
||||
icon: {
|
||||
day: Icons.WiDaySleet,
|
||||
night: Icons.WiNightSleet,
|
||||
},
|
||||
},
|
||||
{
|
||||
code: 1180,
|
||||
icon: {
|
||||
day: Icons.WiDayRain,
|
||||
night: Icons.WiNightRain,
|
||||
},
|
||||
},
|
||||
{
|
||||
code: 1183,
|
||||
icon: {
|
||||
day: Icons.WiDayRain,
|
||||
night: Icons.WiNightRain,
|
||||
},
|
||||
},
|
||||
{
|
||||
code: 1186,
|
||||
icon: {
|
||||
day: Icons.WiDayRain,
|
||||
night: Icons.WiNightRain,
|
||||
},
|
||||
},
|
||||
{
|
||||
code: 1189,
|
||||
icon: {
|
||||
day: Icons.WiDayRain,
|
||||
night: Icons.WiNightRain,
|
||||
},
|
||||
},
|
||||
{
|
||||
code: 1192,
|
||||
icon: {
|
||||
day: Icons.WiDayRain,
|
||||
night: Icons.WiNightRain,
|
||||
},
|
||||
},
|
||||
{
|
||||
code: 1195,
|
||||
icon: {
|
||||
day: Icons.WiDayRain,
|
||||
night: Icons.WiNightRain,
|
||||
},
|
||||
},
|
||||
{
|
||||
code: 1198,
|
||||
icon: {
|
||||
day: Icons.WiDaySleet,
|
||||
night: Icons.WiNightSleet,
|
||||
},
|
||||
},
|
||||
{
|
||||
code: 1201,
|
||||
icon: {
|
||||
day: Icons.WiDaySleet,
|
||||
night: Icons.WiNightSleet,
|
||||
},
|
||||
},
|
||||
{
|
||||
code: 1204,
|
||||
icon: {
|
||||
day: Icons.WiDayRainMix,
|
||||
night: Icons.WiNightRainMix,
|
||||
},
|
||||
},
|
||||
{
|
||||
code: 1207,
|
||||
icon: {
|
||||
day: Icons.WiDayRainMix,
|
||||
night: Icons.WiNightRainMix,
|
||||
},
|
||||
},
|
||||
{
|
||||
code: 1210,
|
||||
icon: {
|
||||
day: Icons.WiDaySnow,
|
||||
night: Icons.WiNightSnow,
|
||||
},
|
||||
},
|
||||
{
|
||||
code: 1213,
|
||||
icon: {
|
||||
day: Icons.WiDaySnow,
|
||||
night: Icons.WiNightSnow,
|
||||
},
|
||||
},
|
||||
{
|
||||
code: 1216,
|
||||
icon: {
|
||||
day: Icons.WiDaySnow,
|
||||
night: Icons.WiNightSnow,
|
||||
},
|
||||
},
|
||||
{
|
||||
code: 1219,
|
||||
icon: {
|
||||
day: Icons.WiDaySnow,
|
||||
night: Icons.WiNightSnow,
|
||||
},
|
||||
},
|
||||
{
|
||||
code: 1222,
|
||||
icon: {
|
||||
day: Icons.WiDaySnow,
|
||||
night: Icons.WiNightSnow,
|
||||
},
|
||||
},
|
||||
{
|
||||
code: 1225,
|
||||
icon: {
|
||||
day: Icons.WiDaySnow,
|
||||
night: Icons.WiNightSnow,
|
||||
},
|
||||
},
|
||||
{
|
||||
code: 1237,
|
||||
icon: {
|
||||
day: Icons.WiDayHail,
|
||||
night: Icons.WiNightHail,
|
||||
},
|
||||
},
|
||||
{
|
||||
code: 1240,
|
||||
icon: {
|
||||
day: Icons.WiDayRain,
|
||||
night: Icons.WiNightRain,
|
||||
},
|
||||
},
|
||||
{
|
||||
code: 1243,
|
||||
icon: {
|
||||
day: Icons.WiDayRain,
|
||||
night: Icons.WiNightRain,
|
||||
},
|
||||
},
|
||||
{
|
||||
code: 1246,
|
||||
icon: {
|
||||
day: Icons.WiDayRain,
|
||||
night: Icons.WiNightRain,
|
||||
},
|
||||
},
|
||||
{
|
||||
code: 1249,
|
||||
icon: {
|
||||
day: Icons.WiDayRainMix,
|
||||
night: Icons.WiNightRainMix,
|
||||
},
|
||||
},
|
||||
{
|
||||
code: 1252,
|
||||
icon: {
|
||||
day: Icons.WiDayRainMix,
|
||||
night: Icons.WiNightRainMix,
|
||||
},
|
||||
},
|
||||
{
|
||||
code: 1255,
|
||||
icon: {
|
||||
day: Icons.WiDaySnow,
|
||||
night: Icons.WiNightSnow,
|
||||
},
|
||||
},
|
||||
{
|
||||
code: 1258,
|
||||
icon: {
|
||||
day: Icons.WiDaySnow,
|
||||
night: Icons.WiNightSnow,
|
||||
},
|
||||
},
|
||||
{
|
||||
code: 1261,
|
||||
icon: {
|
||||
day: Icons.WiDayHail,
|
||||
night: Icons.WiNightHail,
|
||||
},
|
||||
},
|
||||
{
|
||||
code: 1264,
|
||||
icon: {
|
||||
day: Icons.WiDayHail,
|
||||
night: Icons.WiNightHail,
|
||||
},
|
||||
},
|
||||
{
|
||||
code: 1273,
|
||||
icon: {
|
||||
day: Icons.WiDayThunderstorm,
|
||||
night: Icons.WiNightThunderstorm,
|
||||
},
|
||||
},
|
||||
{
|
||||
code: 1276,
|
||||
icon: {
|
||||
day: Icons.WiDayThunderstorm,
|
||||
night: Icons.WiNightThunderstorm,
|
||||
},
|
||||
},
|
||||
{
|
||||
code: 1279,
|
||||
icon: {
|
||||
day: Icons.WiDayThunderstorm,
|
||||
night: Icons.WiNightThunderstorm,
|
||||
},
|
||||
},
|
||||
{
|
||||
code: 1282,
|
||||
icon: {
|
||||
day: Icons.WiDayThunderstorm,
|
||||
night: Icons.WiNightThunderstorm,
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
export default function mapIcon(weatherStatusCode, timeOfDay) {
|
||||
const mapping = conditions.find(
|
||||
(condition) => condition.code === weatherStatusCode
|
||||
);
|
||||
|
||||
if (mapping) {
|
||||
if (timeOfDay === "day") {
|
||||
return mapping.icon.day;
|
||||
} else if (timeOfDay === "night") {
|
||||
return mapping.icon.night;
|
||||
}
|
||||
}
|
||||
|
||||
return Icons.WiDaySunny;
|
||||
}
|
13
src/utils/config.js
Normal file
13
src/utils/config.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
import { join } from "path";
|
||||
import { existsSync, copyFile } from "fs";
|
||||
|
||||
export default function checkAndCopyConfig(config) {
|
||||
const configYaml = join(process.cwd(), "config", config);
|
||||
if (!existsSync(configYaml)) {
|
||||
const configSkeleton = join(process.cwd(), "src", "skeleton", config);
|
||||
copyFile(configSkeleton, configYaml, (err) => {
|
||||
if (err) throw err;
|
||||
console.info("%s was copied to the config folder", config);
|
||||
});
|
||||
}
|
||||
}
|
30
src/utils/docker.js
Normal file
30
src/utils/docker.js
Normal file
|
@ -0,0 +1,30 @@
|
|||
import yaml from "js-yaml";
|
||||
import path from "path";
|
||||
import { promises as fs } from "fs";
|
||||
import checkAndCopyConfig from "utils/config";
|
||||
|
||||
export default async function getDockerArguments(server) {
|
||||
checkAndCopyConfig("docker.yaml");
|
||||
|
||||
const configFile = path.join(process.cwd(), "config", "docker.yaml");
|
||||
const configData = await fs.readFile(configFile, "utf8");
|
||||
const servers = yaml.load(configData);
|
||||
|
||||
if (!server) {
|
||||
if (process.platform !== "win32" && process.platform !== "darwin") {
|
||||
return { socketPath: "/var/run/docker.sock" };
|
||||
} else {
|
||||
return { host: "127.0.0.1" };
|
||||
}
|
||||
} else if (servers[server]) {
|
||||
if (servers[server].socket) {
|
||||
return { socketPath: servers[server].socket };
|
||||
} else if (servers[server].host) {
|
||||
return { host: servers[server].host, port: servers[server].port || null };
|
||||
} else {
|
||||
return servers[server];
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
26
src/utils/stats-helpers.js
Normal file
26
src/utils/stats-helpers.js
Normal file
|
@ -0,0 +1,26 @@
|
|||
export function calculateCPUPercent(stats) {
|
||||
let cpuPercent = 0.0;
|
||||
const cpuDelta =
|
||||
stats.cpu_stats.cpu_usage.total_usage -
|
||||
stats.precpu_stats.cpu_usage.total_usage;
|
||||
const systemDelta =
|
||||
stats.cpu_stats.system_cpu_usage - stats.precpu_stats.system_cpu_usage;
|
||||
|
||||
if (systemDelta > 0.0 && cpuDelta > 0.0) {
|
||||
cpuPercent = (cpuDelta / systemDelta) * stats.cpu_stats.online_cpus * 100.0;
|
||||
}
|
||||
|
||||
return Math.round(cpuPercent * 10) / 10;
|
||||
}
|
||||
|
||||
export function formatBytes(bytes, decimals = 2) {
|
||||
if (bytes === 0) return "0 Bytes";
|
||||
|
||||
const k = 1024;
|
||||
const dm = decimals < 0 ? 0 : decimals;
|
||||
const sizes = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
|
||||
|
||||
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
||||
|
||||
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + " " + sizes[i];
|
||||
}
|
47
src/utils/theme-context.js
Normal file
47
src/utils/theme-context.js
Normal file
|
@ -0,0 +1,47 @@
|
|||
import { createContext, useState, useEffect } from "react";
|
||||
|
||||
const getInitialTheme = () => {
|
||||
if (typeof window !== "undefined" && window.localStorage) {
|
||||
const storedPrefs = window.localStorage.getItem("color-theme");
|
||||
if (typeof storedPrefs === "string") {
|
||||
return storedPrefs;
|
||||
}
|
||||
|
||||
const userMedia = window.matchMedia("(prefers-color-scheme: dark)");
|
||||
if (userMedia.matches) {
|
||||
return "dark";
|
||||
}
|
||||
}
|
||||
|
||||
return "light"; // light theme as the default;
|
||||
};
|
||||
|
||||
export const ThemeContext = createContext();
|
||||
|
||||
export const ThemeProvider = ({ initialTheme, children }) => {
|
||||
const [theme, setTheme] = useState(getInitialTheme);
|
||||
|
||||
const rawSetTheme = (rawTheme) => {
|
||||
const root = window.document.documentElement;
|
||||
const isDark = rawTheme === "dark";
|
||||
|
||||
root.classList.remove(isDark ? "light" : "dark");
|
||||
root.classList.add(rawTheme);
|
||||
|
||||
localStorage.setItem("color-theme", rawTheme);
|
||||
};
|
||||
|
||||
if (initialTheme) {
|
||||
rawSetTheme(initialTheme);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
rawSetTheme(theme);
|
||||
}, [theme]);
|
||||
|
||||
return (
|
||||
<ThemeContext.Provider value={{ theme, setTheme }}>
|
||||
{children}
|
||||
</ThemeContext.Provider>
|
||||
);
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue