From 2f21c0761ddbcef0c6e2ff4c1a55621464b4c744 Mon Sep 17 00:00:00 2001 From: Chris Caron Date: Sun, 27 Oct 2019 19:41:02 -0400 Subject: [PATCH] basic javascript added to simplify ui --- apprise_api/api/forms.py | 2 +- apprise_api/api/templates/base.html | 94 +++++----- apprise_api/api/templates/config.html | 252 +++++++++++++++++++------- apprise_api/api/views.py | 39 ++-- 4 files changed, 261 insertions(+), 126 deletions(-) diff --git a/apprise_api/api/forms.py b/apprise_api/api/forms.py index 455366e..f8e7885 100644 --- a/apprise_api/api/forms.py +++ b/apprise_api/api/forms.py @@ -103,7 +103,7 @@ class NotifyForm(forms.Form): max_length=apprise.NotifyBase.body_maxlen, ) - tag = forms.ChoiceField( + tag = forms.CharField( label=_('Tags'), widget=forms.TextInput( attrs={'placeholder': _('Optional_Tag1, Optional_Tag2, ...')}), diff --git a/apprise_api/api/templates/base.html b/apprise_api/api/templates/base.html index 6296967..3063f6c 100644 --- a/apprise_api/api/templates/base.html +++ b/apprise_api/api/templates/base.html @@ -7,9 +7,9 @@ - + - + {% block title %}{% trans "Apprise API" %}{% endblock %} @@ -17,45 +17,57 @@
- - - + - + + \ No newline at end of file diff --git a/apprise_api/api/templates/config.html b/apprise_api/api/templates/config.html index 0842f75..7bb72c4 100644 --- a/apprise_api/api/templates/config.html +++ b/apprise_api/api/templates/config.html @@ -2,75 +2,187 @@ {% load i18n %} {% block body %}

{% trans "Management for:" %} {{ key }}

-
- -
-

- {% blocktrans %} - Here is where you can store your configuration so that it can be accessed by Apprise. You can always refer to the Apprise Wiki if you're having troubles assembling your URL(s). - You have chosen to associate your configuration with the key {{key}}. If anything was previously associated with this key, it will be replaced if you continue. - {% endblocktrans %} -

-

- {% blocktrans %} - In the future you can return to this configuration screen at any time by placing the following into your browser:{% endblocktrans %} -
{{request.scheme}}://{{request.META.HTTP_HOST}}{{request.path}} -

-
- {% blocktrans %}For example, the following command would cause apprise to retrieve the configuration loaded and send a test notification to all of your added services:{% endblocktrans %} -
apprise --body="Test Message" --tag=all --config={{request.scheme}}://{{request.META.HTTP_HOST}}{% url "get" key %} -
-
-
- -
-
{% trans "Option 1: Add By URL" %}
-

- {% blocktrans %} - Use a comma and/or space to separate one Apprise URL from another. - {% endblocktrans %} -

-{{ form_url }} - -
-

-
- -
-
{% trans "Option 2: Add By Config" %}
-

- {% blocktrans %} - This option grants you a bit more flexability because you can additionally associate tags with your URLs. Those using YAML configuration can also alter the Apprise Asset object as well for a more customized look and feel. - {% endblocktrans %} -

-{{ form_cfg }} - -
-

-
-
-
-

- {% blocktrans %} - You can send a notification using the loaded configuration: - {% endblocktrans %} -

-{{ form_notify }} - -
-

-
+
+ +
+

+ {% blocktrans %} + Here is where you can store your configuration so that it can be accessed by Apprise. You can always refer to the + Apprise Wiki if you're having troubles + assembling your URL(s). + You have chosen to associate your configuration with the key {{key}}. If anything was previously + associated with this key, it will be replaced if you continue. + {% endblocktrans %} +

+

+ {% blocktrans %} + In the future you can return to this configuration screen at any time by placing the following into your + browser:{% endblocktrans %} +
{{request.scheme}}://{{request.META.HTTP_HOST}}{{request.path}} +

+
+ {% blocktrans %}For example, the following command would cause apprise to retrieve the configuration loaded and + send a test notification to all of your added services:{% endblocktrans %} +
apprise --body="Test Message" --tag=all --config={{request.scheme}}://{{request.META.HTTP_HOST}}{% url "get" key %} +
+
+
+ +
+
{% trans "Option 1: Set By URL(s)" %}
+

+ {% blocktrans %} + Use a comma and/or space to separate one Apprise URL from another. + {% endblocktrans %} +

+ {{ form_url }} + +
+

+
+ +
+
{% trans "Option 2: Set By Config" %}
+

+ {% blocktrans %} + This option grants you a bit more flexability because you can additionally associate tags with your URLs. Those + using YAML configuration can also alter the Apprise Asset object as well for a more customized look and feel. + {% endblocktrans %} +

+ {{ form_cfg }} + +
+

+
+
+
+

+ {% blocktrans %} + You can send a notification using the loaded configuration: + {% endblocktrans %} +

+ {{ form_notify }} + +
+

+
+
+{% endblock %} +{% block jsfooter %} + +async function update() { + + // disable the notification tab until we know for certain + // a notification is possible + document.querySelector('.config-overview li a[href="#notify"]') + .parentNode.classList.add('disabled'); + + // perform our status check + let response = await fetch('{% url "get" key %}', { + method: 'POST', + }); + + let result = await response; + if(response.status == 204) + { + // no problem; we simply have no content to retrieve + return ''; + } + else if(response.status == 200) + { + // configuration found + + // Remove our restrictions on sending notifications + document.querySelector('.config-overview li a[href="#notify"]') + .parentNode.classList.remove('disabled'); + + // Set our configuration so it's visible + response.text().then(function (text) { + document.querySelector('#id_config').value = text; + }); + + return response; + } + // if we reach here, we failed + return null; +} + +update(); + +// over-ride manual submit for a nicer user experience +document.querySelector('#addurl').onsubmit = function(event) { + event.preventDefault(); + + const form = this; + const body = new URLSearchParams(new FormData(form)); + + // perform our status check + let response = fetch('{% url "add" key %}', { + method: 'POST', + body: body, + }).then(function(response) { + if(response.status == 200) + { + // update our settings + update(); + + // reset our form + form.reset(); + } + }); + return false; +} + +// over-ride manual submit for a nicer user experience +document.querySelector('#addconfig').onsubmit = function(event) { + event.preventDefault(); + const form = this; + const body = new URLSearchParams(new FormData(form)); + + // perform our status check + let response = fetch('{% url "add" key %}', { + method: 'POST', + body: body, + }).then(function(response) { + if(response.status == 200) + { + // update our settings + update(); + } + }); + return false; +} + +// over-ride manual submit for a nicer user experience +document.querySelector('#donotify').onsubmit = function(event) { + event.preventDefault(); + const form = this; + const body = new URLSearchParams(new FormData(form)); + + // perform our status check + let response = fetch('{% url "notify" key %}', { + method: 'POST', + body: body, + }).then(function(response) { + if(response.status == 200) + { + // update our settings + alert('Notification Sent'); + } + }); + return false; +} + {% endblock %} diff --git a/apprise_api/api/views.py b/apprise_api/api/views.py index 310b68e..f13b16c 100644 --- a/apprise_api/api/views.py +++ b/apprise_api/api/views.py @@ -40,8 +40,19 @@ import json import re # Content-Type Parsing -FORM_CTYPE_RE = re.compile('^(.*form-(data|urlencoded))$', re.I) -JSON_CTYPE_RE = re.compile('^.*json$', re.I) +# application/x-www-form-urlencoded +# application/x-www-form-urlencoded +# multipart/form-data +MIME_IS_FORM = re.compile( + r'(multipart|application)/(x-www-)?form-(data|urlencoded)', re.I) + +# Support JSON formats +# text/json +# text/x-json +# application/json +# application/x-json +MIME_IS_JSON = re.compile( + r'(text|application)/(x-)?json', re.I) class ResponseCode(object): @@ -96,21 +107,21 @@ class AddView(View): Handle a POST request """ # Our default response type - content_type = 'text/plain' + content_type = 'text/plain; charset=utf-8' # our content content = {} - if FORM_CTYPE_RE.match(request.content_type): + if MIME_IS_FORM.match(request.content_type): content = {} form = AddByConfigForm(request.POST) if form.is_valid(): - content.update(form.clean()) + content.update(form.cleaned_data) form = AddByUrlForm(request.POST) if form.is_valid(): - content.update(form.clean()) + content.update(form.cleaned_data) - elif JSON_CTYPE_RE.match(request.content_type): + elif MIME_IS_JSON.match(request.content_type): # Prepare our default response try: # load our JSON content @@ -226,7 +237,7 @@ class DelView(View): Handle a POST request """ # Our default response type - content_type = 'text/plain' + content_type = 'text/plain; charset=utf-8' # Clear the key result = ConfigCache.clear(key) @@ -263,7 +274,7 @@ class GetView(View): Handle a POST request """ # Our default response type - content_type = 'text/plain' + content_type = 'text/plain; charset=utf-8' config, format = ConfigCache.get(key) if config is None: @@ -294,7 +305,7 @@ class GetView(View): # reference to it through the --config (-c) option in the CLI if format == apprise.ConfigFormat.YAML: # update our return content type from the default text - content_type = 'text/yaml' + content_type = 'text/yaml; charset=utf-8' # Return our retrieved content return HttpResponse( @@ -311,17 +322,17 @@ class NotifyView(View): Handle a POST request """ # Our default response type - content_type = 'text/plain' + content_type = 'text/plain; charset=utf-8' # our content content = {} - if FORM_CTYPE_RE.match(request.content_type): + if MIME_IS_FORM.match(request.content_type): content = {} form = NotifyForm(request.POST) if form.is_valid(): - content.update(form.clean()) + content.update(form.cleaned_data) - elif JSON_CTYPE_RE.match(request.content_type): + elif MIME_IS_JSON.match(request.content_type): # Prepare our default response try: # load our JSON content