from time import perf_counter from urllib import error, request LATENCY_WARNING_MS = 500 REQUEST_TIMEOUT_SECONDS = 3 def make_status(status, message, latency_ms=None): return { 'status': status, 'latencyMs': latency_ms, 'message': message } def probe_url(url): started_at = perf_counter() req = request.Request( url, headers={'User-Agent': 'MusicWorkshop/0.1'}, method='GET' ) try: with request.urlopen(req, timeout=REQUEST_TIMEOUT_SECONDS) as response: status_code = response.status except error.HTTPError as exc: status_code = exc.code except (error.URLError, ValueError): return make_status('offline', '无法连接') latency_ms = max(1, round((perf_counter() - started_at) * 1000)) if 500 <= status_code: return make_status('offline', f'服务异常 (HTTP {status_code})') status = 'warning' if latency_ms >= LATENCY_WARNING_MS else 'online' message = ( f'高延迟 (HTTP {status_code})' if status == 'warning' else f'可达 (HTTP {status_code})' ) return make_status(status, message, latency_ms) def probe_metadata_services(metadata_config): services = { 'acoustid': { 'url': metadata_config['acoustidUrl'], 'required_credentials': [metadata_config['acoustidClientKey']] }, 'musicbrainz': { 'url': metadata_config['musicbrainz'] }, 'netease': { 'url': metadata_config['netease'] }, 'qq': { 'url': metadata_config['qq'] }, 'spotify': { 'url': metadata_config['spotifyUrl'], 'required_credentials': [ metadata_config['spotifyClientId'], metadata_config['spotifySecret'] ] }, 'discogs': { 'url': metadata_config['discogsUrl'], 'required_credentials': [metadata_config['discogsToken']] }, 'lastfm': { 'url': metadata_config['lastfmUrl'], 'required_credentials': [metadata_config['lastfmKey']] }, 'genius': { 'url': metadata_config['geniusUrl'], 'required_credentials': [metadata_config['geniusToken']] } } statuses = {} for service_name, service_config in services.items(): credentials = service_config.get('required_credentials', []) if credentials and not all(value.strip() for value in credentials): statuses[service_name] = make_status('none', '缺失凭据,跳过测试') continue url = service_config['url'].strip() if not url: statuses[service_name] = make_status('none', '未配置地址,跳过测试') continue statuses[service_name] = probe_url(url) return statuses