@@ -3,7 +3,10 @@ import { Task } from 'omniboxd/tasks/tasks.entity';
33import { NamespaceResourcesService } from 'omniboxd/namespace-resources/namespace-resources.service' ;
44import { TagService } from 'omniboxd/tag/tag.service' ;
55import { CreateResourceDto } from 'omniboxd/namespace-resources/dto/create-resource.dto' ;
6- import { CollectRequestDto } from 'omniboxd/wizard/dto/collect-request.dto' ;
6+ import {
7+ CollectRequestDto ,
8+ CollectZRequestDto ,
9+ } from 'omniboxd/wizard/dto/collect-request.dto' ;
710import { CollectResponseDto } from 'omniboxd/wizard/dto/collect-response.dto' ;
811import { TaskCallbackDto } from 'omniboxd/wizard/dto/task-callback.dto' ;
912import { ConfigService } from '@nestjs/config' ;
@@ -22,6 +25,8 @@ import { Image, ProcessedImage } from 'omniboxd/wizard/types/wizard.types';
2225import { InternalTaskDto } from 'omniboxd/tasks/dto/task.dto' ;
2326import { isEmpty } from 'omniboxd/utils/is-empty' ;
2427import { FetchTaskRequest } from 'omniboxd/wizard/dto/fetch-task-request.dto' ;
28+ import { MinioService } from 'omniboxd/minio/minio.service' ;
29+ import { createGunzip } from 'zlib' ;
2530
2631@Injectable ( )
2732export class WizardService {
@@ -30,13 +35,16 @@ export class WizardService {
3035 readonly streamService : StreamService ;
3136 readonly wizardApiService : WizardAPIService ;
3237
38+ private readonly gzipHtmlFolder : string = 'collect/html/gzip' ;
39+
3340 constructor (
3441 private readonly wizardTaskService : WizardTaskService ,
3542 private readonly namespaceResourcesService : NamespaceResourcesService ,
3643 private readonly tagService : TagService ,
3744 private readonly messagesService : MessagesService ,
3845 private readonly configService : ConfigService ,
3946 private readonly attachmentsService : AttachmentsService ,
47+ private readonly minioService : MinioService ,
4048 ) {
4149 this . processors = {
4250 collect : new CollectProcessor (
@@ -69,6 +77,51 @@ export class WizardService {
6977 return await this . wizardTaskService . create ( partialTask ) ;
7078 }
7179
80+ async collectZ (
81+ userId : string ,
82+ data : CollectZRequestDto ,
83+ file : Express . Multer . File ,
84+ ) {
85+ if ( ! file ) {
86+ throw new BadRequestException ( 'Missing file' ) ;
87+ }
88+ const { url, title, namespace_id, parentId } = data ;
89+ if ( ! namespace_id || ! parentId || ! url ) {
90+ throw new BadRequestException ( 'Missing required fields' ) ;
91+ }
92+
93+ const resourceDto : CreateResourceDto = {
94+ name : title || url ,
95+ namespaceId : namespace_id ,
96+ resourceType : ResourceType . LINK ,
97+ parentId : parentId ,
98+ attrs : { url } ,
99+ } ;
100+ const resource = await this . namespaceResourcesService . create (
101+ userId ,
102+ resourceDto ,
103+ ) ;
104+
105+ const filename = 'html.gz' ;
106+ const { id } = await this . minioService . put (
107+ filename ,
108+ file . buffer ,
109+ file . mimetype ,
110+ {
111+ folder : this . gzipHtmlFolder ,
112+ metadata : { resourceId : resource . id , url } ,
113+ } ,
114+ ) ;
115+
116+ const task = await this . wizardTaskService . createCollectTask (
117+ userId ,
118+ namespace_id ,
119+ resource . id ,
120+ { html : [ this . gzipHtmlFolder , id ] . join ( '/' ) , url, title } ,
121+ ) ;
122+ return { task_id : task . id , resource_id : resource . id } ;
123+ }
124+
72125 async collect (
73126 userId : string ,
74127 data : CollectRequestDto ,
@@ -305,9 +358,35 @@ export class WizardService {
305358 namespaceId : record . namespace_id ,
306359 } ) ;
307360 const newTask = await this . wizardTaskService . taskRepository . save ( task ) ;
361+ // Fetch HTML content from S3 for collect tasks
362+ if (
363+ newTask . function === 'collect' &&
364+ newTask . input . html ?. startsWith ( this . gzipHtmlFolder ) &&
365+ newTask . input . html ?. length === this . gzipHtmlFolder . length + 36 // 1 + 32 + 3
366+ ) {
367+ const htmlContent = await this . getHtmlFromMinioGzipFile (
368+ newTask . input . html ,
369+ ) ;
370+ newTask . input = { ...newTask . input , html : htmlContent } ;
371+ }
308372 return InternalTaskDto . fromEntity ( newTask ) ;
309373 }
310374
311375 return null ;
312376 }
377+
378+ async getHtmlFromMinioGzipFile ( path : string ) {
379+ const stream = await this . minioService . getObject ( path ) ;
380+ const gunzip = createGunzip ( ) ;
381+ return new Promise < string > ( ( resolve , reject ) => {
382+ const chunks : Buffer [ ] = [ ] ;
383+ stream
384+ . pipe ( gunzip )
385+ . on ( 'data' , ( chunk : Buffer ) => chunks . push ( chunk ) )
386+ . on ( 'end' , ( ) => {
387+ resolve ( Buffer . concat ( chunks ) . toString ( 'utf-8' ) ) ;
388+ } )
389+ . on ( 'error' , reject ) ;
390+ } ) ;
391+ }
313392}
0 commit comments