Fix uploads with same name

Changed filenames
This commit is contained in:
Eduard Kuzmenko 2021-05-16 05:22:53 +04:00
parent f12b693e0f
commit 475f0027fc
2 changed files with 57 additions and 30 deletions

View File

@ -7,39 +7,52 @@
import type { InputFileLocation, InputStickerSet } from "../layer"; import type { InputFileLocation, InputStickerSet } from "../layer";
import type { DownloadOptions } from "../lib/mtproto/apiFileManager"; import type { DownloadOptions } from "../lib/mtproto/apiFileManager";
const FILENAME_JOINER = '_';
export function getFileNameByLocation(location: InputFileLocation, options?: Partial<{ export function getFileNameByLocation(location: InputFileLocation, options?: Partial<{
fileName: string fileName: string
}>) { }>) {
const fileName = '';//(options?.fileName || '').split('.'); const fileName = '';//(options?.fileName || '').split('.');
const ext = fileName[fileName.length - 1] || ''; const ext = fileName[fileName.length - 1] || '';
let str: string;
switch(location._) { switch(location._) {
case 'inputPhotoFileLocation': case 'inputPhotoFileLocation': {
str = ['photo', fileName[0], location.id, location.thumb_size].filter(Boolean).join(FILENAME_JOINER);
break;
}
case 'inputDocumentFileLocation': { case 'inputDocumentFileLocation': {
const thumbPart = location.thumb_size ? '_' + location.thumb_size : ''; str = ['document', fileName[0], location.id, location.thumb_size].filter(Boolean).join(FILENAME_JOINER);
return (fileName[0] ? fileName[0] + '_' : '') + location.id + thumbPart + (ext ? '.' + ext : ext); break;
} }
case 'inputPeerPhotoFileLocation': case 'inputPeerPhotoFileLocation':
return ['peerPhoto', location.photo_id, location.pFlags.big ? 'big' : 'small'].join('_'); str = ['peerPhoto', location.photo_id, location.pFlags.big ? 'big' : 'small'].join(FILENAME_JOINER);
break;
case 'inputStickerSetThumb': { case 'inputStickerSetThumb': {
const id = (location.stickerset as InputStickerSet.inputStickerSetID).id || const id = (location.stickerset as InputStickerSet.inputStickerSetID).id ||
(location.stickerset as InputStickerSet.inputStickerSetShortName).short_name || (location.stickerset as InputStickerSet.inputStickerSetShortName).short_name ||
(location.stickerset as InputStickerSet.inputStickerSetDice).emoticon || (location.stickerset as InputStickerSet.inputStickerSetDice).emoticon ||
location.stickerset._; location.stickerset._;
return ['stickerSetThumb', id, location.thumb_version].join('_'); str = ['stickerSetThumb', id, location.thumb_version].join(FILENAME_JOINER);
break;
} }
case 'inputFileLocation': { case 'inputFileLocation': {
return location.volume_id + '_' + location.local_id + (ext ? '.' + ext : ext); str = location.volume_id + '_' + location.local_id;
break;
} }
default: { default: {
console.error('Unrecognized location:', location); console.error('Unrecognized location:', location);
return ''; str = '';
break;
} }
} }
return str + (ext ? '.' + ext : ext);
} }
export type FileURLType = 'photo' | 'thumb' | 'document' | 'stream' | 'download'; export type FileURLType = 'photo' | 'thumb' | 'document' | 'stream' | 'download';

View File

