Update model translations
This commit is contained in:
@@ -26,6 +26,9 @@ from .translations import (
|
||||
FUEL_TYPE_MAP,
|
||||
GEARBOX_MAP_KO,
|
||||
MODEL_BODY_TYPE_MAP,
|
||||
MODEL_EXACT_TRANSLATIONS,
|
||||
MODEL_PHRASE_TRANSLATIONS,
|
||||
MODEL_TOKEN_TRANSLATIONS,
|
||||
MODEL_TRANSLATIONS,
|
||||
SELL_TYPE_MAP,
|
||||
expand_allowed_brands,
|
||||
@@ -173,7 +176,7 @@ class EncarMapper:
|
||||
model_raw = self._as_str(payload.get("Model") or "UNKNOWN")
|
||||
badge = self._as_str(payload.get("Badge") or "")
|
||||
badge_detail = self._as_str(payload.get("BadgeDetail") or "")
|
||||
model = self._translate_text(model_raw)
|
||||
model = self._translate_model(model_raw)
|
||||
|
||||
year = self._to_year(payload.get("FormYear") or payload.get("Year"))
|
||||
# Price в 만원 (10 000 KRW) → переводим в KRW
|
||||
@@ -352,6 +355,68 @@ class EncarMapper:
|
||||
translated = re.sub(r"\s+", " ", translated).strip()
|
||||
return translated
|
||||
|
||||
def _has_korean(self, text: str) -> bool:
|
||||
return bool(re.search(r"[가-힣]", text))
|
||||
|
||||
def _normalize_model_text(self, text: str) -> str:
|
||||
normalized = self._as_str(text)
|
||||
if not normalized:
|
||||
return normalized
|
||||
# На оригинальном сайте Encar скобок нет — убираем скобки вместе с содержимым.
|
||||
normalized = re.sub(r"[\(\[(【][^)\])】]*[\)\])】]?", " ", normalized)
|
||||
normalized = normalized.replace("·", " ").replace("/", " ")
|
||||
normalized = re.sub(r"(?<=[A-Za-z])-클래스", " 클래스", normalized)
|
||||
normalized = re.sub(r"(?<=[0-9])시리즈", "시리즈", normalized)
|
||||
normalized = re.sub(r"\s+", " ", normalized).strip()
|
||||
return normalized
|
||||
|
||||
def _translate_model(self, text: str) -> str:
|
||||
"""Безопасно переводит модель Encar: точные совпадения + корейские фрагменты.
|
||||
|
||||
Старый общий replace ломал смешанные названия. Здесь английские строки
|
||||
возвращаются как есть, а короткие корейские токены заменяются только
|
||||
когда они реально присутствуют как отдельный смысловой фрагмент.
|
||||
"""
|
||||
original = self._normalize_model_text(text)
|
||||
if not original or not self._has_korean(original):
|
||||
return original
|
||||
|
||||
exact = MODEL_EXACT_TRANSLATIONS.get(original)
|
||||
if exact:
|
||||
return exact
|
||||
|
||||
translated = original
|
||||
|
||||
# Сначала длинные точные модели и фразы — чтобы "렉с턴 스포츠 칸"
|
||||
# не превратился в "Rexton Sport 칸".
|
||||
combined = {**MODEL_EXACT_TRANSLATIONS, **MODEL_PHRASE_TRANSLATIONS, **MODEL_TRANSLATIONS}
|
||||
for source, target in sorted(combined.items(), key=lambda item: len(item[0]), reverse=True):
|
||||
if source in translated:
|
||||
# Заменяем только когда корейский ключ стоит как отдельный
|
||||
# смысловой фрагмент (границы — не корейские символы). Иначе
|
||||
# короткий ключ "레이" (Ray) резал бы "슈팅브레이크" → "슈팅브Ray크".
|
||||
pattern = rf"(?<![가-힣]){re.escape(source)}(?![가-힣])"
|
||||
translated = re.sub(pattern, target, translated)
|
||||
|
||||
# Потом безопасные короткие токены.
|
||||
for source, target in sorted(MODEL_TOKEN_TRANSLATIONS.items(), key=lambda item: len(item[0]), reverse=True):
|
||||
translated = re.sub(rf"(?<![A-Za-z0-9가-힣]){re.escape(source)}(?![A-Za-z0-9가-힣])", target, translated)
|
||||
|
||||
# Типовые слитные варианты Encar: 5시리즈, S-클래스.
|
||||
translated = re.sub(r"(?<=\d)시리즈", " Series", translated)
|
||||
translated = re.sub(r"(?<=[A-Za-z])-?클래스", "-Class", translated)
|
||||
translated = re.sub(r"\b([A-Z]{1,4}) Class\b", r"\1-Class", translated)
|
||||
|
||||
# Оставшиеся непереведённые корейские фрагменты отбрасываем — как на
|
||||
# оригинальном сайте (напр. "슈팅브레이크" исчезает, не портя слово).
|
||||
translated = re.sub(r"[가-힣]+", " ", translated)
|
||||
# Чистим осиротевшую пунктуацию/скобки после удаления корейского.
|
||||
translated = re.sub(r"\(\s*\)", " ", translated)
|
||||
translated = re.sub(r"\s*-\s*(?=$|\))", "", translated)
|
||||
translated = re.sub(r"\s+([),])", r"\1", translated)
|
||||
translated = re.sub(r"\s+", " ", translated).strip(" -")
|
||||
return translated
|
||||
|
||||
def _translate_color(self, color_raw: str) -> str:
|
||||
value = self._as_str(color_raw)
|
||||
if not value:
|
||||
|
||||
326
encar_scraper/partner_dictionary.py
Normal file
326
encar_scraper/partner_dictionary.py
Normal file
@@ -0,0 +1,326 @@
|
||||
"""Korean -> English translation tables for EnCar (partner-provided basis).
|
||||
|
||||
Источник переводов от партнёра. Этот файл — эталон: бренды и модели берём
|
||||
отсюда в первую очередь. Держим секционные словари плюс один плоский для
|
||||
простых поисков.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
ENCAR_KO_EN_TABLES: dict[str, dict[str, str]] = {
|
||||
"makers": {
|
||||
"포르쉐": "Porsche",
|
||||
"메르세데스-벤츠": "Mercedes-Benz",
|
||||
"메르세데스 벤츠": "Mercedes-Benz",
|
||||
"벤츠": "Mercedes-Benz",
|
||||
"메르세데스-AMG": "Mercedes-AMG",
|
||||
"메르세데스 AMG": "Mercedes-AMG",
|
||||
"AMG": "AMG",
|
||||
"BMW": "BMW",
|
||||
"아우디": "Audi",
|
||||
"폭스바겐": "Volkswagen",
|
||||
"렉서스": "Lexus",
|
||||
"토요타": "Toyota",
|
||||
"닛산": "Nissan",
|
||||
"인피니티": "Infiniti",
|
||||
"혼다": "Honda",
|
||||
"마쯔다": "Mazda",
|
||||
"스바루": "Subaru",
|
||||
"미쓰비시": "Mitsubishi",
|
||||
"랜드로버": "Land Rover",
|
||||
"재규어": "Jaguar",
|
||||
"지프": "Jeep",
|
||||
"볼보": "Volvo",
|
||||
"푸조": "Peugeot",
|
||||
"르노": "Renault",
|
||||
"미니": "MINI",
|
||||
"로터스": "Lotus",
|
||||
"벤틀리": "Bentley",
|
||||
"롤스로이스": "Rolls-Royce",
|
||||
"람보르기니": "Lamborghini",
|
||||
"페라리": "Ferrari",
|
||||
"맥라렌": "McLaren",
|
||||
"애스턴마틴": "Aston Martin",
|
||||
"애스톤마틴": "Aston Martin",
|
||||
"마세라티": "Maserati",
|
||||
"코닉세그": "Koenigsegg",
|
||||
"파가니": "Pagani",
|
||||
"부가티": "Bugatti",
|
||||
"캐딜락": "Cadillac",
|
||||
"쉐보레": "Chevrolet",
|
||||
"포드": "Ford",
|
||||
"링컨": "Lincoln",
|
||||
"크라이슬러": "Chrysler",
|
||||
"닷지": "Dodge",
|
||||
"램": "Ram",
|
||||
"테슬라": "Tesla",
|
||||
"제네시스": "Genesis",
|
||||
"현대": "Hyundai",
|
||||
"기아": "Kia",
|
||||
"KG모빌리티": "KG Mobility",
|
||||
"쌍용": "SsangYong",
|
||||
"알파로메오": "Alfa Romeo",
|
||||
"피아트": "Fiat",
|
||||
"시트로엥": "Citroen",
|
||||
"스마트": "Smart",
|
||||
"폴스타": "Polestar",
|
||||
"리비안": "Rivian",
|
||||
"루시드": "Lucid",
|
||||
"BYD": "BYD",
|
||||
"지리": "Geely",
|
||||
"홍치": "Hongqi",
|
||||
"이스즈": "Isuzu",
|
||||
},
|
||||
"models": {
|
||||
"718 박스터": "718 Boxster",
|
||||
"718 카이맨": "718 Cayman",
|
||||
"911": "911",
|
||||
"911 카브리올레": "911 Cabriolet",
|
||||
"카이엔": "Cayenne",
|
||||
"카이엔 쿠페": "Cayenne Coupe",
|
||||
"파나메라": "Panamera",
|
||||
"파나메라 스포츠 투리스모": "Panamera Sport Turismo",
|
||||
"마칸": "Macan",
|
||||
"타이칸": "Taycan",
|
||||
"타이칸 크로스 투리스모": "Taycan Cross Turismo",
|
||||
"918 스파이더": "918 Spyder",
|
||||
"카레라 GT": "Carrera GT",
|
||||
"718 스파이더": "718 Spyder",
|
||||
"박스터": "Boxster",
|
||||
"카이맨": "Cayman",
|
||||
"4.0 스파이더": "4.0 Spyder",
|
||||
"C 클래스": "C-Class",
|
||||
"E 클래스": "E-Class",
|
||||
"S 클래스": "S-Class",
|
||||
"A 클래스": "A-Class",
|
||||
"B 클래스": "B-Class",
|
||||
"CLA": "CLA",
|
||||
"CLS": "CLS",
|
||||
"SL": "SL",
|
||||
"SLK": "SLK",
|
||||
"G 클래스": "G-Class",
|
||||
"GLA": "GLA",
|
||||
"GLB": "GLB",
|
||||
"GLC": "GLC",
|
||||
"GLE": "GLE",
|
||||
"GLS": "GLS",
|
||||
"AMG GT": "AMG GT",
|
||||
"AMG GT 4도어 쿠페": "AMG GT 4-Door Coupe",
|
||||
"V 클래스": "V-Class",
|
||||
"1 시리즈": "1 Series",
|
||||
"2 시리즈": "2 Series",
|
||||
"3 시리즈": "3 Series",
|
||||
"4 시리즈": "4 Series",
|
||||
"5 시리즈": "5 Series",
|
||||
"6 시리즈": "6 Series",
|
||||
"7 시리즈": "7 Series",
|
||||
"8 시리즈": "8 Series",
|
||||
"M2": "M2",
|
||||
"M3": "M3",
|
||||
"M4": "M4",
|
||||
"M5": "M5",
|
||||
"M8": "M8",
|
||||
"X1": "X1",
|
||||
"X2": "X2",
|
||||
"X3": "X3",
|
||||
"X4": "X4",
|
||||
"X5": "X5",
|
||||
"X6": "X6",
|
||||
"X7": "X7",
|
||||
"Z4": "Z4",
|
||||
"A3": "A3",
|
||||
"A4": "A4",
|
||||
"A5": "A5",
|
||||
"A6": "A6",
|
||||
"A7": "A7",
|
||||
"A8": "A8",
|
||||
"Q3": "Q3",
|
||||
"Q5": "Q5",
|
||||
"Q7": "Q7",
|
||||
"Q8": "Q8",
|
||||
"R8": "R8",
|
||||
"TT": "TT",
|
||||
"고스트": "Ghost",
|
||||
"팬텀": "Phantom",
|
||||
"레이스": "Wraith",
|
||||
"던": "Dawn",
|
||||
"컬리넌": "Cullinan",
|
||||
"스펙터": "Spectre",
|
||||
"벤테이가": "Bentayga",
|
||||
"컨티넨탈 GT": "Continental GT",
|
||||
"플라잉스퍼": "Flying Spur",
|
||||
"우라칸": "Huracan",
|
||||
"아벤타도르": "Aventador",
|
||||
"우루스": "Urus",
|
||||
"레부엘토": "Revuelto",
|
||||
"로마": "Roma",
|
||||
"포르토피노": "Portofino",
|
||||
"SF90 스트라달레": "SF90 Stradale",
|
||||
"F8 트리뷰토": "F8 Tributo",
|
||||
"콰트로포르테": "Quattroporte",
|
||||
"기블리": "Ghibli",
|
||||
"르반떼": "Levante",
|
||||
"그란투리스모": "GranTurismo",
|
||||
"반퀴시": "Vanquish",
|
||||
"밴티지": "Vantage",
|
||||
"DB11": "DB11",
|
||||
"DB12": "DB12",
|
||||
"DBS": "DBS",
|
||||
},
|
||||
"body_types": {
|
||||
"세단": "Sedan",
|
||||
"쿠페": "Coupe",
|
||||
"컨버터블": "Convertible",
|
||||
"카브리올레": "Cabriolet",
|
||||
"오픈카": "Open Top",
|
||||
"해치백": "Hatchback",
|
||||
"왜건": "Wagon",
|
||||
"스테이션왜건": "Station Wagon",
|
||||
"SUV": "SUV",
|
||||
"크로스오버": "Crossover",
|
||||
"픽업트럭": "Pickup Truck",
|
||||
"밴": "Van",
|
||||
"미니밴": "Minivan",
|
||||
"트럭": "Truck",
|
||||
"쿠페형 SUV": "Coupe SUV",
|
||||
"기타": "Other",
|
||||
},
|
||||
"fuel_types": {
|
||||
"가솔린": "Gasoline",
|
||||
"디젤": "Diesel",
|
||||
"경유": "Diesel",
|
||||
"하이브리드": "Hybrid",
|
||||
"가솔린 하이브리드": "Gasoline Hybrid",
|
||||
"플러그인 하이브리드": "Plug-in Hybrid",
|
||||
"전기": "Electric",
|
||||
"전기차": "Electric",
|
||||
"수소": "Hydrogen",
|
||||
"LPG": "LPG",
|
||||
"LNG": "LNG",
|
||||
"가솔린+전기": "Gasoline + Electric",
|
||||
"가솔린 + 전기": "Gasoline + Electric",
|
||||
},
|
||||
"transmissions": {
|
||||
"수동": "Manual",
|
||||
"오토": "Automatic",
|
||||
"자동": "Automatic",
|
||||
"자동변속": "Automatic",
|
||||
"세미오토": "Semi-automatic",
|
||||
"CVT": "CVT",
|
||||
"듀얼클러치": "Dual-clutch",
|
||||
},
|
||||
"sell_types": {
|
||||
"일반": "General",
|
||||
"리스": "Lease",
|
||||
"렌트": "Rent",
|
||||
"할부": "Installment",
|
||||
},
|
||||
"lease_types": {
|
||||
"운용리스": "Operating Lease",
|
||||
"금융리스": "Financial Lease",
|
||||
},
|
||||
"regions": {
|
||||
"서울": "Seoul",
|
||||
"부산": "Busan",
|
||||
"인천": "Incheon",
|
||||
"대구": "Daegu",
|
||||
"대전": "Daejeon",
|
||||
"광주": "Gwangju",
|
||||
"울산": "Ulsan",
|
||||
"세종": "Sejong",
|
||||
"경기": "Gyeonggi",
|
||||
"강원": "Gangwon",
|
||||
"충북": "Chungbuk",
|
||||
"충남": "Chungnam",
|
||||
"전북": "Jeonbuk",
|
||||
"전남": "Jeonnam",
|
||||
"경북": "Gyeongbuk",
|
||||
"경남": "Gyeongnam",
|
||||
"제주": "Jeju",
|
||||
},
|
||||
"dealer_companies": {
|
||||
"(주)기억": "Gieok Co., Ltd.",
|
||||
"(주)네바퀴": "Four Wheels Co., Ltd.",
|
||||
"(주)에이스타모터스": "A-Star Motors Co., Ltd.",
|
||||
"(주)우진 오토모빌": "Woojin Automobile Co., Ltd.",
|
||||
"(주)지온컴퍼니": "Zion Company Co., Ltd.",
|
||||
"(주)플로시모터스": "Flossy Motors Co., Ltd.",
|
||||
"㈜오토핸즈": "Auto Hands Co., Ltd.",
|
||||
"GD카": "GD Car",
|
||||
"MK모터스": "MK Motors",
|
||||
"꿈차": "Dream Car",
|
||||
"마이카4": "My Car 4",
|
||||
"블루오토": "Blue Auto",
|
||||
"세영모빌리티(주)": "Seyoung Mobility Co., Ltd.",
|
||||
"스마일자동차": "Smile Motors",
|
||||
"오토링크": "Auto Link",
|
||||
"오토핸즈": "Auto Hands",
|
||||
"우리들모터스": "Woorideul Motors",
|
||||
"주식회사 모터바겐": "Motorwagen Co., Ltd.",
|
||||
"주식회사 아이오토스": "iAutos Co., Ltd.",
|
||||
"주식회사이들컴퍼니": "Ideul Company Co., Ltd.",
|
||||
"카메이트": "Car Mate",
|
||||
"카톡모터스": "Katok Motors",
|
||||
"카피디": "Car PD",
|
||||
"포르쉐 인증 중고차 센터 성수": "Porsche Certified Used Car Center Seongsu",
|
||||
"포르쉐인증중고차센터성수": "Porsche Certified Used Car Center Seongsu",
|
||||
},
|
||||
"dealer_names": {
|
||||
"고준용": "Go Jun-yong",
|
||||
"공민중": "Gong Min-jung",
|
||||
"김경진": "Kim Gyeong-jin",
|
||||
"김명진": "Kim Myeong-jin",
|
||||
"김민수": "Kim Min-su",
|
||||
"김성언": "Kim Seong-eon",
|
||||
"김성진": "Kim Seong-jin",
|
||||
"김영균": "Kim Yeong-gyun",
|
||||
"김완섭": "Kim Wan-seop",
|
||||
"김현진": "Kim Hyeon-jin",
|
||||
"김형진": "Kim Hyeong-jin",
|
||||
"김호영": "Kim Ho-yeong",
|
||||
"문명기": "Moon Myeong-gi",
|
||||
"박원석": "Park Won-seok",
|
||||
"박재현": "Park Jae-hyeon",
|
||||
"방지윤": "Bang Ji-yun",
|
||||
"송슬기": "Song Seul-gi",
|
||||
"신영철": "Shin Yeong-cheol",
|
||||
"신호진": "Shin Ho-jin",
|
||||
"양시언": "Yang Si-eon",
|
||||
"양태규": "Yang Tae-gyu",
|
||||
"윤지완": "Yoon Ji-wan",
|
||||
"이경민": "Lee Gyeong-min",
|
||||
"이재욱": "Lee Jae-uk",
|
||||
"임종현": "Lim Jong-hyeon",
|
||||
"임형욱": "Lim Hyeong-uk",
|
||||
"전태준": "Jeon Tae-jun",
|
||||
"정상필": "Jeong Sang-pil",
|
||||
"조경식": "Jo Gyeong-sik",
|
||||
"조승재": "Jo Seung-jae",
|
||||
"조환성": "Jo Hwan-seong",
|
||||
"차상훈": "Cha Sang-hun",
|
||||
"최경욱": "Choi Gyeong-uk",
|
||||
"하상열": "Ha Sang-yeol",
|
||||
"허지훈": "Heo Ji-hun",
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def _build_flat_map() -> dict[str, str]:
|
||||
result: dict[str, str] = {}
|
||||
for section in ENCAR_KO_EN_TABLES.values():
|
||||
result.update(section)
|
||||
return result
|
||||
|
||||
|
||||
ENCAR_KO_EN_TRANSLATIONS: dict[str, str] = _build_flat_map()
|
||||
|
||||
|
||||
def translate_encar_ko_to_en(value: str, section: str | None = None) -> str:
|
||||
"""Перевод корейского термина Encar на английский.
|
||||
|
||||
Если задан `section`, используется только словарь этой секции. Иначе —
|
||||
плоский объединённый словарь.
|
||||
"""
|
||||
if section is not None:
|
||||
return ENCAR_KO_EN_TABLES.get(section, {}).get(value, value)
|
||||
return ENCAR_KO_EN_TRANSLATIONS.get(value, value)
|
||||
@@ -1,5 +1,15 @@
|
||||
# Словари переводов корейского текста русский / английский.
|
||||
# Используется в encar.py для маппинга данных Encar API.
|
||||
#
|
||||
# Эталон переводов брендов и моделей — словарь партнёра
|
||||
# (`partner_dictionary.py`). Он подмешивается ниже как база: значения оттуда
|
||||
# имеют приоритет для брендов и моделей, а специфичные для проекта записи
|
||||
# (корейские модели Hyundai/Kia/Genesis и т.п., которых нет у партнёра)
|
||||
# сохраняются как дополнение.
|
||||
|
||||
import re
|
||||
|
||||
from .partner_dictionary import ENCAR_KO_EN_TABLES as _PARTNER_TABLES
|
||||
|
||||
|
||||
# Топливо
|
||||
@@ -176,6 +186,12 @@ BRAND_TRANSLATIONS = {
|
||||
"기타 수입차": "Other Imported",
|
||||
}
|
||||
|
||||
# Подмешиваем бренды из эталонного словаря партнёра как базу. Существующие
|
||||
# записи проекта имеют приоритет (не перезаписываются), новые из словаря
|
||||
# партнёра добавляются.
|
||||
for _ko, _en in _PARTNER_TABLES["makers"].items():
|
||||
BRAND_TRANSLATIONS.setdefault(_ko, _en)
|
||||
|
||||
|
||||
# Бренды: английский → алиасы (корейский + русский)
|
||||
|
||||
@@ -277,6 +293,240 @@ def expand_allowed_brands(brands: set[str] | None) -> set[str] | None:
|
||||
|
||||
# Модели / комплектации: корейский → английский
|
||||
|
||||
# Точные переводы базовых названий моделей Encar. Этот словарь используется
|
||||
# перед частичным переводом и не должен содержать общие слова вроде "뉴".
|
||||
MODEL_EXACT_TRANSLATIONS = {
|
||||
# BMW / Mercedes-Benz
|
||||
"1시리즈": "1 Series",
|
||||
"2시리즈": "2 Series",
|
||||
"3시리즈": "3 Series",
|
||||
"4시리즈": "4 Series",
|
||||
"5시리즈": "5 Series",
|
||||
"6시리즈": "6 Series",
|
||||
"7시리즈": "7 Series",
|
||||
"8시리즈": "8 Series",
|
||||
"A-클래스": "A-Class",
|
||||
"B-클래스": "B-Class",
|
||||
"C-클래스": "C-Class",
|
||||
"E-클래스": "E-Class",
|
||||
"S-클래스": "S-Class",
|
||||
"SL-클래스": "SL-Class",
|
||||
"SLK-클래스": "SLK-Class",
|
||||
"GLA-클래스": "GLA-Class",
|
||||
"GLB-클래스": "GLB-Class",
|
||||
"GLC-클래스": "GLC-Class",
|
||||
"GLE-클래스": "GLE-Class",
|
||||
"GLS-클래스": "GLS-Class",
|
||||
"V-클래스": "V-Class",
|
||||
# Hyundai / Kia / Genesis
|
||||
"팰리세이드": "Palisade",
|
||||
"싼타페": "Santa Fe",
|
||||
"투싼": "Tucson",
|
||||
"아반떼": "Avante",
|
||||
"쏘나타": "Sonata",
|
||||
"쏘나타 디 엣지": "Sonata The Edge",
|
||||
"그랜저": "Grandeur",
|
||||
"아이오닉5": "Ioniq 5",
|
||||
"아이오닉6": "Ioniq 6",
|
||||
"아이오닉": "Ioniq",
|
||||
"넥쏘": "Nexo",
|
||||
"벨로스터": "Veloster",
|
||||
"코나": "Kona",
|
||||
"캐스퍼": "Casper",
|
||||
"베뉴": "Venue",
|
||||
"스타렉스": "Starex",
|
||||
"스타리아": "Staria",
|
||||
"아슬란": "Aslan",
|
||||
"베라크루즈": "Veracruz",
|
||||
"카니발": "Carnival",
|
||||
"쏘렌토": "Sorento",
|
||||
"스포티지": "Sportage",
|
||||
"에스컬레이드": "Escalade",
|
||||
"프리미어": "Premier",
|
||||
"1세대": "1st gen",
|
||||
"2세대": "2nd gen",
|
||||
"3세대": "3rd gen",
|
||||
"4세대": "4th gen",
|
||||
"5세대": "5th gen",
|
||||
"6세대": "6th gen",
|
||||
"7세대": "7th gen",
|
||||
"8세대": "8th gen",
|
||||
"모닝": "Morning",
|
||||
"레이": "Ray",
|
||||
"셀토스": "Seltos",
|
||||
"니로": "Niro",
|
||||
"스팅어": "Stinger",
|
||||
"쏘울": "Soul",
|
||||
"모하비": "Mohave",
|
||||
"프라이드": "Pride",
|
||||
"스토닉": "Stonic",
|
||||
"카렌스": "Carens",
|
||||
"제네시스": "Genesis",
|
||||
# Chevrolet / Renault Korea / KG Mobility
|
||||
"스파크": "Spark",
|
||||
"말리부": "Malibu",
|
||||
"트랙스": "Trax",
|
||||
"크루즈": "Cruze",
|
||||
"올란도": "Orlando",
|
||||
"트레일블레이저": "Trailblazer",
|
||||
"콜로라도": "Colorado",
|
||||
"트래버스": "Traverse",
|
||||
"캡티바": "Captiva",
|
||||
"이쿼녹스": "Equinox",
|
||||
"아베오": "Aveo",
|
||||
"볼트": "Volt",
|
||||
"임팔라": "Impala",
|
||||
"맥스크루즈": "Max Cruz",
|
||||
"렉스턴 스포츠 칸": "Rexton Sport Khan",
|
||||
"렉스턴 스포츠": "Rexton Sport",
|
||||
"렉스턴": "Rexton",
|
||||
"토레스": "Torres",
|
||||
"티볼리 에어": "Tivoli Air",
|
||||
"티볼리 아머": "Tivoli Armor",
|
||||
"티볼리": "Tivoli",
|
||||
"코란도 투리스모": "Korando Turismo",
|
||||
"코란도 스포츠": "Korando Sport",
|
||||
"코란도": "Korando",
|
||||
"체어맨": "Chairman",
|
||||
"오피러스": "Opirus",
|
||||
# Import models written in Korean
|
||||
"익스플로러": "Explorer",
|
||||
"머스탱": "Mustang",
|
||||
"카이엔": "Cayenne",
|
||||
"카이엔 쿠페": "Cayenne Coupe",
|
||||
"파나메라": "Panamera",
|
||||
"파나메라 스포츠 투리스모": "Panamera Sport Turismo",
|
||||
"마칸": "Macan",
|
||||
"타이칸": "Taycan",
|
||||
"타이칸 크로스 투리스모": "Taycan Cross Turismo",
|
||||
"918 스파이더": "918 Spyder",
|
||||
"718 스파이더": "718 Spyder",
|
||||
"4.0 스파이더": "4.0 Spyder",
|
||||
"박스터": "Boxster",
|
||||
"카이맨": "Cayman",
|
||||
"911 카브리올레": "911 Cabriolet",
|
||||
"카레라": "Carrera",
|
||||
"티구안": "Tiguan",
|
||||
"골프": "Golf",
|
||||
"제타": "Jetta",
|
||||
"투아렉": "Touareg",
|
||||
"파사트": "Passat",
|
||||
"아테온": "Arteon",
|
||||
"쿠퍼": "Cooper",
|
||||
"컨트리맨": "Countryman",
|
||||
"클럽맨": "Clubman",
|
||||
"디스커버리": "Discovery",
|
||||
"레인지로버": "Range Rover",
|
||||
"이보크": "Evoque",
|
||||
"벨라": "Velar",
|
||||
"디펜더": "Defender",
|
||||
"랭글러": "Wrangler",
|
||||
"체로키": "Cherokee",
|
||||
"레니게이드": "Renegade",
|
||||
"컴패스": "Compass",
|
||||
"루비콘": "Rubicon",
|
||||
"에비에이터": "Aviator",
|
||||
"르반떼": "Levante",
|
||||
"기블리": "Ghibli",
|
||||
"어코드": "Accord",
|
||||
"캠리": "Camry",
|
||||
"프리우스": "Prius",
|
||||
"타스만": "Tasman",
|
||||
"토러스": "Taurus",
|
||||
"카마로": "Camaro",
|
||||
"비틀": "Beetle",
|
||||
"e-트론": "e-tron",
|
||||
"글래디에이터": "Gladiator",
|
||||
"노틸러스": "Nautilus",
|
||||
"시로코": "Scirocco",
|
||||
"아틀라스": "Atlas",
|
||||
"알파드": "Alphard",
|
||||
"익스페디션": "Expedition",
|
||||
"익스프레스Van": "Express Van",
|
||||
"짐니": "Jimny",
|
||||
"쿠가": "Kuga",
|
||||
"클리오": "Clio",
|
||||
"파일럿": "Pilot",
|
||||
"콰트로포르테": "Quattroporte",
|
||||
"고스트": "Ghost",
|
||||
"팬텀": "Phantom",
|
||||
"레이스": "Wraith",
|
||||
"던": "Dawn",
|
||||
"컬리넌": "Cullinan",
|
||||
"스펙터": "Spectre",
|
||||
"벤테이가": "Bentayga",
|
||||
"컨티넨탈 GT": "Continental GT",
|
||||
"플라잉스퍼": "Flying Spur",
|
||||
"우라칸": "Huracan",
|
||||
"아벤타도르": "Aventador",
|
||||
"우루스": "Urus",
|
||||
"레부엘토": "Revuelto",
|
||||
"로마": "Roma",
|
||||
"포르토피노": "Portofino",
|
||||
"SF90 스트라달레": "SF90 Stradale",
|
||||
"F8 트리뷰토": "F8 Tributo",
|
||||
"그란투리스모": "GranTurismo",
|
||||
"반퀴시": "Vanquish",
|
||||
"밴티지": "Vantage",
|
||||
"AMG GT 4도어 쿠페": "AMG GT 4-Door Coupe",
|
||||
}
|
||||
|
||||
# Подмешиваем модели из эталонного словаря партнёра как базу. Существующие
|
||||
# записи проекта имеют приоритет. Дополнительно добавляем нормализованные
|
||||
# варианты ключей партнёра (напр. "5 시리즈" -> "5시리즈", "S 클래스" -> "S-클래스"),
|
||||
# т.к. в сырых данных Encar формат отличается пробелами/дефисами.
|
||||
def _register_partner_models() -> None:
|
||||
for _ko, _en in _PARTNER_TABLES["models"].items():
|
||||
MODEL_EXACT_TRANSLATIONS.setdefault(_ko, _en)
|
||||
# "5 시리즈" -> "5시리즈"
|
||||
_compact = re.sub(r"(?<=\d)\s+시리즈", "시리즈", _ko)
|
||||
# "S 클래스" -> "S-클래스"
|
||||
_compact = re.sub(r"(?<=[A-Za-z])\s+클래스", "-클래스", _compact)
|
||||
if _compact != _ko:
|
||||
MODEL_EXACT_TRANSLATIONS.setdefault(_compact, _en)
|
||||
|
||||
|
||||
_register_partner_models()
|
||||
|
||||
# Безопасные составные фразы. Применяются только к строкам, где есть корейский текст.
|
||||
MODEL_PHRASE_TRANSLATIONS = {
|
||||
"올 뉴": "All New",
|
||||
"더 뉴": "New",
|
||||
"디 올 뉴": "The All New",
|
||||
"베리 뉴": "Very New",
|
||||
"베리": "Very",
|
||||
"뷰티풀": "Beautiful",
|
||||
"넥스트": "Next",
|
||||
"디 ": "The ",
|
||||
"디 엣지": "The Edge",
|
||||
"액티브 투어러": "Active Tourer",
|
||||
"투어러": "Tourer",
|
||||
"그란쿠페": "GranCoupe",
|
||||
"그란 쿠페": "GranCoupe",
|
||||
"스포츠 칸": "Sport Khan",
|
||||
"스포츠": "Sport",
|
||||
"하이브리드": "Hybrid",
|
||||
"일렉트릭": "Electric",
|
||||
"네오": "Neo",
|
||||
"트랜스폼": "Transform",
|
||||
"프라임": "Prime",
|
||||
"마스터": "Master",
|
||||
"어반": "Urban",
|
||||
"볼드": "Bold",
|
||||
"아머": "Armor",
|
||||
"에어": "Air",
|
||||
}
|
||||
|
||||
# Короткие токены переводятся только как отдельные токены, не внутри других слов.
|
||||
MODEL_TOKEN_TRANSLATIONS = {
|
||||
"시리즈": "Series",
|
||||
"클래스": "Class",
|
||||
"세대": "gen",
|
||||
"뉴": "New",
|
||||
"올": "All",
|
||||
"칸": "Khan",
|
||||
}
|
||||
|
||||
MODEL_TRANSLATIONS = {
|
||||
# --- Топливо / тип двигателя ---
|
||||
"가솔린": "Gasoline",
|
||||
@@ -551,6 +801,21 @@ MODEL_TRANSLATIONS = {
|
||||
"그란투리스모": "GranTurismo",
|
||||
"반퀴시": "Vanquish",
|
||||
"밴티지": "Vantage",
|
||||
# --- Дополнительные модели, встреченные в данных Encar ---
|
||||
"시에라": "Sierra",
|
||||
"시빅": "Civic",
|
||||
"레인저": "Ranger",
|
||||
"콜레오스": "Koleos",
|
||||
"그랑 콜레오스": "Grand Koleos",
|
||||
"페이톤": "Phaeton",
|
||||
"티록": "T-Roc",
|
||||
"큐브": "Cube",
|
||||
"크라운": "Crown",
|
||||
"라이즈": "Rise",
|
||||
"시로코": "Scirocco",
|
||||
"이오스": "Eos",
|
||||
"비틀": "Beetle",
|
||||
"폴로": "Polo",
|
||||
# --- Служебные / категории ---
|
||||
"(세부등급": "(sub-trim",
|
||||
"없음)": "none)",
|
||||
|
||||
Reference in New Issue
Block a user