Remove thumbnail generation on mobile app (#292)

* Remove thumbnail generation on mobile

* Remove tconditions for missing thumbnail on the backend

* Remove console.log

* Refactor queue systems

* Convert queue and processor name to constant

* Added corresponding interface to job queue
This commit is contained in:
Alex
2022-07-02 21:06:36 -05:00
committed by GitHub
parent 32b847c26e
commit 76bf1c0379
22 changed files with 270 additions and 141 deletions

View File

@@ -31,6 +31,9 @@ import { SearchAssetDto } from './dto/search-asset.dto';
import { CommunicationGateway } from '../communication/communication.gateway';
import { InjectQueue } from '@nestjs/bull';
import { Queue } from 'bull';
import { IAssetUploadedJob } from '@app/job/index';
import { assetUploadedQueueName } from '@app/job/constants/queue-name.constant';
import { assetUploadedProcessorName } from '@app/job/constants/job-name.constant';
@UseGuards(JwtAuthGuard)
@Controller('asset')
@@ -40,8 +43,8 @@ export class AssetController {
private assetService: AssetService,
private backgroundTaskService: BackgroundTaskService,
@InjectQueue('asset-uploaded-queue')
private assetUploadedQueue: Queue,
@InjectQueue(assetUploadedQueueName)
private assetUploadedQueue: Queue<IAssetUploadedJob>,
) {}
@Post('upload')
@@ -56,7 +59,7 @@ export class AssetController {
)
async uploadFile(
@GetAuthUser() authUser: AuthUserDto,
@UploadedFiles() uploadFiles: { assetData: Express.Multer.File[]; thumbnailData?: Express.Multer.File[] },
@UploadedFiles() uploadFiles: { assetData: Express.Multer.File[] },
@Body(ValidationPipe) assetInfo: CreateAssetDto,
): Promise<'ok' | undefined> {
for (const file of uploadFiles.assetData) {
@@ -66,28 +69,12 @@ export class AssetController {
if (!savedAsset) {
return;
}
if (uploadFiles.thumbnailData != null) {
const assetWithThumbnail = await this.assetService.updateThumbnailInfo(
savedAsset,
uploadFiles.thumbnailData[0].path,
);
await this.assetUploadedQueue.add(
'asset-uploaded',
{ asset: assetWithThumbnail, fileName: file.originalname, fileSize: file.size, hasThumbnail: true },
{ jobId: savedAsset.id },
);
this.wsCommunicateionGateway.server
.to(savedAsset.userId)
.emit('on_upload_success', JSON.stringify(assetWithThumbnail));
} else {
await this.assetUploadedQueue.add(
'asset-uploaded',
{ asset: savedAsset, fileName: file.originalname, fileSize: file.size, hasThumbnail: false },
{ jobId: savedAsset.id },
);
}
await this.assetUploadedQueue.add(
assetUploadedProcessorName,
{ asset: savedAsset, fileName: file.originalname, fileSize: file.size },
{ jobId: savedAsset.id },
);
} catch (e) {
Logger.error(`Error receiving upload file ${e}`);
}

View File

@@ -7,6 +7,7 @@ import { BullModule } from '@nestjs/bull';
import { BackgroundTaskModule } from '../../modules/background-task/background-task.module';
import { BackgroundTaskService } from '../../modules/background-task/background-task.service';
import { CommunicationModule } from '../communication/communication.module';
import { assetUploadedQueueName } from '@app/job/constants/queue-name.constant';
@Module({
imports: [
@@ -14,7 +15,7 @@ import { CommunicationModule } from '../communication/communication.module';
BackgroundTaskModule,
TypeOrmModule.forFeature([AssetEntity]),
BullModule.registerQueue({
name: 'asset-uploaded-queue',
name: assetUploadedQueueName,
defaultJobOptions: {
attempts: 3,
removeOnComplete: true,

View File

@@ -6,7 +6,6 @@ import { extname } from 'path';
import { Request } from 'express';
import { APP_UPLOAD_LOCATION } from '../constants/upload_location.constant';
import { randomUUID } from 'crypto';
// import { CreateAssetDto } from '../api-v1/asset/dto/create-asset.dto';
export const assetUploadOption: MulterOptions = {
fileFilter: (req: Request, file: any, cb: any) => {
@@ -30,34 +29,20 @@ export const assetUploadOption: MulterOptions = {
return;
}
if (file.fieldname == 'assetData') {
const originalUploadFolder = `${basePath}/${req.user.id}/original/${req.body['deviceId']}`;
const originalUploadFolder = `${basePath}/${req.user.id}/original/${req.body['deviceId']}`;
if (!existsSync(originalUploadFolder)) {
mkdirSync(originalUploadFolder, { recursive: true });
}
// Save original to disk
cb(null, originalUploadFolder);
} else if (file.fieldname == 'thumbnailData') {
const thumbnailUploadFolder = `${basePath}/${req.user.id}/thumb/${req.body['deviceId']}`;
if (!existsSync(thumbnailUploadFolder)) {
mkdirSync(thumbnailUploadFolder, { recursive: true });
}
// Save thumbnail to disk
cb(null, thumbnailUploadFolder);
if (!existsSync(originalUploadFolder)) {
mkdirSync(originalUploadFolder, { recursive: true });
}
// Save original to disk
cb(null, originalUploadFolder);
},
filename: (req: Request, file: Express.Multer.File, cb: any) => {
const fileNameUUID = randomUUID();
if (file.fieldname == 'assetData') {
cb(null, `${fileNameUUID}${req.body['fileExtension'].toLowerCase()}`);
} else if (file.fieldname == 'thumbnailData') {
cb(null, `${fileNameUUID}.jpeg`);
}
cb(null, `${fileNameUUID}${req.body['fileExtension'].toLowerCase()}`);
},
}),
};

View File

@@ -3,12 +3,13 @@ import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AssetEntity } from '@app/database/entities/asset.entity';
import { ScheduleTasksService } from './schedule-tasks.service';
import { thumbnailGeneratorQueueName, videoConversionQueueName } from '@app/job/constants/queue-name.constant';
@Module({
imports: [
TypeOrmModule.forFeature([AssetEntity]),
BullModule.registerQueue({
name: 'video-conversion-queue',
name: videoConversionQueueName,
defaultJobOptions: {
attempts: 3,
removeOnComplete: true,
@@ -16,7 +17,7 @@ import { ScheduleTasksService } from './schedule-tasks.service';
},
}),
BullModule.registerQueue({
name: 'thumbnail-generator-queue',
name: thumbnailGeneratorQueueName,
defaultJobOptions: {
attempts: 3,
removeOnComplete: true,

View File

@@ -6,6 +6,9 @@ import { AssetEntity, AssetType } from '@app/database/entities/asset.entity';
import { InjectQueue } from '@nestjs/bull';
import { Queue } from 'bull';
import { randomUUID } from 'crypto';
import { generateWEBPThumbnailProcessorName, mp4ConversionProcessorName } from '@app/job/constants/job-name.constant';
import { thumbnailGeneratorQueueName, videoConversionQueueName } from '@app/job/constants/queue-name.constant';
import { IVideoTranscodeJob } from '@app/job/interfaces/video-transcode.interface';
@Injectable()
export class ScheduleTasksService {
@@ -13,11 +16,11 @@ export class ScheduleTasksService {
@InjectRepository(AssetEntity)
private assetRepository: Repository<AssetEntity>,
@InjectQueue('thumbnail-generator-queue')
@InjectQueue(thumbnailGeneratorQueueName)
private thumbnailGeneratorQueue: Queue,
@InjectQueue('video-conversion-queue')
private videoConversionQueue: Queue,
@InjectQueue(videoConversionQueueName)
private videoConversionQueue: Queue<IVideoTranscodeJob>,
) {}
@Cron(CronExpression.EVERY_DAY_AT_MIDNIGHT)
@@ -36,7 +39,11 @@ export class ScheduleTasksService {
}
for (const asset of assets) {
await this.thumbnailGeneratorQueue.add('generate-webp-thumbnail', { asset: asset }, { jobId: randomUUID() });
await this.thumbnailGeneratorQueue.add(
generateWEBPThumbnailProcessorName,
{ asset: asset },
{ jobId: randomUUID() },
);
}
}
@@ -54,7 +61,7 @@ export class ScheduleTasksService {
});
for (const asset of assets) {
await this.videoConversionQueue.add('mp4-conversion', { asset }, { jobId: randomUUID() });
await this.videoConversionQueue.add(mp4ConversionProcessorName, { asset }, { jobId: randomUUID() });
}
}
}