basic javascript added to simplify ui

This commit is contained in:
Chris Caron
2019-10-27 19:41:02 -04:00
parent 4a8921abb8
commit 2f21c0761d
4 changed files with 261 additions and 126 deletions

View File

@ -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, ...')}),

View File

@ -31,17 +31,26 @@
<div class="col s3">
<ul class="collection z-depth-1">
<a class="collection-item" href="{% url 'config' 'apprise' %}"><i class="tiny material-icons">settings</i> {% trans "Configuration Manager" %}</a>
<a class="collection-item" href="{% url 'config' 'apprise' %}"><i class="tiny material-icons">settings</i>
{% trans "Configuration Manager" %}</a>
</ul>
<ul class="collection z-depth-1">
<a class="collection-item" target="_blank" href="https://github.com/caronc/apprise/wiki#notification-services">📣 {% trans "Notification Services" %}</a>
<a class="collection-item" target="_blank" href="https://github.com/caronc/apprise/wiki/config"><i class="tiny material-icons">local_library</i> {% trans "Configuration Help" %}</a>
<a class="collection-item" target="_blank" href="https://github.com/caronc/apprise/wiki/Troubleshooting"><i class="tiny material-icons">build</i> {% trans "Troubleshooting" %}</a>
<a class="collection-item" target="_blank" href="https://github.com/caronc/apprise/wiki/CLI_Usage"><i class="tiny material-icons">lightbulb_outline</i> {% trans "Using the CLI" %}</a>
<a class="collection-item" target="_blank"
href="https://github.com/caronc/apprise/wiki#notification-services">📣
{% trans "Notification Services" %}</a>
<a class="collection-item" target="_blank" href="https://github.com/caronc/apprise/wiki/config"><i
class="tiny material-icons">local_library</i> {% trans "Configuration Help" %}</a>
<a class="collection-item" target="_blank" href="https://github.com/caronc/apprise/wiki/Troubleshooting"><i
class="tiny material-icons">build</i> {% trans "Troubleshooting" %}</a>
<a class="collection-item" target="_blank" href="https://github.com/caronc/apprise/wiki/CLI_Usage"><i
class="tiny material-icons">lightbulb_outline</i> {% trans "Using the CLI" %}</a>
</ul>
<ul class="collection z-depth-1">
<a class="collection-item" target="_blank" href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=MHANV39UZNQ5E"><i class="tiny material-icons">favorite</i> {% trans "Support Apprise" %}</a>
<a class="collection-item" target="_blank" href="https://github.com/sponsors/caronc"><i class="tiny material-icons">favorite</i> {% trans "Sponsor Developer" %}</a>
<a class="collection-item" target="_blank"
href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=MHANV39UZNQ5E"><i
class="tiny material-icons">favorite</i> {% trans "Support Apprise" %}</a>
<a class="collection-item" target="_blank" href="https://github.com/sponsors/caronc"><i
class="tiny material-icons">favorite</i> {% trans "Sponsor Developer" %}</a>
</ul>
{% block menu %}{% endblock %}
</div>
@ -55,7 +64,10 @@
<script>
document.addEventListener('DOMContentLoaded', function () {
M.AutoInit();
{% block onload %} {% endblock %}
});
{% block jsfooter %} {% endblock %}
</script>
</body>
</html>

View File

@ -4,7 +4,7 @@
<h3>{% trans "Management for:" %} <em>{{ key }}</em></h3>
<div class="row">
<div class="col s12">
<ul class="tabs">
<ul class="tabs config-overview">
<li class="tab col s4"><a class="active" href="#overview">{% trans "Overview" %}</a></li>
<li class="tab col s4"><a href="#config">{%trans "Configuration" %}</a></li>
<li class="tab col s4"><a href="#notify">{%trans "Notifications" %}</a></li>
@ -13,29 +13,34 @@
<div id="overview" class="col s12">
<p>
{% blocktrans %}
Here is where you can store your configuration so that it can be accessed by Apprise. You can always refer to the <a href="https://github.com/caronc/apprise/wiki#notification-services">Apprise Wiki</a> if you're having troubles assembling your URL(s).
You have chosen to associate your configuration with the key <code>{{key}}</code>. If anything was previously associated with this key, it will be replaced if you continue.
Here is where you can store your configuration so that it can be accessed by Apprise. You can always refer to the
<a href="https://github.com/caronc/apprise/wiki#notification-services">Apprise Wiki</a> if you're having troubles
assembling your URL(s).
You have chosen to associate your configuration with the key <code>{{key}}</code>. If anything was previously
associated with this key, it will be replaced if you continue.
{% endblocktrans %}
</p>
<p>
{% blocktrans %}
In the future you can return to this configuration screen at any time by placing the following into your browser:{% endblocktrans %}
In the future you can return to this configuration screen at any time by placing the following into your
browser:{% endblocktrans %}
<br /><code>{{request.scheme}}://{{request.META.HTTP_HOST}}{{request.path}}</code>
</p>
<div class="section">
{% 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 %}
{% 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 %}
<br /><code>apprise --body="Test Message" --tag=all --config={{request.scheme}}://{{request.META.HTTP_HOST}}{% url "get" key %}</code>
</div>
</div>
<div id="config" class="col s12">
<div class="section">
<h5>{% trans "Option 1: Add By URL" %}</h5>
<h5>{% trans "Option 1: Set By URL(s)" %}</h5>
<p>
{% blocktrans %}
Use a comma and/or space to separate one Apprise URL from another.
{% endblocktrans %}
<form action="#" method="post">
<form id="addurl" action="{% url "add" key %}" method="post">
{{ form_url }}
<button class="btn waves-effect waves-light" type="submit" name="action">{% trans "Submit" %}
<i class="material-icons right">send</i>
@ -45,12 +50,13 @@
</div>
<div class="section">
<h5>{% trans "Option 2: Add By Config" %}</h5>
<h5>{% trans "Option 2: Set By Config" %}</h5>
<p>
{% 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.
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 action="#" method="post">
<form id="addconfig" action="{% url "add" key %}" method="post">
{{ form_cfg }}
<button class="btn waves-effect waves-light" type="submit" name="action">{% trans "Submit" %}
<i class="material-icons right">send</i>
@ -64,7 +70,7 @@
{% blocktrans %}
You can send a notification using the loaded configuration:
{% endblocktrans %}
<form action="#" method="post">
<form id="donotify" action="{% url "notify" key %}" method="post">
{{ form_notify }}
<button class="btn waves-effect waves-light" type="submit" name="action">{% trans "Submit" %}
<i class="material-icons right">send</i>
@ -74,3 +80,109 @@
</div>
</div>
{% 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 %}

View File

@ -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