feat: ability to generate url shorten config

This commit is contained in:
diced 2023-01-14 10:25:54 -08:00
parent 81e6e4e5f2
commit 6d49463dad
No known key found for this signature in database
GPG key ID: 370BD1BA142842D1
5 changed files with 92 additions and 25 deletions

View file

@ -7,28 +7,31 @@ export default function Flameshot({ user, open, setOpen }) {
const curl = [ const curl = [
'curl', 'curl',
'-H', '-H',
'"Content-Type: multipart/form-data"',
'-H',
`"authorization: ${user?.token}"`, `"authorization: ${user?.token}"`,
'-F',
'file=@/tmp/ss.png',
`${ `${
window.location.protocol + window.location.protocol +
'//' + '//' +
window.location.hostname + window.location.hostname +
(window.location.port ? ':' + window.location.port : '') (window.location.port ? ':' + window.location.port : '')
}/api/upload`, }/api/${values.type === 'upload-file' ? 'upload' : 'shorten'}`,
]; ];
if (values.type === 'upload-file') {
curl.push('-F', 'file=@/tmp/ss.png');
curl.push('-H', '"Content-Type: multipart/form-data"');
} else {
curl.push('-H', '"Content-Type: application/json"');
}
const extraHeaders = {}; const extraHeaders = {};
if (values.format !== 'RANDOM') { if (values.format !== 'RANDOM' && values.type === 'upload-file') {
extraHeaders['Format'] = values.format; extraHeaders['Format'] = values.format;
} else { } else {
delete extraHeaders['Format']; delete extraHeaders['Format'];
} }
if (values.imageCompression !== 0) { if (values.imageCompression !== 0 && values.type === 'upload-file') {
extraHeaders['Image-Compression-Percent'] = values.imageCompression; extraHeaders['Image-Compression-Percent'] = values.imageCompression;
} else { } else {
delete extraHeaders['Image-Compression-Percent']; delete extraHeaders['Image-Compression-Percent'];
@ -40,16 +43,16 @@ export default function Flameshot({ user, open, setOpen }) {
delete extraHeaders['Zws']; delete extraHeaders['Zws'];
} }
if (values.embed) { if (values.embed && values.type === 'upload-file') {
extraHeaders['Embed'] = 'true'; extraHeaders['Embed'] = 'true';
} else { } else {
delete extraHeaders['Embed']; delete extraHeaders['Embed'];
} }
if (values.noJSON) { if (values.noJSON) {
extraHeaders['X-Zipline-NoJSON'] = 'true'; extraHeaders['No-JSON'] = 'true';
} else { } else {
delete extraHeaders['X-Zipline-NoJSON']; delete extraHeaders['No-JSON'];
} }
for (const [key, value] of Object.entries(extraHeaders)) { for (const [key, value] of Object.entries(extraHeaders)) {
@ -57,16 +60,28 @@ export default function Flameshot({ user, open, setOpen }) {
curl.push(`"${key}: ${value}"`); curl.push(`"${key}: ${value}"`);
} }
const shell = `#!/bin/bash${values.wlCompositorNotSupported ? '\nexport XDG_CURRENT_DESKTOP=sway\n' : ''} console.log(curl);
let shell;
if (values.type === 'upload-file') {
shell = `#!/bin/bash${values.wlCompositorNotSupported ? '\nexport XDG_CURRENT_DESKTOP=sway\n' : ''}
flameshot gui -r > /tmp/ss.png; flameshot gui -r > /tmp/ss.png;
${curl.join(' ')}${values.noJSON ? '' : " | jq -r '.files[0]'"} | tr -d '\\n' | ${ ${curl.join(' ')}${values.noJSON ? '' : " | jq -r '.files[0]'"} | tr -d '\\n' | ${
values.wlCompatibility ? 'wl-copy' : 'xsel -ib' values.wlCompatibility ? 'wl-copy' : 'xsel -ib'
}; };
`; `;
} else if (values.type === 'shorten-url') {
shell = `#!/bin/bash
arg=$1;
${curl.join(' ')} -d "{\\"url\\": \\"$arg\\"}"${values.noJSON ? '' : " | jq -r '.url'"} | tr -d '\\n' | ${
values.wlCompatibility ? 'wl-copy' : 'xsel -ib'
};
`;
}
const pseudoElement = document.createElement('a'); const pseudoElement = document.createElement('a');
pseudoElement.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(shell)); pseudoElement.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(shell));
pseudoElement.setAttribute('download', 'zipline.sh'); pseudoElement.setAttribute('download', `zipline${values.type === 'upload-file' ? '' : '-url'}.sh`);
pseudoElement.style.display = 'none'; pseudoElement.style.display = 'none';
document.body.appendChild(pseudoElement); document.body.appendChild(pseudoElement);
pseudoElement.click(); pseudoElement.click();

