/
vshmidt
/
streamlit
Обзор
Документация
Войти
/
vshmidt
/
streamlit
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
develop
frontend/lib/src/util/FileHelper.ts
152 строки
4 KB
Ken McGrady
Update copyright header to 2026 (#13491)
02 янв 2026, 16:21
Не верифицирован
02 янв 2026, 16:21
374540a
Код
Авторство
О чём код?
/** * Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022-2026) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { type FileRejection } from "react-dropzone" import { UploadFileInfo } from "~lib/components/widgets/FileUploader/UploadFileInfo" import { isFromWindows } from "~lib/util/utils" export enum FileSize { Gigabyte = "gb", Megabyte = "mb", Kilobyte = "kb", Byte = "b", } // There is a shift towards displaying storage in base 10 vs base 2 // but Windows is still displaying things in base 2. This does not handle // all cases but for simplicity general rule is to use base 2 for Windows. export const BYTE_CONVERSION_SIZE = isFromWindows() ? 1024 : 1000 const sizeUnitSequence = [ FileSize.Gigabyte, FileSize.Megabyte, FileSize.Kilobyte, FileSize.Byte, ] export const getSizeDisplay = ( size: number, unit: FileSize, rounding = 1 ): string => { if (!unit) { unit = FileSize.Byte } if (rounding < 0) { rounding = 0 } if (size < 0) { throw new Error("Size must be greater than or equal to 0") } const sizeIndex = sizeUnitSequence.indexOf(unit) const nextUnitSize = size / BYTE_CONVERSION_SIZE if (sizeIndex && size > BYTE_CONVERSION_SIZE / 2) { return getSizeDisplay( nextUnitSize, sizeUnitSequence[sizeIndex - 1], rounding ) } return `${size.toFixed(rounding)}${unit.toUpperCase()}` } export const sizeConverter = ( size: number, inputUnit: FileSize, outputUnit: FileSize ): number => { if (size < 0) { throw Error("Size must be 0 or greater") } const inputLevel = sizeUnitSequence.findIndex(unit => unit === inputUnit) const outputLevel = sizeUnitSequence.findIndex(unit => unit === outputUnit) if (inputLevel === -1 || outputLevel === -1) { // Should not ever occur throw Error("Unexpected byte unit provided") } if (inputLevel === outputLevel) { return size } const levelsBetween = Math.abs(inputLevel - outputLevel) const byteDifference = BYTE_CONVERSION_SIZE ** levelsBetween if (inputLevel > outputLevel) { // Going from smaller to bigger return size / byteDifference } // Going from bigger to smaller return size * byteDifference } /** * Return a human-readable message for the given error. */ const getErrorMessage = ( errorCode: string, file: File, maxUploadSizeInBytes: number ): string => { switch (errorCode) { case "file-too-large": return `File must be ${getSizeDisplay( maxUploadSizeInBytes, FileSize.Byte )} or smaller.` case "file-invalid-type": return `${file.type} files are not allowed.` case "file-too-small": // This should not fire. return `File size is too small.` case "too-many-files": return "Only one file is allowed." default: return "Unexpected error. Please try again." } } /** * Returns an `UploadFileInfo` object for a rejected file */ export const getRejectedFileInfo = ( rejected: FileRejection, fileId: number, maxUploadSizeInBytes: number ): UploadFileInfo => { const { file, errors } = rejected // For directory uploads, use the relative path to preserve directory structure const fileName = file.webkitRelativePath || file.name return new UploadFileInfo( fileName, file.size, fileId, { type: "error", errorMessage: errors .map(error => getErrorMessage(error.code, file, maxUploadSizeInBytes)) .join(" "), }, file ) }