NextcloudThemer/index.js

149 lines
3.3 KiB
JavaScript
Raw Normal View History

2025-02-13 20:48:07 +00:00
import fs from 'fs';
import path from 'path';
import FormData from 'form-data';
import dotenv from 'dotenv';
dotenv.config();
const instance = process.env.NEXTCLOUD_INSTANCE;
const username = process.env.NEXTCLOUD_LOGIN;
const appPassword = process.env.NEXTCLOUD_PASSWORD;
const __dirname = import.meta.dirname;
const authHeader = "Basic " + Buffer.from(`${username}:${appPassword}`).toString("base64");
function dir_project(after) {
return path.join(__dirname, after)
}
function readDir(path, options) {
return new Promise((res, rej) => {
fs.readdir(path, options, (err, files) => {
if (err) rej(err)
else res(files)
});
})
}
function readFile(path, options) {
return new Promise((res, rej) => {
fs.readFile(path, options, (err, data) => {
if (err) rej(err)
else res(data)
});
})
}
function writeFile(path, data, options) {
return new Promise((res, rej) => {
fs.writeFile(path, data, options, (err, data) => {
if (err) rej(err)
else res(data)
});
})
}
function randomItem(array) {
return array[Math.floor((Math.random() * array.length))];
}
async function updateTheming(object) {
let kvPairs = Object.entries(object)
for (const [setting, value] of kvPairs) {
await fetch(`https://${instance}/apps/theming/ajax/updateStylesheet`, {
method: "POST",
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
"Authorization": authHeader,
"OCS-APIRequest": "true"
},
body: JSON.stringify({ setting, value })
});
}
}
async function uploadImage({ image, filename, contentType }) {
const imageBuffer = await readFile(dir_project(image))
const form = new FormData();
form.append('key', 'background');
form.append('image', imageBuffer, { filename, contentType });
const response = await fetch(`https://${instance}/apps/theming/ajax/uploadImage`, {
method: "POST",
headers: {
"Accept": "application/json",
"Authorization": authHeader,
"OCS-APIRequest": "true",
...form.getHeaders()
},
body: form.getBuffer()
});
return await response.text()
}
function convertTheme(theme = "") {
let themeData = theme.split("\n");
return {
theme: {
name: themeData[0],
slogan: themeData[1],
primary_color: themeData[5]
},
background: {
image: themeData[2],
filename: themeData[3],
contentType: themeData[4],
}
}
}
async function getTodaysTheme() {
const directory = await readDir(dir_project("/themes/"));
const lastTheme = await readFile(dir_project("last_theme.txt"), {
encoding: "utf-8"
});
2025-02-14 04:58:52 +00:00
2025-02-13 20:48:07 +00:00
let themeFileName = lastTheme
2025-02-14 04:58:52 +00:00
if (process.argv[2]) {
themeFileName = process.argv[2]
} else {
let i = 50
while (themeFileName == lastTheme) {
themeFileName = randomItem(directory);
if (i < 0) break
i--
}
2025-02-13 20:48:07 +00:00
}
await writeFile(dir_project("last_theme.txt"), themeFileName, {
encoding: "utf-8"
})
const themeFile = await readFile(dir_project("/themes/" + themeFileName), {
encoding: "utf-8"
});
const parsedTheme = convertTheme(themeFile);
return parsedTheme
}
async function updateNextcloud() {
const todaysTheme = await getTodaysTheme();
await updateTheming(todaysTheme.theme);
await uploadImage(todaysTheme.background);
}
updateNextcloud()