From 7d610ecfdc42f1d233a8ec30b2e993f449bcc6bb Mon Sep 17 00:00:00 2001 From: John Smith Date: Tue, 4 Feb 2020 16:12:16 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=8E=B7=E5=8F=96=E5=A4=B4?= =?UTF-8?q?=E5=83=8Ffuture=E6=B2=A1=E6=9C=89=E8=AE=BE=E7=BD=AE=E7=BB=93?= =?UTF-8?q?=E6=9E=9C=E7=9A=84=E9=97=AE=E9=A2=98=E3=80=81=E9=83=A8=E5=88=86?= =?UTF-8?q?=E5=A4=B4=E5=83=8FURL=E6=B2=A1=E6=9C=89=E5=A4=84=E7=90=86?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/chat.py | 4 ++-- models/avatar.py | 35 ++++++++++++++++++++++++----------- 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/api/chat.py b/api/chat.py index 5499f06..abf1ad2 100644 --- a/api/chat.py +++ b/api/chat.py @@ -136,7 +136,7 @@ class Room(blivedm.BLiveClient): }) async def _on_receive_gift(self, gift: blivedm.GiftMessage): - avatar_url = gift.face.replace('http:', '').replace('https:', '') + avatar_url = models.avatar.process_avatar_url(gift.face) models.avatar.update_avatar_cache(gift.uid, avatar_url) if gift.coin_type != 'gold': # 丢人 return @@ -160,7 +160,7 @@ class Room(blivedm.BLiveClient): }) async def _on_super_chat(self, message: blivedm.SuperChatMessage): - avatar_url = message.face.replace('http:', '').replace('https:', '') + avatar_url = models.avatar.process_avatar_url(message.face) models.avatar.update_avatar_cache(message.uid, avatar_url) self.send_message(Command.ADD_SUPER_CHAT, { 'avatarUrl': avatar_url, diff --git a/models/avatar.py b/models/avatar.py index 2d6d529..68937c1 100644 --- a/models/avatar.py +++ b/models/avatar.py @@ -3,6 +3,7 @@ import asyncio import datetime import logging +import re from typing import * import aiohttp @@ -36,7 +37,10 @@ async def get_avatar_url(user_id): avatar_url = await get_avatar_url_from_database(user_id) if avatar_url is not None: return avatar_url - return await get_avatar_url_from_web(user_id) + avatar_url = await get_avatar_url_from_web(user_id) + if avatar_url is not None: + return avatar_url + return DEFAULT_AVATAR_URL def get_avatar_url_from_memory(user_id): @@ -79,12 +83,12 @@ def _do_get_avatar_url_from_database(user_id): return avatar_url -def get_avatar_url_from_web(user_id) -> Awaitable[str]: +def get_avatar_url_from_web(user_id) -> Awaitable[Optional[str]]: future = _main_event_loop.create_future() try: _fetch_task_queue.put_nowait((user_id, future)) except asyncio.QueueFull: - future.set_result(DEFAULT_AVATAR_URL) + future.set_result(None) return future @@ -96,6 +100,7 @@ async def _get_avatar_url_from_web_consumer(): # 先查缓存,防止队列中出现相同uid时重复获取 avatar_url = get_avatar_url_from_memory(user_id) if avatar_url is not None: + future.set_result(avatar_url) continue # 防止在被ban的时候获取 @@ -103,8 +108,8 @@ async def _get_avatar_url_from_web_consumer(): if _last_fetch_failed_time is not None: cur_time = datetime.datetime.now() if (cur_time - _last_fetch_failed_time).total_seconds() < 3 * 60 + 3: - # 3分钟以内被ban则先返回默认头像,解封大约要15分钟 - future.set_result(DEFAULT_AVATAR_URL) + # 3分钟以内被ban,解封大约要15分钟 + future.set_result(None) continue else: _last_fetch_failed_time = None @@ -114,7 +119,7 @@ async def _get_avatar_url_from_web_consumer(): # 限制频率,防止被B站ban await asyncio.sleep(0.2) except: - pass + logger.exception('_get_avatar_url_from_web_consumer error:') async def _get_avatar_url_from_web_coroutine(user_id, future): @@ -136,16 +141,24 @@ async def _do_get_avatar_url_from_web(user_id): # 被B站ban了 global _last_fetch_failed_time _last_fetch_failed_time = datetime.datetime.now() - return DEFAULT_AVATAR_URL + return None data = await r.json() except (aiohttp.ClientConnectionError, asyncio.TimeoutError): - return DEFAULT_AVATAR_URL + return None - avatar_url = data['data']['face'].replace('http:', '').replace('https:', '') + avatar_url = process_avatar_url(data['data']['face']) + update_avatar_cache(user_id, avatar_url) + return avatar_url + + +def process_avatar_url(avatar_url): + # 去掉协议,兼容HTTP、HTTPS + m = re.fullmatch(r'(?:https?:)?(.*)', avatar_url) + if m is not None: + avatar_url = m[1] + # 缩小图片加快传输 if not avatar_url.endswith('noface.gif'): avatar_url += '@48w_48h' - - update_avatar_cache(user_id, avatar_url) return avatar_url