Skip to content

Commit

Permalink
Merge branch 'dev' into feature/MAFOO-25
Browse files Browse the repository at this point in the history
  • Loading branch information
gmkim20713 authored Jul 24, 2024
2 parents 5a14063 + 0508c7f commit 17cf408
Show file tree
Hide file tree
Showing 14 changed files with 290 additions and 129 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ public enum BrandType {
HARU_FILM(Pattern.compile("http://haru\\d+\\.mx\\d+\\.co\\.kr/.*")),
DONT_LOOK_UP(Pattern.compile("https://x\\.dontlxxkup\\.kr/.*")),
MY_FOUR_CUT(Pattern.compile("https://firebasestorage\\.googleapis\\.com:443/v0/b/my4ccu\\.appspot\\.com/.*")),
PHOTOGRAY(Pattern.compile("https://pgshort\\.aprd\\.io/.*")),
;

private final Pattern urlPattern;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import kr.mafoo.photo.util.IdGenerator;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

Expand All @@ -15,6 +16,7 @@
public class AlbumService {
private final AlbumRepository albumRepository;

@Transactional
public Mono<AlbumEntity> createNewAlbum(String ownerMemberId, String albumName, AlbumType albumType) {
AlbumEntity albumEntity = AlbumEntity.newAlbum(IdGenerator.generate(), albumName, albumType, ownerMemberId);
return albumRepository.save(albumEntity);
Expand All @@ -38,6 +40,7 @@ public Mono<AlbumEntity> findByAlbumId(String albumId, String requestMemberId) {
});
}

@Transactional
public Mono<Void> deleteAlbumById(String albumId, String requestMemberId) {
return albumRepository
.findById(albumId)
Expand All @@ -52,6 +55,7 @@ public Mono<Void> deleteAlbumById(String albumId, String requestMemberId) {
});
}

@Transactional
public Mono<AlbumEntity> updateAlbumName(String albumId, String albumName, String requestMemberId) {
return albumRepository
.findById(albumId)
Expand All @@ -66,6 +70,7 @@ public Mono<AlbumEntity> updateAlbumName(String albumId, String albumName, Strin
});
}

@Transactional
public Mono<AlbumEntity> updateAlbumType(String albumId, AlbumType albumType, String requestMemberId) {
return albumRepository
.findById(albumId)
Expand All @@ -80,6 +85,7 @@ public Mono<AlbumEntity> updateAlbumType(String albumId, AlbumType albumType, St
});
}

@Transactional
public Mono<Void> increaseAlbumPhotoCount(String albumId, String requestMemberId) {
return albumRepository
.findById(albumId)
Expand All @@ -94,6 +100,7 @@ public Mono<Void> increaseAlbumPhotoCount(String albumId, String requestMemberId
});
}

