mirror of
https://github.com/mollersuite/monofile.git
synced 2024-11-25 07:06:25 -08:00
does anyone else have uncontrollable urges to meow
This commit is contained in:
parent
afbb29c949
commit
8fb2a55bdd
|
@ -1,8 +1,8 @@
|
||||||
{
|
{
|
||||||
"maxDiscordFiles": 50,
|
"maxDiscordFiles": 500,
|
||||||
"maxDiscordFileSize": 10485760,
|
"maxDiscordFileSize": 10485760,
|
||||||
"targetGuild": "906767804575928390",
|
"targetGuild": "906767804575928390",
|
||||||
"targetChannel": "1160783463696302182",
|
"targetChannel": "1024080525993971913",
|
||||||
"requestTimeout": 120000,
|
"requestTimeout": 120000,
|
||||||
"maxUploadIdLength": 30,
|
"maxUploadIdLength": 30,
|
||||||
"accounts": {
|
"accounts": {
|
||||||
|
|
14
package-lock.json
generated
14
package-lock.json
generated
|
@ -17,6 +17,7 @@
|
||||||
"axios": "^0.27.2",
|
"axios": "^0.27.2",
|
||||||
"body-parser": "^1.20.0",
|
"body-parser": "^1.20.0",
|
||||||
"bytes": "^3.1.2",
|
"bytes": "^3.1.2",
|
||||||
|
"commander": "^11.1.0",
|
||||||
"cookie-parser": "^1.4.6",
|
"cookie-parser": "^1.4.6",
|
||||||
"dotenv": "^16.0.2",
|
"dotenv": "^16.0.2",
|
||||||
"express": "^4.18.1",
|
"express": "^4.18.1",
|
||||||
|
@ -757,6 +758,14 @@
|
||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/commander": {
|
||||||
|
"version": "11.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz",
|
||||||
|
"integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/concat-stream": {
|
"node_modules/concat-stream": {
|
||||||
"version": "1.6.2",
|
"version": "1.6.2",
|
||||||
"resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
|
"resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
|
||||||
|
@ -2420,6 +2429,11 @@
|
||||||
"delayed-stream": "~1.0.0"
|
"delayed-stream": "~1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"commander": {
|
||||||
|
"version": "11.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz",
|
||||||
|
"integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ=="
|
||||||
|
},
|
||||||
"concat-stream": {
|
"concat-stream": {
|
||||||
"version": "1.6.2",
|
"version": "1.6.2",
|
||||||
"resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
|
"resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
"axios": "^0.27.2",
|
"axios": "^0.27.2",
|
||||||
"body-parser": "^1.20.0",
|
"body-parser": "^1.20.0",
|
||||||
"bytes": "^3.1.2",
|
"bytes": "^3.1.2",
|
||||||
|
"commander": "^11.1.0",
|
||||||
"cookie-parser": "^1.4.6",
|
"cookie-parser": "^1.4.6",
|
||||||
"dotenv": "^16.0.2",
|
"dotenv": "^16.0.2",
|
||||||
"express": "^4.18.1",
|
"express": "^4.18.1",
|
||||||
|
|
123
src/server/cli.ts
Normal file
123
src/server/cli.ts
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
import fs from "fs"
|
||||||
|
import { stat } from "fs/promises"
|
||||||
|
import Files from "./lib/files"
|
||||||
|
import { program } from "commander"
|
||||||
|
import { basename } from "path"
|
||||||
|
import { Writable } from "node:stream"
|
||||||
|
const pkg = require(`${process.cwd()}/package.json`)
|
||||||
|
let config = require(`${process.cwd()}/config.json`)
|
||||||
|
|
||||||
|
// init data
|
||||||
|
|
||||||
|
if (!fs.existsSync(__dirname + "/../../.data/"))
|
||||||
|
fs.mkdirSync(__dirname + "/../../.data/")
|
||||||
|
|
||||||
|
// discord
|
||||||
|
let files = new Files(config)
|
||||||
|
|
||||||
|
program
|
||||||
|
.name("monocli")
|
||||||
|
.description("Quickly run monofile to execute a query or so")
|
||||||
|
.version(pkg.version)
|
||||||
|
|
||||||
|
program.command("list")
|
||||||
|
.alias("ls")
|
||||||
|
.description("List files in the database")
|
||||||
|
.action(() => {
|
||||||
|
Object.keys(files.files).forEach(e => console.log(e))
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
program.command("download")
|
||||||
|
.alias("dl")
|
||||||
|
.description("Download a file from the database")
|
||||||
|
.argument("<id>", "ID of the file you'd like to download")
|
||||||
|
.option("-o, --output <path>", 'Folder or filename to output to')
|
||||||
|
.action(async (id, options) => {
|
||||||
|
|
||||||
|
await (new Promise<void>(resolve => setTimeout(() => resolve(), 1000)))
|
||||||
|
|
||||||
|
let fp = files.files[id]
|
||||||
|
|
||||||
|
if (!fp)
|
||||||
|
throw `file ${id} not found`
|
||||||
|
|
||||||
|
let out = options.output as string || `./`
|
||||||
|
|
||||||
|
if (fs.existsSync(out) && (await stat(out)).isDirectory())
|
||||||
|
out = `${out.replace(/\/+$/, "")}/${fp.filename}`
|
||||||
|
|
||||||
|
;(await files.readFileStream(id)).pipe(
|
||||||
|
fs.createWriteStream(out)
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
program.command("upload")
|
||||||
|
.alias("up")
|
||||||
|
.description("Upload a file to the instance")
|
||||||
|
.argument("<file>", "Path to the file you'd like to upload")
|
||||||
|
.option("-id, --fileid <id>", 'Custom file ID to use')
|
||||||
|
.action(async (file, options) => {
|
||||||
|
|
||||||
|
await (new Promise<void>(resolve => setTimeout(() => resolve(), 1000)))
|
||||||
|
|
||||||
|
if (!(fs.existsSync(file) && (await stat(file)).isFile()))
|
||||||
|
throw `${file} is not a file`
|
||||||
|
|
||||||
|
let writable = files.writeFileStream({
|
||||||
|
filename: basename(file),
|
||||||
|
mime: "application/octet-stream",
|
||||||
|
size: (await stat(file)).size,
|
||||||
|
uploadId: options.fileid
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!(writable instanceof Writable))
|
||||||
|
throw JSON.stringify(writable, null, 3)
|
||||||
|
|
||||||
|
;(await fs.createReadStream(file)).pipe(
|
||||||
|
writable
|
||||||
|
)
|
||||||
|
|
||||||
|
console.log(`started: ${file}`)
|
||||||
|
|
||||||
|
writable.on("drain", () => {
|
||||||
|
console.log("Drain")
|
||||||
|
})
|
||||||
|
|
||||||
|
writable.on("finish", () => {
|
||||||
|
console.log("Finished!")
|
||||||
|
})
|
||||||
|
|
||||||
|
writable.on("error", (e) => {
|
||||||
|
console.error(e)
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
program.command("memup")
|
||||||
|
.description("Upload a file to the instance (no stream)")
|
||||||
|
.argument("<file>", "Path to the file you'd like to upload")
|
||||||
|
.option("-id, --fileid <id>", 'Custom file ID to use')
|
||||||
|
.action(async (file, options) => {
|
||||||
|
|
||||||
|
await (new Promise<void>(resolve => setTimeout(() => resolve(), 1000)))
|
||||||
|
|
||||||
|
if (!(fs.existsSync(file) && (await stat(file)).isFile()))
|
||||||
|
throw `${file} is not a file`
|
||||||
|
|
||||||
|
let buf = fs.readFileSync(file)
|
||||||
|
|
||||||
|
let id = files.uploadFile({
|
||||||
|
filename: basename(file),
|
||||||
|
mime: "application/octet-stream",
|
||||||
|
uploadId: options.fileid
|
||||||
|
}, buf)
|
||||||
|
|
||||||
|
console.log(`uploaded: ${await id}`)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
program.parse()
|
|
@ -1,4 +1,19 @@
|
||||||
import fetch, { type RequestInit, type Response, Headers } from "node-fetch"
|
import { type RequestInfo, type RequestInit, type Response, Headers } from "node-fetch"
|
||||||
|
|
||||||
|
// I jerk off to skibidi toilet. His smile is so fucking hot, oh my god, oh.
|
||||||
|
// The voices are getting louder, help me. Oh god, i want to put it inside that toilet and make him beg.
|
||||||
|
// Whenever i see skibidi toilet cum comes out like a waterfall.
|
||||||
|
// Whenever my classmates say anything about toilets the entire school gets flooded with cum everywhere.
|
||||||
|
// Dafuqboom is truly the best artist of all time.
|
||||||
|
|
||||||
|
let ftch_dft: (url: URL | RequestInfo, init?:RequestInit) => Promise<Response>
|
||||||
|
const fetch = async (url: URL | RequestInfo, init?:RequestInit) => {
|
||||||
|
if (ftch_dft) return ftch_dft(url, init)
|
||||||
|
else {
|
||||||
|
ftch_dft = (await import("node-fetch")).default;
|
||||||
|
return ftch_dft(url, init)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const base = "https://discord.com/api/v10"
|
const base = "https://discord.com/api/v10"
|
||||||
const buckets = new Map<string, DiscordAPIBucket>()
|
const buckets = new Map<string, DiscordAPIBucket>()
|
||||||
|
@ -64,14 +79,14 @@ class DiscordAPIBucket {
|
||||||
let rd = extractRatelimitData(base)
|
let rd = extractRatelimitData(base)
|
||||||
|
|
||||||
this.parent = rest
|
this.parent = rest
|
||||||
this.name = rd.bucket_name
|
this.name = rd.bucket_name || Math.random().toString()
|
||||||
this.limit = rd.limit
|
this.limit = rd.limit
|
||||||
this.remaining = rd.remaining
|
this.remaining = rd.remaining
|
||||||
this.expires = rd.expires
|
this.expires = rd.expires
|
||||||
|
|
||||||
this.expirationHold =
|
this.expirationHold =
|
||||||
setTimeout(
|
setTimeout(
|
||||||
this.destroy,
|
this.destroy.bind(this),
|
||||||
parseFloat(base.get("x-ratelimit-reset-after")!)
|
parseFloat(base.get("x-ratelimit-reset-after")!)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -81,7 +96,6 @@ class DiscordAPIBucket {
|
||||||
* @description Renders this bucket invalid
|
* @description Renders this bucket invalid
|
||||||
*/
|
*/
|
||||||
destroy() {
|
destroy() {
|
||||||
|
|
||||||
buckets.delete(this.name)
|
buckets.delete(this.name)
|
||||||
this.dead = true
|
this.dead = true
|
||||||
this.linked_routes.forEach((v) => routeConnections.delete(v))
|
this.linked_routes.forEach((v) => routeConnections.delete(v))
|
||||||
|
|
|
@ -79,9 +79,12 @@ export class Client {
|
||||||
|
|
||||||
let returned = await this.rest.fetch(`/channels/${this.targetChannel}/messages`, {
|
let returned = await this.rest.fetch(`/channels/${this.targetChannel}/messages`, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: fd
|
body: fd,
|
||||||
|
headers: fd.getHeaders()
|
||||||
})
|
})
|
||||||
|
|
||||||
return (await returned.json() as APIMessage)
|
let response = (await returned.json() as APIMessage)
|
||||||
|
console.log(JSON.stringify(response, null, 4))
|
||||||
|
return response
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -114,9 +114,11 @@ namespace StreamHelpers {
|
||||||
private newmessage_debounce : boolean = true
|
private newmessage_debounce : boolean = true
|
||||||
|
|
||||||
api: API
|
api: API
|
||||||
|
files: Files
|
||||||
|
|
||||||
constructor( api: API, targetSize: number ) {
|
constructor( files: Files, targetSize: number ) {
|
||||||
this.api = api
|
this.files = files
|
||||||
|
this.api = files.api
|
||||||
this.targetSize = targetSize
|
this.targetSize = targetSize
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,7 +154,11 @@ namespace StreamHelpers {
|
||||||
if (this.buffer[0]) return this.buffer[0]
|
if (this.buffer[0]) return this.buffer[0]
|
||||||
else {
|
else {
|
||||||
// startmessage.... idk
|
// startmessage.... idk
|
||||||
await this.startMessage(0);
|
await this.startMessage(
|
||||||
|
this.messages.length < Math.ceil(this.targetSize/this.files.config.maxDiscordFileSize/10)
|
||||||
|
? 10
|
||||||
|
: Math.ceil(this.targetSize/this.files.config.maxDiscordFileSize) - this.messages.length*10
|
||||||
|
);
|
||||||
return this.buffer[0]
|
return this.buffer[0]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -165,12 +171,13 @@ export default class Files {
|
||||||
config: Configuration
|
config: Configuration
|
||||||
api: API
|
api: API
|
||||||
files: { [key: string]: FilePointer } = {}
|
files: { [key: string]: FilePointer } = {}
|
||||||
|
data_directory: string = `${process.cwd()}/.data`
|
||||||
|
|
||||||
constructor(config: Configuration) {
|
constructor(config: Configuration) {
|
||||||
this.config = config
|
this.config = config
|
||||||
this.api = new API(process.env.TOKEN!, config.targetChannel)
|
this.api = new API(process.env.TOKEN!, config.targetChannel)
|
||||||
|
|
||||||
readFile(process.cwd() + "/.data/files.json")
|
readFile(this.data_directory+ "/files.json")
|
||||||
.then((buf) => {
|
.then((buf) => {
|
||||||
this.files = JSON.parse(buf.toString() || "{}")
|
this.files = JSON.parse(buf.toString() || "{}")
|
||||||
})
|
})
|
||||||
|
@ -215,7 +222,7 @@ export default class Files {
|
||||||
)
|
)
|
||||||
if (validation) return validation
|
if (validation) return validation
|
||||||
|
|
||||||
let buf = new StreamHelpers.StreamBuffer(this.api, metadata.size)
|
let buf = new StreamHelpers.StreamBuffer(this, metadata.size)
|
||||||
let fs_obj = this
|
let fs_obj = this
|
||||||
|
|
||||||
let wt = new Writable({
|
let wt = new Writable({
|
||||||
|
@ -398,7 +405,7 @@ export default class Files {
|
||||||
*/
|
*/
|
||||||
async write(): Promise<void> {
|
async write(): Promise<void> {
|
||||||
await writeFile(
|
await writeFile(
|
||||||
process.cwd() + "/.data/files.json",
|
this.data_directory + "/files.json",
|
||||||
JSON.stringify(
|
JSON.stringify(
|
||||||
this.files,
|
this.files,
|
||||||
null,
|
null,
|
||||||
|
|
Loading…
Reference in a new issue