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()
|