From fa6d1925b712962eff1bf7ef5df3e0d7a6e7684f Mon Sep 17 00:00:00 2001 From: Alicia Sykes Date: Sat, 20 Apr 2024 21:47:51 +0100 Subject: [PATCH 01/35] =?UTF-8?q?=F0=9F=9A=B8=20Makes=20GitHub=20cards=20h?= =?UTF-8?q?yperlinks=20(fixes=20#1531)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Widgets/GitHubProfile.vue | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/components/Widgets/GitHubProfile.vue b/src/components/Widgets/GitHubProfile.vue index 8f24aa34e6..1598aa5402 100644 --- a/src/components/Widgets/GitHubProfile.vue +++ b/src/components/Widgets/GitHubProfile.vue @@ -1,9 +1,15 @@ @@ -61,6 +67,9 @@ export default { profileCard() { return `${widgetApiEndpoints.readMeStats}?username=${this.username}${this.cardConfig}`; }, + profileCardLink() { + return `https://github.com/${this.username}`; + }, topLanguagesCard() { return `${widgetApiEndpoints.readMeStats}/top-langs/?username=${this.username}` + `${this.cardConfig}&langs_count=12`; @@ -70,8 +79,11 @@ export default { this.repos.forEach((repo) => { const username = repo.split('/')[0]; const repoName = repo.split('/')[1]; - cards.push(`${widgetApiEndpoints.readMeStats}/pin/?username=${username}&repo=${repoName}` - + `${this.cardConfig}&show_owner=true`); + cards.push({ + cardSrc: `${widgetApiEndpoints.readMeStats}/pin/?username=${username}` + + `&repo=${repoName}${this.cardConfig}&show_owner=true`, + cardHref: `https://github.com/${username}/${repoName}`, + }); }); return cards; }, From f295958c443a8b2901b67f3afbf77735a2f8887d Mon Sep 17 00:00:00 2001 From: Alicia Sykes Date: Sun, 21 Apr 2024 14:45:52 +0100 Subject: [PATCH 02/35] =?UTF-8?q?=E2=9C=A8=20Put=20config=20backups=20in?= =?UTF-8?q?=20own=20directory?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env | 2 +- services/save-config.js | 22 ++++++++++++++++------ 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/.env b/.env index 612a0937af..c9ca94a256 100644 --- a/.env +++ b/.env @@ -52,7 +52,7 @@ # VUE_APP_VERSION=2.0.0 # Directory for conf.yml backups -# BACKUP_DIR=./user-data/ +# BACKUP_DIR=./user-data/config-backups # Setup any other user defined vars by prepending VUE_APP_ to the var name # VUE_APP_pihole_ip=http://your.pihole.ip diff --git a/services/save-config.js b/services/save-config.js index f946be54ae..1665c3c435 100644 --- a/services/save-config.js +++ b/services/save-config.js @@ -14,18 +14,23 @@ module.exports = async (newConfig, render) => { return configObj.filename.replaceAll('/', '').replaceAll('..', ''); }; + // Path to config file (with navigational characters stripped) const usersFileName = makeSafeFileName(newConfig); + // Path to user data directory + const userDataDirectory = process.env.USER_DATA_DIR || './user-data/'; + // Define constants for the config file const settings = { - defaultLocation: process.env.USER_DATA_DIR || './user-data/', + defaultLocation: userDataDirectory, + backupLocation: process.env.BACKUP_DIR || path.join(userDataDirectory, 'config-backups'), defaultFile: 'conf.yml', filename: 'conf', backupDenominator: '.backup.yml', }; // Make the full file name and path to save the backup config file - const backupFilePath = `${path.normalize(process.env.BACKUP_DIR || settings.defaultLocation) + const backupFilePath = `${path.normalize(settings.backupLocation) }/${usersFileName || settings.filename}-` + `${Math.round(new Date() / 1000)}${settings.backupDenominator}`; @@ -45,15 +50,20 @@ module.exports = async (newConfig, render) => { message: !success ? errorMsg : getSuccessMessage(), }); - // Makes a backup of the existing config file + // Create a backup of current config, and if backup dir doesn't yet exist, create it await fsPromises - .copyFile(defaultFilePath, backupFilePath) - .catch((error) => render(getRenderMessage(false, `Unable to backup ${settings.defaultFile}: ${error}`))); + .mkdir(settings.backupLocation, { recursive: true }) + .then(() => fsPromises.copyFile(defaultFilePath, backupFilePath)) + .catch((error) => render( + getRenderMessage(false, `Unable to backup ${settings.defaultFile}: ${error}`), + )); // Writes the new content to the conf.yml file await fsPromises .writeFile(defaultFilePath, newConfig.config.toString(), writeFileOptions) - .catch((error) => render(getRenderMessage(false, `Unable to write to ${settings.defaultFile}: ${error}`))); + .catch((error) => render( + getRenderMessage(false, `Unable to write to ${settings.defaultFile}: ${error}`), + )); // If successful, then render hasn't yet been called- call it await render(getRenderMessage(true)); From ecef01b0346238e8009f14ad6bc0193441c67ec9 Mon Sep 17 00:00:00 2001 From: Alicia Sykes Date: Sun, 21 Apr 2024 14:46:38 +0100 Subject: [PATCH 03/35] =?UTF-8?q?=F0=9F=A5=85=20Better=20error=20handling?= =?UTF-8?q?=20when=20config=20cannot=20be=20found?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.vue | 3 + src/components/PageStrcture/CriticalError.vue | 115 ++++++++++++++++++ src/store.js | 50 ++++++-- src/styles/global-styles.scss | 5 + src/utils/StoreMutations.js | 1 + src/utils/defaults.js | 1 + 6 files changed, 164 insertions(+), 11 deletions(-) create mode 100644 src/components/PageStrcture/CriticalError.vue diff --git a/src/App.vue b/src/App.vue index 4cfd5d5db2..fbc3026fc3 100644 --- a/src/App.vue +++ b/src/App.vue @@ -3,6 +3,7 @@
+