feat(app): add manual entry and sharing flows
This commit is contained in:
@@ -5,37 +5,234 @@ import 'package:flutter/foundation.dart';
|
||||
class NaverHtmlExtractor {
|
||||
// 제외할 UI 텍스트 패턴 (확장)
|
||||
static const List<String> _excludePatterns = [
|
||||
'로그인', '메뉴', '검색', '지도', '리뷰', '사진', '네이버', '영업시간',
|
||||
'전화번호', '주소', '찾아오시는길', '예약', '홈', '이용약관', '개인정보',
|
||||
'고객센터', '신고', '공유', '즐겨찾기', '길찾기', '거리뷰', '저장',
|
||||
'더보기', '접기', '펼치기', '닫기', '취소', '확인', '선택', '전체', '삭제',
|
||||
'플레이스', '지도보기', '상세보기', '평점', '별점', '추천', '인기', '최신',
|
||||
'오늘', '내일', '영업중', '영업종료', '휴무', '정기휴무', '임시휴무',
|
||||
'배달', '포장', '매장', '주차', '단체석', '예약가능', '대기', '웨이팅',
|
||||
'영수증', '현금', '카드', '계산서', '할인', '쿠폰', '적립', '포인트',
|
||||
'회원', '비회원', '로그아웃', '마이페이지', '알림', '설정', '도움말',
|
||||
'문의', '제보', '수정', '삭제', '등록', '작성', '댓글', '답글', '좋아요',
|
||||
'싫어요', '스크랩', '북마크', '태그', '해시태그', '팔로우', '팔로잉',
|
||||
'팔로워', '차단', '신고하기', '게시물', '프로필', '활동', '통계', '분석',
|
||||
'다운로드', '업로드', '첨부', '파일', '이미지', '동영상', '음성', '링크',
|
||||
'복사', '붙여넣기', '되돌리기', '다시실행', '새로고침', '뒤로', '앞으로',
|
||||
'시작', '종료', '일시정지', '재생', '정지', '음량', '화면', '전체화면',
|
||||
'최소화', '최대화', '창닫기', '새창', '새탭', '인쇄', '저장하기', '열기',
|
||||
'가져오기', '내보내기', '동기화', '백업', '복원', '초기화', '재설정',
|
||||
'업데이트', '버전', '정보', '소개', '안내', '공지', '이벤트', '혜택',
|
||||
'쿠키', '개인정보처리방침', '서비스이용약관', '위치정보이용약관',
|
||||
'청소년보호정책', '저작권', '라이선스', '제휴', '광고', '비즈니스',
|
||||
'개발자', 'API', '오픈소스', '기여', '후원', '기부', '결제', '환불',
|
||||
'교환', '반품', '배송', '택배', '운송장', '추적', '도착', '출발',
|
||||
'네이버 지도', '카카오맵', '구글맵', 'T맵', '지도 앱', '내비게이션',
|
||||
'경로', '소요시간', '거리', '도보', '자전거', '대중교통', '자동차',
|
||||
'지하철', '버스', '택시', '기차', '비행기', '선박', '도보', '환승',
|
||||
'출구', '입구', '승강장', '매표소', '화장실', '편의시설', '주차장',
|
||||
'엘리베이터', '에스컬레이터', '계단', '경사로', '점자블록', '휠체어',
|
||||
'유모차', '애완동물', '흡연', '금연', '와이파이', '콘센트', '충전',
|
||||
'PC', '프린터', '팩스', '복사기', '회의실', '세미나실', '강당', '공연장',
|
||||
'전시장', '박물관', '미술관', '도서관', '체육관', '수영장', '운동장',
|
||||
'놀이터', '공원', '산책로', '자전거도로', '등산로', '캠핑장', '낚시터'
|
||||
'로그인',
|
||||
'메뉴',
|
||||
'검색',
|
||||
'지도',
|
||||
'리뷰',
|
||||
'사진',
|
||||
'네이버',
|
||||
'영업시간',
|
||||
'전화번호',
|
||||
'주소',
|
||||
'찾아오시는길',
|
||||
'예약',
|
||||
'홈',
|
||||
'이용약관',
|
||||
'개인정보',
|
||||
'고객센터',
|
||||
'신고',
|
||||
'공유',
|
||||
'즐겨찾기',
|
||||
'길찾기',
|
||||
'거리뷰',
|
||||
'저장',
|
||||
'더보기',
|
||||
'접기',
|
||||
'펼치기',
|
||||
'닫기',
|
||||
'취소',
|
||||
'확인',
|
||||
'선택',
|
||||
'전체',
|
||||
'삭제',
|
||||
'플레이스',
|
||||
'지도보기',
|
||||
'상세보기',
|
||||
'평점',
|
||||
'별점',
|
||||
'추천',
|
||||
'인기',
|
||||
'최신',
|
||||
'오늘',
|
||||
'내일',
|
||||
'영업중',
|
||||
'영업종료',
|
||||
'휴무',
|
||||
'정기휴무',
|
||||
'임시휴무',
|
||||
'배달',
|
||||
'포장',
|
||||
'매장',
|
||||
'주차',
|
||||
'단체석',
|
||||
'예약가능',
|
||||
'대기',
|
||||
'웨이팅',
|
||||
'영수증',
|
||||
'현금',
|
||||
'카드',
|
||||
'계산서',
|
||||
'할인',
|
||||
'쿠폰',
|
||||
'적립',
|
||||
'포인트',
|
||||
'회원',
|
||||
'비회원',
|
||||
'로그아웃',
|
||||
'마이페이지',
|
||||
'알림',
|
||||
'설정',
|
||||
'도움말',
|
||||
'문의',
|
||||
'제보',
|
||||
'수정',
|
||||
'삭제',
|
||||
'등록',
|
||||
'작성',
|
||||
'댓글',
|
||||
'답글',
|
||||
'좋아요',
|
||||
'싫어요',
|
||||
'스크랩',
|
||||
'북마크',
|
||||
'태그',
|
||||
'해시태그',
|
||||
'팔로우',
|
||||
'팔로잉',
|
||||
'팔로워',
|
||||
'차단',
|
||||
'신고하기',
|
||||
'게시물',
|
||||
'프로필',
|
||||
'활동',
|
||||
'통계',
|
||||
'분석',
|
||||
'다운로드',
|
||||
'업로드',
|
||||
'첨부',
|
||||
'파일',
|
||||
'이미지',
|
||||
'동영상',
|
||||
'음성',
|
||||
'링크',
|
||||
'복사',
|
||||
'붙여넣기',
|
||||
'되돌리기',
|
||||
'다시실행',
|
||||
'새로고침',
|
||||
'뒤로',
|
||||
'앞으로',
|
||||
'시작',
|
||||
'종료',
|
||||
'일시정지',
|
||||
'재생',
|
||||
'정지',
|
||||
'음량',
|
||||
'화면',
|
||||
'전체화면',
|
||||
'최소화',
|
||||
'최대화',
|
||||
'창닫기',
|
||||
'새창',
|
||||
'새탭',
|
||||
'인쇄',
|
||||
'저장하기',
|
||||
'열기',
|
||||
'가져오기',
|
||||
'내보내기',
|
||||
'동기화',
|
||||
'백업',
|
||||
'복원',
|
||||
'초기화',
|
||||
'재설정',
|
||||
'업데이트',
|
||||
'버전',
|
||||
'정보',
|
||||
'소개',
|
||||
'안내',
|
||||
'공지',
|
||||
'이벤트',
|
||||
'혜택',
|
||||
'쿠키',
|
||||
'개인정보처리방침',
|
||||
'서비스이용약관',
|
||||
'위치정보이용약관',
|
||||
'청소년보호정책',
|
||||
'저작권',
|
||||
'라이선스',
|
||||
'제휴',
|
||||
'광고',
|
||||
'비즈니스',
|
||||
'개발자',
|
||||
'API',
|
||||
'오픈소스',
|
||||
'기여',
|
||||
'후원',
|
||||
'기부',
|
||||
'결제',
|
||||
'환불',
|
||||
'교환',
|
||||
'반품',
|
||||
'배송',
|
||||
'택배',
|
||||
'운송장',
|
||||
'추적',
|
||||
'도착',
|
||||
'출발',
|
||||
'네이버 지도',
|
||||
'카카오맵',
|
||||
'구글맵',
|
||||
'T맵',
|
||||
'지도 앱',
|
||||
'내비게이션',
|
||||
'경로',
|
||||
'소요시간',
|
||||
'거리',
|
||||
'도보',
|
||||
'자전거',
|
||||
'대중교통',
|
||||
'자동차',
|
||||
'지하철',
|
||||
'버스',
|
||||
'택시',
|
||||
'기차',
|
||||
'비행기',
|
||||
'선박',
|
||||
'도보',
|
||||
'환승',
|
||||
'출구',
|
||||
'입구',
|
||||
'승강장',
|
||||
'매표소',
|
||||
'화장실',
|
||||
'편의시설',
|
||||
'주차장',
|
||||
'엘리베이터',
|
||||
'에스컬레이터',
|
||||
'계단',
|
||||
'경사로',
|
||||
'점자블록',
|
||||
'휠체어',
|
||||
'유모차',
|
||||
'애완동물',
|
||||
'흡연',
|
||||
'금연',
|
||||
'와이파이',
|
||||
'콘센트',
|
||||
'충전',
|
||||
'PC',
|
||||
'프린터',
|
||||
'팩스',
|
||||
'복사기',
|
||||
'회의실',
|
||||
'세미나실',
|
||||
'강당',
|
||||
'공연장',
|
||||
'전시장',
|
||||
'박물관',
|
||||
'미술관',
|
||||
'도서관',
|
||||
'체육관',
|
||||
'수영장',
|
||||
'운동장',
|
||||
'놀이터',
|
||||
'공원',
|
||||
'산책로',
|
||||
'자전거도로',
|
||||
'등산로',
|
||||
'캠핑장',
|
||||
'낚시터',
|
||||
];
|
||||
|
||||
/// HTML에서 유효한 한글 텍스트 추출 (UI 텍스트 제외)
|
||||
@@ -52,21 +249,35 @@ class NaverHtmlExtractor {
|
||||
|
||||
// 특정 태그의 내용만 추출 (제목, 본문 등 중요 텍스트가 있을 가능성이 높은 태그)
|
||||
final contentTags = [
|
||||
'h1', 'h2', 'h3', 'h4', 'h5', 'h6',
|
||||
'p', 'span', 'div', 'li', 'td', 'th',
|
||||
'strong', 'em', 'b', 'i', 'a'
|
||||
'h1',
|
||||
'h2',
|
||||
'h3',
|
||||
'h4',
|
||||
'h5',
|
||||
'h6',
|
||||
'p',
|
||||
'span',
|
||||
'div',
|
||||
'li',
|
||||
'td',
|
||||
'th',
|
||||
'strong',
|
||||
'em',
|
||||
'b',
|
||||
'i',
|
||||
'a',
|
||||
];
|
||||
|
||||
final tagPattern = contentTags.map((tag) =>
|
||||
'<$tag[^>]*>([^<]+)</$tag>'
|
||||
).join('|');
|
||||
final tagPattern = contentTags
|
||||
.map((tag) => '<$tag[^>]*>([^<]+)</$tag>')
|
||||
.join('|');
|
||||
|
||||
final tagRegex = RegExp(tagPattern, multiLine: true, caseSensitive: false);
|
||||
final tagMatches = tagRegex.allMatches(cleanHtml);
|
||||
|
||||
// 추출된 텍스트 수집
|
||||
final extractedTexts = <String>[];
|
||||
|
||||
|
||||
for (final match in tagMatches) {
|
||||
final text = match.group(1)?.trim() ?? '';
|
||||
if (text.isNotEmpty && text.contains(RegExp(r'[가-힣]'))) {
|
||||
@@ -77,11 +288,11 @@ class NaverHtmlExtractor {
|
||||
// 모든 태그 제거 후 남은 텍스트도 추가
|
||||
final textOnly = cleanHtml.replaceAll(RegExp(r'<[^>]+>'), ' ');
|
||||
final cleanedText = textOnly.replaceAll(RegExp(r'\s+'), ' ').trim();
|
||||
|
||||
|
||||
// 한글 텍스트 추출
|
||||
final koreanPattern = RegExp(r'[가-힣]+(?:\s[가-힣]+)*');
|
||||
final koreanMatches = koreanPattern.allMatches(cleanedText);
|
||||
|
||||
|
||||
for (final match in koreanMatches) {
|
||||
final text = match.group(0)?.trim() ?? '';
|
||||
if (text.length >= 2) {
|
||||
@@ -91,17 +302,19 @@ class NaverHtmlExtractor {
|
||||
|
||||
// 중복 제거 및 필터링
|
||||
final uniqueTexts = <String>{};
|
||||
|
||||
|
||||
for (final text in extractedTexts) {
|
||||
// UI 패턴 제외
|
||||
bool isExcluded = false;
|
||||
for (final pattern in _excludePatterns) {
|
||||
if (text == pattern || text.startsWith(pattern) || text.endsWith(pattern)) {
|
||||
if (text == pattern ||
|
||||
text.startsWith(pattern) ||
|
||||
text.endsWith(pattern)) {
|
||||
isExcluded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!isExcluded && text.length >= 2 && text.length <= 50) {
|
||||
uniqueTexts.add(text);
|
||||
}
|
||||
@@ -109,13 +322,13 @@ class NaverHtmlExtractor {
|
||||
|
||||
// 리스트로 변환하여 반환
|
||||
final resultList = uniqueTexts.toList();
|
||||
|
||||
|
||||
debugPrint('========== 유효한 한글 텍스트 추출 결과 ==========');
|
||||
for (int i = 0; i < resultList.length; i++) {
|
||||
debugPrint('[$i] ${resultList[i]}');
|
||||
}
|
||||
debugPrint('========== 총 ${resultList.length}개 추출됨 ==========');
|
||||
|
||||
|
||||
return resultList;
|
||||
}
|
||||
|
||||
@@ -217,7 +430,7 @@ class NaverHtmlExtractor {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/// HTML에서 Place URL 추출 (og:url 메타 태그)
|
||||
static String? extractPlaceLink(String html) {
|
||||
try {
|
||||
@@ -232,7 +445,7 @@ class NaverHtmlExtractor {
|
||||
debugPrint('NaverHtmlExtractor: og:url 추출 - $url');
|
||||
return url;
|
||||
}
|
||||
|
||||
|
||||
// canonical 링크 태그에서 추출
|
||||
final canonicalRegex = RegExp(
|
||||
r'<link[^>]+rel="canonical"[^>]+href="([^"]+)"',
|
||||
@@ -247,7 +460,7 @@ class NaverHtmlExtractor {
|
||||
} catch (e) {
|
||||
debugPrint('NaverHtmlExtractor: Place Link 추출 실패 - $e');
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user