合并代码,避免动态加载的不确定性

This commit is contained in:
ljmeng
2024-03-28 00:20:01 +08:00
parent 2b8f5553ec
commit 46c628a671
3 changed files with 126 additions and 134 deletions

View File

@@ -186,7 +186,7 @@
"CrossSeed": {
"name": "青蛙辅种助手",
"description": "参考ReseedPuppy和IYUU辅种插件实现自动辅种支持站点青蛙、AGSVPT、麒麟、UBits、聆音等。",
"version": "1.6",
"version": "1.6.1",
"icon": "qingwa.png",
"author": "233@qingwa",
"level": 2

View File

@@ -1,11 +1,12 @@
import math
import hashlib
import os
from datetime import datetime, timedelta
from pathlib import Path
from threading import Event
from typing import Any, Dict, List, Optional, Tuple
from typing import Any, Dict, List, Optional, Self, Tuple
import pytz
import requests
from app.core.config import settings
from app.core.event import eventmanager
from app.db.models import Site
@@ -23,10 +24,129 @@ from app.utils.string import StringUtils
from app.utils.timer import TimerUtils
from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.triggers.cron import CronTrigger
from bencode import dumps, loads
from plugins.crossseed.cross_seed_helper import (CrossSeedHelper, CSSiteConfig,
TorInfo)
class CSSiteConfig(object):
"""
站点辅种配置类
"""
def __init__(self, site_name: str, site_url: str, site_passkey: str) -> None:
self.name = site_name
self.url = site_url.removesuffix("/")
self.passkey = site_passkey
def get_api_url(self):
if self.name == "憨憨":
return f"{self.url}/npapi/pieces-hash"
return f"{self.url}/api/pieces-hash"
def get_torrent_url(self, torrent_id: str):
return f"{self.url}/download.php?id={torrent_id}&passkey={self.passkey}"
class TorInfo:
def __init__(
self,
site_name: str = None,
torrent_path: str = None,
file_path: str = None,
info_hash: str = None,
pieces_hash: str = None,
torrent_id: str = None,
) -> None:
self.site_name = site_name
self.torrent_path = torrent_path
self.file_path = file_path
self.info_hash = info_hash
self.pieces_hash = pieces_hash
self.torrent_id = torrent_id
self.torrent_announce = None
@staticmethod
def local(torrent_path: str, info_hash: str, pieces_hash: str) -> Self:
return TorInfo(
torrent_path=torrent_path, info_hash=info_hash, pieces_hash=pieces_hash
)
@staticmethod
def remote(site_name: str, pieces_hash: str, torrent_id: str) -> Self:
return TorInfo(
site_name=site_name, pieces_hash=pieces_hash, torrent_id=torrent_id
)
@staticmethod
def from_data(data: bytes) -> tuple[Self, str]:
try:
torrent = loads(data)
info = torrent["info"]
pieces = info["pieces"]
info_hash = hashlib.sha1(dumps(info)).hexdigest()
pieces_hash = hashlib.sha1(pieces).hexdigest()
local_tor = TorInfo(info_hash=info_hash, pieces_hash=pieces_hash)
#从种子中获取 announce, qb可能存在获取不到的情况会存在于fastresume文件中
if "announce" in torrent:
local_tor.torrent_announce = torrent["announce"]
return local_tor, None
except Exception as err:
return None, err
def get_name_id_tag(self):
return f"{self.site_name}:{self.torrent_id}"
def get_name_pieces_tag(self):
return f"{self.site_name}:{self.pieces_hash}"
class CrossSeedHelper(object):
_version = "0.2.0"
def get_local_torrent_info(self, torrent_path: Path | str) -> tuple[TorInfo, str]:
try:
torrent_data = None
if isinstance(torrent_path, Path):
torrent_data = torrent_path.read_bytes()
else:
with open(torrent_path, "rb") as f:
torrent_data = f.read()
local_tor, err = TorInfo.from_data(torrent_data)
if not local_tor:
return None, err
local_tor.torrent_path = str(torrent_path)
return local_tor, ""
except Exception as err:
return None, err
def get_target_torrent(
self, site: CSSiteConfig, pieces_hash_set: list[str]
) -> list[TorInfo]:
"""
返回pieces_hash对应的种子信息包括站点id,pieces_hash,种子id
"""
headers = {
"Content-Type": "application/json",
"Accept": "application/json",
"User-Agent": "CrossSeedHelper",
}
data = {"passkey": site.passkey, "pieces_hash": pieces_hash_set}
try:
response = requests.post(
site.get_api_url(), headers=headers, json=data, timeout=10
)
response.raise_for_status()
except requests.exceptions.RequestException as e:
return None, f"站点{site.name}请求失败:{e}"
rsp_body = response.json()
remote_torrent_infos = []
if isinstance(rsp_body["data"], dict):
for pieces_hash, torrent_id in rsp_body["data"].items():
remote_torrent_infos.append(
TorInfo.remote(site.name, pieces_hash, torrent_id)
)
return remote_torrent_infos, None
class CrossSeed(_PluginBase):
# 插件名称
@@ -36,7 +156,7 @@ class CrossSeed(_PluginBase):
# 插件图标
plugin_icon = "qingwa.png"
# 插件版本
plugin_version = "1.6"
plugin_version = "1.6.1"
# 插件作者
plugin_author = "233@qingwa"
# 作者主页

View File

@@ -1,128 +0,0 @@
import hashlib
from pathlib import Path
from typing import Self
import requests
from bencode import bdecode, bencode
class CSSiteConfig(object):
"""
站点辅种配置类
"""
def __init__(self, site_name: str, site_url: str, site_passkey: str) -> None:
self.name = site_name
self.url = site_url.removesuffix("/")
self.passkey = site_passkey
def get_api_url(self):
if self.name == "憨憨":
return f"{self.url}/npapi/pieces-hash"
return f"{self.url}/api/pieces-hash"
def get_torrent_url(self, torrent_id: str):
return f"{self.url}/download.php?id={torrent_id}&passkey={self.passkey}"
class TorInfo:
def __init__(
self,
site_name: str = None,
torrent_path: str = None,
file_path: str = None,
info_hash: str = None,
pieces_hash: str = None,
torrent_id: str = None,
) -> None:
self.site_name = site_name
self.torrent_path = torrent_path
self.file_path = file_path
self.info_hash = info_hash
self.pieces_hash = pieces_hash
self.torrent_id = torrent_id
self.torrent_announce = None
@staticmethod
def local(torrent_path: str, info_hash: str, pieces_hash: str) -> Self:
return TorInfo(
torrent_path=torrent_path, info_hash=info_hash, pieces_hash=pieces_hash
)
@staticmethod
def remote(site_name: str, pieces_hash: str, torrent_id: str) -> Self:
return TorInfo(
site_name=site_name, pieces_hash=pieces_hash, torrent_id=torrent_id
)
@staticmethod
def from_data(data: bytes) -> tuple[Self, str]:
try:
torrent = bdecode(data)
info = torrent["info"]
pieces = info["pieces"]
info_hash = hashlib.sha1(bencode(info)).hexdigest()
pieces_hash = hashlib.sha1(pieces).hexdigest()
local_tor = TorInfo(info_hash=info_hash, pieces_hash=pieces_hash)
#从种子中获取 announce, qb可能存在获取不到的情况会存在于fastresume文件中
if "announce" in torrent:
local_tor.torrent_announce = torrent["announce"]
return local_tor, None
except Exception as err:
return None, err
def get_name_id_tag(self):
return f"{self.site_name}:{self.torrent_id}"
def get_name_pieces_tag(self):
return f"{self.site_name}:{self.pieces_hash}"
class CrossSeedHelper(object):
_version = "0.2.0"
def get_local_torrent_info(self, torrent_path: Path | str) -> tuple[TorInfo, str]:
try:
torrent_data = None
if isinstance(torrent_path, Path):
torrent_data = torrent_path.read_bytes()
else:
with open(torrent_path, "rb") as f:
torrent_data = f.read()
local_tor, err = TorInfo.from_data(torrent_data)
if not local_tor:
return None, err
local_tor.torrent_path = str(torrent_path)
return local_tor, ""
except Exception as err:
return None, err
def get_target_torrent(
self, site: CSSiteConfig, pieces_hash_set: list[str]
) -> list[TorInfo]:
"""
返回pieces_hash对应的种子信息包括站点id,pieces_hash,种子id
"""
headers = {
"Content-Type": "application/json",
"Accept": "application/json",
"User-Agent": "CrossSeedHelper",
}
data = {"passkey": site.passkey, "pieces_hash": pieces_hash_set}
try:
response = requests.post(
site.get_api_url(), headers=headers, json=data, timeout=10
)
response.raise_for_status()
except requests.exceptions.RequestException as e:
return None, f"站点{site.name}请求失败:{e}"
rsp_body = response.json()
remote_torrent_infos = []
if isinstance(rsp_body["data"], dict):
for pieces_hash, torrent_id in rsp_body["data"].items():
remote_torrent_infos.append(
TorInfo.remote(site.name, pieces_hash, torrent_id)
)
return remote_torrent_infos, None