added Support for ntfy and apprise

This commit is contained in:
jschaufuss@leitwerk.de
2025-08-15 13:02:19 +02:00
parent 839fafdb33
commit 3ba0f3ddcb
13 changed files with 443 additions and 103 deletions

View File

@@ -64,6 +64,21 @@ class ArrSettingsForm(forms.Form):
radarr_api_key = forms.CharField(label="Radarr API Key", required=False,
widget=forms.PasswordInput(render_value=True, attrs=WIDE))
class NotificationSettingsForm(forms.Form):
# ntfy
ntfy_server_url = forms.URLField(label="ntfy Server URL", required=False, widget=forms.URLInput(attrs=WIDE),
help_text="e.g., https://ntfy.sh")
ntfy_topic_default = forms.CharField(label="Default Topic", required=False, widget=forms.TextInput(attrs=WIDE))
ntfy_user = forms.CharField(label="ntfy Username", required=False)
ntfy_password = forms.CharField(label="ntfy Password", required=False, widget=forms.PasswordInput(render_value=True))
ntfy_token = forms.CharField(label="ntfy Bearer Token", required=False, widget=forms.PasswordInput(render_value=True))
# Apprise
apprise_default_url = forms.CharField(
label="Apprise URL(s)", required=False, widget=forms.Textarea(attrs={"rows": 3, "class": "input-wide"}),
help_text="One per line. See https://github.com/caronc/apprise/wiki for URL formats."
)
class MailSettingsForm(forms.Form):
mail_host = forms.CharField(label="Mail Host", required=False)
mail_port = forms.IntegerField(label="Mail Port", required=False, min_value=1, max_value=65535)
@@ -83,3 +98,23 @@ class AccountForm(forms.Form):
email = forms.EmailField(label="Email", required=False)
new_password = forms.CharField(label="New password", required=False, widget=forms.PasswordInput)
repeat_password = forms.CharField(label="Repeat password", required=False, widget=forms.PasswordInput)
class NotificationSettingsForm(forms.Form):
# ntfy
ntfy_server_url = forms.URLField(label="ntfy Server URL", required=False,
widget=forms.URLInput(attrs=WIDE),
help_text="e.g. https://ntfy.sh or your self-hosted URL")
ntfy_topic_default = forms.CharField(label="Default topic", required=False,
widget=forms.TextInput(attrs=WIDE))
ntfy_user = forms.CharField(label="ntfy Username", required=False,
widget=forms.TextInput(attrs=WIDE))
ntfy_password = forms.CharField(label="ntfy Password", required=False,
widget=forms.PasswordInput(render_value=True, attrs=WIDE))
ntfy_token = forms.CharField(label="ntfy Bearer token", required=False,
widget=forms.PasswordInput(render_value=True, attrs=WIDE))
# Apprise
apprise_default_url = forms.CharField(label="Apprise URL(s)", required=False,
widget=forms.Textarea(attrs={"rows": 3, **WIDE}),
help_text="One URL per line. Will be used in addition to any user-provided URLs.")

View File

@@ -0,0 +1,41 @@
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('settingspanel', '0004_alter_appsettings_mail_secure'),
]
operations = [
migrations.AddField(
model_name='appsettings',
name='ntfy_server_url',
field=models.URLField(blank=True, null=True, help_text='Base URL of ntfy server, e.g. https://ntfy.sh'),
),
migrations.AddField(
model_name='appsettings',
name='ntfy_topic_default',
field=models.CharField(max_length=200, blank=True, null=True, help_text="Default topic if user hasn't set one"),
),
migrations.AddField(
model_name='appsettings',
name='ntfy_user',
field=models.CharField(max_length=255, blank=True, null=True),
),
migrations.AddField(
model_name='appsettings',
name='ntfy_password',
field=models.CharField(max_length=255, blank=True, null=True),
),
migrations.AddField(
model_name='appsettings',
name='ntfy_token',
field=models.CharField(max_length=255, blank=True, null=True, help_text='Bearer token, alternative to user/password'),
),
migrations.AddField(
model_name='appsettings',
name='apprise_default_url',
field=models.TextField(blank=True, null=True, help_text='Apprise URL(s). Multiple allowed, one per line.'),
),
]

View File

