diff --git a/scnserver/Makefile b/scnserver/Makefile index ebaf80a..1c83064 100644 --- a/scnserver/Makefile +++ b/scnserver/Makefile @@ -5,9 +5,9 @@ PORT=9090 NAMESPACE=$(shell git rev-parse --abbrev-ref HEAD) HASH=$(shell git rev-parse HEAD) -.PHONY: test swagger +.PHONY: test swagger pygmentize -build: swagger fmt +build: swagger pygmentize fmt mkdir -p _build rm -f ./_build/scn_backend go generate ./... @@ -18,8 +18,8 @@ run: build _build/scn_backend gow: - # go install github.com/mitranim/gow@latest - gow run blackforestbytes.com/portfoliomanager2/cmd/server + which gow || go install github.com/mitranim/gow@latest + gow -e "go,mod,html,css,json,yaml,js" run -tags "timetzdata sqlite_fts5 sqlite_foreign_keys" blackforestbytes.com/simplecloudnotifier/cmd/scnserver docker: build [ ! -f "DOCKER_GIT_INFO" ] || rm DOCKER_GIT_INFO @@ -40,6 +40,13 @@ swagger: which swag || go install github.com/swaggo/swag/cmd/swag@v1.8.12 swag init -generalInfo api/router.go --propertyStrategy snakecase --output ./swagger/ --outputTypes "json,yaml" +pygmentize: website/scn_send.html + +website/scn_send.html: website/scn_send.sh.txt + _pygments/pygmentizew -l bash -f html "$(shell pwd)/website/scn_send.sh.txt" > "$(shell pwd)/website/scn_send.html" + _pygments/pygmentizew -S monokai -f html > "$(shell pwd)/website/css/pygmnetize-dark.css" + _pygments/pygmentizew -S borland -f html > "$(shell pwd)/website/css/pygmnetize-light.css" + run-docker-local: docker mkdir -p .run-data docker run --rm \ diff --git a/scnserver/TODO.md b/scnserver/TODO.md index d2c18ee..c879e14 100644 --- a/scnserver/TODO.md +++ b/scnserver/TODO.md @@ -39,8 +39,6 @@ - jobs to clear requests-db and logs-db after to only keep X entries... - -> logs and request-logging into their own sqlite files (sqlite-files are prepped) - - /send endpoint should be compatible with the [ webhook ] notifier of uptime-kuma (or add another /kuma endpoint) -> https://webhook.site/ @@ -49,13 +47,10 @@ - ios purchase verification - - [X] re-add ack labels as compat table for v1 api user - return channel as "[..] asdf" in compat methods (mark clients as compat and send compat FB to them...) (then we can replace the old server without switching phone clients) (still needs switching of the send-script) - - do not use uuidgen in bash script (potetnially not installed) - use `head /dev/urandom | tr -dc A-Za-z0-9 | head -c 13 ` - - move to KeyToken model * [X] User can have multiple keys with different permissions * [X] compat simply uses default-keys diff --git a/scnserver/_pygments/.gitignore b/scnserver/_pygments/.gitignore new file mode 100644 index 0000000..c3fc06f --- /dev/null +++ b/scnserver/_pygments/.gitignore @@ -0,0 +1,3 @@ +*.pyc +*.swp +env diff --git a/scnserver/_pygments/pygmentizew b/scnserver/_pygments/pygmentizew new file mode 100755 index 0000000..836b55a --- /dev/null +++ b/scnserver/_pygments/pygmentizew @@ -0,0 +1,16 @@ +#!/bin/bash + +set -o nounset # disallow usage of unset vars ( set -u ) +set -o errexit # Exit immediately if a pipeline returns non-zero. ( set -e ) +set -o errtrace # Allow the above trap be inherited by all functions in the script. ( set -E ) +set -o pipefail # Return value of a pipeline is the value of the last (rightmost) command to exit with a non-zero status +IFS=$'\n\t' # Set $IFS to only newline and tab. + +cd "$(dirname "$0")" || exit 1 + +1>&2 virtualenv env +1>&2 source env/bin/activate + +1>&2 pip install Pygments + +pygmentize "$@" diff --git a/scnserver/website/api.html b/scnserver/website/api.html index 7b57029..41ad066 100644 --- a/scnserver/website/api.html +++ b/scnserver/website/api.html @@ -21,16 +21,16 @@
Get your user-id and user-key from the android or iOS app.
And send notifications to your phone by performing a POST request against {{config|baseURL}}/ from anywhere
-curl \
- --data "user_id=${userid}" \
- --data "key=${key}" \
- --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)" \
+curl \
+ --data "user_id=${userid}" \
+ --data "key=${key}" \
+ --data "title=${message_title}" \
+ --data "content=${message_body}" \
+ --data "priority=${0|1|2}" \
+ --data "msg_id=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 32)" \
+ --data "timestamp=$(date +%s)" \
+ --data "channel={channel_name}" \
+ --data "sender_name=$(hostname)" \
{{config|baseURL}}/
Most parameters are optional, you can send a message with only a title (default priority and channel will be used)
diff --git a/scnserver/website/api_more.html b/scnserver/website/api_more.html
index 263f64a..a2c0d43 100644
--- a/scnserver/website/api_more.html
+++ b/scnserver/website/api_more.html
@@ -171,7 +171,7 @@
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.
- To ensure that a message is only send once you can generate a unique id for your message (I would recommend a simple uuidgen).
+ To ensure that a message is only send once you can generate a unique id for your message (I would recommend a simple uuidgen or head /dev/urandom | tr -dc A-Za-z0-9 | head -c 32).
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.
@@ -210,7 +210,7 @@
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.
Here is an example how such a scrippt could look like, you can put it into /usr/local/sbin and call it with scn_send "title" "content" (or with more parameters, see the script itself)
- {{template|scn_send.[theme].html}}
+ {{template|scn_send.html}}
diff --git a/scnserver/website/css/pygmnetize-dark.css b/scnserver/website/css/pygmnetize-dark.css
new file mode 100644
index 0000000..a2af57e
--- /dev/null
+++ b/scnserver/website/css/pygmnetize-dark.css
@@ -0,0 +1,83 @@
+pre { line-height: 125%; }
+td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
+span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
+td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
+span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
+.hll { background-color: #49483e }
+.c { color: #75715e } /* Comment */
+.err { color: #960050; background-color: #1e0010 } /* Error */
+.esc { color: #f8f8f2 } /* Escape */
+.g { color: #f8f8f2 } /* Generic */
+.k { color: #66d9ef } /* Keyword */
+.l { color: #ae81ff } /* Literal */
+.n { color: #f8f8f2 } /* Name */
+.o { color: #f92672 } /* Operator */
+.x { color: #f8f8f2 } /* Other */
+.p { color: #f8f8f2 } /* Punctuation */
+.ch { color: #75715e } /* Comment.Hashbang */
+.cm { color: #75715e } /* Comment.Multiline */
+.cp { color: #75715e } /* Comment.Preproc */
+.cpf { color: #75715e } /* Comment.PreprocFile */
+.c1 { color: #75715e } /* Comment.Single */
+.cs { color: #75715e } /* Comment.Special */
+.gd { color: #f92672 } /* Generic.Deleted */
+.ge { color: #f8f8f2; font-style: italic } /* Generic.Emph */
+.gr { color: #f8f8f2 } /* Generic.Error */
+.gh { color: #f8f8f2 } /* Generic.Heading */
+.gi { color: #a6e22e } /* Generic.Inserted */
+.go { color: #66d9ef } /* Generic.Output */
+.gp { color: #f92672; font-weight: bold } /* Generic.Prompt */
+.gs { color: #f8f8f2; font-weight: bold } /* Generic.Strong */
+.gu { color: #75715e } /* Generic.Subheading */
+.gt { color: #f8f8f2 } /* Generic.Traceback */
+.kc { color: #66d9ef } /* Keyword.Constant */
+.kd { color: #66d9ef } /* Keyword.Declaration */
+.kn { color: #f92672 } /* Keyword.Namespace */
+.kp { color: #66d9ef } /* Keyword.Pseudo */
+.kr { color: #66d9ef } /* Keyword.Reserved */
+.kt { color: #66d9ef } /* Keyword.Type */
+.ld { color: #e6db74 } /* Literal.Date */
+.m { color: #ae81ff } /* Literal.Number */
+.s { color: #e6db74 } /* Literal.String */
+.na { color: #a6e22e } /* Name.Attribute */
+.nb { color: #f8f8f2 } /* Name.Builtin */
+.nc { color: #a6e22e } /* Name.Class */
+.no { color: #66d9ef } /* Name.Constant */
+.nd { color: #a6e22e } /* Name.Decorator */
+.ni { color: #f8f8f2 } /* Name.Entity */
+.ne { color: #a6e22e } /* Name.Exception */
+.nf { color: #a6e22e } /* Name.Function */
+.nl { color: #f8f8f2 } /* Name.Label */
+.nn { color: #f8f8f2 } /* Name.Namespace */
+.nx { color: #a6e22e } /* Name.Other */
+.py { color: #f8f8f2 } /* Name.Property */
+.nt { color: #f92672 } /* Name.Tag */
+.nv { color: #f8f8f2 } /* Name.Variable */
+.ow { color: #f92672 } /* Operator.Word */
+.pm { color: #f8f8f2 } /* Punctuation.Marker */
+.w { color: #f8f8f2 } /* Text.Whitespace */
+.mb { color: #ae81ff } /* Literal.Number.Bin */
+.mf { color: #ae81ff } /* Literal.Number.Float */
+.mh { color: #ae81ff } /* Literal.Number.Hex */
+.mi { color: #ae81ff } /* Literal.Number.Integer */
+.mo { color: #ae81ff } /* Literal.Number.Oct */
+.sa { color: #e6db74 } /* Literal.String.Affix */
+.sb { color: #e6db74 } /* Literal.String.Backtick */
+.sc { color: #e6db74 } /* Literal.String.Char */
+.dl { color: #e6db74 } /* Literal.String.Delimiter */
+.sd { color: #e6db74 } /* Literal.String.Doc */
+.s2 { color: #e6db74 } /* Literal.String.Double */
+.se { color: #ae81ff } /* Literal.String.Escape */
+.sh { color: #e6db74 } /* Literal.String.Heredoc */
+.si { color: #e6db74 } /* Literal.String.Interpol */
+.sx { color: #e6db74 } /* Literal.String.Other */
+.sr { color: #e6db74 } /* Literal.String.Regex */
+.s1 { color: #e6db74 } /* Literal.String.Single */
+.ss { color: #e6db74 } /* Literal.String.Symbol */
+.bp { color: #f8f8f2 } /* Name.Builtin.Pseudo */
+.fm { color: #a6e22e } /* Name.Function.Magic */
+.vc { color: #f8f8f2 } /* Name.Variable.Class */
+.vg { color: #f8f8f2 } /* Name.Variable.Global */
+.vi { color: #f8f8f2 } /* Name.Variable.Instance */
+.vm { color: #f8f8f2 } /* Name.Variable.Magic */
+.il { color: #ae81ff } /* Literal.Number.Integer.Long */
diff --git a/scnserver/website/css/pygmnetize-light.css b/scnserver/website/css/pygmnetize-light.css
new file mode 100644
index 0000000..6d5c779
--- /dev/null
+++ b/scnserver/website/css/pygmnetize-light.css
@@ -0,0 +1,56 @@
+pre { line-height: 125%; }
+td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
+span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
+td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
+span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
+.hll { background-color: #ffffcc }
+.c { color: #008800; font-style: italic } /* Comment */
+.err { color: #a61717; background-color: #e3d2d2 } /* Error */
+.k { color: #000080; font-weight: bold } /* Keyword */
+.ch { color: #008800; font-style: italic } /* Comment.Hashbang */
+.cm { color: #008800; font-style: italic } /* Comment.Multiline */
+.cp { color: #008080 } /* Comment.Preproc */
+.cpf { color: #008800; font-style: italic } /* Comment.PreprocFile */
+.c1 { color: #008800; font-style: italic } /* Comment.Single */
+.cs { color: #008800; font-weight: bold } /* Comment.Special */
+.gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
+.ge { font-style: italic } /* Generic.Emph */
+.gr { color: #aa0000 } /* Generic.Error */
+.gh { color: #999999 } /* Generic.Heading */
+.gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
+.go { color: #888888 } /* Generic.Output */
+.gp { color: #555555 } /* Generic.Prompt */
+.gs { font-weight: bold } /* Generic.Strong */
+.gu { color: #aaaaaa } /* Generic.Subheading */
+.gt { color: #aa0000 } /* Generic.Traceback */
+.kc { color: #000080; font-weight: bold } /* Keyword.Constant */
+.kd { color: #000080; font-weight: bold } /* Keyword.Declaration */
+.kn { color: #000080; font-weight: bold } /* Keyword.Namespace */
+.kp { color: #000080; font-weight: bold } /* Keyword.Pseudo */
+.kr { color: #000080; font-weight: bold } /* Keyword.Reserved */
+.kt { color: #000080; font-weight: bold } /* Keyword.Type */
+.m { color: #0000FF } /* Literal.Number */
+.s { color: #0000FF } /* Literal.String */
+.na { color: #FF0000 } /* Name.Attribute */
+.nt { color: #000080; font-weight: bold } /* Name.Tag */
+.ow { font-weight: bold } /* Operator.Word */
+.w { color: #bbbbbb } /* Text.Whitespace */
+.mb { color: #0000FF } /* Literal.Number.Bin */
+.mf { color: #0000FF } /* Literal.Number.Float */
+.mh { color: #0000FF } /* Literal.Number.Hex */
+.mi { color: #0000FF } /* Literal.Number.Integer */
+.mo { color: #0000FF } /* Literal.Number.Oct */
+.sa { color: #0000FF } /* Literal.String.Affix */
+.sb { color: #0000FF } /* Literal.String.Backtick */
+.sc { color: #800080 } /* Literal.String.Char */
+.dl { color: #0000FF } /* Literal.String.Delimiter */
+.sd { color: #0000FF } /* Literal.String.Doc */
+.s2 { color: #0000FF } /* Literal.String.Double */
+.se { color: #0000FF } /* Literal.String.Escape */
+.sh { color: #0000FF } /* Literal.String.Heredoc */
+.si { color: #0000FF } /* Literal.String.Interpol */
+.sx { color: #0000FF } /* Literal.String.Other */
+.sr { color: #0000FF } /* Literal.String.Regex */
+.s1 { color: #0000FF } /* Literal.String.Single */
+.ss { color: #0000FF } /* Literal.String.Symbol */
+.il { color: #0000FF } /* Literal.Number.Integer.Long */
diff --git a/scnserver/website/css/style-dark.css b/scnserver/website/css/style-dark.css
index 823ff5b..b53f3a1 100644
--- a/scnserver/website/css/style-dark.css
+++ b/scnserver/website/css/style-dark.css
@@ -20,8 +20,9 @@
border-color: #888 !important;
}
-pre.yellow-code,
-pre.yellow-code span {
+.yellow-code,
+.yellow-code pre,
+.yellow-code span {
background: none;
}
@@ -31,4 +32,9 @@ pre.yellow-code span {
#theme-switch:hover {
fill: #88F;
+}
+
+code {
+ background: var(--secondary-back-color);
+ border: .0625rem solid #444;
}
\ No newline at end of file
diff --git a/scnserver/website/css/style.css b/scnserver/website/css/style.css
index 13c80c8..4e6d1d8 100644
--- a/scnserver/website/css/style.css
+++ b/scnserver/website/css/style.css
@@ -41,7 +41,7 @@ body
border-left: .25rem solid #E53935;
}
-.yellow-code
+.yellow-code pre
{
border-left: .25rem solid #FFCB05;
}
@@ -270,6 +270,7 @@ a.card:hover
table.scode_table {
max-height: none;
+ overflow: hidden;
}
table.scode_table td:nth-child(2) {
@@ -300,7 +301,7 @@ pre, pre span
}
#theme-switch {
- position: absolute;
+ position: fixed;
top: 0.75rem;
right: 0.75rem;
cursor: pointer;
@@ -311,3 +312,8 @@ pre, pre span
filter: blur(1px);
fill: #008;
}
+
+code {
+ background: #F9F9F9;
+ border: .0625rem solid var(--secondary-border-color);
+}
\ No newline at end of file
diff --git a/scnserver/website/header.dark.html b/scnserver/website/header.dark.html
index eb52789..fdad8db 100644
--- a/scnserver/website/header.dark.html
+++ b/scnserver/website/header.dark.html
@@ -8,6 +8,8 @@
+
+
diff --git a/scnserver/website/header.light.html b/scnserver/website/header.light.html
index aa4b231..3f47a22 100644
--- a/scnserver/website/header.light.html
+++ b/scnserver/website/header.light.html
@@ -6,6 +6,8 @@
+
+
\ No newline at end of file
diff --git a/scnserver/website/scn_send.dark.html b/scnserver/website/scn_send.dark.html
deleted file mode 100644
index 72583cb..0000000
--- a/scnserver/website/scn_send.dark.html
+++ /dev/null
@@ -1,138 +0,0 @@
-
-
-
-
-
-
-#!/usr/bin/env bash
-
-#
-# Wrapper around SCN ( https://scn.blackforestbytes.com/ )
-# ========================================================
-#
-# ./scn_send [@channel] title [content] [priority]
-#
-#
-# Call with scn_send "${title}"
-# or scn_send "${title}" ${content}"
-# or scn_send "${title}" ${content}" "${priority:0|1|2}"
-# or scn_send "@${channel} "${title}"
-# or scn_send "@${channel} "${title}" ${content}"
-# or scn_send "@${channel} "${title}" ${content}" "${priority:0|1|2}"
-#
-#
-
-################################################################################
-# INSERT YOUR DATA HERE #
-################################################################################
-user_id="999"
-user_key="??"
-################################################################################
-
-usage() {
- echo "Usage: "
- echo " scn_send [@channel] title [content] [priority]"
- echo ""
-}
-
-args=( "$@" )
-
-title=$1
-content=""
-channel=""
-priority=1
-usr_msg_id="$(uuidgen)"
-sendtime="$(date +%s)"
-sender="$(hostname)"
-
-if [ ${#args[@]} -lt 1 ]; then
- echo "[ERROR]: no title supplied via parameter" 1>&2
- usage
- exit 1
-fi
-
-if [[ "${args[0]}" =~ ^@.* ]]; then
- channel="${args[0]}"
- unset "args[0]"
- channel="${channel:1}"
-fi
-
-if [ ${#args[@]} -lt 1 ]; then
- echo "[ERROR]: no title supplied via parameter" 1>&2
- usage
- exit 1
-fi
-
-title="${args[0]}"
-content=""
-
-if [ ${#args[@]} -gt 1 ]; then
- content="${args[0]}"
- unset "args[0]"
-fi
-
-if [ ${#args[@]} -gt 1 ]; then
- priority="${args[0]}"
- unset "args[0]"
-fi
-
-if [ ${#args[@]} -gt 1 ]; then
- echo "Too many arguments to scn_send" 1>&2
- usage
- exit 1
-fi
-
-
-while true ; do
-
- curlresp=$(curl --silent \
- --output /dev/null \
- --write-out "%{http_code}" \
- --data "user_id=$user_id" \
- --data "key=$key" \
- --data "title=$title" \
- --data "timestamp=$sendtime" \
- --data "content=$content" \
- --data "priority=$priority" \
- --data "msg_id=$usr_msg_id" \
- --data "channel=$channel" \
- --data "sender_name=$sender" \
- "https://scn.blackforestbytes.com/" )
-
- if [ "$curlresp" == 200 ] ; then
- echo "Successfully send"
- exit 0
- fi
-
- if [ "$curlresp" == 400 ] ; then
- echo "Bad request - something went wrong" 1>&2
- exit 1
- fi
-
- if [ "$curlresp" == 401 ] ; then
- echo "Unauthorized - wrong userid/userkey" 1>&2
- exit 1
- fi
-
- if [ "$curlresp" == 403 ] ; then
- echo "Quota exceeded - wait one hour before re-try" 1>&2
- sleep 3600
- fi
-
- if [ "$curlresp" == 412 ] ; then
- echo "Precondition Failed - No device linked" 1>&2
- exit 1
- fi
-
- if [ "$curlresp" == 500 ] ; then
- echo "Internal server error - waiting for better times" 1>&2
- sleep 60
- fi
-
- # if none of the above matched we probably hav no network ...
- echo "Send failed (response code $curlresp) ... try again in 5s" 1>&2
- sleep 5
-done
-
-
-
diff --git a/scnserver/website/scn_send.html b/scnserver/website/scn_send.html
new file mode 100644
index 0000000..81e2913
--- /dev/null
+++ b/scnserver/website/scn_send.html
@@ -0,0 +1,142 @@
+#!/usr/bin/env bash
+
+#
+# Wrapper around SCN ( https://scn.blackforestbytes.com/ )
+# ========================================================
+#
+# ./scn_send [@channel] title [content] [priority]
+#
+#
+# Call with scn_send "${title}"
+# or scn_send "${title}" ${content}"
+# or scn_send "${title}" ${content}" "${priority:0|1|2}"
+# or scn_send "@${channel} "${title}"
+# or scn_send "@${channel} "${title}" ${content}"
+# or scn_send "@${channel} "${title}" ${content}" "${priority:0|1|2}"
+#
+#
+
+################################################################################
+# INSERT YOUR DATA HERE #
+################################################################################
+user_id="999" # your user_id
+user_key="??" # use userkey with SEND permissions on the used channel
+################################################################################
+
+usage() {
+ echo "Usage: "
+ echo " scn_send [@channel] title [content] [priority]"
+ echo ""
+}
+
+function cfgcol { [ -t 1 ] && [ -n "$(tput colors)" ] && [ "$(tput colors)" -ge 8 ]; }
+
+function rederr() { if cfgcol; then >&2 echo -e "\x1B[31m$1\x1B[0m"; else >&2 echo "$1"; fi; }
+function green() { if cfgcol; then echo -e "\x1B[32m$1\x1B[0m"; else echo "$1"; fi; }
+
+args=( "$@" )
+
+title=$1
+content=""
+channel=""
+priority=1
+usr_msg_id="$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 32)"
+sendtime="$(date +%s)"
+sender="$(hostname)"
+
+if [ ${#args[@]} -lt 1 ]; then
+ rederr "[ERROR]: no title supplied via parameter"
+ usage
+ exit 1
+fi
+
+if [[ "${args[0]}" =~ ^@.* ]]; then
+ channel="${args[0]}"
+ unset "args[0]"
+ channel="${channel:1}"
+fi
+
+if [ ${#args[@]} -lt 1 ]; then
+ rederr "[ERROR]: no title supplied via parameter"
+ usage
+ exit 1
+fi
+
+title="${args[0]}"
+content=""
+
+if [ ${#args[@]} -gt 1 ]; then
+ content="${args[0]}"
+ unset "args[0]"
+fi
+
+if [ ${#args[@]} -gt 1 ]; then
+ priority="${args[0]}"
+ unset "args[0]"
+fi
+
+if [ ${#args[@]} -gt 1 ]; then
+ rederr "Too many arguments to scn_send"
+ usage
+ exit 1
+fi
+
+
+while true ; do
+
+ outf="$(mktemp)"
+
+ curlresp=$(curl --silent \
+ --output "${outf}" \
+ --write-out "%{http_code}" \
+ --data "user_id=$user_id" \
+ --data "key=$user_key" \
+ --data "title=$title" \
+ --data "timestamp=$sendtime" \
+ --data "content=$content" \
+ --data "priority=$priority" \
+ --data "msg_id=$usr_msg_id" \
+ --data "channel=$channel" \
+ --data "sender_name=$sender" \
+ "https://scn.blackforestbytes.com/" )
+
+ curlout="$(cat "$outf")"
+ rm "$outf"
+
+ if [ "$curlresp" == 200 ] ; then
+ green "Successfully send"
+ exit 0
+ fi
+
+ if [ "$curlresp" == 400 ] ; then
+ rederr "Bad request - something went wrong"
+ echo "$curlout"
+ echo ""
+ exit 1
+ fi
+
+ if [ "$curlresp" == 401 ] ; then
+ rederr "Unauthorized - wrong userid/userkey"
+ exit 1
+ fi
+
+ if [ "$curlresp" == 403 ] ; then
+ rederr "Quota exceeded - wait 5 min before re-try"
+ sleep 300
+ fi
+
+ if [ "$curlresp" == 412 ] ; then
+ rederr "Precondition Failed - No device linked"
+ exit 1
+ fi
+
+ if [ "$curlresp" == 500 ] ; then
+ rederr "Internal server error - waiting for better times"
+ sleep 60
+ fi
+
+ # if none of the above matched we probably have no network ...
+ rederr "Send failed (response code $curlresp) ... try again in 5s"
+ sleep 5
+done
+
diff --git a/scnserver/website/scn_send.light.html b/scnserver/website/scn_send.light.html
deleted file mode 100644
index 707f580..0000000
--- a/scnserver/website/scn_send.light.html
+++ /dev/null
@@ -1,136 +0,0 @@
-
-
-
-
-
-
-#!/usr/bin/env bash
-
-#
-# Wrapper around SCN ( https://scn.blackforestbytes.com/ )
-# ========================================================
-#
-# ./scn_send [@channel] title [content] [priority]
-#
-#
-# Call with scn_send "${title}"
-# or scn_send "${title}" ${content}"
-# or scn_send "${title}" ${content}" "${priority:0|1|2}"
-# or scn_send "@${channel} "${title}"
-# or scn_send "@${channel} "${title}" ${content}"
-# or scn_send "@${channel} "${title}" ${content}" "${priority:0|1|2}"
-#
-#
-
-################################################################################
-# INSERT YOUR DATA HERE #
-################################################################################
-user_id="999"
-key="??"
-################################################################################
-
-usage() {
- echo "Usage: "
- echo " scn_send [@channel] title [content] [priority]"
- echo ""
-}
-
-args=( "$@" )
-
-title=$1
-content=""
-channel=""
-priority=1
-usr_msg_id="$(uuidgen)"
-sendtime="$(date +%s)"
-sender="$(hostname)"
-
-if [ ${#args[@]} -lt 1 ]; then
- echo "[ERROR]: no title supplied via parameter" 1>&2
- usage
- exit 1
-fi
-
-if [[ "${args[0]}" =~ ^@.* ]]; then
- channel="${args[0]}"
- unset "args[0]"
- channel="${channel:1}"
-fi
-
-if [ ${#args[@]} -lt 1 ]; then
- echo "[ERROR]: no title supplied via parameter" 1>&2
- usage
- exit 1
-fi
-
-title="${args[0]}"
-content=""
-
-if [ ${#args[@]} -gt 1 ]; then
- content="${args[0]}"
- unset "args[0]"
-fi
-
-if [ ${#args[@]} -gt 1 ]; then
- priority="${args[0]}"
- unset "args[0]"
-fi
-
-if [ ${#args[@]} -gt 1 ]; then
- echo "Too many arguments to scn_send" 1>&2
- usage
- exit 1
-fi
-
-
-while true ; do
-
- curlresp=$(curl --silent \
- --output /dev/null \
- --write-out "%{http_code}" \
- --data "user_id=$user_id" \
- --data "key=$key" \
- --data "title=$title" \
- --data "timestamp=$sendtime" \
- --data "content=$content" \
- --data "priority=$priority" \
- --data "msg_id=$usr_msg_id" \
- --data "channel=$channel" \
- --data "sender_name=$sender" \
- "https://scn.blackforestbytes.com/" )
-
- if [ "$curlresp" == 200 ] ; then
- echo "Successfully send"
- exit 0
- fi
-
- if [ "$curlresp" == 400 ] ; then
- echo "Bad request - something went wrong" 1>&2
- exit 1
- fi
-
- if [ "$curlresp" == 401 ] ; then
- echo "Unauthorized - wrong userid/userkey" 1>&2
- exit 1
- fi
-
- if [ "$curlresp" == 403 ] ; then
- echo "Quota exceeded - wait one hour before re-try" 1>&2
- sleep 3600
- fi
-
- if [ "$curlresp" == 412 ] ; then
- echo "Precondition Failed - No device linked" 1>&2
- exit 1
- fi
-
- if [ "$curlresp" == 500 ] ; then
- echo "Internal server error - waiting for better times" 1>&2
- sleep 60
- fi
-
- # if none of the above matched we probably hav no network ...
- echo "Send failed (response code $curlresp) ... try again in 5s" 1>&2
- sleep 5
-done
-
\ No newline at end of file
diff --git a/scnserver/website/scn_send.sh.txt b/scnserver/website/scn_send.sh.txt
new file mode 100644
index 0000000..bd03dbe
--- /dev/null
+++ b/scnserver/website/scn_send.sh.txt
@@ -0,0 +1,141 @@
+#!/usr/bin/env bash
+
+#
+# Wrapper around SCN ( https://scn.blackforestbytes.com/ )
+# ========================================================
+#
+# ./scn_send [@channel] title [content] [priority]
+#
+#
+# Call with scn_send "${title}"
+# or scn_send "${title}" ${content}"
+# or scn_send "${title}" ${content}" "${priority:0|1|2}"
+# or scn_send "@${channel} "${title}"
+# or scn_send "@${channel} "${title}" ${content}"
+# or scn_send "@${channel} "${title}" ${content}" "${priority:0|1|2}"
+#
+#
+
+################################################################################
+# INSERT YOUR DATA HERE #
+################################################################################
+user_id="999" # your user_id
+user_key="??" # use userkey with SEND permissions on the used channel
+################################################################################
+
+usage() {
+ echo "Usage: "
+ echo " scn_send [@channel] title [content] [priority]"
+ echo ""
+}
+
+function cfgcol { [ -t 1 ] && [ -n "$(tput colors)" ] && [ "$(tput colors)" -ge 8 ]; }
+
+function rederr() { if cfgcol; then >&2 echo -e "\x1B[31m$1\x1B[0m"; else >&2 echo "$1"; fi; }
+function green() { if cfgcol; then echo -e "\x1B[32m$1\x1B[0m"; else echo "$1"; fi; }
+
+args=( "$@" )
+
+title=$1
+content=""
+channel=""
+priority=1
+usr_msg_id="$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 32)"
+sendtime="$(date +%s)"
+sender="$(hostname)"
+
+if [ ${#args[@]} -lt 1 ]; then
+ rederr "[ERROR]: no title supplied via parameter"
+ usage
+ exit 1
+fi
+
+if [[ "${args[0]}" =~ ^@.* ]]; then
+ channel="${args[0]}"
+ unset "args[0]"
+ channel="${channel:1}"
+fi
+
+if [ ${#args[@]} -lt 1 ]; then
+ rederr "[ERROR]: no title supplied via parameter"
+ usage
+ exit 1
+fi
+
+title="${args[0]}"
+content=""
+
+if [ ${#args[@]} -gt 1 ]; then
+ content="${args[0]}"
+ unset "args[0]"
+fi
+
+if [ ${#args[@]} -gt 1 ]; then
+ priority="${args[0]}"
+ unset "args[0]"
+fi
+
+if [ ${#args[@]} -gt 1 ]; then
+ rederr "Too many arguments to scn_send"
+ usage
+ exit 1
+fi
+
+
+while true ; do
+
+ outf="$(mktemp)"
+
+ curlresp=$(curl --silent \
+ --output "${outf}" \
+ --write-out "%{http_code}" \
+ --data "user_id=$user_id" \
+ --data "key=$user_key" \
+ --data "title=$title" \
+ --data "timestamp=$sendtime" \
+ --data "content=$content" \
+ --data "priority=$priority" \
+ --data "msg_id=$usr_msg_id" \
+ --data "channel=$channel" \
+ --data "sender_name=$sender" \
+ "https://scn.blackforestbytes.com/" )
+
+ curlout="$(cat "$outf")"
+ rm "$outf"
+
+ if [ "$curlresp" == 200 ] ; then
+ green "Successfully send"
+ exit 0
+ fi
+
+ if [ "$curlresp" == 400 ] ; then
+ rederr "Bad request - something went wrong"
+ echo "$curlout"
+ echo ""
+ exit 1
+ fi
+
+ if [ "$curlresp" == 401 ] ; then
+ rederr "Unauthorized - wrong userid/userkey"
+ exit 1
+ fi
+
+ if [ "$curlresp" == 403 ] ; then
+ rederr "Quota exceeded - wait 5 min before re-try"
+ sleep 300
+ fi
+
+ if [ "$curlresp" == 412 ] ; then
+ rederr "Precondition Failed - No device linked"
+ exit 1
+ fi
+
+ if [ "$curlresp" == 500 ] ; then
+ rederr "Internal server error - waiting for better times"
+ sleep 60
+ fi
+
+ # if none of the above matched we probably have no network ...
+ rederr "Send failed (response code $curlresp) ... try again in 5s"
+ sleep 5
+done