refactor(itunes): 重构 iTunes 登录和兑换流程

- 新增 ItunesAccountInfo 模型用于存储账号信息
- 修改 login 和 redeem 方法以使用 ItunesAccountInfo 参数
- 优化了请求代理的使用方式
-调整了错误处理和日志记录
This commit is contained in:
danial
2024-10-31 18:16:59 +08:00
parent 86db04bbbc
commit 911db7d319
6 changed files with 40 additions and 29 deletions

View File

@@ -175,6 +175,7 @@ steps:
trigger:
branch:
- production
- develop
when:
event:
- push

View File

@@ -9,7 +9,7 @@ from loguru import logger
from src.integrations.itunes.models.login import (
ItunesLoginResponse,
ItunesFailLoginPlistData,
ItunesSuccessLoginPlistData,
ItunesSuccessLoginPlistData, ItunesAccountInfo,
)
from src.integrations.itunes.models.redeem import (
RedeemFailResponseModel,
@@ -66,7 +66,7 @@ class AppleClient:
return response.text
def login(
self, sign_map: AuthenticateModel, server_id: str = "", retries: int = 5
self, sign_map: AuthenticateModel, account_info: ItunesAccountInfo, server_id: str = "", retries: int = 5
) -> ItunesLoginResponse:
headers = {
"X-Apple-ActionSignature": sign_map.signature,
@@ -93,9 +93,9 @@ class AppleClient:
params = {}
if server_id != "":
url = (
"https://p"
+ server_id
+ "-buy.itunes.apple.com/WebObjects/MZFinance.woa/wa/authenticate"
"https://p"
+ server_id
+ "-buy.itunes.apple.com/WebObjects/MZFinance.woa/wa/authenticate"
)
params = {"Pod": server_id, "PRH": server_id}
else:
@@ -110,25 +110,26 @@ class AppleClient:
params=params,
data=sign_map.post,
allow_redirects=False,
proxies=ProxyService().get_wrap_proxy(account_info.account_name),
)
if response.is_redirect:
redirect_url = response.headers["Location"]
groups = re.search(r"https://p(\d+)-buy.itunes.apple.com", redirect_url)
server_id = groups.group(1)
return self.login(sign_map, server_id, retries - 1)
return self.login(sign_map, account_info, server_id, retries - 1)
response_dict_data = parse_xml(response.text)
if "failureType" in response_dict_data:
status = 31
# 账户被禁用
if (
response_dict_data.get("metrics", {}).get("dialogId")
== "MZFinance.AccountDisabled"
response_dict_data.get("metrics", {}).get("dialogId")
== "MZFinance.AccountDisabled"
):
status = 14
# 账户被锁定
if (
response_dict_data.get("metrics", {}).get("dialogId")
== "MZFinance.DisabledAndFraudLocked"
response_dict_data.get("metrics", {}).get("dialogId")
== "MZFinance.DisabledAndFraudLocked"
):
status = 14
# 密码错误
@@ -146,10 +147,11 @@ class AppleClient:
)
def redeem(
self,
code: str,
itunes: ItunesLoginModel,
reties=5,
self,
code: str,
itunes: ItunesLoginModel,
account_info: ItunesAccountInfo,
reties=5,
) -> RedeemSuccessResponse | RedeemFailResponseModel:
if reties <= 0:
logger.error("兑换失败,兑换重试次数已用完")
@@ -176,7 +178,7 @@ class AppleClient:
"Content-Type": "application/x-apple-plist; Charset=UTF-8",
"User-Agent": "MacAppStore/2.0 (Macintosh; OS X 12.10) AppleWebKit/600.1.3.41",
"Referer": f"https://p{itunes.server_id}-buy.itunes.apple.com/WebObjects/MZFinance.woa/wa/com.apple"
f".jingle.app.finance.DirectAction/redeemCode?cl=iTunes&pg=Music",
f".jingle.app.finance.DirectAction/redeemCode?cl=iTunes&pg=Music",
}
try:
response = self.__session.post(
@@ -193,11 +195,11 @@ class AppleClient:
has_4gb_limit=False,
).to_xml(),
headers=headers,
proxies=ProxyService().get_wrap_proxy(itunes.account_name),
proxies=ProxyService().get_wrap_proxy(account_info.account_name),
)
except Exception as e:
logger.warning(f"兑换连接错误,重试:{e}\t{traceback.format_exc()}")
return self.redeem(code, itunes, reties - 1)
return self.redeem(code, itunes, account_info, reties - 1)
response.encoding = "utf-8"
try:
logger.info(f"返回状态码:{response.status_code}")
@@ -237,8 +239,8 @@ class AppleClient:
result = RedeemFailResponseModel.model_validate(response.json())
result.origin_log = response.text
if (
result.errorMessageKey
== "MZCommerce.GiftCertificateAlreadyRedeemed"
result.errorMessageKey
== "MZCommerce.GiftCertificateAlreadyRedeemed"
):
# 已经被兑换
result.status = 12
@@ -246,21 +248,21 @@ class AppleClient:
# 没有这个卡密
result.status = 11
elif (
result.errorMessageKey
== "MZCommerce.NatIdYearlyCapExceededException"
result.errorMessageKey
== "MZCommerce.NatIdYearlyCapExceededException"
):
# 年限额
result.status = 31
elif (
result.errorMessageKey
== "MZCommerce.NatIdDailyCapExceededException"
result.errorMessageKey
== "MZCommerce.NatIdDailyCapExceededException"
):
# 日限额
result.status = 31
# 国籍问题
elif (
result.errorMessageKey
== "MZCommerce.GiftCertRedeemStoreFrontMismatch"
result.errorMessageKey
== "MZCommerce.GiftCertRedeemStoreFrontMismatch"
):
result.status = 15
else:

View File

@@ -113,3 +113,7 @@ class ItunesLoginResponse(BaseModel):
..., alias="response"
)
origin_log: str = Field(default="", alias="originLog")
class ItunesAccountInfo(BaseModel):
account_name: str = Field(..., description="账号")

View File

@@ -74,7 +74,6 @@ class AppleAccountModel(BaseModel):
class ItunesLoginModel(BaseModel):
account_name: str = Field(default="")
server_id: str = Field(default="")
dsis: int = Field(default=0)
guid: str = Field(default="")

View File

@@ -5,7 +5,7 @@ from loguru import logger
from src.integrations.itunes.api import AppleClient
from src.integrations.itunes.models.login import (
ItunesSuccessLoginPlistData,
ItunesSuccessLoginPlistData, ItunesAccountInfo,
)
from src.integrations.itunes.models.redeem import (
RedeemSuccessResponse,
@@ -56,7 +56,9 @@ class ItunesService:
)
middle_time_3 = time.time()
logger.info(f"[+] 获取签到证书耗时: {middle_time_3 - middle_time_2}")
login_schema = self.apple_client_service.login(sign_sap_cert.Data)
login_schema = self.apple_client_service.login(sign_sap_cert.Data, ItunesAccountInfo(
account_name=account.account,
))
logger.info(f"[+] 登录耗时: {time.time() - middle_time_3}")
session = get_session()()
@@ -127,6 +129,9 @@ class ItunesService:
dsis=int(item.login_schema.dsis),
passwordToken=item.login_schema.password_token,
),
ItunesAccountInfo(
account_name=item.account_name,
)
)
if isinstance(result, RedeemSuccessResponse):
# 充值成功

View File

@@ -1,5 +1,5 @@
import copy
from time import time
import time
from src.initialization import setting
import random