Skip to content

Commit 9f0867d

Browse files
committed
feat(thumbnail): enhance thumbnail upload process with file type handling
1 parent 8b65858 commit 9f0867d

4 files changed

Lines changed: 57 additions & 45 deletions

File tree

src/commands/upload-file.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ export default class UploadFile extends Command {
137137
if (thumbnailBuffer) {
138138
await ThumbnailService.instance.uploadThumbnail(
139139
thumbnailBuffer,
140+
fileType,
140141
user.bucket,
141142
user.mnemonic,
142143
createdDriveFile.id,

src/services/thumbnail.service.ts

Lines changed: 44 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,44 +3,61 @@ import { DriveFileService } from './drive/drive-file.service';
33
import { StorageTypes } from '@internxt/sdk/dist/drive';
44
import { NetworkFacade } from './network/network-facade.service';
55
import { UploadService } from './network/upload.service';
6+
import { isImageThumbnailable, ThumbnailConfig } from '../utils/thumbnail.utils';
7+
import sharp from 'sharp';
68

79
export class ThumbnailService {
810
public static readonly instance: ThumbnailService = new ThumbnailService();
911

10-
public static readonly MaxWidth = 300;
11-
public static readonly MaxHeight = 300;
12-
public static readonly Quality = 80;
13-
public static readonly Type = 'png';
14-
1512
public uploadThumbnail = async (
1613
fileContent: Buffer,
14+
fileType: string,
1715
userBucket: string,
1816
userMnemonic: string,
1917
file_id: number,
2018
networkFacade: NetworkFacade,
21-
): Promise<StorageTypes.Thumbnail> => {
22-
const size = fileContent.length;
23-
const [thumbnailPromise] = await UploadService.instance.uploadFileStream(
24-
Readable.from(fileContent),
25-
userBucket,
26-
userMnemonic,
27-
size,
28-
networkFacade,
29-
() => {},
30-
);
19+
): Promise<StorageTypes.Thumbnail | undefined> => {
20+
let thumbnailBuffer: Buffer | undefined;
21+
if (isImageThumbnailable(fileType)) {
22+
thumbnailBuffer = await this.getThumbnailFromImageBuffer(fileContent);
23+
}
24+
if (thumbnailBuffer) {
25+
const size = thumbnailBuffer.length;
26+
const [thumbnailPromise] = await UploadService.instance.uploadFileStream(
27+
Readable.from(thumbnailBuffer),
28+
userBucket,
29+
userMnemonic,
30+
size,
31+
networkFacade,
32+
() => {},
33+
);
34+
35+
const thumbnailUploadResult = await thumbnailPromise;
3136

32-
const thumbnailUploadResult = await thumbnailPromise;
37+
const createdThumbnailFile = await DriveFileService.instance.createThumbnail({
38+
file_id: file_id,
39+
max_width: ThumbnailConfig.MaxWidth,
40+
max_height: ThumbnailConfig.MaxHeight,
41+
type: ThumbnailConfig.Type,
42+
size: size,
43+
bucket_id: userBucket,
44+
bucket_file: thumbnailUploadResult.fileId,
45+
encrypt_version: StorageTypes.EncryptionVersion.Aes03,
46+
});
47+
return createdThumbnailFile;
48+
}
49+
};
3350

34-
const createdThumbnailFile = await DriveFileService.instance.createThumbnail({
35-
file_id: file_id,
36-
max_width: ThumbnailService.MaxWidth,
37-
max_height: ThumbnailService.MaxHeight,
38-
type: ThumbnailService.Type,
39-
size: size,
40-
bucket_id: userBucket,
41-
bucket_file: thumbnailUploadResult.fileId,
42-
encrypt_version: StorageTypes.EncryptionVersion.Aes03,
43-
});
44-
return createdThumbnailFile;
51+
private getThumbnailFromImageBuffer = (buffer: Buffer): Promise<Buffer> => {
52+
return sharp(buffer)
53+
.resize({
54+
height: ThumbnailConfig.MaxHeight,
55+
width: ThumbnailConfig.MaxWidth,
56+
fit: 'inside',
57+
})
58+
.png({
59+
quality: ThumbnailConfig.Quality,
60+
})
61+
.toBuffer();
4562
};
4663
}

src/utils/thumbnail.utils.ts

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,10 @@
1-
import sharp from 'sharp';
2-
31
export const ThumbnailConfig = {
42
MaxWidth: 300,
53
MaxHeight: 300,
64
Quality: 100,
75
Type: 'png',
86
} as const;
97

10-
export const getThumbnailFromImageBuffer = (buffer: Buffer): Promise<Buffer> => {
11-
return sharp(buffer)
12-
.resize({
13-
height: ThumbnailConfig.MaxHeight,
14-
width: ThumbnailConfig.MaxWidth,
15-
fit: 'inside',
16-
})
17-
.png({
18-
quality: ThumbnailConfig.Quality,
19-
})
20-
.toBuffer();
21-
};
22-
238
type FileExtensionMap = Record<string, string[]>;
249
const imageExtensions: FileExtensionMap = {
2510
tiff: ['tif', 'tiff'],
@@ -32,19 +17,27 @@ const imageExtensions: FileExtensionMap = {
3217
raw: ['raw', 'cr2', 'nef', 'orf', 'sr2'],
3318
webp: ['webp'],
3419
};
20+
const pdfExtensions: FileExtensionMap = {
21+
pdf: ['pdf'],
22+
};
3523
const thumbnailableImageExtension: string[] = [
3624
...imageExtensions['jpg'],
3725
...imageExtensions['png'],
3826
...imageExtensions['webp'],
3927
...imageExtensions['gif'],
4028
...imageExtensions['tiff'],
4129
];
42-
const pdfExtensions: FileExtensionMap = {
43-
pdf: ['pdf'],
44-
};
4530
const thumbnailablePdfExtension: string[] = pdfExtensions['pdf'];
4631
const thumbnailableExtension: string[] = [...thumbnailableImageExtension];
4732

4833
export const isFileThumbnailable = (fileType: string) => {
4934
return fileType.trim().length > 0 && thumbnailableExtension.includes(fileType);
5035
};
36+
37+
export const isPDFThumbnailable = (fileType: string) => {
38+
return fileType.trim().length > 0 && thumbnailablePdfExtension.includes(fileType);
39+
};
40+
41+
export const isImageThumbnailable = (fileType: string) => {
42+
return fileType.trim().length > 0 && thumbnailableImageExtension.includes(fileType);
43+
};

src/webdav/handlers/PUT.handler.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ export class PUTRequestHandler implements WebDavMethodHandler {
130130
if (thumbnailBuffer) {
131131
await ThumbnailService.instance.uploadThumbnail(
132132
thumbnailBuffer,
133+
fileType,
133134
user.bucket,
134135
user.mnemonic,
135136
file.id,

0 commit comments

Comments
 (0)