@Transactional
public Mono<Void> decreaseAlbumPhotoCount(String albumId, String requestMemberId) {

if (albumId == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import kr.mafoo.photo.util.IdGenerator;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

Expand All @@ -21,6 +22,7 @@ public class PhotoService {
private final QrService qrService;
private final ObjectStorageService objectStorageService;

@Transactional
public Mono<PhotoEntity> createNewPhoto(String qrUrl, String requestMemberId) {
return qrService
.getFileFromQrUrl(qrUrl)
Expand All @@ -46,6 +48,7 @@ public Flux<PhotoEntity> findAllByAlbumId(String albumId, String requestMemberId
});
}

@Transactional
public Mono<Void> deletePhotoById(String photoId, String requestMemberId) {
return photoRepository
.findById(photoId)
Expand All @@ -61,6 +64,7 @@ public Mono<Void> deletePhotoById(String photoId, String requestMemberId) {
});
}

@Transactional
public Mono<PhotoEntity> updatePhotoAlbumId(String photoId, String albumId, String requestMemberId) {
return photoRepository
.findById(photoId)
Expand Down
145 changes: 17 additions & 128 deletions photo-service/src/main/java/kr/mafoo/photo/service/QrService.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,155 +2,44 @@

import kr.mafoo.photo.domain.BrandType;
import kr.mafoo.photo.exception.PhotoBrandNotExistsException;
import kr.mafoo.photo.exception.PhotoQrUrlExpiredException;
import kr.mafoo.photo.exception.RedirectUriNotFoundException;
import kr.mafoo.photo.service.dto.FileDto;
import kr.mafoo.photo.service.vendors.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

import java.net.URI;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Optional;

@Slf4j
@RequiredArgsConstructor
@Service
public class QrService {

private final WebClient externalWebClient;
private final LifeFourCutsQrVendor lifeFourCutsQrVendor;
private final PhotoismQrVendor photoismQrVendor;
private final DontLookUpQrVendor dontLookUpQrVendor;
private final HaruFilmQrVendor haruFilmQrVendor;
private final MyFourCutQrVendor myFourCutQrVendor;
private final PhotoGrayQrVendor photoGrayQrVendor;


public Mono<FileDto> getFileFromQrUrl(String qrUrl) {
BrandType brandType = Optional.ofNullable(BrandType.matchBrandType(qrUrl))
.orElseThrow(PhotoBrandNotExistsException::new);

return switch (brandType) {
case LIFE_FOUR_CUTS -> createFileDto(brandType, getLifeFourCutsFiles(qrUrl));
case PHOTOISM -> createFileDto(brandType, getPhotoismFiles(qrUrl));
case HARU_FILM -> createFileDto(brandType, getHaruFilmFiles(qrUrl));
case DONT_LOOK_UP -> createFileDto(brandType, getDontLookUpFiles(qrUrl));
case MY_FOUR_CUT -> createFileDto(brandType, getMyFourCutFiles(qrUrl));
QrVendor qrVendor = switch (brandType) {
case LIFE_FOUR_CUTS -> lifeFourCutsQrVendor;
case PHOTOISM -> photoismQrVendor;
case HARU_FILM -> haruFilmQrVendor;
case DONT_LOOK_UP -> dontLookUpQrVendor;
case MY_FOUR_CUT -> myFourCutQrVendor;
case PHOTOGRAY -> photoGrayQrVendor;
};

return createFileDto(brandType, qrVendor.extractImageFromQrUrl(qrUrl));
}

private Mono<FileDto> createFileDto(BrandType brandType, Mono<byte[]> fileMono) {
return fileMono.map(file -> new FileDto(brandType, file));
}

private Mono<byte[]> getLifeFourCutsFiles(String qrUrl) {

return getRedirectUri(qrUrl)
.flatMap(redirectUri -> {
String imageUrl = extractValueFromUrl(redirectUri, "path=")[1].replace("index.html", "image.jpg");

// TODO : 추후 비디오 URL 추가 예정
// String videoUrl = redirectUri.toString().replace("index.html", "video.mp4");

return getFileAsByte(imageUrl);
})
.onErrorMap(e -> new PhotoQrUrlExpiredException());
}

private Mono<byte[]> getPhotoismFiles(String qrUrl) {
return getRedirectUri(qrUrl)
.flatMap(redirectUri -> {
String uid = extractValueFromUrl(redirectUri, "u=")[1];

return externalWebClient
.post()
.uri("https://cmsapi.seobuk.kr/v1/etc/seq/resource")
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(Map.of("uid", uid))
.retrieve()
.bodyToMono(LinkedHashMap.class)
.flatMap(responseBody -> {
LinkedHashMap<String, Object> content = (LinkedHashMap<String, Object>) responseBody.get("content");
LinkedHashMap<String, Object> fileInfo = (LinkedHashMap<String, Object>) content.get("fileInfo");
LinkedHashMap<String, Object> picFile = (LinkedHashMap<String, Object>) fileInfo.get("picFile");
String imageUrl = (String) picFile.get("path");

return getFileAsByte(imageUrl);
});
})
.onErrorMap(e -> {
e.printStackTrace();
return new PhotoQrUrlExpiredException();
});
}

private Mono<byte[]> getHaruFilmFiles(String qrUrl) {
String[] urlValueList = extractValueFromUrl(qrUrl, "/@");
String albumCode = urlValueList[1];

String baseUrl = urlValueList[0] + "/base_api?command=albumdn&albumCode=";
String imageUrl = baseUrl + albumCode + "&type=photo&file_name=output.jpg&max=10&limit=+24 hours";

// TODO : 추후 비디오 URL 추가 예정
// String videoUrl = baseUrl + albumCode + "&type=video&max=10&limit=+24 hours";

return getFileAsByte(imageUrl)
.onErrorMap(e -> new PhotoQrUrlExpiredException());
}

private Mono<byte[]> getDontLookUpFiles(String qrUrl) {
String imageName = extractValueFromUrl(qrUrl, ".kr/image/")[1];

String baseUrl = "https://x.dontlxxkup.kr/uploads/";
String imageUrl = baseUrl + imageName;

// TODO : 추후 비디오 URL 추가 예정
// String videoName = imageName.replace("image", "video").replace(".jpg", ".mp4");
// String videoUrl = baseUrl + videoName;

return getRedirectUri(qrUrl)
.flatMap(redirectUri -> {
if (redirectUri.endsWith("/delete")) {
return Mono.error(new PhotoQrUrlExpiredException());
} else {
return getFileAsByte(imageUrl);
}
})
.onErrorResume(
RedirectUriNotFoundException.class, e -> getFileAsByte(imageUrl)
);
}

private Mono<byte[]> getMyFourCutFiles(String qrUrl) {
return getFileAsByte(qrUrl);
}

private Mono<String> getRedirectUri(String url) {
return externalWebClient
.get()
.uri(url)
.retrieve()
.toBodilessEntity()
.flatMap(response -> {
URI redirectUri = response.getHeaders().getLocation();
if (redirectUri == null) {
return Mono.error(new RedirectUriNotFoundException());
} else {
return Mono.just(redirectUri.toString());
}
});
}

private String[] extractValueFromUrl(String url, String delimiter) {
return url.split(delimiter);
}

private Mono<byte[]> getFileAsByte(String url) {
return externalWebClient
.get()
.uri(url)
.accept(MediaType.APPLICATION_OCTET_STREAM)
.retrieve()
.bodyToMono(byte[].class);
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package kr.mafoo.photo.service.vendors;

import kr.mafoo.photo.exception.PhotoQrUrlExpiredException;
import kr.mafoo.photo.exception.RedirectUriNotFoundException;
import kr.mafoo.photo.util.WebClientUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

@RequiredArgsConstructor
@Component
public class DontLookUpQrVendor implements QrVendor {
private final WebClient webClient;

@Override
public Mono<byte[]> extractImageFromQrUrl(String qrUrl) {
String imageName = qrUrl.split(".kr/image/")[1];

String baseUrl = "https://x.dontlxxkup.kr/uploads/";
String imageUrl = baseUrl + imageName;

// TODO : 추후 비디오 URL 추가 예정
// String videoName = imageName.replace("image", "video").replace(".jpg", ".mp4");
// String videoUrl = baseUrl + videoName;

return WebClientUtil.getRedirectUri(webClient, qrUrl)
.flatMap(redirectUri -> {
if (redirectUri.endsWith("/delete")) {
return Mono.error(new PhotoQrUrlExpiredException());
} else {
return WebClientUtil.getBlob(webClient, imageUrl);
}
})
.onErrorResume(
RedirectUriNotFoundException.class, e -> WebClientUtil.getBlob(webClient, imageUrl)
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package kr.mafoo.photo.service.vendors;

import kr.mafoo.photo.exception.PhotoQrUrlExpiredException;
import kr.mafoo.photo.util.WebClientUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

@RequiredArgsConstructor
@Component
public class HaruFilmQrVendor implements QrVendor {
private final WebClient webClient;

@Override
public Mono<byte[]> extractImageFromQrUrl(String qrUrl) {
String[] urlValueList = qrUrl.split("/@");
String albumCode = urlValueList[1];

String baseUrl = urlValueList[0] + "/base_api?command=albumdn&albumCode=";
String imageUrl = baseUrl + albumCode + "&type=photo&file_name=output.jpg&max=10&limit=+24 hours";

// TODO : 추후 비디오 URL 추가 예정
// String videoUrl = baseUrl + albumCode + "&type=video&max=10&limit=+24 hours";

return WebClientUtil.getBlob(webClient, imageUrl)
.onErrorMap(e -> new PhotoQrUrlExpiredException());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package kr.mafoo.photo.service.vendors;

import kr.mafoo.photo.exception.PhotoQrUrlExpiredException;
import kr.mafoo.photo.util.WebClientUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

@RequiredArgsConstructor
@Component
public class LifeFourCutsQrVendor implements QrVendor {
private final WebClient webClient;

@Override
public Mono<byte[]> extractImageFromQrUrl(String qrUrl) {
return WebClientUtil.getRedirectUri(webClient, qrUrl)
.flatMap(redirectUri -> {
String imageUrl = redirectUri.split("path=")[1].replace("index.html", "image.jpg");

// TODO : 추후 비디오 URL 추가 예정
// String videoUrl = redirectUri.toString().replace("index.html", "video.mp4");

return WebClientUtil.getBlob(webClient, imageUrl);
})
.onErrorMap(e -> new PhotoQrUrlExpiredException());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package kr.mafoo.photo.service.vendors;

import kr.mafoo.photo.exception.PhotoQrUrlExpiredException;
import kr.mafoo.photo.util.WebClientUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

@RequiredArgsConstructor
@Component
public class MyFourCutQrVendor implements QrVendor {
private final WebClient webClient;

@Override
public Mono<byte[]> extractImageFromQrUrl(String qrUrl) {
return WebClientUtil
.getBlob(webClient, qrUrl) //just image url
.onErrorMap(e -> new PhotoQrUrlExpiredException());
}
}
Loading

0 comments on commit 17cf408

Please sign in to comment.