Skip to content

Commit

Permalink
[Merge] 'develop' -> 'feature/jin'
Browse files Browse the repository at this point in the history
# Conflicts:
#	src/main/java/com/mpnp/baechelin/api/service/LocationServiceWC.java
#	src/main/java/com/mpnp/baechelin/store/domain/Store.java
#	src/main/java/com/mpnp/baechelin/store/repository/StoreRepository.java
  • Loading branch information
Anna-Jin committed Jul 26, 2022
2 parents 26a35a4 + d06a210 commit 9244498
Show file tree
Hide file tree
Showing 10 changed files with 151 additions and 33 deletions.
5 changes: 5 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ dependencies {
implementation 'io.springfox:springfox-boot-starter:3.0.0'
// commons lang3
implementation 'org.apache.commons:commons-lang3:3.12.0'
//jsoup
implementation 'org.jsoup:jsoup:1.14.3'
//file upload
implementation 'commons-fileupload:commons-fileupload:1.4'
compile 'commons-io:commons-io:2.11.0'

}
tasks.named('test') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

import javax.validation.Valid;

import java.io.IOException;

import static java.lang.System.currentTimeMillis;

@RestController
Expand Down Expand Up @@ -38,4 +40,8 @@ public SuccessResponse getPublicApiV2(@RequestParam String siDoNm,
return new SuccessResponse("공공 API V2 적용 완료");
}