@@ -34,6 +34,16 @@ class AppSettings(models.Model):
acc_username = models.CharField(max_length=150, blank=True, null=True)
acc_email = models.EmailField(blank=True, null=True)
# Notifications - NTFY
ntfy_server_url = models.URLField(blank=True, null=True, help_text="Base URL of ntfy server, e.g. https://ntfy.sh")
ntfy_topic_default = models.CharField(max_length=200, blank=True, null=True, help_text="Default topic if user hasn't set one")
ntfy_user = models.CharField(max_length=255, blank=True, null=True)
ntfy_password = models.CharField(max_length=255, blank=True, null=True)
ntfy_token = models.CharField(max_length=255, blank=True, null=True, help_text="Bearer token, alternative to user/password")
# Notifications - Apprise (default target URLs, optional)
apprise_default_url = models.TextField(blank=True, null=True, help_text="Apprise URL(s). Multiple allowed, one per line.")
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):

View File

@@ -90,6 +90,20 @@
<div class="row"><label>From</label>{{ mail_form.mail_from }}</div>
</div>
<div class="card">
<h2>Notifications</h2>
<h3>ntfy</h3>
<div class="row"><label>Server URL</label>{{ notify_form.ntfy_server_url }}</div>
<div class="row"><label>Default topic</label>{{ notify_form.ntfy_topic_default }}</div>
<div class="row"><label>Username</label>{{ notify_form.ntfy_user }}</div>
<div class="row"><label>Password</label>{{ notify_form.ntfy_password }}</div>
<div class="row"><label>Bearer token</label>{{ notify_form.ntfy_token }}</div>
<h3 style="margin-top:12px;">Apprise</h3>
<div class="row"><label>Default URL(s)</label>{{ notify_form.apprise_default_url }}</div>
<div class="help">Users can also set their own ntfy topic or Apprise URLs in their profile.</div>
</div>
<div class="card">
<h2>Account</h2>
<div class="row"><label>Username</label>{{ account_form.username }}</div>

View File

@@ -2,7 +2,7 @@ from django.shortcuts import render, redirect
from django.views import View
from django.contrib import messages
from django.utils.decorators import method_decorator
from .forms import ArrSettingsForm, MailSettingsForm, AccountForm, FirstRunSetupForm, JellyfinSettingsForm
from .forms import ArrSettingsForm, MailSettingsForm, AccountForm, FirstRunSetupForm, JellyfinSettingsForm, NotificationSettingsForm
from .models import AppSettings
from django.http import JsonResponse
from accounts.utils import jellyfin_admin_required
@@ -96,6 +96,14 @@ class SettingsView(View):
"mail_password": cfg.mail_password or "",
"mail_from": cfg.mail_from or "",
}),
"notify_form": NotificationSettingsForm(initial={
"ntfy_server_url": cfg.ntfy_server_url or "",
"ntfy_topic_default": cfg.ntfy_topic_default or "",
"ntfy_user": cfg.ntfy_user or "",
"ntfy_password": cfg.ntfy_password or "",
"ntfy_token": cfg.ntfy_token or "",
"apprise_default_url": cfg.apprise_default_url or "",
}),
"account_form": AccountForm(initial={
"username": cfg.acc_username or "",
"email": cfg.acc_email or "",
@@ -106,13 +114,15 @@ class SettingsView(View):
jellyfin_form = JellyfinSettingsForm(request.POST)
arr_form = ArrSettingsForm(request.POST)
mail_form = MailSettingsForm(request.POST)
notify_form = NotificationSettingsForm(request.POST)
acc_form = AccountForm(request.POST)
if not (jellyfin_form.is_valid() and arr_form.is_valid() and mail_form.is_valid() and acc_form.is_valid()):
if not (jellyfin_form.is_valid() and arr_form.is_valid() and mail_form.is_valid() and notify_form.is_valid() and acc_form.is_valid()):
return render(request, self.template_name, {
"jellyfin_form": jellyfin_form,
"arr_form": arr_form,
"mail_form": mail_form,
"notify_form": notify_form,
"account_form": acc_form,
})
@@ -136,6 +146,14 @@ class SettingsView(View):
cfg.mail_password = mail_form.cleaned_data.get("mail_password") or None
cfg.mail_from = mail_form.cleaned_data.get("mail_from") or None
# Update Notification settings
cfg.ntfy_server_url = notify_form.cleaned_data.get("ntfy_server_url") or None
cfg.ntfy_topic_default = notify_form.cleaned_data.get("ntfy_topic_default") or None
cfg.ntfy_user = notify_form.cleaned_data.get("ntfy_user") or None
cfg.ntfy_password = notify_form.cleaned_data.get("ntfy_password") or None
cfg.ntfy_token = notify_form.cleaned_data.get("ntfy_token") or None
cfg.apprise_default_url = notify_form.cleaned_data.get("apprise_default_url") or None
# Update account settings
cfg.acc_username = acc_form.cleaned_data.get("username") or None
cfg.acc_email = acc_form.cleaned_data.get("email") or None