PamGram/core/cookies/services.py

100 lines
4.6 KiB
Python
Raw Normal View History

2022-08-04 13:19:17 +00:00
from typing import List
import genshin
from genshin import types, InvalidCookies, TooManyRequests, GenshinException
from logger import Log
from models.base import RegionEnum
2022-08-04 13:19:17 +00:00
from .cache import PublicCookiesCache
from .models import CookiesStatusEnum
from .repositories import CookiesRepository, CookiesNotFoundError
2022-07-26 10:07:31 +00:00
class CookiesService:
def __init__(self, cookies_repository: CookiesRepository) -> None:
self._repository: CookiesRepository = cookies_repository
2022-07-26 10:07:31 +00:00
async def update_cookies(self, user_id: int, cookies: dict, region: RegionEnum):
await self._repository.update_cookies(user_id, cookies, region)
2022-07-26 10:07:31 +00:00
async def add_cookies(self, user_id: int, cookies: dict, region: RegionEnum):
await self._repository.add_cookies(user_id, cookies, region)
async def get_cookies(self, user_id: int, region: RegionEnum):
return await self._repository.get_cookies(user_id, region)
2022-07-26 10:07:31 +00:00
2022-08-04 13:19:17 +00:00
class PublicCookiesService:
def __init__(self, cookies_repository: CookiesRepository, public_cookies_cache: PublicCookiesCache):
self._cache = public_cookies_cache
self._repository: CookiesRepository = cookies_repository
self.count: int = 0
async def refresh(self):
"""刷新公共Cookies 定时任务
:return:
"""
user_list: List[int] = []
cookies_list = await self._repository.get_all_cookies(RegionEnum.HYPERION) # 从数据库获取2
for cookies in cookies_list:
if cookies.status is not None and cookies.status != CookiesStatusEnum.STATUS_SUCCESS:
continue
user_list.append(cookies.user_id)
add, count = await self._cache.add(user_list, RegionEnum.HYPERION)
Log.info(f"国服公共Cookies池已经添加[{add}]个 当前成员数为[{count}]")
user_list.clear()
cookies_list = await self._repository.get_all_cookies(RegionEnum.HOYOLAB)
for cookies in cookies_list:
user_list.append(cookies.user_id)
add, count = await self._cache.add(user_list, RegionEnum.HOYOLAB)
Log.info(f"国际服公共Cookies池已经添加[{add}]个 当前成员数为[{count}]")
async def get_cookies(self, user_id: int, region: RegionEnum = RegionEnum.NULL):
"""获取公共Cookies
:param user_id: 用户ID
:param region: 注册的服务器
:return:
"""
while True:
public_id, count = await self._cache.get(region)
try:
cookies = await self._repository.get_cookies(public_id, region)
except CookiesNotFoundError:
await self._cache.delete(public_id, region)
continue
if region == RegionEnum.HYPERION:
client = genshin.Client(cookies=cookies.cookies, game=types.Game.GENSHIN, region=types.Region.CHINESE)
elif region == RegionEnum.HOYOLAB:
client = genshin.Client(cookies=cookies.cookies, game=types.Game.GENSHIN, region=types.Region.OVERSEAS,
lang="zh-cn")
else:
return None
try:
await client.get_record_card()
except InvalidCookies as exc:
if "[10001]" in str(exc):
Log.warning(f"用户 [{public_id}] Cookies无效")
elif "[-100]" in str(exc):
Log.warning(f"用户 [{public_id}] Cookies无效")
elif "[10103]" in str(exc):
Log.warning(f"用户 [{public_id}] Cookie有效但没有绑定到游戏帐户")
else:
Log.warning("Cookies无效具体原因未知", exc)
cookies.status = CookiesStatusEnum.INVALID_COOKIES
await self._repository.update_cookies_ex(cookies, region)
await self._cache.delete(cookies.user_id, region)
continue
except TooManyRequests as exc:
Log.warning(f"用户 [{public_id}] 查询次数太多(操作频繁)")
cookies.status = CookiesStatusEnum.TOO_MANY_REQUESTS
await self._repository.update_cookies_ex(cookies, region)
await self._cache.delete(cookies.user_id, region)
continue
except GenshinException as exc:
Log.warning(f"用户 [{public_id}] 获取账号信息发生错误,错误信息为", exc)
continue
Log.info(f"用户 user_id[{user_id}] 请求"
f"用户 user_id[{public_id}] 的公共Cookies 该Cookie使用次数为[{count}]次 ")
return cookies