From ecdebf73adba83fc26025809b4cea895aa1b251d Mon Sep 17 00:00:00 2001 From: tycrek Date: Tue, 15 Jun 2021 17:17:17 -0600 Subject: [PATCH] optimized scripts --- README.md | 4 +- generators/gfycat.js | 24 +++-- generators/random.js | 2 +- generators/zws.js | 2 +- setup.js | 215 ++++++++++++++++++++++--------------------- utils.js | 16 ++-- 6 files changed, 135 insertions(+), 128 deletions(-) diff --git a/README.md b/README.md index 4ceda1a..50be2eb 100755 --- a/README.md +++ b/README.md @@ -23,6 +23,7 @@ - ✔️ Multiple access types - **[ZWS](https://zws.im)** - **Mixed-case alphanumeric** + - **Gfycat** - **Original** - ❌ Thumbnail support - ❌ Multiple database types @@ -39,6 +40,7 @@ | ---- | ----------- | | **[ZWS](https://zws.im)** (Zero-width spaces) | The "fancy" mode. When pasted elsewhere, the URL appears to be *just* your domain name. ![ZWS sample](https://user-images.githubusercontent.com/29926144/113785625-bf43a480-96f4-11eb-8dd7-7f164f33ada2.png "ZWS sample") | | **Mixed-case alphanumeric** | The "safe" mode. URL's are browser safe as the character set is just letters & numbers. | +| **Gfycat** | Gfycat-style ID's (for example: `https://gfycat.com/unsungdiscretegrub` "unsung discrete grub") | | **Original** | The "basic" mode. URL matches the same filename as when the file was uploaded. This may be prone to conflicts with files of the same name. | ## Installation @@ -90,7 +92,7 @@ If you need to override a specific part of the config to be different from the g | Header | Purpose | | ------ | ------- | | **`X-Ass-Domain`** | Override the domain returned for the clipboard (useful for multi-domain hosts) | -| **`X-Ass-Access`** | Override the generator used for the resource URI. Must be one of: `original`, `zws`, or `random` ([see above](#access-types)) | +| **`X-Ass-Access`** | Override the generator used for the resource URI. Must be one of: `original`, `zws`, `gfycat`, or `random` ([see above](#access-types)) | ### Fancy embeds diff --git a/generators/gfycat.js b/generators/gfycat.js index 28d3a87..8d4ceec 100644 --- a/generators/gfycat.js +++ b/generators/gfycat.js @@ -1,19 +1,17 @@ const fs = require('fs-extra'); -const adjectiveList = fs.readFileSync("./generators/gfycat/adjectives.txt", "utf-8").split('\n'); -const animalsList = fs.readFileSync("./generators/gfycat/animals.txt", "utf-8").split('\n'); +const adjectives = fs.readFileSync('./generators/gfycat/adjectives.txt').toString().split('\n'); +const animals = fs.readFileSync('./generators/gfycat/animals.txt').toString().split('\n'); +const MIN_LENGTH = require('../setup').gfyIdSize; -function genString(adjCount) { - let adjectivesString = ""; - for (i = 0; i < adjCount; i++) adjectivesString += genAdjective(); - return adjectivesString + genAnimal(); +function genString(count = MIN_LENGTH) { + let gfycat = ''; + for (i = 0; i < (count < MIN_LENGTH ? MIN_LENGTH : count); i++) + gfycat += getWord(adjectives, '-'); + return gfycat.concat(getWord(animals)); }; -function genAnimal() { - return animalsList[Math.floor(Math.random()*animalsList.length)]; +function getWord(list, delim = '') { + return list[Math.floor(Math.random() * list.length)].concat(delim); } -function genAdjective() { - return adjectiveList[Math.floor(Math.random()*adjectiveList.length)] + "-"; -} - -module.exports = (adjectives) => genString(adjectives); +module.exports = ({ gfyLength }) => genString(gfyLength); diff --git a/generators/random.js b/generators/random.js index e47b869..398919b 100644 --- a/generators/random.js +++ b/generators/random.js @@ -1,2 +1,2 @@ const cryptoRandomString = require('crypto-random-string'); -module.exports = (length) => cryptoRandomString({ length, type: 'alphanumeric' }); +module.exports = ({ length }) => cryptoRandomString({ length, type: 'alphanumeric' }); diff --git a/generators/zws.js b/generators/zws.js index 75526a0..7f5b73d 100644 --- a/generators/zws.js +++ b/generators/zws.js @@ -1,3 +1,3 @@ const { randomBytes } = require('crypto'); const zeroWidthChars = ['\u200B', '\u200C', '\u200D', '\u2060']; -module.exports = (size) => [...randomBytes(size)].map(byte => zeroWidthChars[+byte % zeroWidthChars.length]).join('').slice(1) + zeroWidthChars[0]; +module.exports = ({ length }) => [...randomBytes(length)].map(byte => zeroWidthChars[+byte % zeroWidthChars.length]).join('').slice(1) + zeroWidthChars[0]; diff --git a/setup.js b/setup.js index 98f95b2..636a7b3 100755 --- a/setup.js +++ b/setup.js @@ -1,12 +1,3 @@ -const { path, log } = require('./utils'); -const fs = require('fs-extra'); -const prompt = require('prompt'); - -// Disabled the annoying "prompt: " prefix and removes colours -prompt.message = ''; -prompt.colors = false; -prompt.start(); - // Default configuration const config = { host: '0.0.0.0', @@ -22,109 +13,123 @@ const config = { saveAsOriginal: true, }; -// Schema for setup prompts -const setupSchema = { - properties: { - host: { - description: 'Local IP to listen on', - type: 'string', - default: config.host, - required: false - }, - port: { - description: 'Port number to listen on', - type: 'integer', - default: config.port, - required: false - }, - domain: { - description: `Domain name to send to ShareX clients (example: ${config.domain})`, - type: 'string', - required: true, - message: 'You must input a valid domain name or IP to continue' - }, - useSsl: { - description: 'Use SSL (requires reverse proxy!)', - type: 'boolean', - default: config.useSsl, - required: false - }, - isProxied: { - description: 'Will you be running through a reverse proxy', - type: 'boolean', - default: config.isProxied, - required: false - }, - resourceIdSize: { - description: 'Resource ID size (by using a higher value, you will be able to upload more files)', - type: 'integer', - default: config.resourceIdSize, - required: false - }, - gfyIdSize: { - description: 'Adjective count for "gfycat" resource mode', - type: 'integer', - default: config.gfyIdSize, - required: false - }, - resourceIdType: { - description: 'Resource ID type (determines what kind of URL your uploads are visible at. Can be one of: original, zws, random)', - type: 'string', - default: config.resourceIdType, - require: false, - pattern: /(original|zws|random|gfycat)/gi, - message: 'Must be one of: original, zws, random, gfycat' - }, +// If directly called on the command line, run setup script +if (require.main === module) { + const { path, log } = require('./utils'); + const fs = require('fs-extra'); + const prompt = require('prompt'); - diskFilePath: { - description: 'Relative path to save uploads to', - type: 'string', - default: config.diskFilePath, - required: false - }, - saveWithDate: { - description: 'Use date folder structure (e.x. uploads/2021-04/image.png)', - type: 'boolean', - default: config.saveWithDate, - required: false - }, - saveAsOriginal: { - description: 'Save as original file name instead of random', - type: 'boolean', - default: config.saveAsOriginal, - required: false - }, - } -}; + // Disabled the annoying "prompt: " prefix and removes colours + prompt.message = ''; + prompt.colors = false; + prompt.start(); + + // Schema for setup prompts + const setupSchema = { + properties: { + host: { + description: 'Local IP to listen on', + type: 'string', + default: config.host, + required: false + }, + port: { + description: 'Port number to listen on', + type: 'integer', + default: config.port, + required: false + }, + domain: { + description: `Domain name to send to ShareX clients (example: ${config.domain})`, + type: 'string', + required: true, + message: 'You must input a valid domain name or IP to continue' + }, + useSsl: { + description: 'Use SSL (requires reverse proxy!)', + type: 'boolean', + default: config.useSsl, + required: false + }, + isProxied: { + description: 'Will you be running through a reverse proxy', + type: 'boolean', + default: config.isProxied, + required: false + }, + resourceIdSize: { + description: 'Resource ID size (by using a higher value, you will be able to upload more files)', + type: 'integer', + default: config.resourceIdSize, + required: false + }, + gfyIdSize: { + description: 'Adjective count for "gfycat" Resource ID type', + type: 'integer', + default: config.gfyIdSize, + required: false + }, + resourceIdType: { + description: 'Resource ID type (determines what kind of URL your uploads are visible at. Can be one of: original, zws, random)', + type: 'string', + default: config.resourceIdType, + require: false, + pattern: /(original|zws|random|gfycat)/gi, + message: 'Must be one of: original, zws, random, gfycat' + }, -// Schema for confirm prompt. User must enter 'y' or 'n' (case-insensitive) -const confirmSchema = { - properties: { - confirm: { - description: '\nIs the above information correct? (y/n)', - type: 'string', - pattern: /^[y|n]/gim, - message: 'Must respond with either \'y\' or \'n\'', - default: 'y', - required: false, - before: (value) => value.toLowerCase().startsWith('y') + diskFilePath: { + description: 'Relative path to save uploads to', + type: 'string', + default: config.diskFilePath, + required: false + }, + saveWithDate: { + description: 'Use date folder structure (e.x. uploads/2021-04/image.png)', + type: 'boolean', + default: config.saveWithDate, + required: false + }, + saveAsOriginal: { + description: 'Save as original file name instead of random', + type: 'boolean', + default: config.saveAsOriginal, + required: false + }, } + }; + + // Schema for confirm prompt. User must enter 'y' or 'n' (case-insensitive) + const confirmSchema = { + properties: { + confirm: { + description: '\nIs the above information correct? (y/n)', + type: 'string', + pattern: /^[y|n]/gim, + message: 'Must respond with either \'y\' or \'n\'', + default: 'y', + required: false, + before: (value) => value.toLowerCase().startsWith('y') + } + } + }; + + function setup() { + log('<<< ass setup >>>\n'); + let results; + prompt.get(setupSchema) + .then((r) => results = r) + .then(() => log('\nPlease verify your information:\n\n' + Object.keys(results).map((result) => (` ${result}: ${results[result]}`)).join('\n') + '\n')) + .then(() => prompt.get(confirmSchema)) + .then(({ confirm }) => confirm ? fs.writeJson(path('config.json'), results, { spaces: 4 }) : process.exit(1)) + .then(() => log('\nConfig has been saved!')) + .catch((err) => console.error(err)); } -}; -function setup() { - log('<<< ass setup >>>\n'); - let results; - prompt.get(setupSchema) - .then((r) => results = r) - .then(() => log('\nPlease verify your information:\n\n' + Object.keys(results).map((result) => (` ${result}: ${results[result]}`)).join('\n') + '\n')) - .then(() => prompt.get(confirmSchema)) - .then(({ confirm }) => confirm ? fs.writeJson(path('config.json'), results, { spaces: 4 }) : process.exit(1)) - .then(() => log('\nConfig has been saved!')) - .catch((err) => console.error(err)); + setup(); } -setup(); +module.exports = config; /*{ description: 'Enter your password', // Prompt displayed to the user. If not supplied name will be used. diff --git a/utils.js b/utils.js index 3267d44..43af567 100755 --- a/utils.js +++ b/utils.js @@ -9,20 +9,21 @@ const idModes = { zws: 'zws', // Zero-width spaces (see: https://zws.im/) og: 'original', // Use original uploaded filename r: 'random', // Use a randomly generated ID with a mixed-case alphanumeric character set - gfy: 'gfycat' //gfycat-style ID's (example.com/correct-horse-battery-staple) + gfy: 'gfycat' // Gfycat-style ID's (https://gfycat.com/unsungdiscretegrub) }; +const GENERATORS = new Map(); +GENERATORS.set(idModes.zws, zwsGen); +GENERATORS.set(idModes.r, randomGen); +GENERATORS.set(idModes.gfy, gfyGen); + module.exports = { log: console.log, path: (...paths) => Path.join(__dirname, ...paths), saveData: (data) => fs.writeJsonSync(Path.join(__dirname, 'data.json'), data, { spaces: 4 }), verify: (req, tokens) => req.headers.authorization && tokens.includes(req.headers.authorization), generateToken: () => token(), - generateId: (mode, lenth, gfyLength, originalName) => - (mode == idModes.zws) ? zwsGen(lenth) - : (mode == idModes.r) ? randomGen(lenth) - : (mode == idModes.gfy) ? gfyGen(gfyLength) - : originalName, + generateId: (mode, length, gfyLength, originalName) => GENERATORS.has(mode) ? GENERATORS.get(mode)({ length, gfyLength }) : originalName, formatBytes: (bytes, decimals = 2) => { if (bytes === 0) return '0 Bytes'; let sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; @@ -32,7 +33,8 @@ module.exports = { randomHexColour: () => { // From: https://www.geeksforgeeks.org/javascript-generate-random-hex-codes-color/ let letters = "0123456789ABCDEF"; let colour = '#'; - for (var i = 0; i < 6; i++) colour += letters[(Math.floor(Math.random() * 16))]; + for (var i = 0; i < 6; i++) + colour += letters[(Math.floor(Math.random() * 16))]; return colour; } }