feat(app): add manual entry and sharing flows

This commit is contained in:
JiWoong Sul
2025-11-19 16:36:39 +09:00
parent 5ade584370
commit 947fe59486
110 changed files with 5937 additions and 3781 deletions

View File

@@ -2,7 +2,7 @@ import 'package:html/dom.dart';
import 'package:flutter/foundation.dart';
/// 네이버 지도 HTML 파서
///
///
/// 네이버 지도 페이지의 HTML에서 식당 정보를 추출합니다.
class NaverHtmlParser {
// CSS 셀렉터 상수
@@ -13,38 +13,38 @@ class NaverHtmlParser {
'[class*="place_name"]',
'meta[property="og:title"]',
];
static const List<String> _categorySelectors = [
'span.DJJvD',
'span.lnJFt',
'[class*="category"]',
];
static const List<String> _descriptionSelectors = [
'span.IH7VW',
'div.vV_z_',
'meta[name="description"]',
];
static const List<String> _phoneSelectors = [
'span.xlx7Q',
'a[href^="tel:"]',
'[class*="phone"]',
];
static const List<String> _addressSelectors = [
'span.IH7VW',
'span.jWDO_',
'[class*="address"]',
];
static const List<String> _businessHoursSelectors = [
'time.aT6WB',
'div.O8qbU',
'[class*="business"]',
'[class*="hours"]',
];
/// HTML 문서에서 식당 정보 추출
Map<String, dynamic> parseRestaurantInfo(Document document) {
return {
@@ -60,7 +60,7 @@ class NaverHtmlParser {
'businessHours': extractBusinessHours(document),
};
}
/// 식당 이름 추출
String? extractName(Document document) {
try {
@@ -82,7 +82,7 @@ class NaverHtmlParser {
return null;
}
}
/// 카테고리 추출
String? extractCategory(Document document) {
try {
@@ -102,7 +102,7 @@ class NaverHtmlParser {
return null;
}
}
/// 서브 카테고리 추출
String? extractSubCategory(Document document) {
try {
@@ -120,7 +120,7 @@ class NaverHtmlParser {
return null;
}
}
/// 설명 추출
String? extractDescription(Document document) {
try {
@@ -142,7 +142,7 @@ class NaverHtmlParser {
return null;
}
}
/// 전화번호 추출
String? extractPhoneNumber(Document document) {
try {
@@ -164,7 +164,7 @@ class NaverHtmlParser {
return null;
}
}
/// 도로명 주소 추출
String? extractRoadAddress(Document document) {
try {
@@ -184,7 +184,7 @@ class NaverHtmlParser {
return null;
}
}
/// 지번 주소 추출
String? extractJibunAddress(Document document) {
try {
@@ -193,8 +193,8 @@ class NaverHtmlParser {
for (final element in elements) {
final text = element.text.trim();
// 지번 주소 패턴 확인 (숫자-숫자 형식 포함)
if (RegExp(r'\d+\-\d+').hasMatch(text) &&
!text.contains('') &&
if (RegExp(r'\d+\-\d+').hasMatch(text) &&
!text.contains('') &&
!text.contains('')) {
return text;
}
@@ -206,7 +206,7 @@ class NaverHtmlParser {
return null;
}
}
/// 위도 추출
double? extractLatitude(Document document) {
try {
@@ -223,7 +223,7 @@ class NaverHtmlParser {
}
}
}
// 자바스크립트 변수에서 추출 시도
final scripts = document.querySelectorAll('script');
for (final script in scripts) {
@@ -236,14 +236,14 @@ class NaverHtmlParser {
}
}
}
return null;
} catch (e) {
debugPrint('NaverHtmlParser: 위도 추출 실패 - $e');
return null;
}
}
/// 경도 추출
double? extractLongitude(Document document) {
try {
@@ -260,7 +260,7 @@ class NaverHtmlParser {
}
}
}
// 자바스크립트 변수에서 추출 시도
final scripts = document.querySelectorAll('script');
for (final script in scripts) {
@@ -273,14 +273,14 @@ class NaverHtmlParser {
}
}
}
return null;
} catch (e) {
debugPrint('NaverHtmlParser: 경도 추출 실패 - $e');
return null;
}
}
/// 영업시간 추출
String? extractBusinessHours(Document document) {
try {
@@ -288,10 +288,10 @@ class NaverHtmlParser {
final elements = document.querySelectorAll(selector);
for (final element in elements) {
final text = element.text.trim();
if (text.isNotEmpty &&
(text.contains('') ||
text.contains(':') ||
text.contains('영업'))) {
if (text.isNotEmpty &&
(text.contains('') ||
text.contains(':') ||
text.contains('영업'))) {
return text;
}
}
@@ -302,4 +302,4 @@ class NaverHtmlParser {
return null;
}
}
}
}