diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..ca872a4 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "vue.codeActions.enabled": false +} \ No newline at end of file diff --git a/apps/users/src/domain/disk-store/disk-store.interface.ts b/apps/users/src/domain/disk-store/disk-store.interface.ts index 52e473c..521f78a 100644 --- a/apps/users/src/domain/disk-store/disk-store.interface.ts +++ b/apps/users/src/domain/disk-store/disk-store.interface.ts @@ -1,5 +1,6 @@ import { UserM } from "../model/user"; export interface IDiskStore { - getFile(id: number): Promise + getFile(id: number): Promise, + writeStream(response: any, path: string): Promise, } \ No newline at end of file diff --git a/apps/users/src/domain/external-api/externall-api.interface.ts b/apps/users/src/domain/external-api/externall-api.interface.ts index 941402b..d24621b 100644 --- a/apps/users/src/domain/external-api/externall-api.interface.ts +++ b/apps/users/src/domain/external-api/externall-api.interface.ts @@ -1,5 +1,6 @@ import { UserM } from "../model/user"; export interface IExternallApiService { - getUserById(id: number): Promise + getUserById(id: number): Promise, + downloadAndSaveAvatar(url: string): Promise } \ No newline at end of file diff --git a/apps/users/src/infrastructure/controller/controller.module.ts b/apps/users/src/infrastructure/controller/controller.module.ts index e72a3db..22fa083 100644 --- a/apps/users/src/infrastructure/controller/controller.module.ts +++ b/apps/users/src/infrastructure/controller/controller.module.ts @@ -1,10 +1,14 @@ import { Module } from '@nestjs/common'; import { UserController } from './user.controller'; import { UsecaseProxyModule } from '../usecase-proxy/usecase-proxy.module'; +import { HttpModule } from '@nestjs/axios'; +import { DiskStoreModule } from '../disk-store/disk-store.module'; @Module({ imports: [ - UsecaseProxyModule.register() + UsecaseProxyModule.register(), + HttpModule, + DiskStoreModule ], controllers: [ UserController diff --git a/apps/users/src/infrastructure/controller/user.controller.ts b/apps/users/src/infrastructure/controller/user.controller.ts index 391106c..63a8f5e 100644 --- a/apps/users/src/infrastructure/controller/user.controller.ts +++ b/apps/users/src/infrastructure/controller/user.controller.ts @@ -7,6 +7,13 @@ import { addUserUsecase } from '../../usecase/addUser.usecase' import { GetUserFromApiUsecase } from '../../usecase/getUserFromApi.usecase' import { GetUserAvatarUsecase } from '../../usecase/getUserAvatar.usecase' import { RMQ_MESSAGES } from '../constants/rmq.constants'; +import { HttpService } from '@nestjs/axios'; +const fs = require('fs'); +import * as stream from 'stream'; +import { promisify } from 'util'; +import { DiskStoreService } from '../disk-store/disk-store.service'; +const finished = promisify(stream.finished); + @Controller() export class UserController { @@ -17,6 +24,8 @@ export class UserController { private readonly getUserUsecaseProxy: UsecaseProxy, @Inject(UsecaseProxyModule.Get_USER_AVATAR_USECASES_PROXY) private readonly getAvatarUsecaseProxy: UsecaseProxy, + private readonly http: HttpService, + private readonly disk: DiskStoreService, ) { } // @MessagePattern(RMQ_MESSAGES.GET_USER_BY_ID) @Post('users') @@ -48,15 +57,33 @@ export class UserController { @Get('user/:userId/avatar') // async createUser(@Payload() userId: number, @Ctx() context: RmqContext) { async getAvatarByUserId(@Param('userId', ParseIntPipe) userId: number) { - // return 'hello000' + + // try { const user = await this.getAvatarUsecaseProxy.getInstance().getAvatar(userId) return user // } catch (error) { - // console.log('ee', error) - // throw error + // // console.log('ee', error) + // throw error // } } + @Get('user/:userId/avatarff') + async downloadAndSaveAvatar(@Param('userId', ParseIntPipe) userId: number) { + this.http + .request({ + method: 'get', + url: 'https://reqres.in/img/faces/1-image.jpg', + responseType: 'stream', + }) + + .subscribe(async (response) => { + return this.disk.writeStream(response.data, 'd.jpg') + // const writer = fs.createWriteStream('c.jpg'); + // response.data.pipe(writer); + // return finished(writer); + }) + + } } diff --git a/apps/users/src/infrastructure/disk-store/disk-store.module.ts b/apps/users/src/infrastructure/disk-store/disk-store.module.ts index a3c8f70..0cbb0e4 100644 --- a/apps/users/src/infrastructure/disk-store/disk-store.module.ts +++ b/apps/users/src/infrastructure/disk-store/disk-store.module.ts @@ -1,5 +1,6 @@ import { Module } from '@nestjs/common'; import { ExceptionsModule } from '../exceptions/exceptions.module'; +import { DiskStoreService } from './disk-store.service'; @Module({ imports: [ @@ -7,7 +8,7 @@ import { ExceptionsModule } from '../exceptions/exceptions.module'; ExceptionsModule ], controllers: [], - providers: [], - exports: [] + providers: [DiskStoreService], + exports: [DiskStoreService] }) export class DiskStoreModule { } \ No newline at end of file diff --git a/apps/users/src/infrastructure/disk-store/disk-store.service.ts b/apps/users/src/infrastructure/disk-store/disk-store.service.ts index 874f60a..aaffffc 100644 --- a/apps/users/src/infrastructure/disk-store/disk-store.service.ts +++ b/apps/users/src/infrastructure/disk-store/disk-store.service.ts @@ -3,19 +3,33 @@ import { ExceptionsService } from "../exceptions/exceptions.service"; import { HttpService } from "@nestjs/axios"; import { createReadStream } from 'fs' import { Response } from "express"; -// const {join} = require('path') -import { join } from 'path' +import path from 'path' +const fs = require('fs'); +import * as stream from 'stream'; +import { promisify } from 'util'; +const finished = promisify(stream.finished); + // import {} from '' @Injectable() export class DiskStoreService { - constructor( - private readonly httpService: HttpService, - private readonly exceptionService: ExceptionsService, - ) { } - getFile(path: string, res: Response) { - const file = createReadStream(join(process.cwd(), path)); + getFile(filePath: string, res: Response) { + const file = createReadStream(path.join(process.cwd(), filePath)); file.pipe(res); } + createPath(fileName: string) { + const filePath = path.join('uploads', fileName) + } + // async readFile(filePath: string) { + // return fsp.readFile(filePath, { encoding: 'base64' }); + // } + async writeStream(response: any, path: string) { + const writer = fs.createWriteStream(path); + response.pipe(writer); + return finished(writer); + // const writer = fs.createWriteStream('c.jpg'); + // response.data.pipe(writer); + // return finished(writer); + } } \ No newline at end of file diff --git a/apps/users/src/infrastructure/entity/user.entity.ts b/apps/users/src/infrastructure/entity/user.entity.ts index 8a4be22..e1a8fa9 100644 --- a/apps/users/src/infrastructure/entity/user.entity.ts +++ b/apps/users/src/infrastructure/entity/user.entity.ts @@ -1,4 +1,4 @@ -import { Column, Entity, PrimaryGeneratedColumn, ObjectIdColumn, ObjectId } from 'typeorm'; +import { Column, Entity, PrimaryColumn, ObjectIdColumn, ObjectId } from 'typeorm'; @Entity() export class User { @@ -21,7 +21,7 @@ export class User { @Column({ unique: true, nullable: false, - default: '', + // name: 'email_add' }) email: string; diff --git a/apps/users/src/infrastructure/external-api/externall-api.module.ts b/apps/users/src/infrastructure/external-api/externall-api.module.ts index 6a70e30..2014828 100644 --- a/apps/users/src/infrastructure/external-api/externall-api.module.ts +++ b/apps/users/src/infrastructure/external-api/externall-api.module.ts @@ -4,6 +4,7 @@ import { EnvironmentModule } from '../environment/environment.module'; import { EnvironmentService } from '../environment/environment.service'; import { ExternallApiService } from './externall-api.service'; import { ExceptionsModule } from '../exceptions/exceptions.module'; +import { DiskStoreModule } from '../disk-store/disk-store.module'; @Module({ imports: [ @@ -15,7 +16,8 @@ import { ExceptionsModule } from '../exceptions/exceptions.module'; }), inject: [EnvironmentService], }), - ExceptionsModule + ExceptionsModule, + DiskStoreModule ], controllers: [], providers: [ExternallApiService], diff --git a/apps/users/src/infrastructure/external-api/externall-api.service.ts b/apps/users/src/infrastructure/external-api/externall-api.service.ts index ed26746..7b9ba4e 100644 --- a/apps/users/src/infrastructure/external-api/externall-api.service.ts +++ b/apps/users/src/infrastructure/external-api/externall-api.service.ts @@ -5,12 +5,16 @@ import { ExceptionsService } from "../exceptions/exceptions.service"; import { UserM } from "../../domain/model/user"; import { HttpService } from "@nestjs/axios"; import { IExternallApiService } from "../../domain/external-api/externall-api.interface"; +import { DiskStoreService } from "../disk-store/disk-store.service"; +const path = require('path') + @Injectable() export class ExternallApiService implements IExternallApiService { constructor( private readonly httpService: HttpService, private readonly exceptionService: ExceptionsService, + private readonly diskStorageService: DiskStoreService, ) { } // async getUserById(id: number): Promise { // const { data } = await firstValueFrom( @@ -51,7 +55,19 @@ export class ExternallApiService implements IExternallApiService { // } // } } - async getAvatarByUrl(url: string): Promise { - return this.httpService.get(url) + + async downloadAndSaveAvatar(url: string) { + this.httpService.request({ + method: 'get', + url, + responseType: 'stream', + }).subscribe(response => { + // const writeStream = this.diskStorageService.createWriteStream(path) + //ensure that the user can call `then()` only when the file has + //been downloaded entirely. + + return this.diskStorageService.writeStream(response.data, path) + + }); } } \ No newline at end of file diff --git a/apps/users/src/main.ts b/apps/users/src/main.ts index 0ad78a0..329ade3 100644 --- a/apps/users/src/main.ts +++ b/apps/users/src/main.ts @@ -12,9 +12,9 @@ async function bootstrap() { app.useGlobalPipes(new ValidationPipe()); app.setGlobalPrefix(GLOBAL_API_PREFIX) const environmentService = app.get(EnvironmentService) - app.connectMicroservice(environmentService.getRabbitMQOptions(RMQ_SERVICES.USERS)) - app.useGlobalFilters(new HttpExceptionFilter()); - await app.startAllMicroservices() + // app.connectMicroservice(environmentService.getRabbitMQOptions(RMQ_SERVICES.USERS)) + // app.useGlobalFilters(new HttpExceptionFilter()); + // await app.startAllMicroservices() app.listen(environmentService.getAppPort()) } diff --git a/apps/users/src/usecase/getUserAvatar.usecase.ts b/apps/users/src/usecase/getUserAvatar.usecase.ts index d58863e..eb361bc 100644 --- a/apps/users/src/usecase/getUserAvatar.usecase.ts +++ b/apps/users/src/usecase/getUserAvatar.usecase.ts @@ -13,16 +13,18 @@ export class GetUserAvatarUsecase { ) { } async getAvatar(userId: number) { // search in db - const avatar = await this.avatarRepository.findByUserId(userId) - if (avatar && avatar.path) { - // get path and get file by it's path - } + // const avatar = await this.avatarRepository.findByUserId(userId) + // if (avatar && avatar.path) { + // // get path and get file by it's path + // } // get user - const user = await this.externalApiService.getUserById(userId) + // const user = await this.externalApiService.getUserById(userId) + // return user // get avatr - if (user && user.avatar) { - this.externalApiService - } + // if (user && user.avatar) { + // return this.externalApiService.downloadAndSaveFile(user.avatar) + this.externalApiService.downloadAndSaveFile('https://reqres.in/img/faces/1-image.jpg', 'mmmm.jpg') + // } // میشد ابتدا از طریق مدل ولیدیشن انجام داد // const exist = await this.userRepository.findByEmail(newUser.email) // console.log('exist', exist) diff --git a/apps/users/src/usecase/getUserFromApi.usecase.ts b/apps/users/src/usecase/getUserFromApi.usecase.ts index 33fd083..9f9c262 100644 --- a/apps/users/src/usecase/getUserFromApi.usecase.ts +++ b/apps/users/src/usecase/getUserFromApi.usecase.ts @@ -1,9 +1,9 @@ import { IExceptionService } from "../domain/exceptions/exception-service.interface"; -import { UserExternallApi } from "../domain/external-api/externall-api.interface"; +import { IExternallApiService } from "../domain/external-api/externall-api.interface"; export class GetUserFromApiUsecase { constructor( - private readonly externalApiService: UserExternallApi, + private readonly externalApiService: IExternallApiService, private readonly exceptionService: IExceptionService ) { }