Skip to content

Commit

Permalink
Merge pull request #43 from tukcomCD2024/SNOW-110-feat#42/generate-an…
Browse files Browse the repository at this point in the history
…d-get-meme

Snow 110 feat#42/generate and get meme
  • Loading branch information
JunRain2 authored Mar 22, 2024
2 parents 68a10ee + 12aef4b commit c2f6a42
Show file tree
Hide file tree
Showing 14 changed files with 279 additions and 4 deletions.
2 changes: 2 additions & 0 deletions backend/memetory/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ dependencies {
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
implementation 'org.springframework.boot:spring-boot-starter-data-redis:2.3.1.RELEASE' // Redis 라이브러리
implementation 'com.google.code.gson:gson:2.8.7'
implementation 'org.springframework.boot:spring-boot-starter-webflux'

implementation 'com.auth0:java-jwt:4.2.1'
implementation 'org.springframework.boot:spring-boot-starter-security'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,26 @@
package com.example.memetory.domain.meme.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.WebClient;

import com.example.memetory.domain.member.service.MemberService;
import com.example.memetory.domain.meme.dto.GenerateMemeListRequest;
import com.example.memetory.domain.meme.dto.MemeListResponse;
import com.example.memetory.domain.meme.dto.MemeResponse;
import com.example.memetory.domain.meme.dto.MemeServiceDto;
import com.example.memetory.domain.meme.dto.ShotStackCallBackRequest;
import com.example.memetory.domain.meme.service.MemeService;
import com.example.memetory.global.annotation.LoginMemberEmail;

import lombok.RequiredArgsConstructor;

Expand All @@ -20,14 +30,60 @@
public class MemeController {
private final MemeService memeService;

@PostMapping("/create/{id}")
public ResponseEntity<HttpStatus> callBackMeme(@PathVariable Long id,
@Value("${spring.ai-server.url}")
private String AI_SERVER_URL;

@PostMapping("/create/{memberId}")
public ResponseEntity<HttpStatus> callBackMeme(@PathVariable Long memberId,
@RequestBody ShotStackCallBackRequest shotStackCallBackRequest) {

MemeServiceDto memeServiceDto = shotStackCallBackRequest.toServiceDto(id);
MemeServiceDto memeServiceDto = shotStackCallBackRequest.toServiceDto(memberId);

memeService.register(memeServiceDto);

return ResponseEntity.status(HttpStatus.OK).build();
}

@PostMapping
public ResponseEntity<HttpStatus> register(@LoginMemberEmail String email,
@RequestBody GenerateMemeListRequest generateMemeListRequest) {

MemeServiceDto memeServiceDto = generateMemeListRequest.toServiceDto(email);
String aiServerSendJson = memeService.getAIServerSendJson(memeServiceDto);

WebClient
.create(AI_SERVER_URL)
.post()
.contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue(aiServerSendJson))
.retrieve()
.bodyToMono(Void.class)
.subscribe();

return ResponseEntity.status(HttpStatus.OK).build();
}

@GetMapping("/{memeId}")
public ResponseEntity<MemeResponse> findMeme(@LoginMemberEmail String email, @PathVariable Long memeId) {
MemeServiceDto memeServiceDto = MemeServiceDto.create(email, memeId);

if (memeService.checkMember(memeServiceDto)) {
return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
}

return ResponseEntity
.status(HttpStatus.OK)
.body(memeService.getMeme(memeServiceDto));
}

@GetMapping
public ResponseEntity<MemeListResponse> findMemeList(@LoginMemberEmail String email) {
MemeServiceDto memeServiceDto = MemeServiceDto.create(email);

MemeListResponse memeListResponse = memeService.getAllMeme(memeServiceDto);

return ResponseEntity
.status(HttpStatus.OK)
.body(memeListResponse);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.example.memetory.domain.meme.dto;

import java.util.List;

import com.google.gson.annotations.SerializedName;

import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class AIServerSendDto {
@SerializedName("member_id")
private String memberId;
@SerializedName("scene")
private List<GenerateMemeDto> scene;

@Builder
public AIServerSendDto(Long memberId, List<GenerateMemeDto> scene) {
this.memberId = String.valueOf(memberId);
this.scene = scene;
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.example.memetory.domain.meme.dto;

import com.google.gson.annotations.SerializedName;

import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class GenerateMemeDto {
@SerializedName("source_image")
private String sourceImage;
@SerializedName("target_image")
private String targetImage;
@SerializedName("text")
private String text;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.example.memetory.domain.meme.dto;

import java.util.List;

import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class GenerateMemeListRequest {
private List<GenerateMemeDto> scene;

public MemeServiceDto toServiceDto(String email) {
return MemeServiceDto.builder()
.email(email)
.scene(scene)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.example.memetory.domain.meme.dto;

import java.util.List;

import com.example.memetory.domain.meme.entity.Meme;

import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class MemeListResponse {
private List<MemeResponse> memeList;

@Builder
public MemeListResponse(List<MemeResponse> memeList) {
this.memeList = memeList;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.example.memetory.domain.meme.dto;

import java.time.LocalDateTime;

import com.example.memetory.domain.meme.entity.Meme;

import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class MemeResponse {
private Long memeId;
private String s3Url;
private LocalDateTime createAt;
private LocalDateTime updateAt;

@Builder
public MemeResponse(Long memeId, String s3Url, LocalDateTime createAt, LocalDateTime updateAt) {
this.memeId = memeId;
this.s3Url = s3Url;
this.createAt = createAt;
this.updateAt = updateAt;
}

public static MemeResponse of(Meme meme) {
return MemeResponse.builder()
.memeId(meme.getId())
.s3Url(meme.getS3Url())
.createAt(meme.getCreatedAt())
.updateAt(meme.getUpdatedAt())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.example.memetory.domain.meme.dto;

import java.util.List;

import com.example.memetory.domain.member.entity.Member;
import com.example.memetory.domain.meme.entity.Meme;

Expand All @@ -12,7 +14,23 @@
@AllArgsConstructor
public class MemeServiceDto {
private Long memberId;
private Long memeId;
private String s3Url;
private String email;
private List<GenerateMemeDto> scene;

public static MemeServiceDto create(String email, Long memeId) {
return MemeServiceDto.builder()
.email(email)
.memeId(memeId)
.build();
}

public static MemeServiceDto create(String email) {
return MemeServiceDto.builder()
.email(email)
.build();
}

public Meme toEntity(Member member) {
return Meme.builder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@
import jakarta.persistence.ManyToOne;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Meme extends BaseEntity {
@Id
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.example.memetory.domain.meme.exception;

public class NotFoundMemeException extends RuntimeException{
public NotFoundMemeException() {
}

public NotFoundMemeException(String message) {
super(message);
}

public NotFoundMemeException(String message, Throwable cause) {
super(message, cause);
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package com.example.memetory.domain.meme.repository;

import java.util.List;

import org.springframework.data.jpa.repository.JpaRepository;

import com.example.memetory.domain.member.entity.Member;
import com.example.memetory.domain.meme.entity.Meme;

public interface MemeRepository extends JpaRepository<Meme, Long> {
List<Meme> findAllByMember(Member member);
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
package com.example.memetory.domain.meme.service;

import java.util.List;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.example.memetory.domain.member.entity.Member;
import com.example.memetory.domain.member.service.MemberService;
import com.example.memetory.domain.meme.dto.AIServerSendDto;
import com.example.memetory.domain.meme.dto.MemeListResponse;
import com.example.memetory.domain.meme.dto.MemeResponse;
import com.example.memetory.domain.meme.dto.MemeServiceDto;
import com.example.memetory.domain.meme.dto.ShotStackCallBackRequest;
import com.example.memetory.domain.meme.entity.Meme;
import com.example.memetory.domain.meme.exception.NotFoundMemeException;
import com.example.memetory.domain.meme.repository.MemeRepository;
import com.google.gson.Gson;

import lombok.RequiredArgsConstructor;

Expand All @@ -25,4 +31,47 @@ public void register(MemeServiceDto memeServiceDto) {

memeRepository.save(meme);
}

@Transactional(readOnly = true)
public String getAIServerSendJson(MemeServiceDto memeServiceDto) {
Gson gson = new Gson();

Member member = memberService.findByEmail(memeServiceDto.getEmail());

AIServerSendDto aiServerSendDto = AIServerSendDto.builder()
.memberId(member.getId())
.scene(memeServiceDto.getScene())
.build();

return gson.toJson(aiServerSendDto);
}

@Transactional(readOnly = true)
public MemeResponse getMeme(MemeServiceDto memeServiceDto) {
Meme meme = memeRepository.findById(memeServiceDto.getMemeId()).orElseThrow(NotFoundMemeException::new);

return MemeResponse.of(meme);
}

@Transactional(readOnly = true)
public boolean checkMember(MemeServiceDto memeServiceDto) {
Meme meme = memeRepository.findById(memeServiceDto.getMemeId()).orElseThrow(NotFoundMemeException::new);
Member member = memberService.findById(memeServiceDto.getMemberId());

return meme.getMember() != member;
}

@Transactional
public MemeListResponse getAllMeme(MemeServiceDto memeServiceDto) {
Member member = memberService.findByEmail(memeServiceDto.getEmail());

List<MemeResponse> memeList = memeRepository.findAllByMember(member)
.stream()
.map(MemeResponse::of)
.toList();

return MemeListResponse.builder()
.memeList(memeList)
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.springframework.web.bind.annotation.RestController;

import com.example.memetory.domain.member.exception.NotFoundMemberException;
import com.example.memetory.domain.meme.exception.NotFoundMemeException;
import com.example.memetory.global.security.jwt.exception.NotFoundEmailException;
import com.example.memetory.global.security.jwt.exception.NotFoundTokenException;

Expand All @@ -26,4 +27,9 @@ ResponseEntity<HttpEntity> notFoundEmailException() {
ResponseEntity<HttpEntity> notFoundMemberException() {
return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
}

@ExceptionHandler(NotFoundMemeException.class)
ResponseEntity<HttpEntity> notFoundMemeException() {
return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
}
}
3 changes: 3 additions & 0 deletions backend/memetory/src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,6 @@ spring:
port: 6379
refreshToken:
expiration: 1209600

ai-server:
url: "http://localhost:5001/files"

0 comments on commit c2f6a42

Please sign in to comment.