diff --git a/src/main/java/team7/inplace/crawling/application/AddressUtil.java b/src/main/java/team7/inplace/crawling/application/AddressUtil.java index 5ebd55cb..cfe07276 100644 --- a/src/main/java/team7/inplace/crawling/application/AddressUtil.java +++ b/src/main/java/team7/inplace/crawling/application/AddressUtil.java @@ -8,15 +8,19 @@ import lombok.NoArgsConstructor; @NoArgsConstructor(access = PRIVATE) -public class AddressUtil { - private static final String ADDRESS_REGEX = "[가-힣0-9]+(?:도|시|구|군|읍|면|동|리|로|길)[^#,\\n()]+(?:동|읍|면|리|로|길|호|층|번지)[^#,\\n()]+"; +public final class AddressUtil { + private static final String ADDRESS_REGEX = "[가-힣0-9]+(?:도|시|구|군|읍|면|동|리|로|길)\\s*[0-9]*(?:동|읍|면|리|로|길)?\\s*[0-9]+"; - public static String extractAddress(JsonNode snippet) { + public static String extractAddressFromJsonNode(JsonNode snippet) { String videoDescription = snippet.path("description").asText(); + return extractAddressFromString(videoDescription); + } + + public static String extractAddressFromString(String string) { Pattern pattern = Pattern.compile(ADDRESS_REGEX); - Matcher matcher = pattern.matcher(videoDescription); + Matcher matcher = pattern.matcher(string); if (matcher.find()) { return matcher.group(); } diff --git a/src/main/java/team7/inplace/crawling/application/YoutubeCrawlingService.java b/src/main/java/team7/inplace/crawling/application/YoutubeCrawlingService.java index 9a3020d1..9b207d73 100644 --- a/src/main/java/team7/inplace/crawling/application/YoutubeCrawlingService.java +++ b/src/main/java/team7/inplace/crawling/application/YoutubeCrawlingService.java @@ -32,7 +32,7 @@ public List crawlAllVideos() { var videoSnippets = youtubeClient.getVideos(channel.getPlayListUUID(), channel.getLastVideoUUID()); var videoAddresses = videoSnippets.stream() - .map(AddressUtil::extractAddress) + .map(AddressUtil::extractAddressFromJsonNode) .toList(); var placeNodes = videoAddresses.stream() diff --git a/src/main/java/team7/inplace/crawling/application/dto/CrawlingInfo.java b/src/main/java/team7/inplace/crawling/application/dto/CrawlingInfo.java index 7ed84962..0bf0a33f 100644 --- a/src/main/java/team7/inplace/crawling/application/dto/CrawlingInfo.java +++ b/src/main/java/team7/inplace/crawling/application/dto/CrawlingInfo.java @@ -2,6 +2,7 @@ import com.fasterxml.jackson.databind.JsonNode; import java.util.List; +import java.util.Objects; import team7.inplace.crawling.client.dto.PlaceNode; import team7.inplace.place.application.command.PlacesCommand; import team7.inplace.video.application.command.VideoCommand; @@ -19,7 +20,12 @@ public List toVideoCommands() { public List toPlacesCommands() { return placeNodes.stream() - .map(placeNode -> PlacesCommand.Create.from(placeNode.locationNode(), placeNode.placeNode())) + .map(placeNode -> { + if (Objects.isNull(placeNode)) { + return null; + } + return PlacesCommand.Create.from(placeNode.locationNode(), placeNode.placeNode()); + }) .toList(); } } diff --git a/src/main/java/team7/inplace/crawling/client/KakaoMapClient.java b/src/main/java/team7/inplace/crawling/client/KakaoMapClient.java index b56fc71f..d7446d89 100644 --- a/src/main/java/team7/inplace/crawling/client/KakaoMapClient.java +++ b/src/main/java/team7/inplace/crawling/client/KakaoMapClient.java @@ -24,8 +24,9 @@ public class KakaoMapClient { private final RestTemplate restTemplate; public PlaceNode search(String address, String category) { + log.info("KakaoMapClient search address: {}, category: {}", address, category); var locationInfo = getLocateInfo(address, category); - var placeId = locationInfo.has("documents") ? + var placeId = locationInfo.has("documents") && locationInfo.get("documents").hasNonNull(1) ? locationInfo.get("documents").get(0).get("id").asText() : null; if (Objects.isNull(placeId)) { return null; diff --git a/src/main/java/team7/inplace/crawling/domain/YoutubeChannel.java b/src/main/java/team7/inplace/crawling/domain/YoutubeChannel.java index 00f94f9e..1fadeab8 100644 --- a/src/main/java/team7/inplace/crawling/domain/YoutubeChannel.java +++ b/src/main/java/team7/inplace/crawling/domain/YoutubeChannel.java @@ -1,6 +1,9 @@ package team7.inplace.crawling.domain; +import static jakarta.persistence.EnumType.STRING; + import jakarta.persistence.Entity; +import jakarta.persistence.Enumerated; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; @@ -22,6 +25,7 @@ public class YoutubeChannel { private String playListUUID; private String lastVideoUUID; + @Enumerated(value = STRING) private ChannelType channelType; public String getChannelTypeCode() { diff --git a/src/main/java/team7/inplace/place/application/command/PlacesCommand.java b/src/main/java/team7/inplace/place/application/command/PlacesCommand.java index 376f2351..5d7d4559 100644 --- a/src/main/java/team7/inplace/place/application/command/PlacesCommand.java +++ b/src/main/java/team7/inplace/place/application/command/PlacesCommand.java @@ -66,6 +66,10 @@ public Place toEntity() { } public static Create from(JsonNode locationNode, JsonNode placeNode) { + if (Objects.isNull(locationNode) || Objects.isNull(placeNode)) { + return null; + } + var basicInfo = placeNode.get("basicInfo"); String placeName = @@ -74,8 +78,8 @@ public static Create from(JsonNode locationNode, JsonNode placeNode) { ? basicInfo.get("facilityInfo").toString() : "N/A"; String menuImgUrl = basicInfo.has("mainphotourl") ? basicInfo.get("mainphotourl").asText() : ""; - String category = basicInfo.has("category") && basicInfo.get("category").has("catename") - ? basicInfo.get("category").get("catename").asText() : "Unknown Category"; + String category = basicInfo.has("category") && basicInfo.get("category").has("cate1name") + ? basicInfo.get("category").get("cate1name").asText() : "Unknown Category"; String address = basicInfo.has("address") && basicInfo.get("address").has("region") && basicInfo.get("address") .get("region").has("newaddrfullname") @@ -92,8 +96,12 @@ public static Create from(JsonNode locationNode, JsonNode placeNode) { ? locationNode.get("documents").get(0).get("y").asText() : "0.0"; var timeList = basicInfo.has("openHour") ? basicInfo.get("openHour") : null; - var openPeriods = extractOpenPeriods(timeList.has("periodList") ? timeList.get("periodList") : null); - var offDays = extractOffDays(timeList.has("offdayList") ? timeList.get("offdayList") : null); + List openPeriods = Objects.nonNull(timeList) ? + extractOpenPeriods(timeList.has("periodList") ? timeList.get("periodList") : null) + : new ArrayList<>(); + List offDays = Objects.nonNull(timeList) ? + extractOffDays(timeList.has("offdayList") ? timeList.get("offdayList") : null) : new ArrayList<>(); + var menus = extractMenus(placeNode.has("menuInfo") ? placeNode.get("menuInfo") : null); var menuUpdatedAt = placeNode.has("menuInfo") && placeNode.get("menuInfo").has("menuUpdatedAt") ? LocalDateTime.parse(placeNode.get("menuInfo").get("timeexp").asText()) @@ -182,21 +190,25 @@ public String toEntityParams() { public record Menu( String menuName, String menuPrice, - boolean recommend + boolean recommend, + String menuImgUrl, + String description ) { public static Menu from(JsonNode menuNode) { if (Objects.isNull(menuNode)) { - return new Menu("Unknown Menu", "0", false); + return new Menu("Unknown Menu", "0", false, "", ""); } - String menuName = menuNode.has("menu") ? menuNode.get("menu").asText() : "Unknown Menu"; - String menuPrice = menuNode.has("price") ? menuNode.get("price").asText() : "0"; + String menuName = menuNode.has("menu") ? menuNode.get("menu").asText() : " "; + String menuPrice = menuNode.has("price") ? menuNode.get("price").asText() : " "; boolean recommend = menuNode.has("recommend") && menuNode.get("recommend").asBoolean(); + String menuImgUrl = menuNode.has("img") ? menuNode.get("img").asText() : " "; + String description = menuNode.has("desc") ? menuNode.get("desc").asText() : " "; - return new Menu(menuName, menuPrice, recommend); + return new Menu(menuName, menuPrice, recommend, menuImgUrl, description); } public String toEntityParams() { - return menuName + "|" + menuPrice + "|" + recommend; + return menuName + "|" + menuPrice + "|" + recommend + "|" + menuImgUrl + "|" + description; } } } diff --git a/src/main/java/team7/inplace/place/application/dto/PlaceDetailInfo.java b/src/main/java/team7/inplace/place/application/dto/PlaceDetailInfo.java index a68cfee7..93410b68 100644 --- a/src/main/java/team7/inplace/place/application/dto/PlaceDetailInfo.java +++ b/src/main/java/team7/inplace/place/application/dto/PlaceDetailInfo.java @@ -52,7 +52,7 @@ public static MenuInfos of(List menus) { .toList(); List menuList = menus.stream() - .map(menu -> new MenuInfo(menu.getPrice().intValue(), menu.isRecommend(), + .map(menu -> new MenuInfo(menu.getPrice(), menu.isRecommend(), menu.getMenuName())) .toList(); @@ -60,7 +60,7 @@ public static MenuInfos of(List menus) { } public record MenuInfo( - Integer price, + String price, Boolean recommend, String menuName ) { diff --git a/src/main/java/team7/inplace/place/domain/Address.java b/src/main/java/team7/inplace/place/domain/Address.java index 4482278c..2212008b 100644 --- a/src/main/java/team7/inplace/place/domain/Address.java +++ b/src/main/java/team7/inplace/place/domain/Address.java @@ -4,6 +4,7 @@ import jakarta.persistence.Column; import jakarta.persistence.Embeddable; +import java.util.Arrays; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NoArgsConstructor; @@ -29,7 +30,10 @@ private Address(String address1, String address2, String address3) { } public static Address of(String address) { - String[] split = address.split("\\|"); - return new Address(split[0], split[1], split[2]); + String[] split = address.split(" "); + var address1 = split[0]; + var address2 = split[1]; + var address3 = String.join(" ", Arrays.copyOfRange(split, 2, split.length)); + return new Address(address1, address2, address3); } -} +} \ No newline at end of file diff --git a/src/main/java/team7/inplace/place/domain/Category.java b/src/main/java/team7/inplace/place/domain/Category.java index 974d1ea7..8469478e 100644 --- a/src/main/java/team7/inplace/place/domain/Category.java +++ b/src/main/java/team7/inplace/place/domain/Category.java @@ -1,8 +1,26 @@ package team7.inplace.place.domain; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor public enum Category { - CAFE, - WESTERN, - JAPANESE, - KOREAN + CAFE("카페"), + WESTERN("양식"), + JAPANESE("일식"), + KOREAN("한식"), + RESTAURANT("음식점"), + NONE("없음"); + + private final String name; + + public static Category of(String name) { + for (Category category : values()) { + if (category.name.equals(name)) { + return category; + } + } + return NONE; + } } diff --git a/src/main/java/team7/inplace/place/domain/Menu.java b/src/main/java/team7/inplace/place/domain/Menu.java index 316d6e1c..1b8cee65 100644 --- a/src/main/java/team7/inplace/place/domain/Menu.java +++ b/src/main/java/team7/inplace/place/domain/Menu.java @@ -13,7 +13,7 @@ @EqualsAndHashCode @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Menu { - private Long price; + private String price; @ColumnDefault("false") @Column(nullable = false) @@ -22,18 +22,21 @@ public class Menu { @Column(length = 50, nullable = false) private String menuName; - @Column(length = 50) private String menuImgUrl; - - private Menu(Long price, boolean recommend, String menuName) { + + private String description; + + private Menu(String price, boolean recommend, String menuName, String menuImgUrl, String description) { this.price = price; this.recommend = recommend; this.menuName = menuName; + this.menuImgUrl = menuImgUrl; + this.description = description; } public static Menu of(String menu) { String[] menus = menu.split("\\|"); - - return new Menu(Long.parseLong(menus[1]), Boolean.parseBoolean(menus[2]), menus[0]); + return new Menu(menus[1], Boolean.parseBoolean(menus[2]), menus[0], menus[3], menus[4]); } + } diff --git a/src/main/java/team7/inplace/place/domain/Place.java b/src/main/java/team7/inplace/place/domain/Place.java index daa09bdc..1a74c1fa 100644 --- a/src/main/java/team7/inplace/place/domain/Place.java +++ b/src/main/java/team7/inplace/place/domain/Place.java @@ -64,7 +64,7 @@ public Place(String name, String facility, String menuImgsUrl, String category, this.name = name; this.facility = facility; this.menuImgUrl = menuImgsUrl; - this.category = Category.valueOf(category); + this.category = Category.of(category); this.address = Address.of(address); this.coordinate = Coordinate.of(x, y); this.offDays = offDays.stream() diff --git a/src/main/java/team7/inplace/video/application/AliasUtil.java b/src/main/java/team7/inplace/video/application/AliasUtil.java index 02107fa5..679e8017 100644 --- a/src/main/java/team7/inplace/video/application/AliasUtil.java +++ b/src/main/java/team7/inplace/video/application/AliasUtil.java @@ -6,7 +6,7 @@ @RequiredArgsConstructor(access = AccessLevel.PRIVATE) public final class AliasUtil { - public static String makeAlias(String influencerName, Category category){ + public static String makeAlias(String influencerName, Category category) { String alias = mapTemplateToCategory(category); return influencerName + " " + alias; } @@ -18,6 +18,8 @@ private static String mapTemplateToCategory(Category category) { case WESTERN -> Template.WESTERN.getRandomTemplate(); case JAPANESE -> Template.JAPANESE.getRandomTemplate(); case KOREAN -> Template.KOREAN.getRandomTemplate(); + case RESTAURANT -> Template.RESTAURANT.getRandomTemplate(); + default -> Template.NONE.getRandomTemplate(); }; } } diff --git a/src/main/java/team7/inplace/video/application/Template.java b/src/main/java/team7/inplace/video/application/Template.java index b1f2a0d5..aa9da0a4 100644 --- a/src/main/java/team7/inplace/video/application/Template.java +++ b/src/main/java/team7/inplace/video/application/Template.java @@ -30,6 +30,17 @@ public enum Template { "이(가) 전통 한식을 맛볼 수 있는 한식당입니다.", "이(가) 추천하는 가게에서 정성스럽게 준비된 한식으로 든든한 한 끼를!", "이(가) 극찬! 한식의 깊은 맛을 느껴보세요." + }), + + // 기본 템플릿 + RESTAURANT(new String[]{ + "이(가) 추천하는 맛집! 다양한 메뉴를 즐길 수 있습니다.", + "이(가) 방문한 식당에서 맛있는 음식을 즐겨보세요!", + "이(가) 추천하는 맛집에서 특별한 시간을 보내보세요!" + }), + + NONE(new String[]{ + "" }); // 템플릿 배열을 반환하는 메서드 diff --git a/src/main/java/team7/inplace/video/domain/Video.java b/src/main/java/team7/inplace/video/domain/Video.java index 3b2eada2..303982ac 100644 --- a/src/main/java/team7/inplace/video/domain/Video.java +++ b/src/main/java/team7/inplace/video/domain/Video.java @@ -11,32 +11,26 @@ import jakarta.persistence.ManyToOne; import lombok.Getter; import lombok.NoArgsConstructor; -import lombok.NonNull; -import lombok.RequiredArgsConstructor; import team7.inplace.influencer.domain.Influencer; import team7.inplace.place.domain.Place; @Entity @Getter @NoArgsConstructor(access = PROTECTED) -@RequiredArgsConstructor public class Video { @Id @GeneratedValue(strategy = IDENTITY) private Long id; @Column(name = "video_url", nullable = false, columnDefinition = "TEXT") - @NonNull private String videoUrl; @ManyToOne @JoinColumn(name = "influencer_id", nullable = false) - @NonNull private Influencer influencer; @ManyToOne - @JoinColumn(name = "place_id", nullable = false) - @NonNull + @JoinColumn(name = "place_id") private Place place; private Video(Influencer influencer, Place place, String videoUrl) { diff --git a/src/test/java/team7/inplace/crawling/application/AddressUtilTest.java b/src/test/java/team7/inplace/crawling/application/AddressUtilTest.java new file mode 100644 index 00000000..6adcf7cf --- /dev/null +++ b/src/test/java/team7/inplace/crawling/application/AddressUtilTest.java @@ -0,0 +1,27 @@ +package team7.inplace.crawling.application; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class AddressUtilTest { + + @DisplayName("주소 추출 테스트 1") + @Test + void extractAddressFromJsonNodeTest1() { + // given + final String description = """ + [참조은 생고기] + 대구 북구 복현로 78 (복현2동 266-9) + """; + final String address = "대구 북구 복현로 78"; + + // when + String result = AddressUtil.extractAddressFromString(description); + + // then + assertEquals(address, result); + } + +} \ No newline at end of file