-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit d8e8e38
Showing
12 changed files
with
926 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
# Logs | ||
logs | ||
*.log | ||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* | ||
lerna-debug.log* | ||
.pnpm-debug.log* | ||
|
||
# Diagnostic reports (https://nodejs.org/api/report.html) | ||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json | ||
|
||
# Runtime data | ||
pids | ||
*.pid | ||
*.seed | ||
*.pid.lock | ||
|
||
# Directory for instrumented libs generated by jscoverage/JSCover | ||
lib-cov | ||
|
||
# Coverage directory used by tools like istanbul | ||
coverage | ||
*.lcov | ||
|
||
# nyc test coverage | ||
.nyc_output | ||
|
||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) | ||
.grunt | ||
|
||
# Bower dependency directory (https://bower.io/) | ||
bower_components | ||
|
||
# node-waf configuration | ||
.lock-wscript | ||
|
||
# Compiled binary addons (https://nodejs.org/api/addons.html) | ||
build/Release | ||
|
||
# Dependency directories | ||
node_modules/ | ||
jspm_packages/ | ||
|
||
# Snowpack dependency directory (https://snowpack.dev/) | ||
web_modules/ | ||
|
||
# TypeScript cache | ||
*.tsbuildinfo | ||
|
||
# Optional npm cache directory | ||
.npm | ||
|
||
# Optional eslint cache | ||
.eslintcache | ||
|
||
# Optional stylelint cache | ||
.stylelintcache | ||
|
||
# Microbundle cache | ||
.rpt2_cache/ | ||
.rts2_cache_cjs/ | ||
.rts2_cache_es/ | ||
.rts2_cache_umd/ | ||
|
||
# Optional REPL history | ||
.node_repl_history | ||
|
||
# Output of 'npm pack' | ||
*.tgz | ||
|
||
# Yarn Integrity file | ||
.yarn-integrity | ||
|
||
# dotenv environment variable files | ||
.env | ||
.env.development.local | ||
.env.test.local | ||
.env.production.local | ||
.env.local | ||
|
||
# parcel-bundler cache (https://parceljs.org/) | ||
.cache | ||
.parcel-cache | ||
|
||
# Next.js build output | ||
.next | ||
out | ||
|
||
# Nuxt.js build / generate output | ||
.nuxt | ||
dist | ||
|
||
# Gatsby files | ||
.cache/ | ||
# Comment in the public line in if your project uses Gatsby and not Next.js | ||
# https://nextjs.org/blog/next-9-1#public-directory-support | ||
# public | ||
|
||
# vuepress build output | ||
.vuepress/dist | ||
|
||
# vuepress v2.x temp and cache directory | ||
.temp | ||
.cache | ||
|
||
# Docusaurus cache and generated files | ||
.docusaurus | ||
|
||
# Serverless directories | ||
.serverless/ | ||
|
||
# FuseBox cache | ||
.fusebox/ | ||
|
||
# DynamoDB Local files | ||
.dynamodb/ | ||
|
||
# TernJS port file | ||
.tern-port | ||
|
||
# Stores VSCode versions used for testing VSCode extensions | ||
.vscode-test | ||
|
||
# yarn v2 | ||
.yarn/cache | ||
.yarn/unplugged | ||
.yarn/build-state.yml | ||
.yarn/install-state.gz | ||
.pnp.* | ||
|
||
# Clear from any builds | ||
**/*.exe | ||
out.js |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
<center><img src="preview.gif" height="300" alt="Gif Validator preview" /></center> | ||
|
||
|
||
# 💀 GIF Validator | ||
GIF Validator is a utility tool that checks your favorite gifs on Discord and identifies any that are no longer available. This ensures your gif collection remains up-to-date and clean from broken links. | ||
|
||
## ❗ Requirements | ||
If you wish to use original JS files (for example if you don't trust the EXE file) you will need: | ||
- [Node.js](https://nodejs.org/en/) [v21.6.1 or higher] | ||
- [npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) (or any other package manager like yarn/pnpm) | ||
|
||
## ⚙ Installation | ||
|
||
To install Gif Validator, follow these steps: | ||
|
||
1. Clone the repository to your local machine. | ||
2. Navigate to the cloned directory. | ||
3. Run `npm install` to install all the necessary dependencies. | ||
|
||
## ⌨ Usage | ||
|
||
To start using Gif Validator: | ||
|
||
1. Ensure you have set up your Discord API token in the configuration file. | ||
2. Run `npm start` to execute the script. | ||
|
||
The script will validate your gifs and remove any that are no longer available leaving you with a clean collection! | ||
|
||
## 📖 How to Build | ||
|
||
<b>❗ OFFICIAL SUPPORT IS AVAILABLE ONLY FOR WINDOWS</b> | ||
If you have any major Linux Distro (Like Ubuntu, Debian etc.), please make a pull request with needed dependencies, scripts and configuration files for build to work on them! | ||
|
||
Building is fairly simple, just use the following command: | ||
```bash | ||
npm run build-win | ||
``` | ||
...or open the `build.bat` file in the root of the repository. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
@echo off | ||
WHERE node >nul 2>nul | ||
if %ERRORLEVEL% NEQ 0 ( | ||
echo You must install node.js to build this app! | ||
) else ( | ||
echo It is recommended to install signtool to remove corrupted signature warning! | ||
echo https://developer.microsoft.com/en-us/windows/downloads/windows-sdk/ | ||
|
||
.\node_modules\.bin\esbuild index.js --bundle --platform=node --outfile=out.js | ||
|
||
node --experimental-sea-config sea-config.json | ||
node -e "require('fs').copyFileSync(process.execPath, 'gif-validator.exe')" | ||
|
||
if NOT exist "C:\Program Files (x86)\Windows Kits\10\bin\10.0.19041.0\x64\signtool.exe" ( echo Signtool not found. Ignoring... ) else ( "C:\Program Files (x86)\Windows Kits\10\bin\10.0.19041.0\x64\signtool.exe" remove /s gif-validator.exe ) | ||
|
||
npx postject gif-validator.exe NODE_SEA_BLOB sea.blob --sentinel-fuse NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2 | ||
|
||
if exist sea.blob ( del sea.blob ) | ||
if exist out.js ( out.js ) | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
const { Helper } = require("./Helper.js") | ||
const { FrecencyUserSettings } = require("discord-protos") | ||
const { Axios } = require("axios") | ||
|
||
/** Main client class for this project */ | ||
export class GifClient { | ||
constructor(token) { | ||
if(!token) throw new Error("No token provided") | ||
|
||
this.axios = new Axios({ | ||
headers: { | ||
"Authorization": token, | ||
"accept": "*/*", | ||
"Content-Type": "application/json", | ||
"x-discord-locale": "en-US", | ||
"accept-language": "en-US;q=0.9", | ||
"Referer": "https://discord.com/channels/@me", | ||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) discord/1.0.9034 Chrome/108.0.5359.215 Electron/22.3.26 Safari/537.36", | ||
"x-discord-timezone": Intl.DateTimeFormat().resolvedOptions().timeZone, | ||
"x-super-properties": "eyJvcyI6IldpbmRvd3MiLCJicm93c2VyIjoiRGlzY29yZCBDbGllbnQiLCJyZWxlYXNlX2NoYW5uZWwiOiJzdGFibGUiLCJjbGllbnRfdmVyc2lvbiI6IjEuMC45MDM0Iiwib3NfdmVyc2lvbiI6IjEwLjAuMTkwNDUiLCJvc19hcmNoIjoieDY0IiwiYXBwX2FyY2giOiJpYTMyIiwic3lzdGVtX2xvY2FsZSI6ImVuLVVTIiwiYnJvd3Nlcl91c2VyX2FnZW50IjoiTW96aWxsYS81LjAgKFdpbmRvd3MgTlQgMTAuMDsgV09XNjQpIEFwcGxlV2ViS2l0LzUzNy4zNiAoS0hUTUwsIGxpa2UgR2Vja28pIGRpc2NvcmQvMS4wLjkwMzQgQ2hyb21lLzEwOC4wLjUzNTkuMjE1IEVsZWN0cm9uLzIyLjMuMjYgU2FmYXJpLzUzNy4zNiIsImJyb3dzZXJfdmVyc2lvbiI6IjIyLjMuMjYiLCJjbGllbnRfYnVpbGRfbnVtYmVyIjoyNzEyMTYsIm5hdGl2ZV9idWlsZF9udW1iZXIiOjQ0MTQyLCJjbGllbnRfZXZlbnRfc291cmNlIjpudWxsfQ==" | ||
}, | ||
transformResponse: (data) => Helper.tryParseJSON(data, true), | ||
transformRequest: (data) => JSON.stringify(data) | ||
}) | ||
} | ||
|
||
_handleError(response) { | ||
const json = Helper.tryParseJSON(response); | ||
if(json) { | ||
if(json["message"]) { | ||
if(json["message"] === "401: Unauthorized" && json["code"] === 0) throw new Error("Invalid token!") | ||
if(!Helper.statusesOK.some(s => json["message"].startsWith(s))) throw new Error(json) | ||
} | ||
return true | ||
} | ||
return true | ||
} | ||
|
||
/** | ||
* Grabs list of gifs and returns them | ||
* @returns {Promise<{[key: string]: import("discord-protos").FrecencyUserSettings_FavoriteGIF}>} Gifs | ||
*/ | ||
async getGifs() { | ||
const {data} = await this.axios.get(Helper.PROTO_URL(2)) | ||
this._handleError(data) | ||
|
||
const {settings: encodedSettings} = data | ||
const decodedSettings = FrecencyUserSettings.fromBase64(encodedSettings) | ||
|
||
return decodedSettings["favoriteGifs"]["gifs"] | ||
} | ||
|
||
/** | ||
* Validates gifs and removes unavailable ones. | ||
* @param {{[key: string]: import("discord-protos").FrecencyUserSettings_FavoriteGIF}} gifs Gifs | ||
* @returns {Promise<{[key: string]: import("discord-protos").FrecencyUserSettings_FavoriteGIF}>} Valid Gifs | ||
*/ | ||
async validateGifs(gifs) { | ||
let newGifs = {...gifs} | ||
for (let key of Object.keys(gifs)) { | ||
const resp = await this.axios.head(gifs[key].src) | ||
if(!Helper.isOK(resp.status)) delete newGifs[key] | ||
} | ||
return newGifs | ||
} | ||
|
||
/** | ||
* Saves gifs and returns if it succedded | ||
* @param {{[key: string]: import("discord-protos").FrecencyUserSettings_FavoriteGIF}} gifs Gifs to save | ||
* @return {Promise<boolean>} Was save successful? | ||
*/ | ||
async saveGifs(gifs) { | ||
const decodedSettings = { | ||
favoriteGifs: { | ||
gifs: gifs | ||
} | ||
} | ||
const encodedSettings = FrecencyUserSettings.toBase64(decodedSettings); | ||
|
||
const {status, data} = await this.axios.patch(Helper.PROTO_URL(2), {settings: encodedSettings}) | ||
this._handleError(data) | ||
|
||
return Helper.isOK(status) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
/** Helper methods for project */ | ||
export class Helper { | ||
/** Status codes which are taken as OK */ | ||
static statusesOK = [ | ||
...new Array(8).fill(0).map((_, i) => 200 + i), | ||
226 | ||
] | ||
|
||
/** | ||
* Generates url for proto manipulation | ||
* @param {1 | 2 | 3} proto_type Type of proto | ||
* @returns {string} URL | ||
*/ | ||
static PROTO_URL = (proto_type) => "https://discord.com/api/v9/users/@me/settings-proto/".concat(proto_type) | ||
|
||
/** | ||
* Tries to parse a JSON string to object | ||
* @param {string} maybeJson String that might be a JSON | ||
* @param {boolean} shouldReturnBack Should function return string on error? | ||
* @returns {object|null} Parsed object if valid JSON | null if invalid | ||
*/ | ||
static tryParseJSON(maybeJson = "", shouldReturnBack = false){ | ||
try {return JSON.parse(maybeJson)} | ||
catch {return shouldReturnBack ? maybeJson : null} | ||
} | ||
|
||
/** | ||
* Checks if status code is an OK response (200-208 & 226) | ||
* @param {number} status Status code | ||
* @returns {boolean} Is OK? | ||
*/ | ||
static isOK(status) { | ||
return Helper.statusesOK.includes(status) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
const { createInterface } = require("readline") | ||
const { stdin, stdout } = require("process") | ||
|
||
/** Class for prompting user in terminal */ | ||
export class RL { | ||
constructor() { | ||
this.interface = createInterface(stdin, stdout) | ||
} | ||
|
||
/** | ||
* Prompts user | ||
* @param {string} question Question for the readline function | ||
* @param {boolean} require Is method accepting empty strings? | ||
* @returns {Promise<string>} Answer | ||
*/ | ||
async readLine(question = "", require = false) { | ||
const q = (q) => new Promise(resolve => this.interface.question(q, resolve)) | ||
let a = "" | ||
|
||
if(require) while(a.trim().length === 0) a = await q(question) | ||
else a = await q(question) | ||
|
||
return a | ||
} | ||
|
||
/** | ||
* Prompts user staticaally without need of new classes | ||
* @param {string} question Question for the readline function | ||
* @param {boolean} require Is method accepting empty strings? | ||
* @returns {Promise<string>} Answer | ||
*/ | ||
static async readLine(question = "", require = false) { | ||
const instance = new RL() | ||
return instance.readLine(question, require) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
@echo off | ||
|
||
if exist sea.blob ( del sea.blob ) | ||
if exist out.js ( del out.js ) | ||
if exist gif-validator.exe ( del gif-validator.exe ) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
const { GifClient } = require("./classes/GifClient.js"); | ||
const { RL } = require("./classes/RL.js"); | ||
|
||
process.removeAllListeners('warning') | ||
|
||
RL.readLine("Provide your token here: ", true).then(async token => { | ||
const client = new GifClient(token) | ||
|
||
console.log("Grabbing gifs...") | ||
const gifs = await client.getGifs() | ||
|
||
console.log(`Validating ${Object.keys(gifs).length} gifs...`) | ||
const validatedGifs = await client.validateGifs(gifs) | ||
|
||
console.log(`Got ${Object.keys(validatedGifs).length} valid gifs... saving them.`) | ||
const result = await client.saveGifs(validatedGifs); | ||
|
||
if(result) console.log(`Successfully validated and saved ${Object.keys(validatedGifs).length} gifs!`) | ||
else console.log("Something went wrong... maybe discord updated their servers. If so, this app WON'T work anymore.") | ||
|
||
setTimeout(process.exit, 5_000) // Delay before closing | ||
}) |
Oops, something went wrong.