fix github proxy && add webpush api

This commit is contained in:
jxxghp 2024-06-05 18:08:34 +08:00
parent 7e1951b8e4
commit efd0fc39c6
7 changed files with 92 additions and 9 deletions

View File

@ -1,13 +1,15 @@
import json
from typing import Union, Any, List from typing import Union, Any, List
from fastapi import APIRouter, BackgroundTasks, Depends from fastapi import APIRouter, BackgroundTasks, Depends, HTTPException
from fastapi import Request from fastapi import Request
from pywebpush import WebPushException, webpush
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from starlette.responses import PlainTextResponse from starlette.responses import PlainTextResponse
from app import schemas from app import schemas
from app.chain.message import MessageChain from app.chain.message import MessageChain
from app.core.config import settings from app.core.config import settings, global_vars
from app.core.security import verify_token from app.core.security import verify_token
from app.db import get_db from app.db import get_db
from app.db.models import User from app.db.models import User
@ -155,3 +157,33 @@ def set_switchs(switchs: List[NotificationSwitch],
SystemConfigOper().set(SystemConfigKey.NotificationChannels, switch_list) SystemConfigOper().set(SystemConfigKey.NotificationChannels, switch_list)
return schemas.Response(success=True) return schemas.Response(success=True)
@router.post("/subscribe", summary="客户端webpush通知订阅", response_model=schemas.Response)
def subscribe(subscription: schemas.Subscription, _: schemas.TokenPayload = Depends(verify_token)):
"""
客户端webpush通知订阅
"""
global_vars.push_subscription(subscription.dict())
return schemas.Response(success=True)
@router.post("/send-webpush", summary="发送webpush通知", response_model=schemas.Response)
def send_notification(payload: schemas.SubscriptionMessage, _: schemas.TokenPayload = Depends(verify_token)):
"""
发送webpush通知
"""
try:
for sub in global_vars.get_subscriptions():
webpush(
subscription_info=sub,
data=json.dumps(payload.dict()),
vapid_private_key=settings.VAPID.get("private_key"),
vapid_claims={
"sub": settings.VAPID.get("subject")
},
)
return schemas.Response(success=True)
except WebPushException as ex:
print("WebPush Error:", repr(ex))
raise HTTPException(status_code=500, detail=str(ex))

View File

@ -2,7 +2,7 @@ import secrets
import sys import sys
import threading import threading
from pathlib import Path from pathlib import Path
from typing import Optional from typing import Optional, List
from pydantic import BaseSettings, validator from pydantic import BaseSettings, validator
@ -372,6 +372,14 @@ class Settings(BaseSettings):
return [] return []
return [d for d in settings.DOWNLOADER.split(",") if d] return [d for d in settings.DOWNLOADER.split(",") if d]
@property
def VAPID(self):
return {
"subject": f"mailto: <{self.SUPERUSER}@movie-pilot.org>",
"publicKey": "BH3w49sZA6jXUnE-yt4jO6VKh73lsdsvwoJ6Hx7fmPIDKoqGiUl2GEoZzy-iJfn4SfQQcx7yQdHf9RknwrL_lSM",
"privateKey": "JTixnYY0vEw97t9uukfO3UWKfHKJdT5kCQDiv3gu894"
}
def __init__(self, **kwargs): def __init__(self, **kwargs):
super().__init__(**kwargs) super().__init__(**kwargs)
with self.CONFIG_PATH as p: with self.CONFIG_PATH as p:
@ -400,6 +408,8 @@ class GlobalVar(object):
""" """
# 系统停止事件 # 系统停止事件
STOP_EVENT: threading.Event = threading.Event() STOP_EVENT: threading.Event = threading.Event()
# webpush订阅
SUBSCRIPTIONS: List[dict] = []
def stop_system(self): def stop_system(self):
""" """
@ -413,6 +423,18 @@ class GlobalVar(object):
""" """
return self.STOP_EVENT.is_set() return self.STOP_EVENT.is_set()
def get_subscriptions(self):
"""
获取webpush订阅
"""
return self.SUBSCRIPTIONS
def push_subscription(self, subscription: dict):
"""
添加webpush订阅
"""
self.SUBSCRIPTIONS.append(subscription)
# 实例化配置 # 实例化配置
settings = Settings( settings = Settings(

View File

@ -35,6 +35,10 @@ class PluginHelper(metaclass=Singleton):
if self.install_report(): if self.install_report():
self.systemconfig.set(SystemConfigKey.PluginInstallReport, "1") self.systemconfig.set(SystemConfigKey.PluginInstallReport, "1")
@property
def proxies(self):
return None if settings.GITHUB_PROXY else settings.PROXY
@cached(cache=TTLCache(maxsize=1000, ttl=1800)) @cached(cache=TTLCache(maxsize=1000, ttl=1800))
def get_plugins(self, repo_url: str) -> Dict[str, dict]: def get_plugins(self, repo_url: str) -> Dict[str, dict]:
""" """
@ -47,7 +51,7 @@ class PluginHelper(metaclass=Singleton):
if not user or not repo: if not user or not repo:
return {} return {}
raw_url = self._base_url % (user, repo) raw_url = self._base_url % (user, repo)
res = RequestUtils(proxies=settings.PROXY, headers=settings.GITHUB_HEADERS, res = RequestUtils(proxies=self.proxies, headers=settings.GITHUB_HEADERS,
timeout=10).get_res(f"{raw_url}package.json") timeout=10).get_res(f"{raw_url}package.json")
if res: if res:
try: try:
@ -159,7 +163,7 @@ class PluginHelper(metaclass=Singleton):
if item.get("download_url"): if item.get("download_url"):
download_url = f"{settings.GITHUB_PROXY}{item.get('download_url')}" download_url = f"{settings.GITHUB_PROXY}{item.get('download_url')}"
# 下载插件文件 # 下载插件文件
res = RequestUtils(proxies=settings.PROXY, res = RequestUtils(proxies=self.proxies,
headers=settings.GITHUB_HEADERS, timeout=60).get_res(download_url) headers=settings.GITHUB_HEADERS, timeout=60).get_res(download_url)
if not res: if not res:
return False, f"文件 {item.get('name')} 下载失败!" return False, f"文件 {item.get('name')} 下载失败!"

View File

@ -23,6 +23,10 @@ class ResourceHelper(metaclass=Singleton):
self.siteshelper = SitesHelper() self.siteshelper = SitesHelper()
self.check() self.check()
@property
def proxies(self):
return None if settings.GITHUB_PROXY else settings.PROXY
def check(self): def check(self):
""" """
检测是否有更新如有则下载安装 检测是否有更新如有则下载安装
@ -32,7 +36,7 @@ class ResourceHelper(metaclass=Singleton):
if SystemUtils.is_frozen(): if SystemUtils.is_frozen():
return return
logger.info("开始检测资源包版本...") logger.info("开始检测资源包版本...")
res = RequestUtils(proxies=settings.PROXY, headers=settings.GITHUB_HEADERS, timeout=10).get_res(self._repo) res = RequestUtils(proxies=self.proxies, headers=settings.GITHUB_HEADERS, timeout=10).get_res(self._repo)
if res: if res:
try: try:
resource_info = json.loads(res.text) resource_info = json.loads(res.text)
@ -89,7 +93,7 @@ class ResourceHelper(metaclass=Singleton):
logger.info(f"开始更新资源文件:{item.get('name')} ...") logger.info(f"开始更新资源文件:{item.get('name')} ...")
download_url = f"{settings.GITHUB_PROXY}{item.get('download_url')}" download_url = f"{settings.GITHUB_PROXY}{item.get('download_url')}"
# 下载资源文件 # 下载资源文件
res = RequestUtils(proxies=settings.PROXY, headers=settings.GITHUB_HEADERS, res = RequestUtils(proxies=self.proxies, headers=settings.GITHUB_HEADERS,
timeout=180).get_res(download_url) timeout=180).get_res(download_url)
if not res: if not res:
logger.error(f"文件 {item.get('name')} 下载失败!") logger.error(f"文件 {item.get('name')} 下载失败!")

View File

@ -84,3 +84,22 @@ class NotificationSwitch(BaseModel):
synologychat: Optional[bool] = False synologychat: Optional[bool] = False
# VoceChat开关 # VoceChat开关
vocechat: Optional[bool] = False vocechat: Optional[bool] = False
class Subscription(BaseModel):
"""
客户端消息订阅
"""
endpoint: Optional[str]
keys: Optional[dict] = {}
class SubscriptionMessage(BaseModel):
"""
客户端订阅消息体
"""
title: Optional[str]
body: Optional[str]
icon: Optional[str]
url: Optional[str]
data: Optional[dict] = {}

View File

@ -57,3 +57,4 @@ fast-bencode~=1.1.3
pystray~=0.19.5 pystray~=0.19.5
pyotp~=2.9.0 pyotp~=2.9.0
Pinyin2Hanzi~=0.1.1 Pinyin2Hanzi~=0.1.1
pywebpush~=2.0.0

1
update
View File

@ -92,6 +92,7 @@ if [[ "${MOVIEPILOT_AUTO_UPDATE}" = "true" ]] || [[ "${MOVIEPILOT_AUTO_UPDATE}"
if [ -n "${PROXY_HOST}" ]; then if [ -n "${PROXY_HOST}" ]; then
CURL_OPTIONS="-sL -x ${PROXY_HOST}" CURL_OPTIONS="-sL -x ${PROXY_HOST}"
PIP_OPTIONS="--proxy=${PROXY_HOST}" PIP_OPTIONS="--proxy=${PROXY_HOST}"
GITHUB_PROXY=""
echo "使用代理更新程序" echo "使用代理更新程序"
else else
CURL_OPTIONS="-sL" CURL_OPTIONS="-sL"