1
0
mirror of https://github.com/laurent22/joplin.git synced 2024-12-30 10:36:35 +02:00
joplin/packages/lib/downloadController.ts

99 lines
3.3 KiB
TypeScript
Raw Normal View History

import Logger from '@joplin/utils/Logger';
import JoplinError from './JoplinError';
import { ErrorCode } from './errors';
import { bytesToHuman } from '@joplin/utils/bytes';
const logger = Logger.create('downloadController');
export interface DownloadController {
totalBytes: number;
imagesCount: number;
maxImagesCount: number;
imageCountExpected: number;
printStats(imagesCountExpected: number): void;
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
handleChunk(request: any): (chunk: any)=> void;
limitMessage(): string;
}
export class LimitedDownloadController implements DownloadController {
private totalBytes_ = 0;
// counts before the downloaded has finished, so at the end if the totalBytes > maxTotalBytesAllowed
// it means that imageCount will be higher than the total downloaded during the process
private imagesCount_ = 0;
// how many images links the content has
private imageCountExpected_ = 0;
private isLimitExceeded_ = false;
private maxTotalBytes = 0;
public readonly maxImagesCount: number;
private ownerId = '';
public constructor(ownerId: string, maxTotalBytes: number, maxImagesCount: number) {
this.ownerId = ownerId;
this.maxTotalBytes = maxTotalBytes;
this.maxImagesCount = maxImagesCount;
}
public set totalBytes(value: number) {
if (this.totalBytes_ >= this.maxTotalBytes) {
throw new JoplinError(`Total bytes stored (${this.totalBytes_}) has exceeded the amount established (${this.maxTotalBytes})`, ErrorCode.DownloadLimiter);
}
this.totalBytes_ = value;
}
public get totalBytes() {
return this.totalBytes_;
}
public set imagesCount(value: number) {
if (this.imagesCount_ > this.maxImagesCount) {
throw new JoplinError(`Total images to be stored (${this.imagesCount_}) has exceeded the amount established (${this.maxImagesCount})`, ErrorCode.DownloadLimiter);
}
this.imagesCount_ = value;
}
public get imagesCount() {
return this.imagesCount_;
}
public set imageCountExpected(value: number) {
this.imageCountExpected_ = value;
}
public get imageCountExpected() {
return this.imageCountExpected_;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
public handleChunk(request: any) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
return (chunk: any) => {
try {
this.totalBytes += chunk.length;
} catch (error) {
request.destroy(error);
}
};
}
public printStats() {
if (!this.isLimitExceeded_) return;
const owner = `Owner id: ${this.ownerId}`;
const totalBytes = `Total bytes stored: ${this.totalBytes}. Maximum: ${this.maxTotalBytes}`;
const totalImages = `Images initiated for download: ${this.imagesCount_}. Maximum: ${this.maxImagesCount}. Expected: ${this.imageCountExpected}`;
logger.info(`${owner} - ${totalBytes} - ${totalImages}`);
}
public limitMessage() {
if (this.imagesCount_ > this.maxImagesCount) {
return `The maximum image count of ${this.maxImagesCount} has been exceeded. Image count in your content: ${this.imageCountExpected}`;
}
if (this.totalBytes >= this.maxTotalBytes) {
return `The maximum content size ${bytesToHuman(this.maxTotalBytes)} has been exceeded. Content size: (${bytesToHuman(this.totalBytes)})`;
}
return '';
}
}