接口跑通,基础功能全部实现
This commit is contained in:
@@ -6,10 +6,9 @@ Handles Weibo super topic sign-in operations
|
||||
import os
|
||||
import sys
|
||||
import asyncio
|
||||
import httpx
|
||||
import logging
|
||||
import random
|
||||
from datetime import datetime, timedelta
|
||||
from datetime import datetime
|
||||
from typing import Dict, Any, List, Optional
|
||||
from uuid import UUID
|
||||
from sqlalchemy import select, update
|
||||
@@ -230,118 +229,116 @@ class SignInService:
|
||||
logger.debug(f"Browser fingerprint: {fingerprint}")
|
||||
|
||||
async def _get_super_topics_list(self, account: WeiboAccount) -> List[WeiboSuperTopic]:
|
||||
"""Get list of super topics for account"""
|
||||
"""
|
||||
Fetch the real list of followed super topics from Weibo API.
|
||||
Delegates to WeiboClient.get_super_topics().
|
||||
"""
|
||||
try:
|
||||
# Mock implementation - in real system, fetch from Weibo API
|
||||
# Simulate API call delay
|
||||
await asyncio.sleep(1)
|
||||
|
||||
# Return mock super topics
|
||||
return [
|
||||
WeiboSuperTopic(
|
||||
id="topic_001",
|
||||
title="Python编程",
|
||||
url="https://weibo.com/p/100808xxx",
|
||||
is_signed=False,
|
||||
sign_url="https://weibo.com/p/aj/general/button",
|
||||
reward_exp=2,
|
||||
reward_credit=1
|
||||
),
|
||||
WeiboSuperTopic(
|
||||
id="topic_002",
|
||||
title="人工智能",
|
||||
url="https://weibo.com/p/100808yyy",
|
||||
is_signed=False,
|
||||
sign_url="https://weibo.com/p/aj/general/button",
|
||||
reward_exp=2,
|
||||
reward_credit=1
|
||||
),
|
||||
WeiboSuperTopic(
|
||||
id="topic_003",
|
||||
title="机器学习",
|
||||
url="https://weibo.com/p/100808zzz",
|
||||
is_signed=True, # Already signed
|
||||
sign_url="https://weibo.com/p/aj/general/button",
|
||||
reward_exp=2,
|
||||
reward_credit=1
|
||||
)
|
||||
]
|
||||
topics = await self.weibo_client.get_super_topics(account)
|
||||
logger.info(f"Fetched {len(topics)} super topics for account {account.weibo_user_id}")
|
||||
return topics
|
||||
except Exception as e:
|
||||
logger.error(f"Error fetching super topics: {e}")
|
||||
logger.error(f"Error fetching super topics for {account.weibo_user_id}: {e}")
|
||||
return []
|
||||
|
||||
async def _execute_topic_signin(self, account: WeiboAccount, topics: List[WeiboSuperTopic], task_id: str) -> Dict[str, List[str]]:
|
||||
"""Execute sign-in for each super topic"""
|
||||
signed = []
|
||||
already_signed = []
|
||||
errors = []
|
||||
|
||||
for topic in topics:
|
||||
"""
|
||||
Execute sign-in for each super topic with retry logic and
|
||||
per-topic progress updates.
|
||||
"""
|
||||
signed: List[str] = []
|
||||
already_signed: List[str] = []
|
||||
errors: List[str] = []
|
||||
max_retries = 2
|
||||
|
||||
total = len(topics) if topics else 1
|
||||
for idx, topic in enumerate(topics):
|
||||
# Update progress: 50% -> 80% spread across topics
|
||||
pct = 50 + int((idx / total) * 30)
|
||||
await self._update_task_progress(task_id, pct)
|
||||
|
||||
try:
|
||||
# Add small delay between requests
|
||||
await asyncio.sleep(random.uniform(0.5, 1.5))
|
||||
|
||||
if topic.is_signed:
|
||||
already_signed.append(topic.title)
|
||||
# Write log for already signed
|
||||
await self._write_signin_log(
|
||||
account_id=str(account.id),
|
||||
topic_title=topic.title,
|
||||
status="failed_already_signed",
|
||||
reward_info=None,
|
||||
error_message="Already signed today"
|
||||
error_message="Already signed today",
|
||||
)
|
||||
continue
|
||||
|
||||
# Execute signin for this topic
|
||||
success, reward_info, error_msg = await self.weibo_client.sign_super_topic(
|
||||
account=account,
|
||||
topic=topic,
|
||||
task_id=task_id
|
||||
)
|
||||
|
||||
if success:
|
||||
signed.append(topic.title)
|
||||
logger.info(f"✅ Successfully signed topic: {topic.title}")
|
||||
|
||||
# Write success log
|
||||
await self._write_signin_log(
|
||||
account_id=str(account.id),
|
||||
topic_title=topic.title,
|
||||
status="success",
|
||||
reward_info=reward_info,
|
||||
error_message=None
|
||||
|
||||
# Retry loop
|
||||
last_error: Optional[str] = None
|
||||
succeeded = False
|
||||
for attempt in range(1, max_retries + 1):
|
||||
# Inter-request delay (longer for retries)
|
||||
delay = random.uniform(1.0, 3.0) * attempt
|
||||
await asyncio.sleep(delay)
|
||||
|
||||
success, reward_info, error_msg = await self.weibo_client.sign_super_topic(
|
||||
account=account,
|
||||
topic=topic,
|
||||
task_id=task_id,
|
||||
)
|
||||
else:
|
||||
errors.append(f"Failed to sign topic: {topic.title}")
|
||||
|
||||
# Write failure log
|
||||
|
||||
if success:
|
||||
# "Already signed" from the API is still a success
|
||||
if error_msg and "already" in error_msg.lower():
|
||||
already_signed.append(topic.title)
|
||||
await self._write_signin_log(
|
||||
account_id=str(account.id),
|
||||
topic_title=topic.title,
|
||||
status="failed_already_signed",
|
||||
reward_info=None,
|
||||
error_message=error_msg,
|
||||
)
|
||||
else:
|
||||
signed.append(topic.title)
|
||||
logger.info(f"✅ Signed topic: {topic.title}")
|
||||
await self._write_signin_log(
|
||||
account_id=str(account.id),
|
||||
topic_title=topic.title,
|
||||
status="success",
|
||||
reward_info=reward_info,
|
||||
error_message=None,
|
||||
)
|
||||
succeeded = True
|
||||
break
|
||||
|
||||
last_error = error_msg
|
||||
logger.warning(
|
||||
f"Attempt {attempt}/{max_retries} failed for "
|
||||
f"{topic.title}: {error_msg}"
|
||||
)
|
||||
|
||||
if not succeeded:
|
||||
errors.append(f"{topic.title}: {last_error}")
|
||||
await self._write_signin_log(
|
||||
account_id=str(account.id),
|
||||
topic_title=topic.title,
|
||||
status="failed_network",
|
||||
reward_info=None,
|
||||
error_message=error_msg
|
||||
error_message=last_error,
|
||||
)
|
||||
|
||||
|
||||
except Exception as e:
|
||||
error_msg = f"Error signing topic {topic.title}: {str(e)}"
|
||||
logger.error(error_msg)
|
||||
errors.append(error_msg)
|
||||
|
||||
# Write error log
|
||||
err = f"Error signing topic {topic.title}: {e}"
|
||||
logger.error(err)
|
||||
errors.append(err)
|
||||
await self._write_signin_log(
|
||||
account_id=str(account.id),
|
||||
topic_title=topic.title,
|
||||
status="failed_network",
|
||||
reward_info=None,
|
||||
error_message=str(e)
|
||||
error_message=str(e),
|
||||
)
|
||||
|
||||
|
||||
return {
|
||||
"signed": signed,
|
||||
"already_signed": already_signed,
|
||||
"errors": errors
|
||||
"already_signed": already_signed,
|
||||
"errors": errors,
|
||||
}
|
||||
|
||||
async def _write_signin_log(
|
||||
|
||||
Reference in New Issue
Block a user