View file

@ -3,10 +3,12 @@ import { useForm } from '@mantine/form';
import { DownloadIcon } from 'components/icons'; import { DownloadIcon } from 'components/icons';
import Link from 'components/Link'; import Link from 'components/Link';
import MutedText from 'components/MutedText'; import MutedText from 'components/MutedText';
import { useState } from 'react';
export function GeneratorModal({ opened, onClose, title, onSubmit, ...other }) { export function GeneratorModal({ opened, onClose, title, onSubmit, ...other }) {
const form = useForm({ const form = useForm({
initialValues: { initialValues: {
type: 'upload-file',
format: 'RANDOM', format: 'RANDOM',
imageCompression: 0, imageCompression: 0,
zeroWidthSpace: false, zeroWidthSpace: false,
@ -17,6 +19,13 @@ export function GeneratorModal({ opened, onClose, title, onSubmit, ...other }) {
}, },
}); });
const [isUploadFile, setIsUploadFile] = useState(true);
const onChangeType = (value) => {
setIsUploadFile(value === 'upload-file');
form.setFieldValue('type', value);
};
return ( return (
<Modal opened={opened} onClose={onClose} title={<Title order={3}>{title}</Title>} size='lg'> <Modal opened={opened} onClose={onClose} title={<Title order={3}>{title}</Title>} size='lg'>
{other.desc && ( {other.desc && (
@ -25,6 +34,18 @@ export function GeneratorModal({ opened, onClose, title, onSubmit, ...other }) {
</MutedText> </MutedText>
)} )}
<form onSubmit={form.onSubmit((values) => onSubmit(values))}> <form onSubmit={form.onSubmit((values) => onSubmit(values))}>
<Select
label='Type'
data={[
{ value: 'upload-file', label: 'Upload file' },
{ value: 'shorten-url', label: 'Shorten URLs' },
]}
id='type'
my='sm'
{...form.getInputProps('type')}
onChange={onChangeType}
/>
<Select <Select
label='Select file name format' label='Select file name format'
data={[ data={[
@ -34,6 +55,8 @@ export function GeneratorModal({ opened, onClose, title, onSubmit, ...other }) {
{ value: 'NAME', label: 'Name (keeps original file name)' }, { value: 'NAME', label: 'Name (keeps original file name)' },
]} ]}
id='format' id='format'
my='sm'
disabled={!isUploadFile}
{...form.getInputProps('format')} {...form.getInputProps('format')}
/> />
@ -42,8 +65,9 @@ export function GeneratorModal({ opened, onClose, title, onSubmit, ...other }) {
description='Set the image compression level (0-100). 0 is no compression, 100 is maximum compression.' description='Set the image compression level (0-100). 0 is no compression, 100 is maximum compression.'
max={100} max={100}
min={0} min={0}
mt='md' my='sm'
id='imageCompression' id='imageCompression'
disabled={!isUploadFile}
{...form.getInputProps('imageCompression')} {...form.getInputProps('imageCompression')}
/> />
@ -58,6 +82,7 @@ export function GeneratorModal({ opened, onClose, title, onSubmit, ...other }) {
description='Image will display with embedded metadata' description='Image will display with embedded metadata'
label='Embed' label='Embed'
id='embed' id='embed'
disabled={!isUploadFile}
{...form.getInputProps('embed', { type: 'checkbox' })} {...form.getInputProps('embed', { type: 'checkbox' })}
/> />
<Checkbox <Checkbox
@ -106,6 +131,7 @@ export function GeneratorModal({ opened, onClose, title, onSubmit, ...other }) {
<Code>XDG_CURRENT_DESKTOP=sway</Code> to workaround Flameshot&apos;s errors <Code>XDG_CURRENT_DESKTOP=sway</Code> to workaround Flameshot&apos;s errors
</> </>
} }
disabled={!isUploadFile}
id='wlCompositorNotSupported' id='wlCompositorNotSupported'
{...form.getInputProps('wlCompositorNotSupported', { type: 'checkbox' })} {...form.getInputProps('wlCompositorNotSupported', { type: 'checkbox' })}
/> />

View file

@ -3,7 +3,7 @@ import { GeneratorModal } from './GeneratorModal';
export default function ShareX({ user, open, setOpen }) { export default function ShareX({ user, open, setOpen }) {
const [config, setConfig] = useState({ const [config, setConfig] = useState({
Version: '13.2.1', Version: '14.1.0',
Name: 'Zipline', Name: 'Zipline',
DestinationType: 'ImageUploader, TextUploader', DestinationType: 'ImageUploader, TextUploader',
RequestMethod: 'POST', RequestMethod: 'POST',
@ -19,10 +19,28 @@ export default function ShareX({ user, open, setOpen }) {
URL: '$json:files[0]$', URL: '$json:files[0]$',
Body: 'MultipartFormData', Body: 'MultipartFormData',
FileFormName: 'file', FileFormName: 'file',
Data: undefined,
}); });
const onSubmit = (values) => { const onSubmit = (values) => {
if (values.format !== 'RANDOM') { if (values.type === 'shorten-url') {
config.RequestURL = `${
window.location.protocol +
'//' +
window.location.hostname +
(window.location.port ? ':' + window.location.port : '')
}/api/shorten`;
config.URL = '$json:url$';
config.Body = 'JSON';
delete config.FileFormName;
config.Data = JSON.stringify({ url: '{input}' });
setConfig(config);
} else {
delete config.Data;
setConfig(config);
}
if (values.format !== 'RANDOM' && values.type === 'upload-file') {
config.Headers['Format'] = values.format; config.Headers['Format'] = values.format;
setConfig(config); setConfig(config);
} else { } else {
@ -30,7 +48,7 @@ export default function ShareX({ user, open, setOpen }) {
setConfig(config); setConfig(config);
} }
if (values.imageCompression !== 0) { if (values.imageCompression !== 0 && values.type === 'upload-file') {
config.Headers['Image-Compression-Percent'] = values.imageCompression; config.Headers['Image-Compression-Percent'] = values.imageCompression;
setConfig(config); setConfig(config);
} else { } else {
@ -46,7 +64,7 @@ export default function ShareX({ user, open, setOpen }) {
setConfig(config); setConfig(config);
} }
if (values.embed) { if (values.embed && values.type === 'upload-file') {
config.Headers['Embed'] = 'true'; config.Headers['Embed'] = 'true';
setConfig(config); setConfig(config);
} else { } else {
@ -56,10 +74,11 @@ export default function ShareX({ user, open, setOpen }) {
if (values.noJSON) { if (values.noJSON) {
config.URL = '{response}'; config.URL = '{response}';
config.Headers['X-Zipline-NoJSON'] = 'true'; config.Headers['No-JSON'] = 'true';
setConfig(config); setConfig(config);
} else { } else {
delete config.Headers['X-Zipline-NoJSON']; delete config.Headers['No-JSON'];
config.URL = values.type === 'upload-file' ? '$json:files[0]$' : '$json:url$';
setConfig(config); setConfig(config);
} }

View file

@ -66,10 +66,17 @@ async function handler(req: NextApiReq, res: NextApiRes) {
); );
} }
const fullUrl = `${zconfig.core.return_https ? 'https' : 'http'}://${req.headers.host}${
zconfig.uploader.route === '/' ? '' : zconfig.uploader.route
}/${req.body.vanity ? req.body.vanity : invis ? invis.invis : url.id}`;
if (req.headers['no-json']) {
res.setHeader('Content-Type', 'text/plain');
return res.end(fullUrl);
}
return res.json({ return res.json({
url: `${zconfig.core.return_https ? 'https' : 'http'}://${req.headers.host}${zconfig.urls.route}/${ url: fullUrl,
req.body.vanity ? req.body.vanity : invis ? invis.invis : url.id
}`,
}); });
} }

View file

@ -374,7 +374,7 @@ async function handler(req: NextApiReq, res: NextApiRes) {
} }
} }
if (req.headers['x-zipline-nojson']) { if (req.headers['no-json']) {
res.setHeader('Content-Type', 'text/plain'); res.setHeader('Content-Type', 'text/plain');
return res.end(response.files.join(',')); return res.end(response.files.join(','));
} }