首次提交by MimoCode
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
from abc import ABC, abstractmethod
|
||||
|
||||
|
||||
class NotificationProvider(ABC):
|
||||
@abstractmethod
|
||||
async def send(self, title: str, content: str) -> bool:
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def validate_config(self) -> bool:
|
||||
pass
|
||||
@@ -0,0 +1,46 @@
|
||||
from typing import List, Optional
|
||||
from app.notifications.base import NotificationProvider
|
||||
from app.config import settings
|
||||
|
||||
|
||||
class NotificationManager:
|
||||
_instance = None
|
||||
|
||||
def __new__(cls):
|
||||
if cls._instance is None:
|
||||
cls._instance = super().__new__(cls)
|
||||
cls._instance._initialized = False
|
||||
return cls._instance
|
||||
|
||||
def __init__(self):
|
||||
if self._initialized:
|
||||
return
|
||||
self.providers: List[NotificationProvider] = []
|
||||
self._initialized = True
|
||||
|
||||
def add_provider(self, provider: NotificationProvider):
|
||||
self.providers.append(provider)
|
||||
|
||||
async def send_notification(self, title: str, content: str):
|
||||
for provider in self.providers:
|
||||
try:
|
||||
await provider.send(title, content)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def load_providers(self):
|
||||
from app.notifications.serverchan import ServerChanProvider
|
||||
from app.notifications.pushplus import PushPlusProvider
|
||||
|
||||
if "serverchan" in settings.NOTIFICATION_PROVIDERS:
|
||||
provider = ServerChanProvider()
|
||||
if provider.validate_config():
|
||||
self.add_provider(provider)
|
||||
|
||||
if "pushplus" in settings.NOTIFICATION_PROVIDERS:
|
||||
provider = PushPlusProvider()
|
||||
if provider.validate_config():
|
||||
self.add_provider(provider)
|
||||
|
||||
|
||||
notification_manager = NotificationManager()
|
||||
@@ -0,0 +1,27 @@
|
||||
import httpx
|
||||
from app.notifications.base import NotificationProvider
|
||||
from app.config import settings
|
||||
|
||||
|
||||
class PushPlusProvider(NotificationProvider):
|
||||
def __init__(self):
|
||||
self.token = settings.PUSHPLUS_TOKEN
|
||||
|
||||
def validate_config(self) -> bool:
|
||||
return bool(self.token)
|
||||
|
||||
async def send(self, title: str, content: str) -> bool:
|
||||
if not self.validate_config():
|
||||
return False
|
||||
|
||||
url = "https://www.pushplus.plus/send"
|
||||
data = {
|
||||
"token": self.token,
|
||||
"title": title,
|
||||
"content": content
|
||||
}
|
||||
|
||||
async with httpx.AsyncClient() as client:
|
||||
response = await client.post(url, json=data)
|
||||
result = response.json()
|
||||
return result.get("code") == 200
|
||||
@@ -0,0 +1,25 @@
|
||||
import httpx
|
||||
from app.notifications.base import NotificationProvider
|
||||
from app.config import settings
|
||||
|
||||
|
||||
class ServerChanProvider(NotificationProvider):
|
||||
def __init__(self):
|
||||
self.key = settings.SERVERCHAN_KEY
|
||||
|
||||
def validate_config(self) -> bool:
|
||||
return bool(self.key)
|
||||
|
||||
async def send(self, title: str, content: str) -> bool:
|
||||
if not self.validate_config():
|
||||
return False
|
||||
|
||||
url = f"https://sctapi.ftqq.com/{self.key}.send"
|
||||
data = {
|
||||
"title": title,
|
||||
"desp": content
|
||||
}
|
||||
|
||||
async with httpx.AsyncClient() as client:
|
||||
response = await client.post(url, data=data)
|
||||
return response.status_code == 200
|
||||
Reference in New Issue
Block a user