move server/* to scnserver/*

This commit is contained in:
2022-12-21 12:35:56 +01:00
parent 2b4d77bab4
commit bbf7962e29
123 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,47 @@
<!DOCTYPE html>
<html lang="en">
<head>
{{template|header.[theme].html}}
</head>
<body>
<div id="copyinfo">
<a tabindex="-1" href="https://www.blackforestbytes.com">&#169; blackforestbytes</a>
<a tabindex="-1" href="https://www.mikescher.com">made by Mike Schw&ouml;rer</a>
</div>
{{template|theme_switch.[theme].html}}
<div id="mainpnl">
<a tabindex="-1" href="/documentation/swagger" class="button bordered edge-btn" id="tl_linkDocs"><span class="icn-openapi"></span><span class="tl_btntxt">API Documentation</span></a>
<a tabindex="-1" href="/" class="button bordered edge-btn" id="tr_link">Send</a>
<a tabindex="-1" href="/" class="linkcaption"><h1>Simple Cloud Notifier</h1></a>
<p>Get your user-id and user-key from the android or iOS app.<br/>And send notifications to your phone by performing a POST request against <code>{{config|baseURL}}/</code> from anywhere</p>
<pre>
curl \
--data "user_id=${userid}" \
--data "user_key=${userkey}" \
--data "title=${message_title}" \
--data "content=${message_body}" \
--data "priority=${0|1|2}" \
--data "msg_id=$(uuidgen)" \
--data "timestamp=$(date +%s)" \
--data "channel={channel_name}" \
--data "sender_name=$(hostname)" \
{{config|baseURL}}/</pre>
<p>Most parameters are optional, you can send a message with only a title (default priority and channel will be used)</p>
<pre>
curl \
--data "user_id={userid}" \
--data "user_key={userkey}" \
--data "title={message_title}" \
{{config|baseURL}}/</pre>
<a href="/api_more" class="button bordered tertiary" style="float: right; min-width: 100px; text-align: center">More</a>
</div>
</body>
</html>

View File

@@ -0,0 +1,218 @@
<!DOCTYPE html>
<html lang="en">
<head>
{{template|header.[theme].html}}
</head>
<body>
<div id="copyinfo">
<a tabindex="-1" href="https://www.blackforestbytes.com">&#169; blackforestbytes</a>
<a tabindex="-1" href="https://www.mikescher.com">made by Mike Schw&ouml;rer</a>
</div>
{{template|theme_switch.[theme].html}}
<div id="mainpnl">
<a tabindex="-1" href="/documentation/swagger" class="button bordered edge-btn" id="tl_linkDocs"><span class="icn-openapi"></span><span class="tl_btntxt">API Documentation</span></a>
<a tabindex="-1" href="/" class="button bordered edge-btn" id="tr_link">Send</a>
<a tabindex="-1" href="/" class="linkcaption"><h1>Simple Cloud Notifier</h1></a>
<h2>Introduction</h2>
<div class="section">
<p>
With this API you can send push notifications to your phone.
</p>
<p>
To receive them you will need to install the <a href="https://play.google.com/store/apps/details?id=com.blackforestbytes.simplecloudnotifier">SimpleCloudNotifier</a> app from the play store.
When you open the app you can click on the account tab to see you unique <code>user_id</code> and <code>user_key</code>.
These two values are used to identify and authenticate your device so that send messages can be routed to your phone.
</p>
<p>
You can at any time generate a new <code>user_key</code> in the app and invalidate the old one.
</p>
<p>
There is also a <a href="/">web interface</a> for this API to manually send notifications to your phone or to test your setup.
</p>
</div>
<h2>Quota</h2>
<div class="section">
<p>
By default you can send up to 50 messages per day per device.
If you need more you can upgrade your account in the app to get 1000 messages per day, this has the additional benefit of removing ads and supporting the development of the app (and making sure I can pay the server costs).
</p>
</div>
<h2>API Requests</h2>
<div class="section">
<p>
To send a new notification you send a <code>POST</code> request to the URL <code>{{config|baseURL}}/</code>.
All Parameters can either directly be submitted as URL parameters or they can be put into the POST body (either multipart/form-data or JSON).
</p>
<p>
You <i>need</i> to supply a valid <code>[user_id, user_key]</code> pair and a <code>title</code> for your message, all other parameter are optional.
</p>
</div>
<h2>API Response</h2>
<div class="section">
<p>
If the operation was successful the API will respond with an HTTP statuscode 200 and an JSON payload indicating the send message and your remaining quota
</p>
<pre class="red-code">{
"success":true,
"message":"Message sent",
"messagecount": 634,
"quota":17,
"quota_max":100,
"scn_msg_id":993625
}</pre>
<p>
If the operation is <b>not</b> successful the API will respond with a 4xx or 500 HTTP statuscode.
</p>
<table class="scode_table">
<thead>
<tr>
<th>Statuscode</th>
<th>Explanation</th>
</tr>
</thead>
<tbody>
<tr>
<td data-label="Statuscode">200 (OK)</td>
<td data-label="Explanation">Message sent</td>
</tr>
<tr>
<td data-label="Statuscode">400 (Bad Request)</td>
<td data-label="Explanation">The request is invalid (missing parameters or wrong values)</td>
</tr>
<tr>
<td data-label="Statuscode">401 (Unauthorized)</td>
<td data-label="Explanation">The user_id was not found or the user_key is wrong</td>
</tr>
<tr>
<td data-label="Statuscode">403 (Forbidden)</td>
<td data-label="Explanation">The user has exceeded its daily quota - wait 24 hours or upgrade your account</td>
</tr>
<tr>
<td data-label="Statuscode">500 (Internal Server Error)</td>
<td data-label="Explanation">There was an internal error while sending your data - try again later</td>
</tr>
</tbody>
</table>
<p>
There is also always a JSON payload with additional information.
The <code>success</code> field is always there and in the error case you can read the <code>message</code> field to get a more information about the problem.
</p>
<pre class="red-code">{
"success": false,
"error": 2101,
"errhighlight": -1,
"message": "Daily quota reached (100)"
}</pre>
</div>
<h2>Message Content</h2>
<div class="section">
<p>
Every message must have a title set.
But you also (optionally) add more content, while the title has a max length of 120 characters, the content can be up to 10.000 characters.
You can see the whole message with title and content in the app or when clicking on the notification.
</p>
<p>
If needed the content can be supplied in the <code>content</code> parameter.
</p>
<pre>curl \
--data "user_id={userid}" \
--data "user_key={userkey}" \
--data "title={message_title}" \
--data "content={message_content}" \
{{config|baseURL}}/</pre>
</div>
<h2>Message Priority</h2>
<div class="section">
<p>
Currently you can send a message with three different priorities: 0 (low), 1 (normal) and 2 (high).
In the app you can then configure a different behaviour for different priorities, e.g. only playing a sound if the notification is high priority.
</p>
<p>
Priorites are either 0, 1 or 2 and are supplied in the <code>priority</code> parameter.
If no priority is supplied the message will get the default priority of 1.
</p>
<pre>curl \
--data "user_id={userid}" \
--data "user_key={userkey}" \
--data "title={message_title}" \
--data "priority={0|1|2}" \
{{config|baseURL}}/</pre>
</div>
<h2>Channel</h2>
<div class="section">
<p>
By default all messages are sent to the user default channel (typically <code>main</code>)
You can specify a different channel with the <code>channel</code> parameter, if the channel does not already exist it will be created.
Channel names are case-insensitive and can only contain letters, numbers, underscores and minuses ( <code>/[[:alnum:]\-_]+/</code> )
</p>
<pre>curl \
--data "user_id={userid}" \
--data "user_key={userkey}" \
--data "title={message_title}" \
--data "channel={my_channel}" \
{{config|baseURL}}/</pre>
</div>
<h2>Message Uniqueness (Idempotency)</h2>
<div class="section">
<p>
Sometimes your script can run in an environment with an unstable connection and you want to implement an automatic re-try mechanism to send a message again if the last try failed due to bad connectivity.
</p>
<p>
To ensure that a message is only send once you can generate a unique id for your message (I would recommend a simple <code>uuidgen</code>).
If you send a message with a UUID that was already used in the near past the API still returns OK, but no new message is sent.
</p>
<p>
The message_id is optional - but if you want to use it you need to supply it via the <code>msg_id</code> parameter.
</p>
<pre>curl \
--data "user_id={userid}" \
--data "user_key={userkey}" \
--data "title={message_title}" \
--data "msg_id={message_id}" \
{{config|baseURL}}/</pre>
<p>
Be aware that the server only saves send messages for a short amount of time. Because of that you can only use this to prevent duplicates in a short time-frame, older messages with the same ID are probably already deleted and the message will be send again.
</p>
</div>
<h2>Custom Time</h2>
<div class="section">
<p>
You can modify the displayed timestamp of a message by sending the <code>timestamp</code> parameter. The format must be a valid UNIX timestamp (elapsed seconds since 1970-01-01 GMT)
</p>
<p>
The custom timestamp must be within 48 hours of the current time. This parameter is only intended to supply a more precise value in case the message sending was delayed.
</p>
<pre>curl \
--data "user_id={userid}" \
--data "user_key={userkey}" \
--data "title={message_title}" \
--data "timestamp={unix_timestamp}" \
{{config|baseURL}}/</pre>
</div>
<h2>Bash script example</h2>
<div class="section">
<p>
Depending on your use case it can be useful to create a bash script that handles things like resending messages if you have connection problems or waiting if there is no quota left.<br/>
Here is an example how such a scrippt could look like, you can put it into <code>/usr/local/sbin</code> and call it with <code>scn_send "title" "content"</code> (or with more parameters, see the script itself)
</p>
{{template|scn_send.[theme].html}}
</div>
</div>
</body>
</html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,34 @@
#mainpnl {
box-shadow: initial;
}
#mainpnl h1
{
text-align: center;
margin-top: 0;
margin-bottom: 24px;
font-weight: bold;
color: #CFCFCF;
text-shadow: #000 0 0 2px, #666 0 0 8px;
}
.edge-btn {
position: absolute;
border-color: #888 !important;
}
pre.yellow-code,
pre.yellow-code span {
background: none;
}
#theme-switch {
fill: #EA0;
}
#theme-switch:hover {
fill: #88F;
}

File diff suppressed because one or more lines are too long

15
scnserver/website/css/toastify.min.css vendored Normal file
View File

@@ -0,0 +1,15 @@
/**
* Minified by jsDelivr using clean-css v4.2.0.
* Original file: /npm/toastify.js@1.3.0/src/toastify.css
*
* Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files
*/
/*!
* Toastify js 1.2.2
* https://github.com/apvarun/toastify-js
* @license MIT licensed
*
* Copyright (C) 2018 Varun A P
*/
.toastify{padding:12px 20px;color:#fff;display:inline-block;box-shadow:0 3px 6px -1px rgba(0,0,0,.12),0 10px 36px -4px rgba(77,96,232,.3);background:-webkit-linear-gradient(315deg,#73a5ff,#5477f5);background:linear-gradient(135deg,#73a5ff,#5477f5);position:fixed;opacity:0;transition:all .4s cubic-bezier(.215,.61,.355,1);border-radius:2px;cursor:pointer;text-decoration:none;max-width:calc(50% - 20px)}.toastify.on{opacity:1}.toast-close{opacity:.4;padding:0 5px}.right{right:15px}.left{left:15px}.top{top:-150px}.bottom{bottom:-150px}.rounded{border-radius:25px}.avatar{width:1.5em;height:1.5em;margin:0 5px;border-radius:2px}@media only screen and (max-width:360px){.left,.right{margin-left:auto;margin-right:auto;left:0;right:0;max-width:fit-content}}
/*# sourceMappingURL=/sm/734ed69e2fe87a4469526acc0a10708fa8e0211c7d4359f9e034ceb89bb5d540.map */

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

View File

@@ -0,0 +1,14 @@
<meta charset="utf-8">
<title>Simple Cloud Notifications</title>
<link rel="stylesheet" href="/css/toastify.min.css"/>
<link rel="stylesheet" href="/css/mini-default.min.css"> <!-- https://minicss.org/ -->
<link rel="stylesheet" href="/css/style.css">
<link rel="stylesheet" href="/css/mini-dark.min.css">
<link rel="stylesheet" href="/css/style-dark.css">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/png" href="/favicon.png"/>
<link rel="icon" type="image/png" href="/favicon.ico"/>

View File

@@ -0,0 +1,11 @@
<meta charset="utf-8">
<title>Simple Cloud Notifications</title>
<link rel="stylesheet" href="/css/toastify.min.css"/>
<link rel="stylesheet" href="/css/mini-default.min.css"> <!-- https://minicss.org/ -->
<link rel="stylesheet" href="/css/style.css">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/png" href="/favicon.png"/>
<link rel="icon" type="image/png" href="/favicon.ico"/>

View File

@@ -0,0 +1,69 @@
<!DOCTYPE html>
<html lang="en">
<head>
{{template|header.[theme].html}}
</head>
<body>
<div id="copyinfo">
<a tabindex="-1" href="https://www.blackforestbytes.com">&#169; blackforestbytes</a>
<a tabindex="-1" href="https://www.mikescher.com">made by Mike Schw&ouml;rer</a>
</div>
{{template|theme_switch.[theme].html}}
<form id="mainpnl">
<a tabindex="-1" href="https://play.google.com/store/apps/details?id=com.blackforestbytes.simplecloudnotifier" class="button bordered edge-btn" id="tl_link1"><span class="icn-google-play"></span></a>
<a tabindex="-1" href="#" class="button bordered edge-btn" id="tl_link2"><span class="icn-app-store"></span></a>
<a tabindex="-1" href="/api" class="button bordered edge-btn" id="tr_link">API</a>
<a tabindex="-1" href="/" class="linkcaption"><h1>Simple Cloud Notifier</h1></a>
<div class="row responsive-label">
<div class="col-sm-12 col-md-3"><label for="uid" class="doc">UserID</label></div>
<div class="col-sm-12 col-md"><input placeholder="UserID" id="uid" class="doc" type="number"></div>
</div>
<div class="row responsive-label">
<div class="col-sm-12 col-md-3"><label for="ukey" class="doc">Authentification Key</label></div>
<div class="col-sm-12 col-md"><input placeholder="Key" id="ukey" class="doc" type="text" maxlength="64"></div>
</div>
<div class="row responsive-label">
<div class="col-sm-12 col-md-3"><label for="chan" class="doc">Channel</label></div>
<div class="col-sm-12 col-md"><input placeholder="Channel Name" id="chan" class="doc" type="text" maxlength="80"></div>
</div>
<div class="row responsive-label">
<div class="col-sm-12 col-md-3"><label for="prio" class="doc">Priority</label></div>
<div class="col-sm-12 col-md">
<select id="prio" class="doc" type="text" style="width:100%;">
<option value="0" >Low</option>
<option value="1" selected>Normal</option>
<option value="2" >High</option>
</select>
</div>
</div>
<div class="row responsive-label">
<div class="col-sm-12 col-md-3"><label for="tit" class="doc">Message Title</label></div>
<div class="col-sm-12 col-md"><input placeholder="Message" id="tit" class="doc" type="text" maxlength="80"></div>
</div>
<div class="row responsive-label">
<div class="col-sm-12 col-md-3"><label for="cnt" class="doc">Message Content</label></div>
<div class="col-sm-12 col-md"><textarea id="cnt" class="doc" rows="8" maxlength="2048"></textarea></div>
</div>
<div class="row">
<div class="col-sm-12 col-md-3"></div>
<div class="col-sm-12 col-md"><button type="submit" class="primary bordered" id="btnSend">Send</button></div>
</div>
</form>
<script src="/js/logic.js" type="text/javascript" ></script>
<script src="/js/toastify.js"></script>
</body>
</html>

View File

@@ -0,0 +1,109 @@
function send()
{
let me = document.getElementById("btnSend");
if (me.classList.contains("btn-disabled")) return;
me.innerHTML = "<div class=\"spinnerbox\"><div class=\"spinner primary\"></div></div>";
me.classList.add("btn-disabled");
let uid = document.getElementById("uid");
let key = document.getElementById("ukey");
let tit = document.getElementById("tit");
let cnt = document.getElementById("cnt");
let pio = document.getElementById("prio");
let cha = document.getElementById("chan");
uid.classList.remove('input-invalid');
key.classList.remove('input-invalid');
msg.classList.remove('input-invalid');
cnt.classList.remove('input-invalid');
pio.classList.remove('input-invalid');
let data = new FormData();
data.append('user_id', uid.value);
data.append('user_key', key.value);
if (tit.value !== '') data.append('title', tit.value);
if (cnt.value !== '') data.append('content', cnt.value);
if (pio.value !== '') data.append('priority', pio.value);
if (cha.value !== '') data.append('channel', cha.value);
let xhr = new XMLHttpRequest();
xhr.open('POST', '/send.php', true);
xhr.onreadystatechange = function ()
{
if (xhr.readyState !== 4) return;
console.log('Status: ' + xhr.status);
if (xhr.status === 200 || xhr.status === 401 || xhr.status === 403 || xhr.status === 412)
{
let resp = JSON.parse(xhr.responseText);
if (!resp.success || xhr.status !== 200)
{
if (resp.errhighlight === 101) uid.classList.add('input-invalid');
if (resp.errhighlight === 102) key.classList.add('input-invalid');
if (resp.errhighlight === 103) tit.classList.add('input-invalid');
if (resp.errhighlight === 104) cnt.classList.add('input-invalid');
if (resp.errhighlight === 105) pio.classList.add('input-invalid');
if (resp.errhighlight === 106) cha.classList.add('input-invalid');
Toastify({
text: resp.message,
gravity: "top",
positionLeft: false,
backgroundColor: "#D32F2F",
}).showToast();
}
else
{
window.location.href =
'/message_sent' +
'?ok=' + 1 +
'&message_count=' + resp.messagecount +
'&quota=' + resp.quota +
'&quota_remain=' + (resp.quota_max-resp.quota) +
'&quota_max=' + resp.quota_max +
'&preset_user_id=' + uid.value +
'&preset_user_key=' + key.value +
'&preset_channel=' + cha.value;
}
}
else
{
Toastify({
text: 'Request failed: Statuscode=' + xhr.status,
gravity: "top",
positionLeft: false,
backgroundColor: "#D32F2F",
}).showToast();
}
me.classList.remove("btn-disabled");
me.innerHTML = "Send";
};
xhr.send(data);
}
window.addEventListener("load", function ()
{
const qp = new URLSearchParams(window.location.search);
let btn = document.getElementById("btnSend");
let uid = document.getElementById("uid");
let key = document.getElementById("ukey");
let tit = document.getElementById("tit");
let cnt = document.getElementById("cnt");
let pio = document.getElementById("prio");
let cha = document.getElementById("chan");
btn.onclick = function () { send(); return false; };
if (qp.has('preset_priority')) pio.selectedIndex = parseInt(qp.get("preset_priority"));
if (qp.has('preset_user_key')) key.value = qp.get("preset_user_key");
if (qp.has('preset_user_id')) uid.value = qp.get("preset_user_id");
if (qp.has('preset_title')) tit.value = qp.get("preset_title");
if (qp.has('preset_content')) cnt.value = qp.get("preset_content");
if (qp.has('preset_channel')) cha.value = qp.get("preset_channel");
}, false);

View File

@@ -0,0 +1,34 @@
window.addEventListener("load", function ()
{
const qp = new URLSearchParams(window.location.search);
const spanQuota1 = document.getElementById("insQuota1");
const spanQuota2 = document.getElementById("insQuota2");
const linkSucc = document.getElementById("succ_link");
const linkErr = document.getElementById("err_link");
spanQuota1.innerText = qp.get('quota_remain') ?? 'ERR';
spanQuota2.innerText = qp.get('quota_max') ?? 'ERR';
const preset_user_id = qp.get('preset_user_id') ?? 'ERR';
const preset_user_key = qp.get('preset_user_key') ?? 'ERR';
let hrefBack = "/?preset_user_id="+preset_user_id+"&preset_user_key="+preset_user_key
if (qp.has('preset_channel') && qp.get('preset_channel') !== '') hrefBack += "&preset_channel="+qp.get('preset_channel')
linkSucc.setAttribute("href", hrefBack);
if (qp.get("ok") === "1") {
linkSucc.classList.remove('display_none');
linkErr.classList.add('display_none');
} else {
linkSucc.classList.add('display_none');
linkErr.classList.remove('display_none');
}
}, false);

View File

@@ -0,0 +1,8 @@
/**
* Minified by jsDelivr using UglifyJS v3.4.3.
* Original file: /npm/toastify-js@1.3.0/src/toastify.js
*
* Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files
*/
!function(t,o){"object"==typeof module&&module.exports?(require("./toastify.css"),module.exports=o()):t.Toastify=o()}(this,function(t){var i=function(t){return new i.lib.init(t)};function r(t,o){return!(!t||"string"!=typeof o)&&!!(t.className&&-1<t.className.trim().split(/\s+/gi).indexOf(o))}return i.lib=i.prototype={toastify:"1.2.2",constructor:i,init:function(t){return t||(t={}),this.options={},this.options.text=t.text||"Hi there!",this.options.duration=t.duration||3e3,this.options.selector=t.selector,this.options.callback=t.callback||function(){},this.options.destination=t.destination,this.options.newWindow=t.newWindow||!1,this.options.close=t.close||!1,this.options.gravity="bottom"==t.gravity?"bottom":"top",this.options.positionLeft=t.positionLeft||!1,this.options.backgroundColor=t.backgroundColor,this.options.avatar=t.avatar||"",this.options.className=t.className||"",this},buildToast:function(){if(!this.options)throw"Toastify is not initialized";var t=document.createElement("div");if(t.className="toastify on "+this.options.className,!0===this.options.positionLeft?t.className+=" left":t.className+=" right",t.className+=" "+this.options.gravity,this.options.backgroundColor&&(t.style.background=this.options.backgroundColor),t.innerHTML=this.options.text,""!==this.options.avatar){var o=document.createElement("img");o.src=this.options.avatar,o.className="avatar",!0===this.options.positionLeft?t.appendChild(o):t.insertAdjacentElement("beforeend",o)}if(!0===this.options.close){var i=document.createElement("span");i.innerHTML="&#10006;",i.className="toast-close",i.addEventListener("click",function(t){t.stopPropagation(),this.removeElement(t.target.parentElement),window.clearTimeout(t.target.parentElement.timeOutValue)}.bind(this));var n=0<window.innerWidth?window.innerWidth:screen.width;!0===this.options.positionLeft&&360<n?t.insertAdjacentElement("afterbegin",i):t.appendChild(i)}return void 0!==this.options.destination&&t.addEventListener("click",function(t){t.stopPropagation(),!0===this.options.newWindow?window.open(this.options.destination,"_blank"):window.location=this.options.destination}.bind(this)),t},showToast:function(){var t,o=this.buildToast();if(!(t=void 0===this.options.selector?document.body:document.getElementById(this.options.selector)))throw"Root element is not defined";return t.insertBefore(o,t.firstChild),i.reposition(),o.timeOutValue=window.setTimeout(function(){this.removeElement(o)}.bind(this),this.options.duration),this},removeElement:function(t){t.className=t.className.replace(" on",""),window.setTimeout(function(){t.parentNode.removeChild(t),this.options.callback.call(t),i.reposition()}.bind(this),400)}},i.reposition=function(){for(var t,o={top:15,bottom:15},i={top:15,bottom:15},n={top:15,bottom:15},e=document.getElementsByClassName("toastify"),s=0;s<e.length;s++){t=!0===r(e[s],"top")?"top":"bottom";var a=e[s].offsetHeight;(0<window.innerWidth?window.innerWidth:screen.width)<=360?(e[s].style[t]=n[t]+"px",n[t]+=a+15):!0===r(e[s],"left")?(e[s].style[t]=o[t]+"px",o[t]+=a+15):(e[s].style[t]=i[t]+"px",i[t]+=a+15)}return this},i.lib.init.prototype=i.lib,i});
//# sourceMappingURL=/sm/3f68e387be4f7a323a891120e4e01e3bee54a927113a386cf5e598b3cd442fcc.map

View File

@@ -0,0 +1,49 @@
<!DOCTYPE html>
<html lang="en">
<head>
{{template|header.[theme].html}}
</head>
<body>
<div id="copyinfo">
<a tabindex="-1" href="https://www.blackforestbytes.com">&#169; blackforestbytes</a>
<a tabindex="-1" href="https://www.mikescher.com">made by Mike Schw&ouml;rer</a>
</div>
{{template|theme_switch.[theme].html}}
<div id="mainpnl">
<a tabindex="-1" href="https://play.google.com/store/apps/details?id=com.blackforestbytes.simplecloudnotifier" class="button bordered edge-btn" id="tl_link1"><span class="icn-google-play"></span></a>
<a tabindex="-1" href="#" class="button bordered edge-btn" id="tl_link2"><span class="icn-app-store"></span></a>
<a tabindex="-1" href="/" class="button bordered edge-btn" id="tr_link">Send</a>
<a tabindex="-1" href="/" class="linkcaption"><h1>Simple Cloud Notifier</h1></a>
<div class="fullcenterflex">
<a id="succ_link" class="display_none card success" href="/">
<div class="section">
<h3 class="doc">Message sent</h3>
<p class="doc">Message succesfully sent<br>
<span id="insQuota1">ERR</span>/<span id="insQuota2">ERR</span> remaining</p>
</div>
</a>
<a id="err_link" class="card error" href="/">
<div class="section">
<h3 class="doc">Failure</h3>
<p class="doc">Unknown error</p>
</div>
</a>
</div>
</div>
<script src="/js/message_sent.js" type="text/javascript" ></script>
</body>
</html>

View File

@@ -0,0 +1,138 @@
<!-- https://hilite.me/ | bash | monokai -->
<!-- HTML generated using hilite.me -->
<pre style="color:#7e7e7e; margin: 0; line-height: 125%" class="yellow-code">
<span style="color: #75715e">#!/usr/bin/env bash</span>
<span style="color: #75715e">#</span>
<span style="color: #75715e"># Wrapper around SCN ( https://scn.blackforestbytes.com/ )</span>
<span style="color: #75715e"># ========================================================</span>
<span style="color: #75715e">#</span>
<span style="color: #75715e"># ./scn_send [@channel] title [content] [priority]</span>
<span style="color: #75715e">#</span>
<span style="color: #75715e">#</span>
<span style="color: #75715e"># Call with scn_send &quot;${title}&quot;</span>
<span style="color: #75715e"># or scn_send &quot;${title}&quot; ${content}&quot;</span>
<span style="color: #75715e"># or scn_send &quot;${title}&quot; ${content}&quot; &quot;${priority:0|1|2}&quot;</span>
<span style="color: #75715e"># or scn_send &quot;@${channel} &quot;${title}&quot;</span>
<span style="color: #75715e"># or scn_send &quot;@${channel} &quot;${title}&quot; ${content}&quot;</span>
<span style="color: #75715e"># or scn_send &quot;@${channel} &quot;${title}&quot; ${content}&quot; &quot;${priority:0|1|2}&quot;</span>
<span style="color: #75715e">#</span>
<span style="color: #75715e">#</span>
<span style="color: #75715e">################################################################################</span>
<span style="color: #75715e"># INSERT YOUR DATA HERE #</span>
<span style="color: #75715e">################################################################################</span>
<span style="color: #f8f8f2">user_id</span><span style="color: #f92672">=</span><span style="color: #e6db74">&quot;999&quot;</span>
<span style="color: #f8f8f2">user_key</span><span style="color: #f92672">=</span><span style="color: #e6db74">&quot;??&quot;</span>
<span style="color: #75715e">################################################################################</span>
usage<span style="color: #f92672">()</span> <span style="color: #f92672">{</span>
<span style="color: #f8f8f2">echo</span> <span style="color: #e6db74">&quot;Usage: &quot;</span>
<span style="color: #f8f8f2">echo</span> <span style="color: #e6db74">&quot; scn_send [@channel] title [content] [priority]&quot;</span>
<span style="color: #f8f8f2">echo</span> <span style="color: #e6db74">&quot;&quot;</span>
<span style="color: #f92672">}</span>
<span style="color: #f8f8f2">args</span><span style="color: #f92672">=(</span> <span style="color: #e6db74">&quot;$@&quot;</span> <span style="color: #f92672">)</span>
<span style="color: #f8f8f2">title</span><span style="color: #f92672">=</span><span style="color: #f8f8f2">$1</span>
<span style="color: #f8f8f2">content</span><span style="color: #f92672">=</span><span style="color: #e6db74">&quot;&quot;</span>
<span style="color: #f8f8f2">channel</span><span style="color: #f92672">=</span><span style="color: #e6db74">&quot;&quot;</span>
<span style="color: #f8f8f2">priority</span><span style="color: #f92672">=</span>1
<span style="color: #f8f8f2">usr_msg_id</span><span style="color: #f92672">=</span><span style="color: #e6db74">&quot;$(uuidgen)&quot;</span>
<span style="color: #f8f8f2">sendtime</span><span style="color: #f92672">=</span><span style="color: #e6db74">&quot;$(date +%s)&quot;</span>
<span style="color: #f8f8f2">sender</span><span style="color: #f92672">=</span><span style="color: #e6db74">&quot;$(hostname)&quot;</span>
<span style="color: #66d9ef">if</span> <span style="color: #f92672">[</span> <span style="color: #66d9ef">${#</span><span style="color: #f8f8f2">args[@]</span><span style="color: #66d9ef">}</span> -lt 1 <span style="color: #f92672">]</span>; <span style="color: #66d9ef">then</span>
<span style="color: #66d9ef"> </span><span style="color: #f8f8f2">echo</span> <span style="color: #e6db74">&quot;[ERROR]: no title supplied via parameter&quot;</span> 1&gt;&amp;2
usage
<span style="color: #f8f8f2">exit </span>1
<span style="color: #66d9ef">fi</span>
<span style="color: #66d9ef">if</span> <span style="color: #f92672">[[</span> <span style="color: #e6db74">&quot;${args[0]}&quot;</span> <span style="color: #f92672">=</span>~ ^@.* <span style="color: #f92672">]]</span>; <span style="color: #66d9ef">then</span>
<span style="color: #66d9ef"> </span><span style="color: #f8f8f2">channel</span><span style="color: #f92672">=</span><span style="color: #e6db74">&quot;${args[0]}&quot;</span>
<span style="color: #f8f8f2">unset</span> <span style="color: #e6db74">&quot;args[0]&quot;</span>
<span style="color: #f8f8f2">channel</span><span style="color: #f92672">=</span><span style="color: #e6db74">&quot;${channel:1}&quot;</span>
<span style="color: #66d9ef">fi</span>
<span style="color: #66d9ef">if</span> <span style="color: #f92672">[</span> <span style="color: #66d9ef">${#</span><span style="color: #f8f8f2">args[@]</span><span style="color: #66d9ef">}</span> -lt 1 <span style="color: #f92672">]</span>; <span style="color: #66d9ef">then</span>
<span style="color: #66d9ef"> </span><span style="color: #f8f8f2">echo</span> <span style="color: #e6db74">&quot;[ERROR]: no title supplied via parameter&quot;</span> 1&gt;&amp;2
usage
<span style="color: #f8f8f2">exit </span>1
<span style="color: #66d9ef">fi</span>
<span style="color: #f8f8f2">title</span><span style="color: #f92672">=</span><span style="color: #e6db74">&quot;${args[0]}&quot;</span>
<span style="color: #f8f8f2">content</span><span style="color: #f92672">=</span><span style="color: #e6db74">&quot;&quot;</span>
<span style="color: #66d9ef">if</span> <span style="color: #f92672">[</span> <span style="color: #66d9ef">${#</span><span style="color: #f8f8f2">args[@]</span><span style="color: #66d9ef">}</span> -gt 1 <span style="color: #f92672">]</span>; <span style="color: #66d9ef">then</span>
<span style="color: #66d9ef"> </span><span style="color: #f8f8f2">content</span><span style="color: #f92672">=</span><span style="color: #e6db74">&quot;${args[0]}&quot;</span>
<span style="color: #f8f8f2">unset</span> <span style="color: #e6db74">&quot;args[0]&quot;</span>
<span style="color: #66d9ef">fi</span>
<span style="color: #66d9ef">if</span> <span style="color: #f92672">[</span> <span style="color: #66d9ef">${#</span><span style="color: #f8f8f2">args[@]</span><span style="color: #66d9ef">}</span> -gt 1 <span style="color: #f92672">]</span>; <span style="color: #66d9ef">then</span>
<span style="color: #66d9ef"> </span><span style="color: #f8f8f2">priority</span><span style="color: #f92672">=</span><span style="color: #e6db74">&quot;${args[0]}&quot;</span>
<span style="color: #f8f8f2">unset</span> <span style="color: #e6db74">&quot;args[0]&quot;</span>
<span style="color: #66d9ef">fi</span>
<span style="color: #66d9ef">if</span> <span style="color: #f92672">[</span> <span style="color: #66d9ef">${#</span><span style="color: #f8f8f2">args[@]</span><span style="color: #66d9ef">}</span> -gt 1 <span style="color: #f92672">]</span>; <span style="color: #66d9ef">then</span>
<span style="color: #66d9ef"> </span><span style="color: #f8f8f2">echo</span> <span style="color: #e6db74">&quot;Too many arguments to scn_send&quot;</span> 1&gt;&amp;2
usage
<span style="color: #f8f8f2">exit </span>1
<span style="color: #66d9ef">fi</span>
<span style="color: #66d9ef">while </span><span style="color: #f8f8f2">true</span> ; <span style="color: #66d9ef">do</span>
<span style="color: #66d9ef"> </span><span style="color: #f8f8f2">curlresp</span><span style="color: #f92672">=</span><span style="color: #66d9ef">$(</span>curl --silent <span style="color: #ae81ff">\</span>
--output /dev/null <span style="color: #ae81ff">\</span>
--write-out <span style="color: #e6db74">&quot;%{http_code}&quot;</span> <span style="color: #ae81ff">\</span>
--data <span style="color: #e6db74">&quot;user_id=$user_id&quot;</span> <span style="color: #ae81ff">\</span>
--data <span style="color: #e6db74">&quot;user_key=$user_key&quot;</span> <span style="color: #ae81ff">\</span>
--data <span style="color: #e6db74">&quot;title=$title&quot;</span> <span style="color: #ae81ff">\</span>
--data <span style="color: #e6db74">&quot;timestamp=$sendtime&quot;</span> <span style="color: #ae81ff">\</span>
--data <span style="color: #e6db74">&quot;content=$content&quot;</span> <span style="color: #ae81ff">\</span>
--data <span style="color: #e6db74">&quot;priority=$priority&quot;</span> <span style="color: #ae81ff">\</span>
--data <span style="color: #e6db74">&quot;msg_id=$usr_msg_id&quot;</span> <span style="color: #ae81ff">\</span>
--data <span style="color: #e6db74">&quot;channel=$channel&quot;</span> <span style="color: #ae81ff">\</span>
--data <span style="color: #e6db74">&quot;sender_name=$sender&quot;</span> <span style="color: #ae81ff">\</span>
<span style="color: #e6db74">&quot;https://scn.blackforestbytes.com/&quot;</span> <span style="color: #66d9ef">)</span>
<span style="color: #66d9ef">if</span> <span style="color: #f92672">[</span> <span style="color: #e6db74">&quot;$curlresp&quot;</span> <span style="color: #f92672">==</span> 200 <span style="color: #f92672">]</span> ; <span style="color: #66d9ef">then</span>
<span style="color: #66d9ef"> </span><span style="color: #f8f8f2">echo</span> <span style="color: #e6db74">&quot;Successfully send&quot;</span>
<span style="color: #f8f8f2">exit </span>0
<span style="color: #66d9ef">fi</span>
<span style="color: #66d9ef"> if</span> <span style="color: #f92672">[</span> <span style="color: #e6db74">&quot;$curlresp&quot;</span> <span style="color: #f92672">==</span> 400 <span style="color: #f92672">]</span> ; <span style="color: #66d9ef">then</span>
<span style="color: #66d9ef"> </span><span style="color: #f8f8f2">echo</span> <span style="color: #e6db74">&quot;Bad request - something went wrong&quot;</span> 1&gt;&amp;2
<span style="color: #f8f8f2">exit </span>1
<span style="color: #66d9ef">fi</span>
<span style="color: #66d9ef"> if</span> <span style="color: #f92672">[</span> <span style="color: #e6db74">&quot;$curlresp&quot;</span> <span style="color: #f92672">==</span> 401 <span style="color: #f92672">]</span> ; <span style="color: #66d9ef">then</span>
<span style="color: #66d9ef"> </span><span style="color: #f8f8f2">echo</span> <span style="color: #e6db74">&quot;Unauthorized - wrong userid/userkey&quot;</span> 1&gt;&amp;2
<span style="color: #f8f8f2">exit </span>1
<span style="color: #66d9ef">fi</span>
<span style="color: #66d9ef"> if</span> <span style="color: #f92672">[</span> <span style="color: #e6db74">&quot;$curlresp&quot;</span> <span style="color: #f92672">==</span> 403 <span style="color: #f92672">]</span> ; <span style="color: #66d9ef">then</span>
<span style="color: #66d9ef"> </span><span style="color: #f8f8f2">echo</span> <span style="color: #e6db74">&quot;Quota exceeded - wait one hour before re-try&quot;</span> 1&gt;&amp;2
sleep 3600
<span style="color: #66d9ef">fi</span>
<span style="color: #66d9ef"> if</span> <span style="color: #f92672">[</span> <span style="color: #e6db74">&quot;$curlresp&quot;</span> <span style="color: #f92672">==</span> 412 <span style="color: #f92672">]</span> ; <span style="color: #66d9ef">then</span>
<span style="color: #66d9ef"> </span><span style="color: #f8f8f2">echo</span> <span style="color: #e6db74">&quot;Precondition Failed - No device linked&quot;</span> 1&gt;&amp;2
<span style="color: #f8f8f2">exit </span>1
<span style="color: #66d9ef">fi</span>
<span style="color: #66d9ef"> if</span> <span style="color: #f92672">[</span> <span style="color: #e6db74">&quot;$curlresp&quot;</span> <span style="color: #f92672">==</span> 500 <span style="color: #f92672">]</span> ; <span style="color: #66d9ef">then</span>
<span style="color: #66d9ef"> </span><span style="color: #f8f8f2">echo</span> <span style="color: #e6db74">&quot;Internal server error - waiting for better times&quot;</span> 1&gt;&amp;2
sleep 60
<span style="color: #66d9ef">fi</span>
<span style="color: #75715e"># if none of the above matched we probably hav no network ...</span>
<span style="color: #f8f8f2">echo</span> <span style="color: #e6db74">&quot;Send failed (response code $curlresp) ... try again in 5s&quot;</span> 1&gt;&amp;2
sleep 5
<span style="color: #66d9ef">done</span>
</pre>

View File

@@ -0,0 +1,136 @@
<!-- https://hilite.me/ | bash | borland -->
<!-- HTML generated using hilite.me -->
<pre style="color:#000000; margin: 0; line-height: 125%" class="yellow-code">
<span style="color: #008800; font-style: italic">#!/usr/bin/env bash</span>
<span style="color: #008800; font-style: italic">#</span>
<span style="color: #008800; font-style: italic"># Wrapper around SCN ( https://scn.blackforestbytes.com/ )</span>
<span style="color: #008800; font-style: italic"># ========================================================</span>
<span style="color: #008800; font-style: italic">#</span>
<span style="color: #008800; font-style: italic"># ./scn_send [@channel] title [content] [priority]</span>
<span style="color: #008800; font-style: italic">#</span>
<span style="color: #008800; font-style: italic">#</span>
<span style="color: #008800; font-style: italic"># Call with scn_send &quot;${title}&quot;</span>
<span style="color: #008800; font-style: italic"># or scn_send &quot;${title}&quot; ${content}&quot;</span>
<span style="color: #008800; font-style: italic"># or scn_send &quot;${title}&quot; ${content}&quot; &quot;${priority:0|1|2}&quot;</span>
<span style="color: #008800; font-style: italic"># or scn_send &quot;@${channel} &quot;${title}&quot;</span>
<span style="color: #008800; font-style: italic"># or scn_send &quot;@${channel} &quot;${title}&quot; ${content}&quot;</span>
<span style="color: #008800; font-style: italic"># or scn_send &quot;@${channel} &quot;${title}&quot; ${content}&quot; &quot;${priority:0|1|2}&quot;</span>
<span style="color: #008800; font-style: italic">#</span>
<span style="color: #008800; font-style: italic">#</span>
<span style="color: #008800; font-style: italic">################################################################################</span>
<span style="color: #008800; font-style: italic"># INSERT YOUR DATA HERE #</span>
<span style="color: #008800; font-style: italic">################################################################################</span>
user_id=<span style="color: #0000FF">&quot;999&quot;</span>
user_key=<span style="color: #0000FF">&quot;??&quot;</span>
<span style="color: #008800; font-style: italic">################################################################################</span>
usage() {
echo <span style="color: #0000FF">&quot;Usage: &quot;</span>
echo <span style="color: #0000FF">&quot; scn_send [@channel] title [content] [priority]&quot;</span>
echo <span style="color: #0000FF">&quot;&quot;</span>
}
args=( <span style="color: #0000FF">&quot;$@&quot;</span> )
title=$1
content=<span style="color: #0000FF">&quot;&quot;</span>
channel=<span style="color: #0000FF">&quot;&quot;</span>
priority=1
usr_msg_id=<span style="color: #0000FF">&quot;$(uuidgen)&quot;</span>
sendtime=<span style="color: #0000FF">&quot;$(date +%s)&quot;</span>
sender=<span style="color: #0000FF">&quot;$(hostname)&quot;</span>
<span style="color: #000080; font-weight: bold">if</span> [ <span style="color: #000080; font-weight: bold">${#</span>args[@]<span style="color: #000080; font-weight: bold">}</span> -lt 1 ]; <span style="color: #000080; font-weight: bold">then</span>
<span style="color: #000080; font-weight: bold"> </span>echo <span style="color: #0000FF">&quot;[ERROR]: no title supplied via parameter&quot;</span> 1&gt;&amp;2
usage
exit 1
<span style="color: #000080; font-weight: bold">fi</span>
<span style="color: #000080; font-weight: bold">if</span> [[ <span style="color: #0000FF">&quot;${args[0]}&quot;</span> =~ ^@.* ]]; <span style="color: #000080; font-weight: bold">then</span>
<span style="color: #000080; font-weight: bold"> </span>channel=<span style="color: #0000FF">&quot;${args[0]}&quot;</span>
unset <span style="color: #0000FF">&quot;args[0]&quot;</span>
channel=<span style="color: #0000FF">&quot;${channel:1}&quot;</span>
<span style="color: #000080; font-weight: bold">fi</span>
<span style="color: #000080; font-weight: bold">if</span> [ <span style="color: #000080; font-weight: bold">${#</span>args[@]<span style="color: #000080; font-weight: bold">}</span> -lt 1 ]; <span style="color: #000080; font-weight: bold">then</span>
<span style="color: #000080; font-weight: bold"> </span>echo <span style="color: #0000FF">&quot;[ERROR]: no title supplied via parameter&quot;</span> 1&gt;&amp;2
usage
exit 1
<span style="color: #000080; font-weight: bold">fi</span>
title=<span style="color: #0000FF">&quot;${args[0]}&quot;</span>
content=<span style="color: #0000FF">&quot;&quot;</span>
<span style="color: #000080; font-weight: bold">if</span> [ <span style="color: #000080; font-weight: bold">${#</span>args[@]<span style="color: #000080; font-weight: bold">}</span> -gt 1 ]; <span style="color: #000080; font-weight: bold">then</span>
<span style="color: #000080; font-weight: bold"> </span>content=<span style="color: #0000FF">&quot;${args[0]}&quot;</span>
unset <span style="color: #0000FF">&quot;args[0]&quot;</span>
<span style="color: #000080; font-weight: bold">fi</span>
<span style="color: #000080; font-weight: bold">if</span> [ <span style="color: #000080; font-weight: bold">${#</span>args[@]<span style="color: #000080; font-weight: bold">}</span> -gt 1 ]; <span style="color: #000080; font-weight: bold">then</span>
<span style="color: #000080; font-weight: bold"> </span>priority=<span style="color: #0000FF">&quot;${args[0]}&quot;</span>
unset <span style="color: #0000FF">&quot;args[0]&quot;</span>
<span style="color: #000080; font-weight: bold">fi</span>
<span style="color: #000080; font-weight: bold">if</span> [ <span style="color: #000080; font-weight: bold">${#</span>args[@]<span style="color: #000080; font-weight: bold">}</span> -gt 1 ]; <span style="color: #000080; font-weight: bold">then</span>
<span style="color: #000080; font-weight: bold"> </span>echo <span style="color: #0000FF">&quot;Too many arguments to scn_send&quot;</span> 1&gt;&amp;2
usage
exit 1
<span style="color: #000080; font-weight: bold">fi</span>
<span style="color: #000080; font-weight: bold">while </span>true ; <span style="color: #000080; font-weight: bold">do</span>
<span style="color: #000080; font-weight: bold"> </span>curlresp=<span style="color: #000080; font-weight: bold">$(</span>curl --silent <span style="color: #0000FF">\</span>
--output /dev/null <span style="color: #0000FF">\</span>
--write-out <span style="color: #0000FF">&quot;%{http_code}&quot;</span> <span style="color: #0000FF">\</span>
--data <span style="color: #0000FF">&quot;user_id=$user_id&quot;</span> <span style="color: #0000FF">\</span>
--data <span style="color: #0000FF">&quot;user_key=$user_key&quot;</span> <span style="color: #0000FF">\</span>
--data <span style="color: #0000FF">&quot;title=$title&quot;</span> <span style="color: #0000FF">\</span>
--data <span style="color: #0000FF">&quot;timestamp=$sendtime&quot;</span> <span style="color: #0000FF">\</span>
--data <span style="color: #0000FF">&quot;content=$content&quot;</span> <span style="color: #0000FF">\</span>
--data <span style="color: #0000FF">&quot;priority=$priority&quot;</span> <span style="color: #0000FF">\</span>
--data <span style="color: #0000FF">&quot;msg_id=$usr_msg_id&quot;</span> <span style="color: #0000FF">\</span>
--data <span style="color: #0000FF">&quot;channel=$channel&quot;</span> <span style="color: #0000FF">\</span>
--data <span style="color: #0000FF">&quot;sender_name=$sender&quot;</span> <span style="color: #0000FF">\</span>
<span style="color: #0000FF">&quot;https://scn.blackforestbytes.com/&quot;</span> <span style="color: #000080; font-weight: bold">)</span>
<span style="color: #000080; font-weight: bold">if</span> [ <span style="color: #0000FF">&quot;$curlresp&quot;</span> == 200 ] ; <span style="color: #000080; font-weight: bold">then</span>
<span style="color: #000080; font-weight: bold"> </span>echo <span style="color: #0000FF">&quot;Successfully send&quot;</span>
exit 0
<span style="color: #000080; font-weight: bold">fi</span>
<span style="color: #000080; font-weight: bold"> if</span> [ <span style="color: #0000FF">&quot;$curlresp&quot;</span> == 400 ] ; <span style="color: #000080; font-weight: bold">then</span>
<span style="color: #000080; font-weight: bold"> </span>echo <span style="color: #0000FF">&quot;Bad request - something went wrong&quot;</span> 1&gt;&amp;2
exit 1
<span style="color: #000080; font-weight: bold">fi</span>
<span style="color: #000080; font-weight: bold"> if</span> [ <span style="color: #0000FF">&quot;$curlresp&quot;</span> == 401 ] ; <span style="color: #000080; font-weight: bold">then</span>
<span style="color: #000080; font-weight: bold"> </span>echo <span style="color: #0000FF">&quot;Unauthorized - wrong userid/userkey&quot;</span> 1&gt;&amp;2
exit 1
<span style="color: #000080; font-weight: bold">fi</span>
<span style="color: #000080; font-weight: bold"> if</span> [ <span style="color: #0000FF">&quot;$curlresp&quot;</span> == 403 ] ; <span style="color: #000080; font-weight: bold">then</span>
<span style="color: #000080; font-weight: bold"> </span>echo <span style="color: #0000FF">&quot;Quota exceeded - wait one hour before re-try&quot;</span> 1&gt;&amp;2
sleep 3600
<span style="color: #000080; font-weight: bold">fi</span>
<span style="color: #000080; font-weight: bold"> if</span> [ <span style="color: #0000FF">&quot;$curlresp&quot;</span> == 412 ] ; <span style="color: #000080; font-weight: bold">then</span>
<span style="color: #000080; font-weight: bold"> </span>echo <span style="color: #0000FF">&quot;Precondition Failed - No device linked&quot;</span> 1&gt;&amp;2
exit 1
<span style="color: #000080; font-weight: bold">fi</span>
<span style="color: #000080; font-weight: bold"> if</span> [ <span style="color: #0000FF">&quot;$curlresp&quot;</span> == 500 ] ; <span style="color: #000080; font-weight: bold">then</span>
<span style="color: #000080; font-weight: bold"> </span>echo <span style="color: #0000FF">&quot;Internal server error - waiting for better times&quot;</span> 1&gt;&amp;2
sleep 60
<span style="color: #000080; font-weight: bold">fi</span>
<span style="color: #008800; font-style: italic"># if none of the above matched we probably hav no network ...</span>
echo <span style="color: #0000FF">&quot;Send failed (response code $curlresp) ... try again in 5s&quot;</span> 1&gt;&amp;2
sleep 5
<span style="color: #000080; font-weight: bold">done</span>
</pre>

View File

@@ -0,0 +1,26 @@
<div id="theme-switch">
<svg xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="32px" height="32px" viewBox="0 0 493.761 493.762">
<path d="M290.652,402.646h-87.595c-6.781,0-12.283,5.503-12.283,12.283c0,6.785,5.502,12.287,12.283,12.287h87.595 c6.781,0,12.289-5.502,12.289-12.287C302.942,408.149,297.435,402.646,290.652,402.646z"/>
<path d="M224.299,474.245c1.666,11.026,11.086,19.517,22.586,19.517c11.488,0,20.93-8.487,22.589-19.517 c15.037-0.888,26.987-13.245,26.987-28.504H197.25C197.25,461.009,209.235,473.375,224.299,474.245z"/>
<path d="M246.884,70.87c9.062,0,16.387-7.335,16.387-16.381V16.381C263.271,7.332,255.947,0,246.884,0 c-9.053,0-16.377,7.332-16.377,16.381v38.108C230.508,63.535,237.832,70.87,246.884,70.87z"/>
<path d="M139.39,94.736c3.217,4.417,8.209,6.761,13.283,6.761c3.326,0,6.699-1.017,9.609-3.129 c7.313-5.312,8.945-15.555,3.633-22.873l-22.396-30.84c-5.326-7.312-15.549-8.96-22.887-3.632 c-7.311,5.309-8.943,15.555-3.631,22.873L139.39,94.736z"/>
<path d="M354.354,334.861c-5.313-7.312-15.549-8.934-22.881-3.621c-7.306,5.317-8.937,15.562-3.61,22.879l22.409,30.841 c3.196,4.407,8.188,6.753,13.265,6.753c3.338,0,6.698-1.017,9.608-3.128c7.312-5.319,8.942-15.565,3.619-22.884L354.354,334.861 z"/>
<path d="M99.502,149.684l-36.252-11.79c-8.686-2.799-17.846,1.911-20.648,10.518c-2.803,8.597,1.904,17.843,10.508,20.642 l36.252,11.79c1.693,0.544,3.387,0.809,5.066,0.809c6.91,0,13.324-4.4,15.582-11.327 C112.812,161.729,108.106,152.482,99.502,149.684z"/>
<path d="M440.649,260.538l-36.243-11.773c-8.611-2.778-17.841,1.918-20.638,10.516c-2.802,8.606,1.918,17.848,10.521,20.646 l36.252,11.772c1.681,0.545,3.373,0.807,5.054,0.807c6.909,0,13.323-4.407,15.581-11.324 C453.971,272.572,449.258,263.337,440.649,260.538z"/>
<path d="M89.375,248.765L53.11,260.522c-8.604,2.79-13.324,12.026-10.521,20.635c2.238,6.927,8.664,11.334,15.574,11.334 c1.668,0,3.381-0.267,5.061-0.811l36.258-11.756c8.611-2.792,13.33-12.03,10.529-20.635 C107.229,250.689,98.059,245.986,89.375,248.765z"/>
<path d="M399.35,181.653c1.681,0,3.373-0.265,5.056-0.809l36.243-11.773c8.608-2.799,13.322-12.039,10.526-20.642 c-2.803-8.6-12.077-13.3-20.635-10.518l-36.252,11.772c-8.604,2.798-13.322,12.038-10.521,20.642 C386.02,177.246,392.44,181.653,399.35,181.653z"/>
<path d="M139.412,334.855l-22.431,30.822c-5.326,7.318-3.707,17.563,3.619,22.883c2.896,2.119,6.27,3.138,9.609,3.138 c5.074,0,10.066-2.336,13.264-6.744l22.43-30.824c5.326-7.316,3.707-17.562-3.619-22.883 C154.991,325.898,144.702,327.538,139.412,334.855z"/>
<path d="M350.258,44.654l-22.396,30.84c-5.312,7.318-3.681,17.562,3.633,22.873c2.91,2.112,6.283,3.129,9.608,3.129 c5.074,0,10.065-2.343,13.276-6.761l22.396-30.841c5.311-7.318,3.68-17.564-3.634-22.873 C365.786,35.68,355.584,37.326,350.258,44.654z"/>
<path d="M365.194,215.404c0-65.354-52.976-118.333-118.322-118.333c-65.359,0-118.336,52.979-118.336,118.333 c0,27.569,9.482,52.884,25.322,72.981c13.881,17.612,27.027,36.839,38.42,56.187v39.306h108.516v-38.263 c11.288-18.818,25.881-40.484,39.065-57.211C355.713,268.301,365.194,242.991,365.194,215.404z"/>
</svg>
</div>
<script type="application/javascript">
window.addEventListener("load", function () {
document.getElementById("theme-switch").onclick = function () {
document.cookie = "theme=light";
location.reload();
return false;
};
});
</script>

View File

@@ -0,0 +1,26 @@
<div id="theme-switch">
<svg xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="32px" height="32px" viewBox="0 0 493.761 493.762">
<path d="M290.652,402.646h-87.595c-6.781,0-12.283,5.503-12.283,12.283c0,6.785,5.502,12.287,12.283,12.287h87.595 c6.781,0,12.289-5.502,12.289-12.287C302.942,408.149,297.435,402.646,290.652,402.646z"/>
<path d="M224.299,474.245c1.666,11.026,11.086,19.517,22.586,19.517c11.488,0,20.93-8.487,22.589-19.517 c15.037-0.888,26.987-13.245,26.987-28.504H197.25C197.25,461.009,209.235,473.375,224.299,474.245z"/>
<path d="M246.884,70.87c9.062,0,16.387-7.335,16.387-16.381V16.381C263.271,7.332,255.947,0,246.884,0 c-9.053,0-16.377,7.332-16.377,16.381v38.108C230.508,63.535,237.832,70.87,246.884,70.87z"/>
<path d="M139.39,94.736c3.217,4.417,8.209,6.761,13.283,6.761c3.326,0,6.699-1.017,9.609-3.129 c7.313-5.312,8.945-15.555,3.633-22.873l-22.396-30.84c-5.326-7.312-15.549-8.96-22.887-3.632 c-7.311,5.309-8.943,15.555-3.631,22.873L139.39,94.736z"/>
<path d="M354.354,334.861c-5.313-7.312-15.549-8.934-22.881-3.621c-7.306,5.317-8.937,15.562-3.61,22.879l22.409,30.841 c3.196,4.407,8.188,6.753,13.265,6.753c3.338,0,6.698-1.017,9.608-3.128c7.312-5.319,8.942-15.565,3.619-22.884L354.354,334.861 z"/>
<path d="M99.502,149.684l-36.252-11.79c-8.686-2.799-17.846,1.911-20.648,10.518c-2.803,8.597,1.904,17.843,10.508,20.642 l36.252,11.79c1.693,0.544,3.387,0.809,5.066,0.809c6.91,0,13.324-4.4,15.582-11.327 C112.812,161.729,108.106,152.482,99.502,149.684z"/>
<path d="M440.649,260.538l-36.243-11.773c-8.611-2.778-17.841,1.918-20.638,10.516c-2.802,8.606,1.918,17.848,10.521,20.646 l36.252,11.772c1.681,0.545,3.373,0.807,5.054,0.807c6.909,0,13.323-4.407,15.581-11.324 C453.971,272.572,449.258,263.337,440.649,260.538z"/>
<path d="M89.375,248.765L53.11,260.522c-8.604,2.79-13.324,12.026-10.521,20.635c2.238,6.927,8.664,11.334,15.574,11.334 c1.668,0,3.381-0.267,5.061-0.811l36.258-11.756c8.611-2.792,13.33-12.03,10.529-20.635 C107.229,250.689,98.059,245.986,89.375,248.765z"/>
<path d="M399.35,181.653c1.681,0,3.373-0.265,5.056-0.809l36.243-11.773c8.608-2.799,13.322-12.039,10.526-20.642 c-2.803-8.6-12.077-13.3-20.635-10.518l-36.252,11.772c-8.604,2.798-13.322,12.038-10.521,20.642 C386.02,177.246,392.44,181.653,399.35,181.653z"/>
<path d="M139.412,334.855l-22.431,30.822c-5.326,7.318-3.707,17.563,3.619,22.883c2.896,2.119,6.27,3.138,9.609,3.138 c5.074,0,10.066-2.336,13.264-6.744l22.43-30.824c5.326-7.316,3.707-17.562-3.619-22.883 C154.991,325.898,144.702,327.538,139.412,334.855z"/>
<path d="M350.258,44.654l-22.396,30.84c-5.312,7.318-3.681,17.562,3.633,22.873c2.91,2.112,6.283,3.129,9.608,3.129 c5.074,0,10.065-2.343,13.276-6.761l22.396-30.841c5.311-7.318,3.68-17.564-3.634-22.873 C365.786,35.68,355.584,37.326,350.258,44.654z"/>
<path d="M365.194,215.404c0-65.354-52.976-118.333-118.322-118.333c-65.359,0-118.336,52.979-118.336,118.333 c0,27.569,9.482,52.884,25.322,72.981c13.881,17.612,27.027,36.839,38.42,56.187v39.306h108.516v-38.263 c11.288-18.818,25.881-40.484,39.065-57.211C355.713,268.301,365.194,242.991,365.194,215.404z"/>
</svg>
</div>
<script type="application/javascript">
window.addEventListener("load", function () {
document.getElementById("theme-switch").onclick = function () {
document.cookie = "theme=dark";
location.reload();
return false;
};
});
</script>

View File

@@ -0,0 +1,8 @@
package website
import "embed"
//go:embed *
//go:embed css/*
//go:embed js/*
var Assets embed.FS