mirror of
https://github.com/diced/zipline.git
synced 2025-05-11 18:36:02 +02:00
feat: gfycat style file names
This commit is contained in:
parent
9607bfcb66
commit
cbd9191488
13 changed files with 6609 additions and 20 deletions
|
@ -0,0 +1,3 @@
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "Zipline" ADD COLUMN "filesRandomWordsNumAdjectives" INTEGER NOT NULL DEFAULT 2,
|
||||||
|
ADD COLUMN "filesRandomWordsSeparator" TEXT NOT NULL DEFAULT '-';
|
|
@ -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
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
|
@ -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' />}>
|
||||||
|
|
|
@ -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',
|
||||||
|
|
|
@ -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'),
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 = {};
|
||||||
|
|
42
src/lib/uploader/randomWords.ts
Normal file
42
src/lib/uploader/randomWords.ts
Normal 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;
|
||||||
|
}
|
1505
src/lib/uploader/wordlists/adjectives.ts
Normal file
1505
src/lib/uploader/wordlists/adjectives.ts
Normal file
File diff suppressed because it is too large
Load diff
1754
src/lib/uploader/wordlists/animals.ts
Normal file
1754
src/lib/uploader/wordlists/animals.ts
Normal file
File diff suppressed because it is too large
Load diff
|
@ -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()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue