2022-08-04 13:19:17 +00:00
|
|
|
|
from typing import List, Union
|
|
|
|
|
|
2023-03-14 01:27:22 +00:00
|
|
|
|
from core.base_service import BaseService
|
|
|
|
|
from core.basemodel import RegionEnum
|
|
|
|
|
from core.dependence.redisdb import RedisDB
|
|
|
|
|
from core.services.cookies.error import CookiesCachePoolExhausted
|
2022-08-04 13:19:17 +00:00
|
|
|
|
from utils.error import RegionNotFoundError
|
|
|
|
|
|
2023-03-14 01:27:22 +00:00
|
|
|
|
__all__ = ("PublicCookiesCache",)
|
2022-08-04 13:19:17 +00:00
|
|
|
|
|
2023-03-14 01:27:22 +00:00
|
|
|
|
|
|
|
|
|
class PublicCookiesCache(BaseService.Component):
|
2022-08-04 13:19:17 +00:00
|
|
|
|
"""使用优先级(score)进行排序,对使用次数最少的Cookies进行审核"""
|
|
|
|
|
|
|
|
|
|
def __init__(self, redis: RedisDB):
|
|
|
|
|
self.client = redis.client
|
|
|
|
|
self.score_qname = "cookie:public"
|
2022-09-08 01:08:37 +00:00
|
|
|
|
self.user_times_qname = "cookie:public:times"
|
2022-08-04 13:19:17 +00:00
|
|
|
|
self.end = 20
|
2022-09-08 01:08:37 +00:00
|
|
|
|
self.user_times_ttl = 60 * 60 * 24
|
2022-08-04 13:19:17 +00:00
|
|
|
|
|
2022-09-08 01:08:37 +00:00
|
|
|
|
def get_public_cookies_queue_name(self, region: RegionEnum):
|
2022-08-04 13:19:17 +00:00
|
|
|
|
if region == RegionEnum.HYPERION:
|
2022-09-14 14:23:07 +00:00
|
|
|
|
return f"{self.score_qname}:yuanshen"
|
2023-03-14 01:27:22 +00:00
|
|
|
|
if region == RegionEnum.HOYOLAB:
|
2022-09-14 14:23:07 +00:00
|
|
|
|
return f"{self.score_qname}:genshin"
|
2023-03-14 01:27:22 +00:00
|
|
|
|
raise RegionNotFoundError(region.name)
|
2022-08-04 13:19:17 +00:00
|
|
|
|
|
2022-09-08 01:08:37 +00:00
|
|
|
|
async def putback_public_cookies(self, uid: int, region: RegionEnum):
|
2022-08-04 13:19:17 +00:00
|
|
|
|
"""重新添加单个到缓存列表
|
|
|
|
|
:param uid:
|
|
|
|
|
:param region:
|
|
|
|
|
:return:
|
|
|
|
|
"""
|
2022-09-08 01:08:37 +00:00
|
|
|
|
qname = self.get_public_cookies_queue_name(region)
|
2022-08-04 13:19:17 +00:00
|
|
|
|
score_maps = {f"{uid}": 0}
|
|
|
|
|
result = await self.client.zrem(qname, f"{uid}")
|
|
|
|
|
if result == 1:
|
|
|
|
|
await self.client.zadd(qname, score_maps)
|
|
|
|
|
return result
|
|
|
|
|
|
2022-09-08 01:08:37 +00:00
|
|
|
|
async def add_public_cookies(self, uid: Union[List[int], int], region: RegionEnum):
|
2022-08-04 13:19:17 +00:00
|
|
|
|
"""单个或批量添加到缓存列表
|
|
|
|
|
:param uid:
|
|
|
|
|
:param region:
|
|
|
|
|
:return: 成功返回列表大小
|
|
|
|
|
"""
|
2022-09-08 01:08:37 +00:00
|
|
|
|
qname = self.get_public_cookies_queue_name(region)
|
2022-08-04 13:19:17 +00:00
|
|
|
|
if isinstance(uid, int):
|
|
|
|
|
score_maps = {f"{uid}": 0}
|
|
|
|
|
elif isinstance(uid, list):
|
2022-09-14 14:23:07 +00:00
|
|
|
|
score_maps = {f"{i}": 0 for i in uid}
|
2022-08-04 13:19:17 +00:00
|
|
|
|
else:
|
2022-09-14 14:23:07 +00:00
|
|
|
|
raise TypeError("uid variable type error")
|
2022-08-04 13:19:17 +00:00
|
|
|
|
async with self.client.pipeline(transaction=True) as pipe:
|
|
|
|
|
# nx:只添加新元素。不要更新已经存在的元素
|
|
|
|
|
await pipe.zadd(qname, score_maps, nx=True)
|
|
|
|
|
await pipe.zcard(qname)
|
|
|
|
|
add, count = await pipe.execute()
|
|
|
|
|
return int(add), count
|
|
|
|
|
|
2022-09-08 01:08:37 +00:00
|
|
|
|
async def get_public_cookies(self, region: RegionEnum):
|
2022-08-04 13:19:17 +00:00
|
|
|
|
"""从缓存列表获取
|
|
|
|
|
:param region:
|
|
|
|
|
:return:
|
|
|
|
|
"""
|
2022-09-08 01:08:37 +00:00
|
|
|
|
qname = self.get_public_cookies_queue_name(region)
|
2022-09-14 14:23:07 +00:00
|
|
|
|
scores = await self.client.zrange(qname, 0, self.end, withscores=True, score_cast_func=int)
|
|
|
|
|
if len(scores) <= 0:
|
2022-08-04 13:19:17 +00:00
|
|
|
|
raise CookiesCachePoolExhausted
|
2022-09-14 14:23:07 +00:00
|
|
|
|
key = scores[0][0]
|
|
|
|
|
score = scores[0][1]
|
2022-08-04 13:19:17 +00:00
|
|
|
|
async with self.client.pipeline(transaction=True) as pipe:
|
|
|
|
|
await pipe.zincrby(qname, 1, key)
|
|
|
|
|
await pipe.execute()
|
|
|
|
|
return int(key), score + 1
|
|
|
|
|
|
2022-09-08 01:08:37 +00:00
|
|
|
|
async def delete_public_cookies(self, uid: int, region: RegionEnum):
|
|
|
|
|
qname = self.get_public_cookies_queue_name(region)
|
2022-08-04 13:19:17 +00:00
|
|
|
|
async with self.client.pipeline(transaction=True) as pipe:
|
|
|
|
|
await pipe.zrem(qname, uid)
|
|
|
|
|
return await pipe.execute()
|
|
|
|
|
|
2022-09-08 01:08:37 +00:00
|
|
|
|
async def get_public_cookies_count(self, limit: bool = True):
|
2022-08-04 13:19:17 +00:00
|
|
|
|
async with self.client.pipeline(transaction=True) as pipe:
|
|
|
|
|
if limit:
|
|
|
|
|
await pipe.zcount(0, self.end)
|
|
|
|
|
else:
|
|
|
|
|
await pipe.zcard(self.score_qname)
|
|
|
|
|
return await pipe.execute()
|
2022-09-08 01:08:37 +00:00
|
|
|
|
|
2023-04-04 15:45:07 +00:00
|
|
|
|
async def incr_by_user_times(self, user_id: Union[List[int], int], amount: int = 1):
|
2022-09-14 14:23:07 +00:00
|
|
|
|
qname = f"{self.user_times_qname}:{user_id}"
|
2023-04-04 15:45:07 +00:00
|
|
|
|
times = await self.client.incrby(qname, amount)
|
2022-09-08 01:08:37 +00:00
|
|
|
|
if times <= 1:
|
|
|
|
|
await self.client.expire(qname, self.user_times_ttl)
|
|
|
|
|
return times
|