Skip to content

Commit

Permalink
Merge pull request #243 from boostcampwm2023/feat/add_userRating
Browse files Browse the repository at this point in the history
비디오 응답 시 userRating 추가
  • Loading branch information
msjang4 authored Dec 11, 2023
2 parents e7b3eb3 + 9861a36 commit 458c752
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 21 deletions.
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
"source.fixAll.eslint": true
},
}
18 changes: 14 additions & 4 deletions server/src/user/user.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ export class UserService {
.sort({ _id: -1 })
.limit(limit);

const videos = await this.getVideoInfos(videoData, uploader);
const videos = await this.getVideoInfos(videoData, uploader, uuid);
return { videos };
}

Expand All @@ -140,22 +140,32 @@ export class UserService {
return { uploader, uploaderId };
}

async getVideoInfos(videoData: Array<any>, uploader: object) {
async getVideoInfos(videoData: Array<any>, uploader: object, uuid: string) {
const videos = await Promise.all(
videoData.map(async (video) => {
const { thumbnailExtension, raterCount, totalRating, ...videoInfo } =
video;
const rating = raterCount
? (totalRating / raterCount).toFixed(1)
: null;
const userRating = await this.videoService.getUserRating(
uuid,
videoInfo._id,
);
const manifest = `${process.env.MANIFEST_URL_PREFIX}/${videoInfo._id}_master.m3u8`;
const thumbnailImageUrl = await createPresignedUrl(
process.env.THUMBNAIL_BUCKET,
`${videoInfo._id}.${thumbnailExtension}`,
'GET',
);
return {
video: { ...videoInfo, manifest, rating, thumbnailImageUrl },
video: {
...videoInfo,
manifest,
rating,
userRating,
thumbnailImageUrl,
},
uploader,
};
}),
Expand Down Expand Up @@ -209,7 +219,7 @@ export class UserService {
_id: action.videoId,
}).populate('uploaderId', '-_id -actions');
const video = videoData
? await this.videoService.getVideoInfo(videoData.toObject())
? await this.videoService.getVideoInfo(videoData.toObject(), uuid)
: { video: null, uploader: null };
return { ...video, ratedAt: action.updatedAt };
}),
Expand Down
6 changes: 6 additions & 0 deletions server/src/video/dto/video-response.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ export class VideoResponseDto {
*/
rating: string;

/**
* 유저가 준 점수
* @example 5
*/
userRating: number | null;

/**
* 카테고리
* @example "챌린지"
Expand Down
15 changes: 9 additions & 6 deletions server/src/video/video.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,17 +92,20 @@ export class VideoController {
*/
@Get('top-rated')
@ApiSuccessResponse(200, 'TOP 10 조회 성공', VideoListResponseDto)
getTopRatedVideo(@Query() query: TopVideoQueryDto) {
return this.videoService.getTopRatedVideo(query.category);
getTopRatedVideo(
@Query() query: TopVideoQueryDto,
@RequestUser() user: User,
) {
return this.videoService.getTopRatedVideo(query.category, user.id);
}

/**
* 인기 비디오 반환
*/
@Get('trend')
@ApiSuccessResponse(200, '비디오 조회 성공', VideoListResponseDto)
getTrendVideo(@Query('limit') limit: number) {
return this.videoService.getTrendVideo(limit);
getTrendVideo(@Query('limit') limit: number, @RequestUser() user: User) {
return this.videoService.getTrendVideo(limit, user.id);
}

/**
Expand All @@ -111,8 +114,8 @@ export class VideoController {
@Get(':id')
@ApiSuccessResponse(200, '비디오 조회 성공', VideoInfoDto)
@ApiFailResponse('비디오를 찾을 수 없음', [VideoNotFoundException])
getVideo(@Param('id') videoId: string) {
return this.videoService.getVideo(videoId);
getVideo(@Param('id') videoId: string, @RequestUser() user: User) {
return this.videoService.getVideo(videoId, user.id);
}

/**
Expand Down
36 changes: 26 additions & 10 deletions server/src/video/video.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,14 +98,15 @@ export class VideoService {
const SEED_MAX = 1_000_000;
const viewSeed = seed ?? Math.floor(Math.random() * SEED_MAX);
const videoInfos = await Promise.all(
videos.map((video) => this.getVideoInfo(video)),
videos.map((video) => this.getVideoInfo(video, userId)),
);
return { videos: videoInfos, seed: viewSeed };
}

async getVideoInfo(video: any): Promise<VideoInfoDto> {
async getVideoInfo(video: any, userId: string): Promise<VideoInfoDto> {
const { totalRating, raterCount, uploaderId, ...videoInfo } = video;
const rating = raterCount ? (totalRating / raterCount).toFixed(1) : null;
const userRating = await this.getUserRating(userId, videoInfo._id);

const manifest = `${process.env.MANIFEST_URL_PREFIX}/${videoInfo._id}_master.m3u8`;

Expand All @@ -132,11 +133,26 @@ export class VideoService {
};

return {
video: { ...videoInfo, manifest, rating, thumbnailImageUrl },
video: { ...videoInfo, manifest, rating, userRating, thumbnailImageUrl },
uploader,
};
}

async getUserRating(uuid: string, videoId: string) {
const userData = await this.UserModel.findOne(
{
uuid,
'actions.videoId': videoId,
},
{
_id: 0,
'actions.$': 1,
},
);
const userRating = userData ? userData.actions.pop().rating : null;
return userRating;
}

async uploadVideo(videoDto: VideoDto, uuid: string, videoId: string) {
if (!Types.ObjectId.isValid(videoId)) throw new BadRequestFormatException();
const checkDuplicate = await this.VideoModel.findOne({ _id: videoId });
Expand Down Expand Up @@ -191,7 +207,7 @@ export class VideoService {
accessKey,
secretKey,
};
console.log(data);

try {
await axios.post(process.env.ENCODING_API_URL, data);
} catch (error) {
Expand Down Expand Up @@ -241,7 +257,7 @@ export class VideoService {
};
}

async getTrendVideo(limit: number) {
async getTrendVideo(limit: number, userId: string) {
const fields = Object.keys(this.VideoModel.schema.paths).reduce(
(acc, field) => {
acc[field] = 1;
Expand Down Expand Up @@ -273,13 +289,13 @@ export class VideoService {
});

const videos = await Promise.all(
trendVideos.map((video) => this.getVideoInfo(video)),
trendVideos.map((video) => this.getVideoInfo(video, userId)),
);

return { videos };
}

async getTopRatedVideo(category: string) {
async getTopRatedVideo(category: string, userId: string) {
const videoTotal = await this.VideoModel.aggregate([
{ $match: { category } },
{
Expand Down Expand Up @@ -328,12 +344,12 @@ export class VideoService {
});

const videos = await Promise.all(
top10Videos.map((video) => this.getVideoInfo(video)),
top10Videos.map((video) => this.getVideoInfo(video, userId)),
);
return { videos };
}

async getVideo(videoId: string) {
async getVideo(videoId: string, userId: string) {
const video = await this.VideoModel.findOne(
{ _id: videoId },
{},
Expand All @@ -342,6 +358,6 @@ export class VideoService {
if (!video) {
throw new VideoNotFoundException();
}
return this.getVideoInfo(video);
return this.getVideoInfo(video, userId);
}
}

0 comments on commit 458c752

Please sign in to comment.