Skip to content

Commit

Permalink
feat(be): add incre view page
Browse files Browse the repository at this point in the history
  • Loading branch information
harisato committed Jul 13, 2023
1 parent f7fc0b1 commit 6aec80d
Show file tree
Hide file tree
Showing 16 changed files with 722 additions and 1,211 deletions.
12 changes: 8 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@
"build": "nest build",
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
"start": "nest start",
"start:dev": "nest start --watch",
"start:dev": "ts-node src/main.ts",
"start:debug": "nest start --debug --watch",
"start:prod": "node dist/main",
"watch:dev": "ts-node-dev src/main.ts",
"debug:dev": "cross-env TS_NODE_CACHE=false ts-node-dev --inspect --ignore '/^src/.*\\.spec\\.ts$/' src/main.ts",
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
"test": "jest",
"test:watch": "jest --watch",
Expand All @@ -30,6 +32,7 @@
"@nestjs/core": "^9.0.0",
"@nestjs/jwt": "^10.1.0",
"@nestjs/platform-express": "^9.0.0",
"@nestjs/schedule": "^3.0.1",
"@nestjs/swagger": "^7.0.12",
"axios": "^1.4.0",
"bull": "^4.10.4",
Expand All @@ -40,14 +43,15 @@
"js-yaml": "^4.1.0",
"lodash": "^4.17.21",
"mmmagic": "^0.5.3",
"redis": "^4.6.7",
"reflect-metadata": "^0.1.13",
"rimraf": "^5.0.1",
"rimraf": "^3.0.2",
"rxjs": "^7.2.0"
},
"devDependencies": {
"@nestjs/cli": "^9.0.0",
"@nestjs/schematics": "^9.0.0",
"@nestjs/testing": "^9.0.0",
"@types/cron": "^2.0.1",
"@types/decompress": "^4.2.4",
"@types/express": "^4.17.13",
"@types/jest": "29.5.1",
Expand All @@ -66,8 +70,8 @@
"source-map-support": "^0.5.20",
"supertest": "^6.1.3",
"ts-jest": "^29.0.3",
"ts-loader": "^9.2.3",
"ts-node": "^10.0.0",
"ts-node-dev": "^2.0.0",
"tsconfig-paths": "4.2.0",
"typescript": "^5.0.0"
},
Expand Down
4 changes: 4 additions & 0 deletions src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,16 @@ import { JwtModule } from '@nestjs/jwt';
import { FilesModule } from './files/files.module';
import { GraphqlModule } from './graphql/graphql.module';
import { UserModule } from './user/user.module';
import { ScheduleModule } from '@nestjs/schedule';
import { TasksModule } from './task/task.module';

