Skip to content

Commit 7d52a87

Browse files
committed
fix: update JWT expiration to use timezone-aware UTC datetime and enhance caching logic for search responses
1 parent bfc5cbe commit 7d52a87

File tree

4 files changed

+46
-32
lines changed

4 files changed

+46
-32
lines changed

_auth.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ async def generateJWT(payload: dict):
1919
生成 JWT Token
2020
:return: str
2121
"""
22-
payload['exp'] = datetime.datetime.utcnow() + datetime.timedelta(hours=12)
22+
# Use timezone-aware UTC datetime per deprecation guidance
23+
payload['exp'] = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=12)
2324
return jwt.encode(payload, os.getenv('SESSION_SECRET'), algorithm="HS256")
2425

2526

_search.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -128,10 +128,14 @@ async def search(request: Request, background_tasks: BackgroundTasks):
128128
try:
129129
id = f"search_{keyword}_{page}_{size}_{datetime.datetime.now().strftime('%Y-%m-%d')}"
130130
if await redis_key_exists(id):
131-
data = json.loads(await redis_get_key(id))
132-
data["msg"] = "cached"
133-
return JSONResponse(data)
131+
cached = await redis_get_key(id)
132+
if cached is not None:
133+
cached_data = json.loads(cached)
134+
if isinstance(cached_data, dict):
135+
cached_data["msg"] = "cached"
136+
return JSONResponse(cached_data, status_code=200, headers={"X-Cache": "HIT" if "msg" in cached_data and cached_data["msg"] == "cached" else "MISS"})
134137
except Exception as e:
138+
logging.info(f"Invalid Request: {data}, {e}")
135139
pass
136140
try:
137141
result = await search_api(keyword, page, size)
@@ -167,10 +171,12 @@ async def keyword(request: Request):
167171
"msg": "ok"}, status_code=200, headers={"X-Info": "Success"})
168172
redis_key = f"keyword_{datetime.datetime.now().strftime('%Y-%m-%d')}_{_keyword}"
169173
try:
170-
if await redis_get_key(redis_key):
171-
data = await redis_get_key(redis_key)
172-
data = json.loads(data)
173-
data["msg"] = "cached"
174+
cached = await redis_get_key(redis_key)
175+
if cached is not None:
176+
parsed = json.loads(cached)
177+
if isinstance(parsed, dict):
178+
parsed["msg"] = "cached"
179+
data = parsed
174180
else:
175181
data = await link_keywords(_keyword)
176182
await redis_set_key(redis_key, json.dumps(data), ex=86400) # 缓存一天

_utils.py

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
import json
44
import logging
55
import urllib
6+
import urllib.parse
67
import uuid
8+
from typing import Optional
79

810
from fake_useragent import UserAgent
911
from httpx import AsyncClient
@@ -83,17 +85,16 @@ def _getRandomUserAgent():
8385

8486

8587
async def pushNotification(baseURL: str, msg: str, icon: str = '', click_url: str = '', is_passive: bool = False,
86-
headers=None):
88+
headers: Optional[dict] = None):
8789
"""
8890
推送通知
89-
:param baseURL: str
90-
:param msg: str
91-
:param icon: str
92-
:param click_url: str
93-
:param is_passive: bool
94-
:param headers: dict
95-
:param data: dict
96-
:param log_data: dict -> {'push_id': str, 'push_receiver': str}
91+
:param baseURL: 推送服务基础 URL
92+
:param msg: 推送消息内容
93+
:param icon: 图标 URL,可选
94+
:param click_url: 点击跳转 URL,可选
95+
:param is_passive: 是否被动推送(静默)
96+
:param headers: 额外请求头,可选
97+
:return: bool 是否推送成功
9798
"""
9899
# url = https://api.day.app/uKeSrwm3ainGgn5SAmRyg9/{msg}?icon={icon}&url={url}&passive={is_passive}
99100
if headers is None:
@@ -118,25 +119,29 @@ async def pushNotification(baseURL: str, msg: str, icon: str = '', click_url: st
118119

119120
# url 编码关键词
120121
def url_encode(keyword):
121-
return urllib.parse.quote(keyword.encode())
122+
# ensure str input and use urllib.parse.quote for encoding
123+
if isinstance(keyword, bytes):
124+
keyword = keyword.decode('utf-8', errors='ignore')
125+
return urllib.parse.quote(str(keyword))
122126

123127

124128
async def generatePushTask(baseURL: str, msg: str, user_id: str, receiver: str, icon=None, click_url=None,
125-
is_passive=None, headers: dict = None, taskID: str = uuid.uuid4().hex,
129+
is_passive=None, headers: Optional[dict] = None, taskID: str = uuid.uuid4().hex,
126130
push_receiver: str = "yuki", push_by: str = "system"):
127131
"""
128-
:param push_by: 推送者 默认为system
129-
:param push_channel: 推送渠道 默认为bark
130-
:param push_receiver: 用户email
131-
:param taskID: 任务ID 默认为uuid
132-
:param headers: 请求头
133-
:param icon: 图标
134-
:param user_id: 用户ID
135-
:param msg: 消息
136-
:param baseURL: 基础URL
137-
:param click_url: 点击通知后跳转的URL
138-
:param receiver: 接收者
139-
:param is_passive: 是否被动推送 就是不会有声音
132+
生成推送任务并暂存到 Redis 队列
133+
:param baseURL: 推送服务基础 URL
134+
:param msg: 推送消息内容
135+
:param user_id: 用户 ID
136+
:param receiver: 接收者标识
137+
:param icon: 图标 URL,可选
138+
:param click_url: 点击跳转 URL,可选
139+
:param is_passive: 是否被动推送(静默)
140+
:param headers: 请求头,可选
141+
:param taskID: 任务 ID(默认随机)
142+
:param push_receiver: 推送接收者(日志)
143+
:param push_by: 推送发起者(日志)
144+
:return: bool
140145
示例: generatePushTask("https://api.day.app/uKeSrwm3ainGgn5SAmRyg9/", "You have a new notification!", str(12345),
141146
"https://example.com", False, None, None, None, uuid.uuid4().hex, "system",
142147
"bark")

app.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,5 +281,7 @@ async def add_process_time_header(request, call_next):
281281
import uvicorn
282282
import watchfiles
283283

284-
watchfiles.filters = ["*venv", "\\.env$"]
284+
# Some versions of watchfiles don't expose a `filters` attribute; guard access.
285+
if hasattr(watchfiles, 'filters'):
286+
watchfiles.filters = ["*venv", "\\.env$"]
285287
uvicorn.run(app, host="0.0.0.0", port=8000)

0 commit comments

Comments
 (0)