commit fd0c05b64d56e0f36236e8cbd150c06945c63b80 Author: MeowcaTheoRange Date: Thu Feb 13 14:48:07 2025 -0600 first commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5e435ec --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +node_modules/ +themes/ +assets/ +.env +package-lock.json \ No newline at end of file diff --git a/index.js b/index.js new file mode 100644 index 0000000..2c50bdb --- /dev/null +++ b/index.js @@ -0,0 +1,147 @@ +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" + }); + + // let themeFileName = "test.txt" + + let i = 50 + let themeFileName = lastTheme + while (themeFileName == lastTheme) { + themeFileName = randomItem(directory); + if (i < 0) break + i-- + } + + 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() \ No newline at end of file diff --git a/last_theme.txt b/last_theme.txt new file mode 100644 index 0000000..370c030 --- /dev/null +++ b/last_theme.txt @@ -0,0 +1 @@ +caillougetsgrounded.txt \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..e3fdf5e --- /dev/null +++ b/package.json @@ -0,0 +1,13 @@ +{ + "name": "nextcloud-themer", + "version": "1.0.0", + "scripts": { + "dev": "node index.js" + }, + "license": "KKPL-v2.2", + "type": "module", + "dependencies": { + "dotenv": "^16.4.7", + "form-data": "^4.0.1" + } +}