feat: gfycat style file names

This commit is contained in:
diced 2025-02-13 21:07:32 -08:00
parent 9607bfcb66
commit cbd9191488
No known key found for this signature in database
GPG key ID: 370BD1BA142842D1
13 changed files with 6609 additions and 20 deletions

View file

@ -0,0 +1,3 @@
-- AlterTable
ALTER TABLE "Zipline" ADD COLUMN "filesRandomWordsNumAdjectives" INTEGER NOT NULL DEFAULT 2,
ADD COLUMN "filesRandomWordsSeparator" TEXT NOT NULL DEFAULT '-';

View file

@ -20,8 +20,8 @@ model Zipline {
coreTempDirectory String // default join(tmpdir(), 'zipline') coreTempDirectory String // default join(tmpdir(), 'zipline')
chunksEnabled Boolean @default(true) chunksEnabled Boolean @default(true)
chunksMax String @default("95mb") chunksMax String @default("95mb")
chunksSize String @default("25mb") chunksSize String @default("25mb")
tasksDeleteInterval String @default("30m") tasksDeleteInterval String @default("30m")
tasksClearInvitesInterval String @default("30m") tasksClearInvitesInterval String @default("30m")
@ -29,15 +29,17 @@ model Zipline {
tasksThumbnailsInterval String @default("30m") tasksThumbnailsInterval String @default("30m")
tasksMetricsInterval String @default("30m") tasksMetricsInterval String @default("30m")
filesRoute String @default("/u") filesRoute String @default("/u")
filesLength Int @default(6) filesLength Int @default(6)
filesDefaultFormat String @default("random") filesDefaultFormat String @default("random")
filesDisabledExtensions String[] filesDisabledExtensions String[]
filesMaxFileSize String @default("100mb") filesMaxFileSize String @default("100mb")
filesDefaultExpiration String? filesDefaultExpiration String?
filesAssumeMimetypes Boolean @default(false) filesAssumeMimetypes Boolean @default(false)
filesDefaultDateFormat String @default("YYYY-MM-DD_HH:mm:ss") filesDefaultDateFormat String @default("YYYY-MM-DD_HH:mm:ss")
filesRemoveGpsMetadata Boolean @default(false) filesRemoveGpsMetadata Boolean @default(false)
filesRandomWordsNumAdjectives Int @default(2)
filesRandomWordsSeparator String @default("-")
urlsRoute String @default("/go") urlsRoute String @default("/go")
urlsLength Int @default(6) urlsLength Int @default(6)
@ -59,13 +61,13 @@ model Zipline {
invitesEnabled Boolean @default(true) invitesEnabled Boolean @default(true)
invitesLength Int @default(6) invitesLength Int @default(6)
websiteTitle String @default("Zipline") websiteTitle String @default("Zipline")
websiteTitleLogo String? websiteTitleLogo String?
websiteExternalLinks Json @default("[{ \"name\": \"GitHub\", \"url\": \"https://github.com/diced/zipline\"}, { \"name\": \"Documentation\", \"url\": \"https://zipline.diced.sh/\"}]") websiteExternalLinks Json @default("[{ \"name\": \"GitHub\", \"url\": \"https://github.com/diced/zipline\"}, { \"name\": \"Documentation\", \"url\": \"https://zipline.diced.sh/\"}]")
websiteLoginBackground String? websiteLoginBackground String?
websiteLoginBackgroundBlur Boolean @default(true) websiteLoginBackgroundBlur Boolean @default(true)
websiteDefaultAvatar String? websiteDefaultAvatar String?
websiteTos String? websiteTos String?
websiteThemeDefault String @default("system") websiteThemeDefault String @default("system")
websiteThemeDark String @default("builtin:dark_gray") websiteThemeDark String @default("builtin:dark_gray")
@ -243,7 +245,7 @@ model File {
updatedAt DateTime @updatedAt updatedAt DateTime @updatedAt
deletesAt DateTime? deletesAt DateTime?
name String // name & file saved on datasource name String // name & file saved on datasource
originalName String? // original name of file when uploaded originalName String? // original name of file when uploaded
size BigInt size BigInt
type String type String

1501
public/adjectives.txt Normal file

File diff suppressed because it is too large Load diff

1750
public/animals.txt Normal file

File diff suppressed because it is too large Load diff

View file

@ -32,6 +32,8 @@ export default function ServerSettingsFiles({
filesAssumeMimetypes: boolean; filesAssumeMimetypes: boolean;
filesDefaultDateFormat: string; filesDefaultDateFormat: string;
filesRemoveGpsMetadata: boolean; filesRemoveGpsMetadata: boolean;
filesRandomWordsNumAdjectives: number;
filesRandomWordsSeparator: string;
}>({ }>({
initialValues: { initialValues: {
filesRoute: '/u', filesRoute: '/u',
@ -43,6 +45,8 @@ export default function ServerSettingsFiles({
filesAssumeMimetypes: false, filesAssumeMimetypes: false,
filesDefaultDateFormat: 'YYYY-MM-DD_HH:mm:ss', filesDefaultDateFormat: 'YYYY-MM-DD_HH:mm:ss',
filesRemoveGpsMetadata: false, filesRemoveGpsMetadata: false,
filesRandomWordsNumAdjectives: 3,
filesRandomWordsSeparator: '-',
}, },
}); });
@ -86,6 +90,8 @@ export default function ServerSettingsFiles({
filesAssumeMimetypes: data?.filesAssumeMimetypes ?? false, filesAssumeMimetypes: data?.filesAssumeMimetypes ?? false,
filesDefaultDateFormat: data?.filesDefaultDateFormat ?? 'YYYY-MM-DD_HH:mm:ss', filesDefaultDateFormat: data?.filesDefaultDateFormat ?? 'YYYY-MM-DD_HH:mm:ss',
filesRemoveGpsMetadata: data?.filesRemoveGpsMetadata ?? false, filesRemoveGpsMetadata: data?.filesRemoveGpsMetadata ?? false,
filesRandomWordsNumAdjectives: data?.filesRandomWordsNumAdjectives ?? 3,
filesRandomWordsSeparator: data?.filesRandomWordsSeparator ?? '-',
}); });
}, [data]); }, [data]);
@ -159,6 +165,21 @@ export default function ServerSettingsFiles({
placeholder='YYYY-MM-DD_HH:mm:ss' placeholder='YYYY-MM-DD_HH:mm:ss'
{...form.getInputProps('filesDefaultDateFormat')} {...form.getInputProps('filesDefaultDateFormat')}
/> />
<NumberInput
label='Random Words Num Adjectives'
description='The number of adjectives to use for the random-words/gfycat format.'
min={1}
max={10}
{...form.getInputProps('filesRandomWordsNumAdjectives')}
/>
<TextInput
label='Random Words Separator'
description='The separator to use for the random-words/gfycat format.'
placeholder='-'
{...form.getInputProps('filesRandomWordsSeparator')}
/>
</SimpleGrid> </SimpleGrid>
<Button type='submit' mt='md' loading={isLoading} leftSection={<IconDeviceFloppy size='1rem' />}> <Button type='submit' mt='md' loading={isLoading} leftSection={<IconDeviceFloppy size='1rem' />}>

View file

@ -40,6 +40,8 @@ export const rawConfig: any = {
assumeMimetypes: undefined, assumeMimetypes: undefined,
defaultDateFormat: undefined, defaultDateFormat: undefined,
removeGpsMetadata: undefined, removeGpsMetadata: undefined,
randomWordsNumAdjectives: undefined,
randomWordsSeperator: undefined,
}, },
urls: { urls: {
route: undefined, route: undefined,
@ -188,6 +190,8 @@ export const DATABASE_TO_PROP = {
filesAssumeMimetypes: 'files.assumeMimetypes', filesAssumeMimetypes: 'files.assumeMimetypes',
filesDefaultDateFormat: 'files.defaultDateFormat', filesDefaultDateFormat: 'files.defaultDateFormat',
filesRemoveGpsMetadata: 'files.removeGpsMetadata', filesRemoveGpsMetadata: 'files.removeGpsMetadata',
filesRandomWordsNumAdjectives: 'files.randomWordsNumAdjectives',
filesRandomWordsSeperator: 'files.randomWordsSeperator',
urlsRoute: 'urls.route', urlsRoute: 'urls.route',
urlsLength: 'urls.length', urlsLength: 'urls.length',

View file

@ -87,13 +87,15 @@ export const schema = z.object({
files: z.object({ files: z.object({
route: z.string().startsWith('/').min(1).trim().toLowerCase().default('/u'), route: z.string().startsWith('/').min(1).trim().toLowerCase().default('/u'),
length: z.number().default(6), length: z.number().default(6),
defaultFormat: z.enum(['random', 'date', 'uuid', 'name', 'gfycat']).default('random'), defaultFormat: z.enum(['random', 'date', 'uuid', 'name', 'gfycat', 'random-words']).default('random'),
disabledExtensions: z.array(z.string()).default([]), disabledExtensions: z.array(z.string()).default([]),
maxFileSize: z.string().default('100mb'), maxFileSize: z.string().default('100mb'),
defaultExpiration: z.string().nullable().default(null), defaultExpiration: z.string().nullable().default(null),
assumeMimetypes: z.boolean().default(false), assumeMimetypes: z.boolean().default(false),
defaultDateFormat: z.string().default('YYYY-MM-DD_HH:mm:ss'), defaultDateFormat: z.string().default('YYYY-MM-DD_HH:mm:ss'),
removeGpsMetadata: z.boolean().default(false), removeGpsMetadata: z.boolean().default(false),
randomWordsNumAdjectives: z.number().default(3),
randomWordsSeperator: z.string().default('-'),
}), }),
urls: z.object({ urls: z.object({
route: z.string().startsWith('/').min(1).trim().toLowerCase().default('/go'), route: z.string().startsWith('/').min(1).trim().toLowerCase().default('/go'),

View file

@ -4,6 +4,7 @@ import { Config } from '../config/validate';
import { randomCharacters } from '../crypto'; import { randomCharacters } from '../crypto';
import { randomUUID } from 'crypto'; import { randomUUID } from 'crypto';
import { parse } from 'path'; import { parse } from 'path';
import { randomWords } from './randomWords';
export function formatFileName(nameFormat: Config['files']['defaultFormat'], originalName?: string) { export function formatFileName(nameFormat: Config['files']['defaultFormat'], originalName?: string) {
switch (nameFormat) { switch (nameFormat) {
@ -17,7 +18,9 @@ export function formatFileName(nameFormat: Config['files']['defaultFormat'], ori
const { name } = parse(originalName!); const { name } = parse(originalName!);
return name; return name;
case 'random-words':
case 'gfycat': case 'gfycat':
return randomWords(config.files.randomWordsNumAdjectives, config.files.randomWordsSeperator);
default: default:
return randomCharacters(config.files.length); return randomCharacters(config.files.length);
} }

View file

@ -135,7 +135,7 @@ function headerError(header: keyof UploadHeaders, message: string) {
}; };
} }
const FORMATS = ['random', 'uuid', 'date', 'name']; const FORMATS = ['random', 'uuid', 'date', 'name', 'gfycat', 'random-words'];
export function parseHeaders(headers: UploadHeaders, fileConfig: Config['files']): UploadOptions { export function parseHeaders(headers: UploadHeaders, fileConfig: Config['files']): UploadOptions {
const response: UploadOptions = {}; const response: UploadOptions = {};

View file

@ -0,0 +1,42 @@
import { readFileSync } from 'fs';
import fallbackAdjectives from './wordlists/adjectives';
import fallbackAnimals from './wordlists/animals';
import { log } from '../logger';
const logger = log('random_words');
function importWords(): {
adjectives: string[];
animals: string[];
} {
try {
const adjectives = readFileSync('./public/adjectives.txt', 'utf-8');
const animals = readFileSync('./public/animals.txt', 'utf-8');
return {
adjectives: adjectives.split('\n'),
animals: animals.split('\n'),
};
} catch (e) {
logger.error((e as Error).message).debug('using fallback wordlists');
return {
adjectives: fallbackAdjectives,
animals: fallbackAnimals,
};
}
}
export function randomWords(numAdjectives: number = 2, seperator: string = '-') {
const { adjectives, animals } = importWords();
let words = '';
for (let i = 0; i !== numAdjectives; ++i) {
words += adjectives[Math.floor(Math.random() * adjectives.length)] + seperator;
}
words += animals[Math.floor(Math.random() * animals.length)];
return words;
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -134,6 +134,8 @@ export default fastifyPlugin(
filesAssumeMimetypes: z.boolean(), filesAssumeMimetypes: z.boolean(),
filesDefaultDateFormat: z.string(), filesDefaultDateFormat: z.string(),
filesRemoveGpsMetadata: z.boolean(), filesRemoveGpsMetadata: z.boolean(),
filesRandomWordsNumAdjectives: z.number().min(1).max(20),
filesRandomWordsSeparator: z.string(),
urlsRoute: z urlsRoute: z
.string() .string()