add IYUU站点绑定

This commit is contained in:
jxxghp
2024-04-11 21:01:32 +08:00
parent 6834b4bb90
commit 3c379282d4
4 changed files with 330 additions and 42 deletions

View File

@@ -496,5 +496,13 @@
"icon": "FeiShu_A.png",
"author": "InfinityPacer",
"level": 2
},
"IyuuAuth": {
"name": "IYUU站点绑定",
"description": "为IYUU账号绑定认证站点以便用于用户认证和辅种。",
"version": "1.0",
"icon": "Iyuu_A.png",
"author": "jxxghp",
"level": 1
}
}

View File

@@ -0,0 +1,225 @@
import os
from typing import Any, List, Dict, Tuple
from app.log import logger
from app.plugins import _PluginBase
from app.plugins.iyuuauth.iyuu_helper import IyuuHelper
class IyuuAuth(_PluginBase):
# 插件名称
plugin_name = "IYUU站点绑定"
# 插件描述
plugin_desc = "为IYUU账号绑定认证站点以便用于用户认证和辅种。"
# 插件图标
plugin_icon = "Iyuu_A.png"
# 插件版本
plugin_version = "1.0"
# 插件作者
plugin_author = "jxxghp"
# 作者主页
author_url = "https://github.com/jxxghp"
# 插件配置项ID前缀
plugin_config_prefix = "iyuuauth_"
# 加载顺序
plugin_order = 25
# 可使用的用户级别
auth_level = 1
# 私有属性
iyuu = None
_enabled = False
_token = None
_site = None
_passkey = None
_uid = None
def init_plugin(self, config: dict = None):
if config:
self._enabled = config.get("enabled")
self._token = config.get("token") or os.environ.get("IYUU_SIGN")
self._site = config.get("site")
self._passkey = config.get("passkey")
self._uid = config.get("uid")
if self._token:
self.iyuu = IyuuHelper(self._token)
# 开始绑定站点
if self._enabled:
if not self._token or not self._passkey or not self._uid:
logger.warn("IYUU站点绑定插件配置不完整请检查配置")
self.systemmessage.put("IYUU站点绑定插件配置不完整请检查配置")
return
state, message = self.iyuu.bind_site(site=self._site, passkey=self._passkey, uid=self._uid)
if not state:
logger.warn(f"IYUU站点绑定失败错误信息{message}")
self.systemmessage.put(f"IYUU站点绑定失败错误信息{message}")
else:
logger.info("IYUU站点绑定成功")
self.systemmessage.put("IYUU站点绑定成功")
self._enabled = False
self.update_config({
"enabled": self._enabled,
"token": self._token,
"site": self._site,
"passkey": self._passkey,
"uid": self._uid
})
def get_state(self) -> bool:
return self._enabled and (True if self._token else False)
@staticmethod
def get_command() -> List[Dict[str, Any]]:
pass
def get_api(self) -> List[Dict[str, Any]]:
pass
def get_form(self) -> Tuple[List[dict], Dict[str, Any]]:
"""
拼装插件配置页面需要返回两块数据1、页面配置2、数据结构
"""
# 编历 NotificationType 枚举,生成消息类型选项
SiteOptions = []
if self.iyuu:
for item in self.iyuu.get_auth_sites() or []:
SiteOptions.append({
"title": item.get("site"),
"value": item.get("id")
})
return [
{
'component': 'VForm',
'content': [
{
'component': 'VRow',
'content': [
{
'component': 'VCol',
'props': {
'cols': 12,
'md': 6
},
'content': [
{
'component': 'VSwitch',
'props': {
'model': 'enabled',
'label': '启用插件',
}
}
]
}
]
},
{
'component': 'VRow',
'content': [
{
'component': 'VCol',
'props': {
'cols': 12
},
'content': [
{
'component': 'VTextField',
'props': {
'model': 'token',
'label': 'IYUU令牌',
'placeholder': 'IYUUxxx',
}
}
]
}
]
},
{
'component': 'VRow',
'content': [
{
'component': 'VCol',
'props': {
'cols': 12,
'md': 4,
},
'content': [
{
'component': 'VSelect',
'props': {
'model': 'site',
'label': '绑定站点',
'items': SiteOptions
}
}
]
},
{
'component': 'VCol',
'props': {
'cols': 12,
'md': 4,
},
'content': [
{
'component': 'VTextfield',
'props': {
'model': 'passkey',
'label': '站点密钥',
}
}
]
},
{
'component': 'VCol',
'props': {
'cols': 12,
'md': 4,
},
'content': [
{
'component': 'VTextfield',
'props': {
'model': 'uid',
'label': '用户UID',
}
}
]
}
]
},
{
'component': 'VRow',
'content': [
{
'component': 'VCol',
'props': {
'cols': 12,
},
'content': [
{
'component': 'VAlert',
'props': {
'type': 'info',
'variant': 'tonal',
'text': '如果设置了`IYUU_SIGN`环境变量则会自动读取,否则需要先填写 IYUU令牌 保存,重新打开插件才能选择绑定站点。'
}
}
]
}
]
}
]
}
], {
"enabled": False,
"token": os.environ.get("IYUU_SIGN")
}
def get_page(self) -> List[dict]:
pass
def stop_service(self):
"""
退出插件
"""
pass

