mirror of
https://git.oceanpay.cc/danial/kami_itunes_third_api.git
synced 2025-12-18 22:20:08 +00:00
refactor(itunes): 重构 iTunes 登录和兑换流程
- 新增 ItunesAccountInfo 模型用于存储账号信息 - 修改 login 和 redeem 方法以使用 ItunesAccountInfo 参数 - 优化了请求代理的使用方式 -调整了错误处理和日志记录
This commit is contained in:
@@ -175,6 +175,7 @@ steps:
|
||||
trigger:
|
||||
branch:
|
||||
- production
|
||||
- develop
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -113,3 +113,7 @@ class ItunesLoginResponse(BaseModel):
|
||||
..., alias="response"
|
||||
)
|
||||
origin_log: str = Field(default="", alias="originLog")
|
||||
|
||||
|
||||
class ItunesAccountInfo(BaseModel):
|
||||
account_name: str = Field(..., description="账号")
|
||||
|
||||
@@ -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="")
|
||||
|
||||
@@ -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):
|
||||
# 充值成功
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import copy
|
||||
from time import time
|
||||
import time
|
||||
from src.initialization import setting
|
||||
import random
|
||||
|
||||
|
||||
Reference in New Issue
Block a user