@GetMapping("test")
public void go() throws IOException, InterruptedException {
publicApiServiceV2.start();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ public LocationInfoDto.LocationResponse convertGeoAndStoreNameToKeyword(String l
return null;
}
return LocationInfoDto.LocationResponse.builder()
.storeId(Long.parseLong(latLngDoc.getId()))
.storeId(Long.valueOf(latLngDoc.getId()))
.latitude(latLngDoc.getY())
.longitude(latLngDoc.getX())
.category(categoryFilter(latLngDoc.getCategory_name()))
Expand Down Expand Up @@ -177,7 +177,7 @@ private void getStoreResults(String lat, String lng, String address, String type
.longitude(latLngDoc.getX())
.category(categoryFilter(latLngDoc.getCategory_name()))
.storeName(latLngDoc.getPlace_name())
.storeId(Long.parseLong(latLngDoc.getId()))
.storeId(Long.valueOf(latLngDoc.getId()))
.phoneNumber(latLngDoc.getPhone())
.build();
if (newResult.validate()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,12 @@
import com.mpnp.baechelin.api.model.PublicApiCategoryForm;
import com.mpnp.baechelin.api.model.PublicApiV2Form;
import com.mpnp.baechelin.common.DataClarification;
import com.mpnp.baechelin.config.AppConfig;
import com.mpnp.baechelin.store.domain.Store;
import com.mpnp.baechelin.api.dto.LocationInfoDto;
import com.mpnp.baechelin.store.repository.StoreRepository;
import com.mpnp.baechelin.store.service.StoreImageService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
Expand All @@ -26,7 +25,6 @@
import java.util.stream.Collectors;

@Service
@Transactional
@Slf4j
@RequiredArgsConstructor
/**
Expand All @@ -35,10 +33,11 @@
public class PublicApiServiceV2 {
private final StoreRepository storeRepository;
private final LocationService locationService;

private final StoreImageService storeImageService;
@Value("${public.api.v2.key}")
private String publicV2Key;

@Value("${public.api.v2.key2}")
private String publicV2Key2;

/**
* @return 헤더 세팅 - V2에서는 공통으로 XML 사용
Expand Down Expand Up @@ -88,7 +87,7 @@ public void processApi(String siDoNm, String cggNm, int pageNo) {
/**
* @param formResult 공공 API 결과에서 각각의 Row
*/
private void processForm(PublicApiV2Form formResult) {
public void processForm(PublicApiV2Form formResult) {
if (formResult == null || formResult.getServList() == null) return;
// servList + Barrier Free Tag + category
for (PublicApiV2Form.ServList servList : formResult.getServList()) {
Expand All @@ -109,12 +108,10 @@ private void mapApiToStoreWithPaging(PublicApiV2Form.ServList servList) {
// TODO 태그가 비어있다면 어떻게 해야 할 지 ? -> 저장 혹은 버리기 (현재 버리기로 구현)
if (barrierTagList.isEmpty()) return;

// 위도, 경도, 업장 이름을 통해 업장 정보를 얻어온다
/*
* Strategy = 업장명 + 위/경도를 사용해 Store가 존재한다면, 하나만 저장
* 존재하지 않는다면, 주소 + 위/경도를 사용해 해당 건물의 배리어 프리 매장들을
* 주소 + 위/경도를 사용해 해당 건물의 배리어 프리 매장들을
* 등록하도록 변경 */
if (searchWithStoreName(servList, barrierTagList)) return;
// if (searchWithStoreName(servList, barrierTagList)) return;
// 검색 결과가 없을 경우
searchWithAddress(servList, barrierTagList);
}
Expand All @@ -124,22 +121,26 @@ private void mapApiToStoreWithPaging(PublicApiV2Form.ServList servList) {
* @param barrierTagList 배리어 태그 리스트
* @return 검색 결과 존재 여부
*/
private boolean searchWithStoreName(PublicApiV2Form.ServList servList, List<String> barrierTagList) {
@Transactional
boolean searchWithStoreName(PublicApiV2Form.ServList servList, List<String> barrierTagList) {
LocationInfoDto.LocationResponse resultDto =
locationService.convertGeoAndStoreNameToKeyword(servList.getFaclLat(), servList.getFaclLng(), servList.getFaclNm());
if (resultDto == null)
return false;
Store nStore = new Store(resultDto, servList, barrierTagList);
if (!storeRepository.existsById(nStore.getId()))
storeRepository.save(nStore);
if (!storeRepository.existsById(nStore.getId())) {
storeRepository.saveAndFlush(nStore);
storeImageService.saveImage(nStore.getId());
}
return true;
}

/**
* @param servList 대상 Row
* @param barrierTagList 배리어 태그 리스트
*/
private void searchWithAddress(PublicApiV2Form.ServList servList, List<String> barrierTagList) {
@Transactional
public void searchWithAddress(PublicApiV2Form.ServList servList, List<String> barrierTagList) {
List<LocationInfoDto.LocationResponse> locationResponseMapList = locationService
.convertGeoAndAddressToKeyword(servList.getFaclLat(), servList.getFaclLng(), DataClarification.clarifyString(servList.getLcMnad()));

Expand All @@ -148,7 +149,8 @@ private void searchWithAddress(PublicApiV2Form.ServList servList, List<String> b

// ID 값으로 store 중복 검사해 중복되지 않을 시에만 리스트에 저장
if (!storeRepository.existsById(nStore.getId())) {
storeRepository.save(nStore);
storeRepository.saveAndFlush(nStore);
storeImageService.saveImage(nStore.getId());
}
}
}
Expand All @@ -162,7 +164,7 @@ public List<String> tagStrToList(String sisulNum) {
String publicV2CategoryUri = "http://apis.data.go.kr/B554287/DisabledPersonConvenientFacility/getFacInfoOpenApiJpEvalInfoList";
URI uri = UriComponentsBuilder
.fromUriString(publicV2CategoryUri)
.queryParam("serviceKey", publicV2Key)
.queryParam("serviceKey", publicV2Key2)
.queryParam("wfcltId", sisulNum)
.build()
.encode()
Expand Down Expand Up @@ -209,7 +211,7 @@ private List<String> getStrings(PublicApiCategoryForm.ServList serv) {
return null;
}

public boolean start() throws IOException, InterruptedException {
public void start() throws IOException, InterruptedException {
List<String[]> list = new ArrayList<>();
BufferedReader br = null;
File file = ResourceUtils.getFile("classpath:static/sigungu.csv");
Expand All @@ -223,6 +225,5 @@ public boolean start() throws IOException, InterruptedException {
System.out.println("String 프린트중 : " + Arrays.toString(strings));
processApi(strings[0], strings[1], 1);
}
return true;
}
}
3 changes: 2 additions & 1 deletion src/main/java/com/mpnp/baechelin/exception/ErrorCode.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ public enum ErrorCode {
WRONG_INPUT(400, "E_WRI400", "입력 값을 확인해주세요."),
API_LOAD_FAILURE(500, "E-ALF500", "API 로딩에 실패하였습니다."),
API_NO_RESULT(500, "E-ANR500", "API 결과가 존재하지 않습니다."),
NULL_POINTER_EXCEPTION(500, "E-NPE500", "Null 값이 들어올 수 없습니다.");
NULL_POINTER_EXCEPTION(500, "E-NPE500", "빈 값이 들어올 수 없습니다."),
IMAGE_PROCESS_FAIL(500,"E-IPF500","이미지 오류 발생");

private final int status;
private final String code;
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/com/mpnp/baechelin/store/domain/Category.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
import java.util.Arrays;
@Getter
public enum Category {
KOREAN("한식"), WESTERN("양식"), JAPANESE("일식"), ASIAN("아시안음식"), CHINESE("중식"),
KOREAN("한식"), WESTERN("양식"), JAPANESE("일식"), ASIAN("아시아음식"), CHINESE("중식"),
FAMILY("패밀리레스토랑"), SNACK("간식"), CAFE("카페"), HOFF("술집"),
FASTFOOD("패스트푸드"), BOONSIK("분식"),
ETC("기타");
private final String desc;

Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/mpnp/baechelin/store/domain/Store.java
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public class Store {

public Store(PublicApiV1Form.Row row) {
//storeId - 임시
this.id = row.getStoreId();
this.id = Long.valueOf(row.getStoreId());
this.name = row.getSISULNAME();
this.address = DataClarification.clarifyString(row.getADDR());
this.phoneNumber = row.getTEL();
Expand Down Expand Up @@ -114,7 +114,7 @@ public Store updatePointAvg(double changePoint) {
}

public Store(LocationInfoDto.LocationResponse sr, PublicApiV2Form.ServList servList, List<String> barrierTagList) {
this.id = sr.getStoreId();
this.id = Long.valueOf(sr.getStoreId());
this.name = sr.getStoreName();
this.latitude = new BigDecimal(servList.getFaclLat());
this.longitude = new BigDecimal(servList.getFaclLng());
Expand Down
9 changes: 0 additions & 9 deletions src/main/java/com/mpnp/baechelin/store/domain/StoreImage.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,6 @@ public class StoreImage extends TimeStamped {
@JoinColumn(name = "STORE_ID", nullable = false)
private Store store;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "REVIEW_ID")
private Review review;

public void setReview(Review review) {
this.review = review;
}


// 값이 많지 않아 builder 생략
public StoreImage(String storeImageUrl) {
this.storeImageUrl = storeImageUrl;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.mpnp.baechelin.store.repository;

import com.mpnp.baechelin.store.domain.StoreImage;
import org.springframework.data.jpa.repository.JpaRepository;

public interface StoreImgRepository extends JpaRepository<StoreImage, Integer> {
}
106 changes: 106 additions & 0 deletions src/main/java/com/mpnp/baechelin/store/service/StoreImageService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package com.mpnp.baechelin.store.service;

import com.mpnp.baechelin.exception.CustomException;
import com.mpnp.baechelin.exception.ErrorCode;
import com.mpnp.baechelin.store.domain.Store;
import com.mpnp.baechelin.store.domain.StoreImage;
import com.mpnp.baechelin.store.repository.StoreImgRepository;
import com.mpnp.baechelin.store.repository.StoreRepository;
import com.mpnp.baechelin.util.AwsS3Manager;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItem;
import org.apache.commons.io.IOUtils;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import javax.transaction.Transactional;
import java.io.*;


import java.net.URL;
import java.nio.file.Files;
import java.util.UUID;

@Service
@RequiredArgsConstructor
@Slf4j
public class StoreImageService {
private final AwsS3Manager awsS3Manager;
private final StoreImgRepository storeImgRepository;
private final StoreRepository storeRepository;
@Value("${user.agent}")
private String userAgent;
@Transactional
public void saveImage(Long storeId) {
Store store = storeRepository.findById(storeId).orElseThrow(() -> new CustomException(ErrorCode.WRONG_INPUT));
String storeImgUrl = saveImageByStoreId(storeId);
if (storeImgUrl == null) return;
StoreImage img = StoreImage.builder()
.store(store)
.storeImageUrl(storeImgUrl)
.build();
storeImgRepository.saveAndFlush(img);
}

private String saveImageByStoreId(Long storeId) {
String url = "https://place.map.kakao.com/placePrint.daum?confirmid=" + storeId;
Connection conn = Jsoup.connect(url);
Document doc = null;
Elements elem = null;
try {
Connection.Response response = Jsoup.connect(url)
.method(Connection.Method.GET)
.userAgent(userAgent)
.execute();
Document document = response.parse();
Elements select = document.select("body div div div.popup_body div.wrap_info div img");
String val = select.select("img").attr("src");
if (val.equals("")) return null;
return downloadImage("https:" + val);
} catch (IOException ignored) {
throw new CustomException(ErrorCode.IMAGE_PROCESS_FAIL);
}
}

private String downloadImage(String imgUrl) throws IOException {
log.info("imageurlcheck : {}", imgUrl);
ClassPathResource resource = new ClassPathResource("");
String fileName = resource.getPath() + UUID.randomUUID() + ".jpg";
URL url = new URL(imgUrl);
InputStream is = url.openStream();
OutputStream os = new FileOutputStream(fileName);
byte[] b = new byte[2048];
int length;
while ((length = is.read(b)) != -1) {
os.write(b, 0, length);
}
is.close();
os.close();

File file = new File(fileName);
FileItem fileItem = new DiskFileItem("originFile", Files.probeContentType(file.toPath()), false, file.getName(), (int) file.length(), file.getParentFile());

try {
FileInputStream fileInputStream = new FileInputStream(file);
OutputStream outputStream = fileItem.getOutputStream();
IOUtils.copy(fileInputStream, outputStream);
fileInputStream.close();
outputStream.close();
} catch (IOException ex) {
throw new CustomException(ErrorCode.IMAGE_PROCESS_FAIL);
}

MultipartFile multipartFile = new CommonsMultipartFile(fileItem);
boolean deleteResult = file.delete();
return awsS3Manager.uploadFile(multipartFile);
}
}

0 comments on commit 9244498

Please sign in to comment.