25.09.06
parent
5972366cae
commit
a92dd232ee
|
@ -33,7 +33,7 @@ async def get_favicon(
|
||||||
bg_tasks: BackgroundTasks,
|
bg_tasks: BackgroundTasks,
|
||||||
url: Optional[str] = Query(None, description="网址:eg. https://www.baidu.com"),
|
url: Optional[str] = Query(None, description="网址:eg. https://www.baidu.com"),
|
||||||
refresh: Optional[str] = Query(None, include_in_schema=False),
|
refresh: Optional[str] = Query(None, include_in_schema=False),
|
||||||
sync: Optional[str] = Query('true', description="是否使用同步方式获取")
|
sync: Optional[str] = Query('false', description="是否使用同步方式获取")
|
||||||
):
|
):
|
||||||
"""获取网站图标"""
|
"""获取网站图标"""
|
||||||
return await _service.get_favicon_handler(request, bg_tasks, url, refresh, sync)
|
return await _service.get_favicon_handler(request, bg_tasks, url, refresh, sync)
|
||||||
|
|
|
@ -37,9 +37,6 @@ class FaviconService:
|
||||||
"""图标服务类,封装所有与图标获取、缓存和处理相关的功能"""
|
"""图标服务类,封装所有与图标获取、缓存和处理相关的功能"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
# 使用锁保证线程安全
|
|
||||||
self._lock = Lock()
|
|
||||||
|
|
||||||
# 全局计数器和集合
|
# 全局计数器和集合
|
||||||
self.url_count = 0
|
self.url_count = 0
|
||||||
self.request_icon_count = 0
|
self.request_icon_count = 0
|
||||||
|
@ -274,7 +271,6 @@ class FaviconService:
|
||||||
icon_content = None
|
icon_content = None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with self._lock:
|
|
||||||
if entity.domain in self.domain_list:
|
if entity.domain in self.domain_list:
|
||||||
self._queue_pull(True, self.total_queue)
|
self._queue_pull(True, self.total_queue)
|
||||||
return _cached or default_icon_content
|
return _cached or default_icon_content
|
||||||
|
@ -333,7 +329,6 @@ class FaviconService:
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"写入缓存文件失败: {e}")
|
logger.error(f"写入缓存文件失败: {e}")
|
||||||
|
|
||||||
with self._lock:
|
|
||||||
self.request_icon_count += 1
|
self.request_icon_count += 1
|
||||||
|
|
||||||
return icon_content
|
return icon_content
|
||||||
|
@ -341,7 +336,6 @@ class FaviconService:
|
||||||
logger.error(f"获取图标时发生错误 {entity.domain}: {e}")
|
logger.error(f"获取图标时发生错误 {entity.domain}: {e}")
|
||||||
return _cached or default_icon_content
|
return _cached or default_icon_content
|
||||||
finally:
|
finally:
|
||||||
with self._lock:
|
|
||||||
if entity.domain in self.domain_list:
|
if entity.domain in self.domain_list:
|
||||||
self.domain_list.remove(entity.domain)
|
self.domain_list.remove(entity.domain)
|
||||||
# 任务完成,从两个队列中移出元素
|
# 任务完成,从两个队列中移出元素
|
||||||
|
@ -350,7 +344,6 @@ class FaviconService:
|
||||||
|
|
||||||
def get_count(self) -> Dict[str, int]:
|
def get_count(self) -> Dict[str, int]:
|
||||||
"""获取统计数据"""
|
"""获取统计数据"""
|
||||||
with self._lock:
|
|
||||||
return {
|
return {
|
||||||
'url_count': self.url_count,
|
'url_count': self.url_count,
|
||||||
'request_icon_count': self.request_icon_count,
|
'request_icon_count': self.request_icon_count,
|
||||||
|
@ -369,9 +362,8 @@ class FaviconService:
|
||||||
) -> dict[str, str] | Response:
|
) -> dict[str, str] | Response:
|
||||||
"""处理获取图标的请求"""
|
"""处理获取图标的请求"""
|
||||||
|
|
||||||
logger.info(f"队列大小:{self.icon_queue.qsize()} | {self.total_queue.qsize()}")
|
logger.info(f"队列大小:{self.icon_queue.qsize()} | {self.total_queue.qsize()} | {len(favicon.failed_urls)}")
|
||||||
|
|
||||||
with self._lock:
|
|
||||||
self.url_count += 1
|
self.url_count += 1
|
||||||
|
|
||||||
# 验证URL参数
|
# 验证URL参数
|
||||||
|
@ -387,7 +379,6 @@ class FaviconService:
|
||||||
return self.get_default(self.time_of_7_days)
|
return self.get_default(self.time_of_7_days)
|
||||||
|
|
||||||
# 检查内存缓存中的失败URL
|
# 检查内存缓存中的失败URL
|
||||||
with self._lock:
|
|
||||||
if entity.domain in favicon.failed_urls:
|
if entity.domain in favicon.failed_urls:
|
||||||
_expire_time = favicon.failed_urls[entity.domain]
|
_expire_time = favicon.failed_urls[entity.domain]
|
||||||
if int(time.time()) <= _expire_time:
|
if int(time.time()) <= _expire_time:
|
||||||
|
@ -401,12 +392,11 @@ class FaviconService:
|
||||||
if cached_icon:
|
if cached_icon:
|
||||||
# 使用缓存图标
|
# 使用缓存图标
|
||||||
icon_content = cached_icon
|
icon_content = cached_icon
|
||||||
with self._lock:
|
|
||||||
self.request_cache_count += 1
|
self.request_cache_count += 1
|
||||||
|
|
||||||
# 确定内容类型和缓存时间
|
# 确定内容类型和缓存时间
|
||||||
content_type = filetype.guess_mime(icon_content) if icon_content else ""
|
content_type = filetype.guess_mime(icon_content) if icon_content else ""
|
||||||
cache_time = self.time_of_1_hours * random.randint(1, 6) if self._is_default_icon_byte(icon_content) else self.time_of_7_days
|
cache_time = self.time_of_12_hours if self._is_default_icon_byte(icon_content) else self.time_of_7_days
|
||||||
|
|
||||||
# 乐观缓存机制:检查缓存是否已过期但仍有缓存内容
|
# 乐观缓存机制:检查缓存是否已过期但仍有缓存内容
|
||||||
# _cached 存在但 cached_icon 为 None 表示缓存已过期
|
# _cached 存在但 cached_icon 为 None 表示缓存已过期
|
||||||
|
@ -422,10 +412,10 @@ class FaviconService:
|
||||||
media_type=content_type if content_type else "image/x-icon",
|
media_type=content_type if content_type else "image/x-icon",
|
||||||
headers=self._get_header(content_type, cache_time))
|
headers=self._get_header(content_type, cache_time))
|
||||||
else:
|
else:
|
||||||
|
_referrer = request.headers.get('referrer') or request.headers.get('referer')
|
||||||
# 检查sync参数
|
# 检查sync参数
|
||||||
is_sync = sync in ['true', '1', 'True']
|
is_sync = sync in ['true', '1', 'True']
|
||||||
|
if (not is_sync) or (_referrer and not _referrer.startswith('https://api.xinac.net')):
|
||||||
if not is_sync:
|
|
||||||
# 返回默认图片并加入后台队列
|
# 返回默认图片并加入后台队列
|
||||||
logger.info(f"返回默认图片并加入后台队列: {entity.domain}")
|
logger.info(f"返回默认图片并加入后台队列: {entity.domain}")
|
||||||
# 开始图标处理,加入两个队列
|
# 开始图标处理,加入两个队列
|
||||||
|
@ -458,7 +448,7 @@ class FaviconService:
|
||||||
|
|
||||||
# 确定内容类型和缓存时间
|
# 确定内容类型和缓存时间
|
||||||
content_type = filetype.guess_mime(icon_content) if icon_content else ""
|
content_type = filetype.guess_mime(icon_content) if icon_content else ""
|
||||||
cache_time = self.time_of_1_hours * random.randint(1, 6) if self._is_default_icon_byte(icon_content) else self.time_of_7_days
|
cache_time = self.time_of_12_hours if self._is_default_icon_byte(icon_content) else self.time_of_7_days
|
||||||
|
|
||||||
return Response(content=icon_content,
|
return Response(content=icon_content,
|
||||||
media_type=content_type if content_type else "image/x-icon",
|
media_type=content_type if content_type else "image/x-icon",
|
||||||
|
|
Loading…
Reference in New Issue