| 209 | )] |
| 210 | |
| 211 | class handler(BaseHTTPRequestHandler): |
| 212 | async def _handle_preview(self): |
| 213 | try: |
| 214 | match = re.match(r'/api/preview/(\d+)/(\d+)', self.path) |
| 215 | if not match: |
| 216 | self.send_error(400, "Invalid URL format") |
| 217 | return |
| 218 | |
| 219 | folder_id = int(match.group(1)) |
| 220 | time = int(match.group(2)) |
| 221 | |
| 222 | frame_data = preview_extractor.extract_frame(folder_id, time) |
| 223 | |
| 224 | if frame_data: |
| 225 | self.send_response(200) |
| 226 | self.send_header('Content-Type', 'image/webp') |
| 227 | self.send_header('Cache-Control', 'no-cache, no-store, must-revalidate') |
| 228 | self.end_headers() |
| 229 | self.wfile.write(frame_data) |
| 230 | else: |
| 231 | self.send_error(404, "Preview not found") |
| 232 | |
| 233 | except Exception as e: |
| 234 | logger.error(f"预览图处理错误: {str(e)}") |
| 235 | self.send_error(500, str(e)) |
| 236 | |
| 237 | async def _handle_bot(self): |
| 238 | content_length = int(self.headers.get('Content-Length', 0)) |
| 239 | post_data = self.rfile.read(content_length) |
| 240 | data = json.loads(post_data) |
| 241 | |
| 242 | try: |
| 243 | async with asyncio.timeout(45): |
| 244 | update = Update.de_json(data, Application.builder().token(TOKEN).build().bot) |
| 245 | |
| 246 | if update.inline_query: |
| 247 | results = await handle_inline_query(update) |
| 248 | await update.inline_query.answer(results, cache_time=0, is_personal=True) |
| 249 | |
| 250 | response = {"status": "ok"} |
| 251 | except asyncio.TimeoutError: |
| 252 | logger.error("请求超时") |
| 253 | response = {"status": "error", "message": "请求超时"} |
| 254 | except Exception as e: |
| 255 | logger.error(f"Webhook 错误: {str(e)}") |
| 256 | response = {"status": "error", "message": str(e)} |
| 257 | |
| 258 | self.send_response(200) |
| 259 | self.send_header('Content-Type', 'application/json') |
| 260 | self.end_headers() |
| 261 | self.wfile.write(json.dumps(response).encode()) |
| 262 | |
| 263 | def do_GET(self): |
| 264 | if self.path.startswith('/api/preview/'): |
| 265 | asyncio.run(self._handle_preview()) |
| 266 | |
| 267 | def do_POST(self): |
| 268 | if self.path == '/api/bot': |
nothing calls this directly
no outgoing calls
no test coverage detected