Files
submanager/lib/services/subscription_url_matcher.dart
2025-09-07 19:33:11 +09:00

111 lines
3.9 KiB
Dart

// ServiceInfo를 외부에서 접근 가능하도록 export
export 'url_matcher/models/service_info.dart';
import 'url_matcher/models/service_info.dart';
import 'url_matcher/data/service_data_repository.dart';
import 'url_matcher/services/url_matcher_service.dart';
import 'url_matcher/services/category_mapper_service.dart';
import 'url_matcher/services/cancellation_url_service.dart';
import 'url_matcher/services/service_name_resolver.dart';
import 'url_matcher/services/sms_extractor_service.dart';
/// 구독 서비스와 웹사이트 URL 매칭을 처리하는 서비스 클래스 (Facade 패턴)
class SubscriptionUrlMatcher {
static ServiceDataRepository? _dataRepository;
static UrlMatcherService? _urlMatcher;
static CategoryMapperService? _categoryMapper;
static CancellationUrlService? _cancellationService;
static ServiceNameResolver? _nameResolver;
static SmsExtractorService? _smsExtractor;
/// 서비스 초기화
static Future<void> initialize() async {
if (_dataRepository != null && _dataRepository!.isInitialized) return;
// 1. 데이터 저장소 초기화
_dataRepository = ServiceDataRepository();
await _dataRepository!.initialize();
// 2. 서비스 초기화
_categoryMapper = CategoryMapperService(_dataRepository!);
_urlMatcher = UrlMatcherService(_dataRepository!, _categoryMapper!);
_cancellationService =
CancellationUrlService(_dataRepository!, _urlMatcher!);
_nameResolver = ServiceNameResolver(_dataRepository!);
_smsExtractor = SmsExtractorService(_urlMatcher!, _categoryMapper!);
}
/// 도메인 추출 (www와 TLD 제외)
static String? extractDomain(String url) {
return _urlMatcher?.extractDomain(url);
}
/// URL로 서비스 찾기
static Future<ServiceInfo?> findServiceByUrl(String url) async {
await initialize();
return _urlMatcher?.findServiceByUrl(url);
}
/// 서비스명으로 URL 찾기 (기존 suggestUrl 메서드 유지)
static String? suggestUrl(String serviceName) {
return _urlMatcher?.suggestUrl(serviceName);
}
/// 서비스명 또는 URL로 해지 안내 페이지 URL 찾기
static Future<String?> findCancellationUrl({
String? serviceName,
String? websiteUrl,
String locale = 'kr',
}) async {
await initialize();
return _cancellationService?.findCancellationUrl(
serviceName: serviceName,
websiteUrl: websiteUrl,
locale: locale,
);
}
/// 서비스에 공식 해지 안내 페이지가 있는지 확인
static Future<bool> hasCancellationPage(String serviceNameOrUrl) async {
await initialize();
return await _cancellationService?.hasCancellationPage(serviceNameOrUrl) ??
false;
}
/// 서비스명으로 카테고리 찾기
static Future<String?> findCategoryByServiceName(String serviceName) async {
await initialize();
return _categoryMapper?.findCategoryByServiceName(serviceName);
}
/// 현재 로케일에 따라 서비스 표시명 가져오기
static Future<String> getServiceDisplayName({
required String serviceName,
required String locale,
}) async {
await initialize();
return await _nameResolver?.getServiceDisplayName(
serviceName: serviceName,
locale: locale,
) ??
serviceName;
}
/// SMS에서 URL과 서비스 정보 추출
static Future<ServiceInfo?> extractServiceFromSms(String smsText) async {
await initialize();
return _smsExtractor?.extractServiceFromSms(smsText);
}
/// URL이 알려진 서비스 URL인지 확인
static Future<bool> isKnownServiceUrl(String url) async {
await initialize();
return await _urlMatcher?.isKnownServiceUrl(url) ?? false;
}
/// 입력된 서비스 이름이나 문자열에서 매칭되는 URL을 찾아 반환 (레거시 호환성)
static String? findMatchingUrl(String text, {bool usePartialMatch = true}) {
return _urlMatcher?.findMatchingUrl(text, usePartialMatch: usePartialMatch);
}
}