feat: gfycat url #322
This commit is contained in:
parent
5b9b454330
commit
f8cd847588
12 changed files with 3354 additions and 69 deletions
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
Warnings:
|
||||
|
||||
- You are about to drop the column `format` on the `File` table. All the data in the column will be lost.
|
||||
|
||||
*/
|
||||
-- AlterTable
|
||||
ALTER TABLE "File" DROP COLUMN "format";
|
||||
|
||||
-- DropEnum
|
||||
DROP TYPE "FileNameFormat";
|
|
@ -40,13 +40,6 @@ model Folder {
|
|||
files File[]
|
||||
}
|
||||
|
||||
enum FileNameFormat {
|
||||
UUID
|
||||
DATE
|
||||
RANDOM
|
||||
NAME
|
||||
}
|
||||
|
||||
model File {
|
||||
id Int @id @default(autoincrement())
|
||||
name String
|
||||
|
@ -61,7 +54,6 @@ model File {
|
|||
embed Boolean @default(false)
|
||||
password String?
|
||||
invisible InvisibleFile?
|
||||
format FileNameFormat @default(RANDOM)
|
||||
|
||||
user User? @relation(fields: [userId], references: [id], onDelete: SetNull)
|
||||
userId Int?
|
||||
|
|
1501
public/adjectives.txt
Normal file
1501
public/adjectives.txt
Normal file
File diff suppressed because it is too large
Load diff
1750
public/animals.txt
Normal file
1750
public/animals.txt
Normal file
File diff suppressed because it is too large
Load diff
|
@ -103,10 +103,11 @@ export function GeneratorModal({ opened, onClose, title, onSubmit, ...other }) {
|
|||
<Select
|
||||
label='Select file name format'
|
||||
data={[
|
||||
{ value: 'RANDOM', label: 'Random (alphanumeric)' },
|
||||
{ value: 'DATE', label: 'Date' },
|
||||
{ value: 'UUID', label: 'UUID' },
|
||||
{ value: 'NAME', label: 'Name (keeps original file name)' },
|
||||
{ value: 'random', label: 'Random (alphanumeric)' },
|
||||
{ value: 'date', label: 'Date' },
|
||||
{ value: 'uuid', label: 'UUID' },
|
||||
{ value: 'name', label: 'Name (keeps original file name)' },
|
||||
{ value: 'gfycat', label: 'Gfycat' },
|
||||
]}
|
||||
id='format'
|
||||
my='sm'
|
||||
|
|
|
@ -152,10 +152,11 @@ export function OptionsModal({
|
|||
icon={<IconFileInfo size='1rem' />}
|
||||
data={[
|
||||
{ value: 'default', label: 'Default' },
|
||||
{ value: 'RANDOM', label: 'Random' },
|
||||
{ value: 'NAME', label: 'Original Name' },
|
||||
{ value: 'DATE', label: 'Date (format configured by server)' },
|
||||
{ value: 'UUID', label: 'UUID' },
|
||||
{ value: 'random', label: 'Random' },
|
||||
{ value: 'name', label: 'Original Name' },
|
||||
{ value: 'date', label: 'Date (format configured by server)' },
|
||||
{ value: 'uuid', label: 'UUID' },
|
||||
{ value: 'gfycat', label: 'Gfycat' },
|
||||
]}
|
||||
/>
|
||||
<PasswordInput
|
||||
|
|
6
src/lib/format/date.ts
Normal file
6
src/lib/format/date.ts
Normal file
|
@ -0,0 +1,6 @@
|
|||
import dayjs from 'dayjs';
|
||||
import config from 'lib/config';
|
||||
|
||||
export default function date() {
|
||||
return dayjs().format(config.uploader.format_date);
|
||||
}
|
26
src/lib/format/gfycat.ts
Normal file
26
src/lib/format/gfycat.ts
Normal file
|
@ -0,0 +1,26 @@
|
|||
import { readFile } from 'fs/promises';
|
||||
|
||||
export type GfyCatWords = {
|
||||
adjectives: string[];
|
||||
animals: string[];
|
||||
};
|
||||
|
||||
export async function importWords(): Promise<GfyCatWords> {
|
||||
const adjectives = (await readFile('public/adjectives.txt', 'utf-8')).split('\n');
|
||||
const animals = (await readFile('public/animals.txt', 'utf-8')).split('\n');
|
||||
|
||||
return {
|
||||
adjectives,
|
||||
animals,
|
||||
};
|
||||
}
|
||||
|
||||
function randomWord(words: string[]) {
|
||||
return words[Math.floor(Math.random() * words.length)];
|
||||
}
|
||||
|
||||
export default async function gfycat() {
|
||||
const words = await importWords();
|
||||
|
||||
return `${randomWord(words.adjectives)}${randomWord(words.adjectives)}${randomWord(words.animals)}`;
|
||||
}
|
24
src/lib/format/index.ts
Normal file
24
src/lib/format/index.ts
Normal file
|
@ -0,0 +1,24 @@
|
|||
import date from './date';
|
||||
import gfycat from './gfycat';
|
||||
import random from './random';
|
||||
import uuid from './uuid';
|
||||
|
||||
export type NameFormat = 'random' | 'date' | 'uuid' | 'name' | 'gfycat';
|
||||
export const NameFormats: NameFormat[] = ['random', 'date', 'uuid', 'name', 'gfycat'];
|
||||
export default async function formatFileName(nameFormat: NameFormat, originalName?: string) {
|
||||
console.log(nameFormat, originalName);
|
||||
switch (nameFormat) {
|
||||
case 'random':
|
||||
return random();
|
||||
case 'date':
|
||||
return date();
|
||||
case 'uuid':
|
||||
return uuid();
|
||||
case 'name':
|
||||
return originalName.split('.')[0];
|
||||
case 'gfycat':
|
||||
return gfycat();
|
||||
default:
|
||||
return random();
|
||||
}
|
||||
}
|
6
src/lib/format/random.ts
Normal file
6
src/lib/format/random.ts
Normal file
|
@ -0,0 +1,6 @@
|
|||
import { randomChars } from 'lib/util';
|
||||
import config from 'lib/config';
|
||||
|
||||
export default function random() {
|
||||
return randomChars(config.uploader.length);
|
||||
}
|
5
src/lib/format/uuid.ts
Normal file
5
src/lib/format/uuid.ts
Normal file
|
@ -0,0 +1,5 @@
|
|||
import { randomUUID } from 'crypto';
|
||||
|
||||
export default function uuid() {
|
||||
return randomUUID({ disableEntropyCache: true });
|
||||
}
|
|
@ -1,10 +1,11 @@
|
|||
import { FileNameFormat, InvisibleFile } from '@prisma/client';
|
||||
import { InvisibleFile } from '@prisma/client';
|
||||
import { randomUUID } from 'crypto';
|
||||
import dayjs from 'dayjs';
|
||||
import { readdir, readFile, unlink, writeFile } from 'fs/promises';
|
||||
import zconfig from 'lib/config';
|
||||
import datasource from 'lib/datasource';
|
||||
import { sendUpload } from 'lib/discord';
|
||||
import formatFileName, { NameFormat, NameFormats } from 'lib/format';
|
||||
import Logger from 'lib/logger';
|
||||
import { NextApiReq, NextApiRes, withZipline } from 'lib/middleware/withZipline';
|
||||
import prisma from 'lib/prisma';
|
||||
|
@ -54,8 +55,8 @@ async function handler(req: NextApiReq, res: NextApiRes) {
|
|||
if (!expiry) return res.badRequest('invalid date (UPLOADER_DEFAULT_EXPIRATION)');
|
||||
}
|
||||
|
||||
const rawFormat = ((req.headers.format || '') as string).toUpperCase() || zconfig.uploader.default_format;
|
||||
const format: FileNameFormat = Object.keys(FileNameFormat).includes(rawFormat) && FileNameFormat[rawFormat];
|
||||
const rawFormat = ((req.headers['format'] as string) || zconfig.uploader.default_format).toLowerCase();
|
||||
const format = NameFormats.includes(rawFormat as NameFormat) ? rawFormat : 'random';
|
||||
|
||||
const imageCompressionPercent = req.headers['image-compression-percent']
|
||||
? Number(req.headers['image-compression-percent'])
|
||||
|
@ -124,25 +125,7 @@ async function handler(req: NextApiReq, res: NextApiRes) {
|
|||
const ext = filename.split('.').length === 1 ? '' : filename.split('.').pop();
|
||||
if (zconfig.uploader.disabled_extensions.includes(ext))
|
||||
return res.error('disabled extension recieved: ' + ext);
|
||||
let fileName: string;
|
||||
|
||||
switch (format) {
|
||||
case FileNameFormat.RANDOM:
|
||||
fileName = randomChars(zconfig.uploader.length);
|
||||
break;
|
||||
case FileNameFormat.DATE:
|
||||
fileName = dayjs().format(zconfig.uploader.format_date);
|
||||
break;
|
||||
case FileNameFormat.UUID:
|
||||
fileName = randomUUID({ disableEntropyCache: true });
|
||||
break;
|
||||
case FileNameFormat.NAME:
|
||||
fileName = filename.split('.')[0];
|
||||
break;
|
||||
default:
|
||||
fileName = randomChars(zconfig.uploader.length);
|
||||
break;
|
||||
}
|
||||
let fileName = await formatFileName(format, filename);
|
||||
|
||||
let password = null;
|
||||
if (req.headers.password) {
|
||||
|
@ -158,7 +141,6 @@ async function handler(req: NextApiReq, res: NextApiRes) {
|
|||
mimetype,
|
||||
userId: user.id,
|
||||
embed: !!req.headers.embed,
|
||||
format,
|
||||
password,
|
||||
expiresAt: expiry,
|
||||
maxViews: fileMaxViews,
|
||||
|
@ -250,35 +232,16 @@ async function handler(req: NextApiReq, res: NextApiRes) {
|
|||
const ext = file.originalname.split('.').length === 1 ? '' : file.originalname.split('.').pop();
|
||||
if (zconfig.uploader.disabled_extensions.includes(ext))
|
||||
return res.badRequest(`file[${i}]: disabled extension recieved: ${ext}`);
|
||||
let fileName: string;
|
||||
|
||||
switch (format) {
|
||||
case FileNameFormat.RANDOM:
|
||||
fileName = randomChars(zconfig.uploader.length);
|
||||
break;
|
||||
case FileNameFormat.DATE:
|
||||
fileName = dayjs().format(zconfig.uploader.format_date);
|
||||
break;
|
||||
case FileNameFormat.UUID:
|
||||
fileName = randomUUID({ disableEntropyCache: true });
|
||||
break;
|
||||
case FileNameFormat.NAME:
|
||||
fileName = file.originalname.split('.')[0];
|
||||
break;
|
||||
default:
|
||||
if (req.headers['x-zipline-filename']) {
|
||||
fileName = req.headers['x-zipline-filename'] as string;
|
||||
const existing = await prisma.file.findFirst({
|
||||
where: {
|
||||
name: fileName,
|
||||
},
|
||||
});
|
||||
if (existing) return res.badRequest(`file[${i}]: filename already exists: '${fileName}'`);
|
||||
|
||||
break;
|
||||
}
|
||||
fileName = randomChars(zconfig.uploader.length);
|
||||
break;
|
||||
let fileName = await formatFileName(format, file.originalname);
|
||||
console.log(fileName);
|
||||
if (req.headers['x-zipline-filename']) {
|
||||
fileName = req.headers['x-zipline-filename'] as string;
|
||||
const existing = await prisma.file.findFirst({
|
||||
where: {
|
||||
name: fileName,
|
||||
},
|
||||
});
|
||||
if (existing) return res.badRequest(`file[${i}]: filename already exists: '${fileName}'`);
|
||||
}
|
||||
|
||||
let password = null;
|
||||
|
@ -294,7 +257,6 @@ async function handler(req: NextApiReq, res: NextApiRes) {
|
|||
mimetype: req.headers.uploadtext ? 'text/plain' : compressionUsed ? 'image/jpeg' : file.mimetype,
|
||||
userId: user.id,
|
||||
embed: !!req.headers.embed,
|
||||
format,
|
||||
password,
|
||||
expiresAt: expiry,
|
||||
maxViews: fileMaxViews,
|
||||
|
|
Loading…
Reference in a new issue