View File

@@ -0,0 +1,90 @@
import hashlib
from typing import Optional, Tuple, List
from app.utils.http import RequestUtils
class IyuuHelper(object):
_version = "2.0.0"
_api_base = "http://api.bolahg.cn/%s"
_sites = {}
_token = None
def __init__(self, token: str):
self._token = token
if self._token:
self.init_config()
def init_config(self):
pass
def __request_iyuu(self, url: str, method: str = "get", params: dict = None) -> Tuple[Optional[dict], str]:
"""
向IYUUApi发送请求
"""
if params:
if not params.get("sign"):
params.update({"sign": self._token})
if not params.get("version"):
params.update({"version": self._version})
else:
params = {"sign": self._token, "version": self._version}
# 开始请求
if method == "get":
ret = RequestUtils(
accept_type="application/json"
).get_res(f"{url}", params=params)
else:
ret = RequestUtils(
accept_type="application/json"
).post_res(f"{url}", data=params)
if ret:
result = ret.json()
if result.get('ret') == 200:
return result.get('data'), ""
else:
return None, f"请求IYUU失败状态码{result.get('ret')},返回信息:{result.get('msg')}"
elif ret is not None:
return None, f"请求IYUU失败状态码{ret.status_code},错误原因:{ret.reason}"
else:
return None, f"请求IYUU失败未获取到返回信息"
@staticmethod
def get_sha1(json_str: str) -> str:
return hashlib.sha1(json_str.encode('utf-8')).hexdigest()
def get_auth_sites(self) -> List[dict]:
"""
返回支持鉴权的站点列表
[
{
"id": 2,
"site": "pthome",
"bind_check": "passkey,uid"
}
]
"""
result, msg = self.__request_iyuu(url=self._api_base % 'App.Api.GetRecommendSites')
if result:
return result.get('recommend') or []
else:
print(msg)
return []
def bind_site(self, site: str, passkey: str, uid: str):
"""
绑定站点
:param site: 站点名称
:param passkey: passkey
:param uid: 用户id
:return: 状态码、错误信息
"""
result, msg = self.__request_iyuu(url=self._api_base % 'App.Api.Bind',
method="get",
params={
"token": self._token,
"site": site,
"passkey": self.get_sha1(passkey),
"id": uid
})
return result, msg

View File

@@ -1,6 +1,7 @@
import hashlib
import json
import time
from typing import Tuple, Optional
from app.utils.http import RequestUtils
@@ -11,7 +12,7 @@ class IyuuHelper(object):
_sites = {}
_token = None
def __init__(self, token):
def __init__(self, token: str):
self._token = token
if self._token:
self.init_config()
@@ -19,7 +20,7 @@ class IyuuHelper(object):
def init_config(self):
pass
def __request_iyuu(self, url, method="get", params=None):
def __request_iyuu(self, url: str, method: str = "get", params: dict = None) -> Tuple[Optional[dict], str]:
"""
向IYUUApi发送请求
"""
@@ -50,7 +51,7 @@ class IyuuHelper(object):
else:
return None, f"请求IYUU失败未获取到返回信息"
def get_torrent_url(self, sid):
def get_torrent_url(self, sid: str) -> Tuple[Optional[str], Optional[str]]:
if not sid:
return None, None
if not self._sites:
@@ -60,7 +61,7 @@ class IyuuHelper(object):
site = self._sites.get(sid)
return site.get('base_url'), site.get('download_page')
def __get_sites(self):
def __get_sites(self) -> dict:
"""
返回支持辅种的全部站点
:return: 站点列表、错误信息
@@ -92,7 +93,7 @@ class IyuuHelper(object):
print(msg)
return {}
def get_seed_info(self, info_hashs: list):
def get_seed_info(self, info_hashs: list) -> Tuple[Optional[dict], str]:
"""
返回info_hash对应的站点id、种子id
{
@@ -126,41 +127,5 @@ class IyuuHelper(object):
return result, msg
@staticmethod
def get_sha1(json_str) -> str:
def get_sha1(json_str: str) -> str:
return hashlib.sha1(json_str.encode('utf-8')).hexdigest()
def get_auth_sites(self):
"""
返回支持鉴权的站点列表
[
{
"id": 2,
"site": "pthome",
"bind_check": "passkey,uid"
}
]
"""
result, msg = self.__request_iyuu(url=self._api_base % 'App.Api.GetRecommendSites')
if result:
return result.get('recommend') or []
else:
print(msg)
return []
def bind_site(self, site, passkey, uid):
"""
绑定站点
:param site: 站点名称
:param passkey: passkey
:param uid: 用户id
:return: 状态码、错误信息
"""
result, msg = self.__request_iyuu(url=self._api_base % 'App.Api.Bind',
method="get",
params={
"token": self._token,
"site": site,
"passkey": self.get_sha1(passkey),
"id": uid
})
return result, msg