mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-05-11 18:10:15 +08:00
feat:分享订阅删除功能
This commit is contained in:
@@ -462,6 +462,17 @@ def subscribe_share(
|
||||
return schemas.Response(success=state, message=errmsg)
|
||||
|
||||
|
||||
@router.delete("/share/{share_id}", summary="删除分享", response_model=schemas.Response)
|
||||
def subscribe_share_delete(
|
||||
share_id: int,
|
||||
_: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
"""
|
||||
删除分享
|
||||
"""
|
||||
state, errmsg = SubscribeHelper().share_delete(share_id=share_id)
|
||||
return schemas.Response(success=state, message=errmsg)
|
||||
|
||||
|
||||
@router.post("/fork", summary="复用订阅", response_model=schemas.Response)
|
||||
def subscribe_fork(
|
||||
sub: schemas.SubscribeShare,
|
||||
|
||||
@@ -174,6 +174,10 @@ def get_global_setting():
|
||||
exclude={"SECRET_KEY", "RESOURCE_SECRET_KEY", "API_TOKEN", "TMDB_API_KEY", "TVDB_API_KEY", "FANART_API_KEY",
|
||||
"COOKIECLOUD_KEY", "COOKIECLOUD_PASSWORD", "GITHUB_TOKEN", "REPO_GITHUB_TOKEN"}
|
||||
)
|
||||
# 追加用户唯一ID
|
||||
info.update({
|
||||
"USER_UNIQUE_ID": SystemUtils.generate_user_unique_id()
|
||||
})
|
||||
return schemas.Response(success=True,
|
||||
data=info)
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ from app.db.systemconfig_oper import SystemConfigOper
|
||||
from app.schemas.types import SystemConfigKey
|
||||
from app.utils.http import RequestUtils
|
||||
from app.utils.singleton import Singleton
|
||||
from app.utils.system import SystemUtils
|
||||
|
||||
|
||||
class SubscribeHelper(metaclass=Singleton):
|
||||
@@ -34,6 +35,7 @@ class SubscribeHelper(metaclass=Singleton):
|
||||
|
||||
def __init__(self):
|
||||
self.systemconfig = SystemConfigOper()
|
||||
self.share_user_id = SystemUtils.generate_user_unique_id()
|
||||
if settings.SUBSCRIBE_STATISTIC_SHARE:
|
||||
if not self.systemconfig.get(SystemConfigKey.SubscribeReport):
|
||||
if self.sub_report():
|
||||
@@ -133,6 +135,7 @@ class SubscribeHelper(metaclass=Singleton):
|
||||
"share_title": share_title,
|
||||
"share_comment": share_comment,
|
||||
"share_user": share_user,
|
||||
"share_uid": self.share_user_id,
|
||||
**subscribe_dict
|
||||
})
|
||||
if res is None:
|
||||
@@ -144,6 +147,24 @@ class SubscribeHelper(metaclass=Singleton):
|
||||
else:
|
||||
return False, res.json().get("message")
|
||||
|
||||
def share_delete(self, share_id: int) -> Tuple[bool, str]:
|
||||
"""
|
||||
删除分享
|
||||
"""
|
||||
if not settings.SUBSCRIBE_STATISTIC_SHARE:
|
||||
return False, "当前没有开启订阅数据共享功能"
|
||||
res = RequestUtils(proxies=settings.PROXY,
|
||||
timeout=5).delete_res(f"{self._sub_share}/{share_id}",
|
||||
params={"share_uid": self.share_user_id})
|
||||
if res is None:
|
||||
return False, "连接MoviePilot服务器失败"
|
||||
if res.ok:
|
||||
# 清除 get_shares 的缓存,以便实时看到结果
|
||||
self._shares_cache.clear()
|
||||
return True, ""
|
||||
else:
|
||||
return False, res.json().get("message")
|
||||
|
||||
def sub_fork(self, share_id: int) -> Tuple[bool, str]:
|
||||
"""
|
||||
复用分享的订阅
|
||||
|
||||
@@ -88,6 +88,8 @@ class SubscribeShare(BaseModel):
|
||||
share_comment: Optional[str] = None
|
||||
# 分享人
|
||||
share_user: Optional[str] = None
|
||||
# 分享人唯一ID
|
||||
share_uid: Optional[str] = None
|
||||
# 订阅名称
|
||||
name: Optional[str] = None
|
||||
# 订阅年份
|
||||
|
||||
@@ -207,6 +207,32 @@ class RequestUtils:
|
||||
raise_exception=raise_exception,
|
||||
**kwargs)
|
||||
|
||||
def delete_res(self,
|
||||
url: str,
|
||||
data: Any = None,
|
||||
params: dict = None,
|
||||
allow_redirects: bool = True,
|
||||
raise_exception: bool = False,
|
||||
**kwargs) -> Optional[Response]:
|
||||
"""
|
||||
发送DELETE请求并返回响应对象
|
||||
:param url: 请求的URL
|
||||
:param data: 请求的数据
|
||||
:param params: 请求的参数
|
||||
:param allow_redirects: 是否允许重定向
|
||||
:param raise_exception: 是否在发生异常时抛出异常,否则默认拦截异常返回None
|
||||
:param kwargs: 其他请求参数,如headers, cookies, proxies等
|
||||
:return: HTTP响应对象,若发生RequestException则返回None
|
||||
:raises: requests.exceptions.RequestException 仅raise_exception为True时会抛出
|
||||
"""
|
||||
return self.request(method="delete",
|
||||
url=url,
|
||||
data=data,
|
||||
params=params,
|
||||
allow_redirects=allow_redirects,
|
||||
raise_exception=raise_exception,
|
||||
**kwargs)
|
||||
|
||||
@staticmethod
|
||||
def cookie_parse(cookies_str: str, array: bool = False) -> Union[list, dict]:
|
||||
"""
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import datetime
|
||||
import hashlib
|
||||
import os
|
||||
import platform
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import uuid
|
||||
from glob import glob
|
||||
from pathlib import Path
|
||||
from typing import List, Optional, Tuple, Union
|
||||
@@ -556,3 +558,45 @@ class SystemUtils:
|
||||
# 确保是空文件夹
|
||||
if folder.is_dir() and not any(folder.iterdir()):
|
||||
folder.rmdir()
|
||||
|
||||
@staticmethod
|
||||
def generate_user_unique_id():
|
||||
"""
|
||||
根据优先级依次尝试生成稳定唯一ID:
|
||||
1. 文件系统唯一标识符。
|
||||
2. MAC 地址。
|
||||
3. 主机名。
|
||||
"""
|
||||
|
||||
def get_filesystem_unique_id():
|
||||
"""
|
||||
获取文件系统的唯一标识符。
|
||||
使用根目录的设备号和 inode。
|
||||
"""
|
||||
try:
|
||||
stat_info = os.stat("/")
|
||||
fs_id = f"{stat_info.st_dev}-{stat_info.st_ino}"
|
||||
return hashlib.sha256(fs_id.encode("utf-8")).hexdigest()
|
||||
except Exception as e:
|
||||
print(str(e))
|
||||
return None
|
||||
|
||||
def get_mac_address_id():
|
||||
"""
|
||||
获取设备的 MAC 地址并生成唯一标识符。
|
||||
"""
|
||||
try:
|
||||
mac_address = uuid.getnode()
|
||||
if (mac_address >> 40) % 2: # 检查是否是虚拟MAC地址
|
||||
raise ValueError("MAC地址可能是虚拟地址")
|
||||
mac_str = f"{mac_address:012x}"
|
||||
return hashlib.sha256(mac_str.encode("utf-8")).hexdigest()
|
||||
except Exception as e:
|
||||
print(str(e))
|
||||
return None
|
||||
|
||||
for method in [get_filesystem_unique_id, get_mac_address_id]:
|
||||
unique_id = method()
|
||||
if unique_id:
|
||||
return unique_id
|
||||
return None
|
||||
|
||||
Reference in New Issue
Block a user