"""외부 장소 DB 의 분류 → 우리 업종(PlaceCategory).""" from typing import Optional from common.enums import PlaceCategory # 카카오 category_group_code. _BY_GROUP_CODE = { "AD5": PlaceCategory.LODGING, "CE7": PlaceCategory.CAFE, "FD6": PlaceCategory.RESTAURANT, } _HOSPITAL_GROUP_CODE = "HP8" # 분류 문자열 키워드. _KEYWORDS: list[tuple[PlaceCategory, tuple[str, ...]]] = [ # "피부"·"성형" 이 아니라 "피부과"·"성형외과" 다. (PlaceCategory.CLINIC, ("피부과", "성형외과")), (PlaceCategory.LODGING, ("숙박", "펜션", "호텔", "모텔", "리조트", "게스트하우스", "민박")), (PlaceCategory.CAFE, ("카페", "커피", "베이커리", "제과", "디저트")), (PlaceCategory.RESTAURANT, ("음식점", "한식", "일식", "중식", "양식", "분식", "주점", "술집", "치킨", "횟집", "뷔페", "패스트푸드")), ] def guess_category( category_name: Optional[str], group_code: Optional[str] = None ) -> Optional[PlaceCategory]: """분류 문자열(+ 카카오 그룹코드)로 업종을 추정한다.""" text = (category_name or "").replace(" ", "") code = (group_code or "").strip().upper() if code == _HOSPITAL_GROUP_CODE: # 병원이라는 것까지만 안다. return PlaceCategory.CLINIC if _match(text) is PlaceCategory.CLINIC else None if code in _BY_GROUP_CODE: by_code = _BY_GROUP_CODE[code] # 그룹코드를 문자열로 덮는 경우가 하나 있다: 카카오가 베이커리·브런치 가게를 FD6(음식점)으로 주면서 분류 문자열엔 "카페"를 다는 일이 있다. if by_code is PlaceCategory.RESTAURANT and _match(text) is PlaceCategory.CAFE: return PlaceCategory.CAFE return by_code return _match(text) def _match(text: str) -> Optional[PlaceCategory]: for category, words in _KEYWORDS: if any(word in text for word in words): return category return None # ── 음식 중분류(TourAPI lclsSystm2) 추정 ───────────────────────────────── 주변 맛집에서 **같은 중분류(경쟁 업소)를 빼는** 기준이다. _FOOD_CLASS_KEYWORDS: list[tuple[str, tuple[str, ...]]] = [ ("FD05", ("카페", "커피", "찻집", "디저트", "음료", "주스", "빙수", "케이크", "브런치")), ("FD04", ("주점", "술집", "호프", "맥주", "이자카야", "포차", "와인바", "칵테일", "펍")), ("FD03", ("제과", "베이커리", "빵", "도넛", "피자", "햄버거", "샌드위치", "치킨", "분식", "김밥", "떡볶이", "간식", "토스트", "패스트푸드")), ("FD02", ("중식", "중국", "일식", "일본", "초밥", "라멘", "양식", "서양", "이탈리", "파스타", "스테이크", "프렌치", "프랑스", "멕시", "아시아", "베트남", "태국", "인도", "퓨전")), ("FD01", ("한식", "한정식", "백반", "국밥", "찌개", "국수", "냉면", "삼겹", "갈비", "곱창", "족발", "보쌈", "해장국", "설렁탕", "감자탕", "칼국수", "횟집", "회")), ] def guess_food_class(category_name: Optional[str]) -> Optional[str]: """외부 분류 문자열 → TourAPI 음식 중분류 코드(FD01~FD05).""" text = (category_name or "").replace(" ", "") if not text: return None for code, words in _FOOD_CLASS_KEYWORDS: if any(word in text for word in words): return code return None