@ -45,17 +45,17 @@ type MyUploadFile = UploadFile.uploadFile;
const MAX_FILE_SAVE_SIZE = 20e6; const MAX_FILE_SAVE_SIZE = 20e6;
export class ApiFileManager { export class ApiFileManager {
public cacheStorage = new CacheStorageController('cachedFiles'); private cacheStorage = new CacheStorageController('cachedFiles');
public cachedDownloadPromises: { private cachedDownloadPromises: {
[fileName: string]: CancellablePromise<Blob> [fileName: string]: CancellablePromise<Blob>
} = {}; } = {};
public uploadPromises: { private uploadPromises: {
[fileName: string]: CancellablePromise<InputFile> [fileName: string]: Set<CancellablePromise<InputFile>>
} = {}; } = {};
public downloadPulls: { private downloadPulls: {
[dcId: string]: Array<{ [dcId: string]: Array<{
id: number, id: number,
queueId: number, queueId: number,
@ -67,7 +67,7 @@ export class ApiFileManager {
activeDelta: number activeDelta: number
}> }>
} = {}; } = {};
public downloadActives: {[dcId: string]: number} = {}; private downloadActives: {[dcId: string]: number} = {};
public webpConvertPromises: {[fileName: string]: CancellablePromise<Uint8Array>} = {}; public webpConvertPromises: {[fileName: string]: CancellablePromise<Uint8Array>} = {};
@ -76,9 +76,9 @@ export class ApiFileManager {
private queueId = 0; private queueId = 0;
private debug = Modes.debug; private debug = Modes.debug;
public downloadRequest(dcId: 'upload', id: number, cb: () => Promise<void>, activeDelta: number, queueId?: number): Promise<void>; private downloadRequest(dcId: 'upload', id: number, cb: () => Promise<void>, activeDelta: number, queueId?: number): Promise<void>;
public downloadRequest(dcId: number, id: number, cb: () => Promise<MyUploadFile>, activeDelta: number, queueId?: number): Promise<MyUploadFile>; private downloadRequest(dcId: number, id: number, cb: () => Promise<MyUploadFile>, activeDelta: number, queueId?: number): Promise<MyUploadFile>;
public downloadRequest(dcId: number | string, id: number, cb: () => Promise<MyUploadFile | void>, activeDelta: number, queueId: number = 0) { private downloadRequest(dcId: number | string, id: number, cb: () => Promise<MyUploadFile | void>, activeDelta: number, queueId: number = 0) {
if(this.downloadPulls[dcId] === undefined) { if(this.downloadPulls[dcId] === undefined) {
this.downloadPulls[dcId] = []; this.downloadPulls[dcId] = [];
this.downloadActives[dcId] = 0; this.downloadActives[dcId] = 0;
@ -97,7 +97,7 @@ export class ApiFileManager {
return promise; return promise;
} }
public downloadCheck(dcId: string | number) { private downloadCheck(dcId: string | number) {
const downloadPull = this.downloadPulls[dcId]; const downloadPull = this.downloadPulls[dcId];
const downloadLimit = dcId === 'upload' ? 24 : 24; const downloadLimit = dcId === 'upload' ? 24 : 24;
//const downloadLimit = Infinity; //const downloadLimit = Infinity;
@ -136,18 +136,23 @@ export class ApiFileManager {
this.queueId = queueId; this.queueId = queueId;
} }
public getFileStorage() { private getFileStorage() {
return this.cacheStorage; return this.cacheStorage;
} }
public cancelDownload(fileName: string) { public cancelDownload(fileName: string) {
const promise = this.cachedDownloadPromises[fileName] || this.uploadPromises[fileName]; const promises = (this.cachedDownloadPromises[fileName] ? [this.cachedDownloadPromises[fileName]] : []) ||
(this.uploadPromises[fileName] ? Array.from(this.uploadPromises[fileName]) : []);
let canceled = false;
for(let i = 0, length = promises.length; i < length; ++i) {
const promise = promises[i];
if(promise && !promise.isRejected && !promise.isFulfilled) { if(promise && !promise.isRejected && !promise.isFulfilled) {
promise.cancel(); promise.cancel();
return true; canceled = true;
}
} }
return false; return canceled;
} }
public requestFilePart(dcId: number, location: InputFileLocation, offset: number, limit: number, id = 0, queueId = 0, checkCancel?: () => void) { public requestFilePart(dcId: number, location: InputFileLocation, offset: number, limit: number, id = 0, queueId = 0, checkCancel?: () => void) {
@ -184,13 +189,13 @@ export class ApiFileManager {
return bytes * 1024; return bytes * 1024;
} }
uncompressTGS = (bytes: Uint8Array, fileName: string) => { private uncompressTGS = (bytes: Uint8Array, fileName: string) => {
//this.log('uncompressTGS', bytes, bytes.slice().buffer); //this.log('uncompressTGS', bytes, bytes.slice().buffer);
// slice нужен потому что в uint8array - 5053 length, в arraybuffer - 5084 // slice нужен потому что в uint8array - 5053 length, в arraybuffer - 5084
return cryptoWorker.gzipUncompress<string>(bytes.slice().buffer, true); return cryptoWorker.gzipUncompress<string>(bytes.slice().buffer, true);
}; };
convertWebp = (bytes: Uint8Array, fileName: string) => { private convertWebp = (bytes: Uint8Array, fileName: string) => {
const convertPromise = deferredPromise<Uint8Array>(); const convertPromise = deferredPromise<Uint8Array>();
const task = {type: 'convertWebp', payload: {fileName, bytes}}; const task = {type: 'convertWebp', payload: {fileName, bytes}};
@ -203,8 +208,8 @@ export class ApiFileManager {
return Promise.reject({type: 'BROWSER_BLOB_NOT_SUPPORTED'}); return Promise.reject({type: 'BROWSER_BLOB_NOT_SUPPORTED'});
} }
let size = options.size ?? 0; const size = options.size ?? 0;
let {dcId, location} = options; const {dcId, location} = options;
let process: ApiFileManager['uncompressTGS'] | ApiFileManager['convertWebp']; let process: ApiFileManager['uncompressTGS'] | ApiFileManager['convertWebp'];
@ -393,10 +398,14 @@ export class ApiFileManager {
this.cachedDownloadPromises[fileName] = deferred; this.cachedDownloadPromises[fileName] = deferred;
deferred.finally(() => {
delete this.cachedDownloadPromises[fileName];
});
return deferred; return deferred;
} }
public deleteFile(fileName: string) { private deleteFile(fileName: string) {
//this.log('will delete file:', fileName); //this.log('will delete file:', fileName);
delete this.cachedDownloadPromises[fileName]; delete this.cachedDownloadPromises[fileName];
return this.getFileStorage().delete(fileName); return this.getFileStorage().delete(fileName);
@ -581,10 +590,15 @@ export class ApiFileManager {
}; };
deferred.finally(() => { deferred.finally(() => {
set.delete(deferred);
if(!set.size) {
delete this.uploadPromises[fileName]; delete this.uploadPromises[fileName];
}
}); });
return this.uploadPromises[fileName] = deferred; const set = this.uploadPromises[fileName] ?? (this.uploadPromises[fileName] = new Set());
set.add(deferred);
return deferred;
} }
} }