@Module({
imports: [
JwtModule,
ScheduleModule.forRoot(),
ChapterModule,
MangaModule,
TasksModule,
ConfigModule.forRoot({
load: [configuration],
isGlobal: true,
Expand Down
7 changes: 7 additions & 0 deletions src/chapter/chapter.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
Body,
Controller,
Param,
Patch,
Post,
Put,
UploadedFiles,
Expand All @@ -18,6 +19,7 @@ import {
UpdateChapterParamDto,
UpdateChapterRequestDto,
} from './dto/update-chapter-request.dto';
import { IncreaseChapterViewParamDto } from './dto/increase-chapter-view-request.dto';

@Controller('chapter')
export class ChapterController {
Expand Down Expand Up @@ -47,4 +49,9 @@ export class ChapterController {
) {
return this.chapterSvc.update(param, data, files);
}

@Patch(':chapterId/increase')
increaseView(@Param() { chapterId }: IncreaseChapterViewParamDto) {
return this.chapterSvc.increase(chapterId);
}
}
3 changes: 2 additions & 1 deletion src/chapter/chapter.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import { ChapterService } from './chapter.service';
import { ChapterController } from './chapter.controller';
import { GraphqlModule } from '../graphql/graphql.module';
import { FilesModule } from '../files/files.module';
import { RedisModule } from '../redis/redis.module';

@Module({
imports: [JwtModule, GraphqlModule, FilesModule],
imports: [JwtModule, GraphqlModule, FilesModule, RedisModule],
providers: [ChapterService],
controllers: [ChapterController],
})
Expand Down
59 changes: 49 additions & 10 deletions src/chapter/chapter.service.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Injectable, Logger } from '@nestjs/common';
import { Injectable, Logger, NotFoundException } from '@nestjs/common';

import * as _ from 'lodash';
import { existsSync, mkdirSync, readdirSync, writeFileSync } from 'fs';
import * as path from 'path';
import { ConfigService } from '@nestjs/config';
import { plainToInstance } from 'class-transformer';
import { rimraf } from 'rimraf';
import rimraf from 'rimraf';
import {
ChapterImage,
CreateChapterRequestDto,
Expand All @@ -18,6 +18,7 @@ import {
UpdateChapterParamDto,
UpdateChapterRequestDto,
} from './dto/update-chapter-request.dto';
import { RedisService } from '../redis/redis.service';

@Injectable()
export class ChapterService {
Expand All @@ -27,6 +28,7 @@ export class ChapterService {
private configService: ConfigService,
private graphqlSvc: GraphqlService,
private filesService: FilesService,
private redisClientService: RedisService,
) {}

async create(
Expand Down Expand Up @@ -110,7 +112,6 @@ export class ChapterService {
userId,
mangaId: manga_id,
chapterNumber: chapter_number,
thumbnailPath: path.join(storageFolder, thumbnail.originalname),
chapterImagePaths: chapter_images.chapter_languages.map((m: any) => ({
languageId: m.language_id,
filePath: path.join(storageFolder, m.file_name),
Expand Down Expand Up @@ -157,6 +158,9 @@ export class ChapterService {
) {
const { chapterId: chapter_id } = param;
const { userId, token } = ContextProvider.getAuthUser();

const storageFolder = `./uploads/${userId}`;

const {
chapter_number,
chapter_name,
Expand Down Expand Up @@ -184,6 +188,11 @@ export class ChapterService {
if (!chapter.data.chapters_by_pk || chapter.data.chapters_by_pk === null) {
throw Error('Not found');
}

if (!existsSync(storageFolder)) {
mkdirSync(storageFolder, { recursive: true });
}

const { manga_id } = chapter.data.chapters_by_pk;
let { thumbnail_url } = chapter.data.chapters_by_pk;

Expand All @@ -192,11 +201,6 @@ export class ChapterService {
JSON.parse(data.chapter_images),
);

const storageFolder = `./uploads/${userId}`;
if (!existsSync(storageFolder)) {
mkdirSync(storageFolder, { recursive: true });
}

files.forEach((file) => {
writeFileSync(`./uploads/${userId}/${file.originalname}`, file.buffer);
});
Expand Down Expand Up @@ -254,7 +258,6 @@ export class ChapterService {
userId,
mangaId: manga_id,
chapterNumber: chapter_number,
thumbnailPath: path.join(storageFolder, thumbnail.originalname),
chapterImagePaths: chapter_images.chapter_languages.map((m: any) => ({
languageId: m.language_id,
filePath: path.join(storageFolder, m.file_name),
Expand Down Expand Up @@ -288,6 +291,43 @@ export class ChapterService {
return result.data;
}

//PATCH
async increase(chapterId: number) {
// get chapter info
const { data } = await this.graphqlSvc.query(
this.configService.get<string>('graphql.endpoint'),
'',
`query GetChapter($id: Int!) {
chapters_by_pk(id: $id) {
id
status
}
}`,
'GetChapter',
{
id: chapterId,
},
);

if (!data.chapters_by_pk || data.chapters_by_pk === null) {
throw new NotFoundException('chapter not found');
}

// set chapter to set
this.redisClientService.client.sAdd(
['punkga', 'dev', 'chapters'].join(':'),
chapterId.toString(),
);

// increase
this.redisClientService.client.incr(
['punkga', 'dev', 'chapter', chapterId.toString(), 'view'].join(':'),
);
return {
success: true,
};
}

async insertChapterLanguages(
token: string,
chapterId: number,
Expand Down Expand Up @@ -348,7 +388,6 @@ export class ChapterService {
userId: string;
mangaId: number;
chapterNumber: number;
thumbnailPath: string;
chapterImagePaths: IChapterLanguages[];
}): Promise<IUploadedFile[]> {
const { userId, mangaId, chapterNumber, chapterImagePaths } = _payload;
Expand Down
6 changes: 3 additions & 3 deletions src/chapter/dto/create-chapter-request.dto.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ApiProperty } from '@nestjs/swagger';
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { IsNumber, IsString } from 'class-validator';
import { ChapterStatus, ChapterType } from '../../common/enum';

Expand Down Expand Up @@ -42,9 +42,9 @@ export class CreateChapterRequestDto {
@ApiProperty({ enum: ChapterStatus, enumName: 'ChapterStatus' })
status: ChapterStatus;

@ApiProperty({ type: 'string', format: 'binary' })
@ApiPropertyOptional({ type: 'string', format: 'binary' })
thumbnail: Express.Multer.File;

@ApiProperty({ type: ['string'], format: 'binary' })
@ApiPropertyOptional({ type: ['string'], format: 'binary' })
files: Express.Multer.File[];
}
8 changes: 8 additions & 0 deletions src/chapter/dto/increase-chapter-view-request.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsNumber } from 'class-validator';

export class IncreaseChapterViewParamDto {
@ApiProperty()
@IsNumber()
chapterId: number;
}
2 changes: 1 addition & 1 deletion src/files/files.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Injectable, Logger } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { readFileSync } from 'fs';
import { MAGIC_MIME_TYPE, Magic } from 'mmmagic';
import * as decompress from 'decompress';
import decompress from 'decompress';
import { IFileInfo } from '../chapter/interfaces';

@Injectable()
Expand Down
17 changes: 15 additions & 2 deletions src/graphql/graphql.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,23 @@ export class GraphqlService {
query: string,
operationName: string,
variables: any,
additionHeaders?: any,
) {
const headers = {
const defaultHeaders = {
'content-type': 'application/json',
Authorization: `Bearer ${token}`,
};

const authHeaders =
token !== ''
? {
Authorization: `Bearer ${token}`,
}
: {};

const headers = {
...defaultHeaders,
...authHeaders,
...additionHeaders,
};

const response = await axios.post(
Expand Down
8 changes: 8 additions & 0 deletions src/redis/redis.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { Module } from '@nestjs/common';
import { RedisService } from './redis.service';

@Module({
providers: [RedisService],
exports: [RedisService],
})
export class RedisModule {}
28 changes: 28 additions & 0 deletions src/redis/redis.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Injectable, Logger, OnModuleDestroy } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { RedisClientType, createClient } from 'redis';

@Injectable()
export class RedisService implements OnModuleDestroy {
private redisClient: RedisClientType;

private readonly logger = new Logger(RedisService.name);
constructor(private configService: ConfigService) {
this.redisClient = createClient({
url: this.configService.get<string>('redis.url'),
});
this.redisClient.connect().then(() => {
this.logger.log('Redis Connected');
});
}

onModuleDestroy() {
this.redisClient.quit().then((msg: string) => {
this.logger.log(`Quit Redis ${msg}`);
});
}

get client() {
return this.redisClient;
}
}
11 changes: 11 additions & 0 deletions src/task/task.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Module } from '@nestjs/common';
import { TasksService } from './task.service';
import { RedisModule } from '../redis/redis.module';
import { GraphqlModule } from '../graphql/graphql.module';

@Module({
imports: [RedisModule, GraphqlModule],
providers: [TasksService],
exports: [TasksService],
})
export class TasksModule {}
Loading

0 comments on commit 6aec80d

Please sign in to comment.