💄 Limit the size and number of uploaded files
💄 Limit the size and number of uploaded files
This commit is contained in:
@@ -53,6 +53,8 @@
|
||||
template: '',
|
||||
r: 0.0,
|
||||
k: 4,
|
||||
max_file_size: 10,
|
||||
max_file_count: 5,
|
||||
hybrid: false
|
||||
};
|
||||
|
||||
@@ -386,6 +388,41 @@
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class=" my-2 flex gap-1.5">
|
||||
<div class=" w-full justify-between">
|
||||
<div class="self-center text-xs font-medium min-w-fit mb-1">
|
||||
{$i18n.t('Max File Count')}
|
||||
</div>
|
||||
<div class="self-center">
|
||||
<input
|
||||
class=" w-full rounded-lg py-1.5 px-4 text-sm bg-gray-50 dark:text-gray-300 dark:bg-gray-850 outline-none"
|
||||
type="number"
|
||||
placeholder={$i18n.t('Enter Max File Count')}
|
||||
bind:value={querySettings.max_file_count}
|
||||
autocomplete="off"
|
||||
min="0"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="w-full">
|
||||
<div class=" self-center text-xs font-medium min-w-fit mb-1">
|
||||
{$i18n.t('Max File Size(MB)')}
|
||||
</div>
|
||||
|
||||
<div class="self-center">
|
||||
<input
|
||||
class="w-full rounded-lg py-1.5 px-4 text-sm bg-gray-50 dark:text-gray-300 dark:bg-gray-850 outline-none"
|
||||
type="number"
|
||||
placeholder={$i18n.t('Enter Max File Size(MB)')}
|
||||
bind:value={querySettings.max_file_size}
|
||||
autocomplete="off"
|
||||
min="0"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class=" flex w-full justify-between">
|
||||
<div class=" self-center text-xs font-medium">{$i18n.t('Hybrid Search')}</div>
|
||||
|
||||
|
||||
@@ -15,8 +15,16 @@
|
||||
user as _user
|
||||
} from '$lib/stores';
|
||||
import { blobToFile, findWordIndices } from '$lib/utils';
|
||||
import { processDocToVectorDB } from '$lib/apis/rag';
|
||||
import { transcribeAudio } from '$lib/apis/audio';
|
||||
|
||||
import {
|
||||
getQuerySettings,
|
||||
processDocToVectorDB,
|
||||
uploadDocToVectorDB,
|
||||
uploadWebToVectorDB,
|
||||
uploadYoutubeTranscriptionToVectorDB
|
||||
} from '$lib/apis/rag';
|
||||
|
||||
import { uploadFile } from '$lib/apis/files';
|
||||
import {
|
||||
SUPPORTED_FILE_TYPE,
|
||||
@@ -54,6 +62,7 @@
|
||||
let commandsElement;
|
||||
|
||||
let inputFiles;
|
||||
let querySettings;
|
||||
let dragged = false;
|
||||
|
||||
let user = null;
|
||||
@@ -169,7 +178,67 @@
|
||||
}
|
||||
};
|
||||
|
||||
const processFileCountLimit = async (querySettings, inputFiles) => {
|
||||
const maxFiles = querySettings.max_file_count;
|
||||
const currentFilesCount = files.length;
|
||||
const inputFilesCount = inputFiles.length;
|
||||
const totalFilesCount = currentFilesCount + inputFilesCount;
|
||||
|
||||
if (currentFilesCount >= maxFiles || totalFilesCount > maxFiles) {
|
||||
toast.error(
|
||||
$i18n.t('File count exceeds the limit of {{size}}', {
|
||||
count: maxFiles
|
||||
})
|
||||
);
|
||||
if (currentFilesCount >= maxFiles) {
|
||||
return [false, null];
|
||||
}
|
||||
if (totalFilesCount > maxFiles) {
|
||||
inputFiles = inputFiles.slice(0, maxFiles - currentFilesCount);
|
||||
}
|
||||
}
|
||||
return [true, inputFiles];
|
||||
};
|
||||
|
||||
const processFileSizeLimit = async (querySettings, file) => {
|
||||
if (file.size <= querySettings.max_file_size * 1024 * 1024) {
|
||||
if (['image/gif', 'image/webp', 'image/jpeg', 'image/png'].includes(file['type'])) {
|
||||
if (visionCapableModels.length === 0) {
|
||||
toast.error($i18n.t('Selected model(s) do not support image inputs'));
|
||||
return;
|
||||
}
|
||||
let reader = new FileReader();
|
||||
reader.onload = (event) => {
|
||||
files = [
|
||||
...files,
|
||||
{
|
||||
type: 'image',
|
||||
url: `${event.target.result}`
|
||||
}
|
||||
];
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
} else {
|
||||
uploadFileHandler(file);
|
||||
}
|
||||
} else {
|
||||
toast.error(
|
||||
$i18n.t('File size exceeds the limit of {{size}}MB', {
|
||||
size: querySettings.max_file_size
|
||||
})
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
onMount(() => {
|
||||
const initializeSettings = async () => {
|
||||
try {
|
||||
querySettings = await getQuerySettings(localStorage.token);
|
||||
} catch (error) {
|
||||
console.error('Error fetching query settings:', error);
|
||||
}
|
||||
};
|
||||
initializeSettings();
|
||||
window.setTimeout(() => chatTextAreaElement?.focus(), 0);
|
||||
|
||||
const dropZone = document.querySelector('body');
|
||||
@@ -198,27 +267,19 @@
|
||||
const inputFiles = Array.from(e.dataTransfer?.files);
|
||||
|
||||
if (inputFiles && inputFiles.length > 0) {
|
||||
inputFiles.forEach((file) => {
|
||||
console.log(inputFiles);
|
||||
const [canProcess, filesToProcess] = await processFileCountLimit(
|
||||
querySettings,
|
||||
inputFiles
|
||||
);
|
||||
if (!canProcess) {
|
||||
dragged = false;
|
||||
return;
|
||||
}
|
||||
console.log(filesToProcess);
|
||||
filesToProcess.forEach((file) => {
|
||||
console.log(file, file.name.split('.').at(-1));
|
||||
if (['image/gif', 'image/webp', 'image/jpeg', 'image/png'].includes(file['type'])) {
|
||||
if (visionCapableModels.length === 0) {
|
||||
toast.error($i18n.t('Selected model(s) do not support image inputs'));
|
||||
return;
|
||||
}
|
||||
let reader = new FileReader();
|
||||
reader.onload = (event) => {
|
||||
files = [
|
||||
...files,
|
||||
{
|
||||
type: 'image',
|
||||
url: `${event.target.result}`
|
||||
}
|
||||
];
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
} else {
|
||||
uploadFileHandler(file);
|
||||
}
|
||||
processFileSizeLimit(querySettings, file);
|
||||
});
|
||||
} else {
|
||||
toast.error($i18n.t(`File not found.`));
|
||||
@@ -341,26 +402,19 @@
|
||||
on:change={async () => {
|
||||
if (inputFiles && inputFiles.length > 0) {
|
||||
const _inputFiles = Array.from(inputFiles);
|
||||
_inputFiles.forEach((file) => {
|
||||
if (['image/gif', 'image/webp', 'image/jpeg', 'image/png'].includes(file['type'])) {
|
||||
if (visionCapableModels.length === 0) {
|
||||
toast.error($i18n.t('Selected model(s) do not support image inputs'));
|
||||
return;
|
||||
}
|
||||
let reader = new FileReader();
|
||||
reader.onload = (event) => {
|
||||
files = [
|
||||
...files,
|
||||
{
|
||||
type: 'image',
|
||||
url: `${event.target.result}`
|
||||
}
|
||||
];
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
} else {
|
||||
uploadFileHandler(file);
|
||||
}
|
||||
console.log(_inputFiles);
|
||||
const [canProcess, filesToProcess] = await processFileCountLimit(
|
||||
querySettings,
|
||||
_inputFiles
|
||||
);
|
||||
if (!canProcess) {
|
||||
filesInputElement.value = '';
|
||||
return;
|
||||
}
|
||||
console.log(filesToProcess);
|
||||
filesToProcess.forEach((file) => {
|
||||
console.log(file, file.name.split('.').at(-1));
|
||||
processFileSizeLimit(querySettings, file);
|
||||
});
|
||||
} else {
|
||||
toast.error($i18n.t(`File not found.`));
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
import { createNewDoc, deleteDocByName, getDocs } from '$lib/apis/documents';
|
||||
|
||||
import { SUPPORTED_FILE_TYPE, SUPPORTED_FILE_EXTENSIONS } from '$lib/constants';
|
||||
import { processDocToVectorDB, uploadDocToVectorDB } from '$lib/apis/rag';
|
||||
import { getQuerySettings, processDocToVectorDB, uploadDocToVectorDB } from '$lib/apis/rag';
|
||||
import { blobToFile, transformFileName } from '$lib/utils';
|
||||
|
||||
import Checkbox from '$lib/components/common/Checkbox.svelte';
|
||||
@@ -24,6 +24,7 @@
|
||||
let importFiles = '';
|
||||
|
||||
let inputFiles = '';
|
||||
let querySettings;
|
||||
let query = '';
|
||||
let documentsImportInputElement: HTMLInputElement;
|
||||
let tags = [];
|
||||
@@ -98,7 +99,17 @@
|
||||
}
|
||||
};
|
||||
|
||||
const initializeSettings = async () => {
|
||||
try {
|
||||
querySettings = await getQuerySettings(localStorage.token);
|
||||
} catch (error) {
|
||||
console.error('Error fetching query settings:', error);
|
||||
}
|
||||
};
|
||||
|
||||
onMount(() => {
|
||||
initializeSettings();
|
||||
|
||||
documents.subscribe((docs) => {
|
||||
tags = docs.reduce((a, e, i, arr) => {
|
||||
return [...new Set([...a, ...(e?.content?.tags ?? []).map((tag) => tag.name)])];
|
||||
@@ -136,16 +147,24 @@
|
||||
if (inputFiles && inputFiles.length > 0) {
|
||||
for (const file of inputFiles) {
|
||||
console.log(file, file.name.split('.').at(-1));
|
||||
if (
|
||||
SUPPORTED_FILE_TYPE.includes(file['type']) ||
|
||||
SUPPORTED_FILE_EXTENSIONS.includes(file.name.split('.').at(-1))
|
||||
) {
|
||||
uploadDoc(file);
|
||||
if (file.size <= querySettings.max_file_size * 1024 * 1024) {
|
||||
if (
|
||||
SUPPORTED_FILE_TYPE.includes(file['type']) ||
|
||||
SUPPORTED_FILE_EXTENSIONS.includes(file.name.split('.').at(-1))
|
||||
) {
|
||||
uploadDoc(file);
|
||||
} else {
|
||||
toast.error(
|
||||
`Unknown File Type '${file['type']}', but accepting and treating as plain text`
|
||||
);
|
||||
uploadDoc(file);
|
||||
}
|
||||
} else {
|
||||
toast.error(
|
||||
`Unknown File Type '${file['type']}', but accepting and treating as plain text`
|
||||
$i18n.t('File size exceeds the limit of {{size}}MB', {
|
||||
size: querySettings.max_file_size
|
||||
})
|
||||
);
|
||||
uploadDoc(file);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user