Added a Apprise URL Details Endpoint (/details) (#105)

This commit is contained in:
Chris Caron
2023-02-26 10:33:14 -05:00
committed by GitHub
parent ae99d35671
commit 30d87c8284
9 changed files with 375 additions and 111 deletions

View File

@ -35,6 +35,7 @@ from django.utils.translation import gettext_lazy as _
from django.core.serializers.json import DjangoJSONEncoder
from .utils import ConfigCache
from .utils import apply_global_filters
from .forms import AddByUrlForm
from .forms import AddByConfigForm
from .forms import NotifyForm
@ -76,6 +77,10 @@ class JSONEncoder(DjangoJSONEncoder):
def default(self, obj):
if isinstance(obj, set):
return list(obj)
elif isinstance(obj, apprise.AppriseLocale.LazyTranslation):
return str(obj)
return super().default(obj)
@ -104,6 +109,63 @@ class WelcomeView(View):
return render(request, self.template_name, {})
@method_decorator((gzip_page, never_cache), name='dispatch')
class DetailsView(View):
"""
A Django view used to list all supported endpoints
"""
template_name = 'details.html'
def get(self, request):
"""
Handle a GET request
"""
# Detect the format our response should be in
json_response = \
MIME_IS_JSON.match(
request.content_type
if request.content_type
else request.headers.get(
'accept', request.headers.get(
'content-type', ''))) is not None
# Show All flag
# Support 'yes', '1', 'true', 'enable', 'active', and +
show_all = request.GET.get('all', 'no')[0].lower() in (
'a', 'y', '1', 't', 'e', '+')
# Our status
status = ResponseCode.okay
#
# Apply Any Global Filters (if identified)
#
apply_global_filters()
# Create an Apprise Object
a_obj = apprise.Apprise()
# Load our details
details = a_obj.details(show_disabled=show_all)
# Sort our result set
details['schemas'] = sorted(
details['schemas'], key=lambda i: str(i['service_name']))
# Return our content
return render(request, self.template_name, {
'show_all': show_all,
'details': details,
}, status=status) if not json_response else \
JsonResponse(
details,
encoder=JSONEncoder,
safe=False,
status=status)
@method_decorator(never_cache, name='dispatch')
class ConfigView(View):
"""
@ -134,7 +196,13 @@ class AddView(View):
Handle a POST request
"""
# Detect the format our response should be in
json_response = MIME_IS_JSON.match(request.content_type) is not None
json_response = \
MIME_IS_JSON.match(
request.content_type
if request.content_type
else request.headers.get(
'accept', request.headers.get(
'content-type', ''))) is not None
if settings.APPRISE_CONFIG_LOCK:
# General Access Control
@ -323,7 +391,13 @@ class DelView(View):
Handle a POST request
"""
# Detect the format our response should be in
json_response = MIME_IS_JSON.match(request.content_type) is not None
json_response = \
MIME_IS_JSON.match(
request.content_type
if request.content_type
else request.headers.get(
'accept', request.headers.get(
'content-type', ''))) is not None
if settings.APPRISE_CONFIG_LOCK:
# General Access Control
@ -383,7 +457,13 @@ class GetView(View):
"""
# Detect the format our response should be in
json_response = MIME_IS_JSON.match(request.content_type) is not None
json_response = \
MIME_IS_JSON.match(
request.content_type
if request.content_type
else request.headers.get(
'accept', request.headers.get(
'content-type', ''))) is not None
if settings.APPRISE_CONFIG_LOCK:
# General Access Control
@ -465,7 +545,13 @@ class NotifyView(View):
Handle a POST request
"""
# Detect the format our response should be in
json_response = MIME_IS_JSON.match(request.content_type) is not None
json_response = \
MIME_IS_JSON.match(
request.content_type
if request.content_type
else request.headers.get(
'accept', request.headers.get(
'content-type', ''))) is not None
# our content
content = {}
@ -599,59 +685,7 @@ class NotifyView(View):
#
# Apply Any Global Filters (if identified)
#
if settings.APPRISE_ALLOW_SERVICES:
alphanum_re = re.compile(
r'^(?P<name>[a-z][a-z0-9]+)', re.IGNORECASE)
entries = \
[alphanum_re.match(x).group('name').lower()
for x in re.split(r'[ ,]+', settings.APPRISE_ALLOW_SERVICES)
if alphanum_re.match(x)]
for plugin in set(apprise.common.NOTIFY_SCHEMA_MAP.values()):
if entries:
# Get a list of the current schema's associated with
# a given plugin
schemas = set(apprise.plugins.details(plugin)
['tokens']['schema']['values'])
# Check what was defined and see if there is a hit
for entry in entries:
if entry in schemas:
# We had a hit; we're done
break
if entry in schemas:
entries.remove(entry)
# We can keep this plugin enabled and move along to the
# next one...
continue
# if we reach here, we have to block our plugin
plugin.enabled = False
for entry in entries:
# Generate some noise for those who have bad configurations
logger.warning(
'APPRISE_ALLOW_SERVICES plugin %s:// was not found - '
'ignoring.', entry)
elif settings.APPRISE_DENY_SERVICES:
alphanum_re = re.compile(
r'^(?P<name>[a-z][a-z0-9]+)', re.IGNORECASE)
entries = \
[alphanum_re.match(x).group('name').lower()
for x in re.split(r'[ ,]+', settings.APPRISE_DENY_SERVICES)
if alphanum_re.match(x)]
for name in entries:
try:
# Force plugin to be disabled
apprise.common.NOTIFY_SCHEMA_MAP[name].enabled = False
except KeyError:
logger.warning(
'APPRISE_DENY_SERVICES plugin %s:// was not found -'
' ignoring.', name)
apply_global_filters()
# Prepare our keyword arguments (to be passed into an AppriseAsset
# object)
@ -892,59 +926,7 @@ class StatelessNotifyView(View):
#
# Apply Any Global Filters (if identified)
#
if settings.APPRISE_ALLOW_SERVICES:
alphanum_re = re.compile(
r'^(?P<name>[a-z][a-z0-9]+)', re.IGNORECASE)
entries = \
[alphanum_re.match(x).group('name').lower()
for x in re.split(r'[ ,]+', settings.APPRISE_ALLOW_SERVICES)
if alphanum_re.match(x)]
for plugin in set(apprise.common.NOTIFY_SCHEMA_MAP.values()):
if entries:
# Get a list of the current schema's associated with
# a given plugin
schemas = set(apprise.plugins.details(plugin)
['tokens']['schema']['values'])
# Check what was defined and see if there is a hit
for entry in entries:
if entry in schemas:
# We had a hit; we're done
break
if entry in schemas:
entries.remove(entry)
# We can keep this plugin enabled and move along to the
# next one...
continue
# if we reach here, we have to block our plugin
plugin.enabled = False
for entry in entries:
# Generate some noise for those who have bad configurations
logger.warning(
'APPRISE_ALLOW_SERVICES plugin %s:// was not found - '
'ignoring.', entry)
elif settings.APPRISE_DENY_SERVICES:
alphanum_re = re.compile(
r'^(?P<name>[a-z][a-z0-9]+)', re.IGNORECASE)
entries = \
[alphanum_re.match(x).group('name').lower()
for x in re.split(r'[ ,]+', settings.APPRISE_DENY_SERVICES)
if alphanum_re.match(x)]
for name in entries:
try:
# Force plugin to be disabled
apprise.common.NOTIFY_SCHEMA_MAP[name].enabled = False
except KeyError:
logger.warning(
'APPRISE_DENY_SERVICES plugin %s:// was not found -'
' ignoring.', name)
apply_global_filters()
# Prepare our apprise object
a_obj = apprise.Apprise(asset=asset)
@ -1012,7 +994,7 @@ class JsonUrlView(View):
# Privacy flag
# Support 'yes', '1', 'true', 'enable', 'active', and +
privacy = settings.APPRISE_CONFIG_LOCK or \
request.GET.get('privacy', 'no')[0] in (
request.GET.get('privacy', 'no')[0].lower() in (
'a', 'y', '1', 't', 'e', '+')
# Optionally filter on tags. Use comma to identify more then one