]> git.plutz.net Git - rawnet/commitdiff
Merge commit 'b5943a26698776a9814850ed2356eda5076fa00a'
authorPaul Hänsch <paul@plutz.net>
Wed, 29 Sep 2021 11:09:40 +0000 (13:09 +0200)
committerPaul Hänsch <paul@plutz.net>
Wed, 29 Sep 2021 11:09:40 +0000 (13:09 +0200)
16 files changed:
.gitignore
Makefile [new file with mode: 0644]
cgilite/.gitignore [new file with mode: 0644]
cgilite/cgilite.sh [moved from cgilite.sh with 100% similarity]
cgilite/common.css [moved from common.css with 100% similarity]
cgilite/file.sh [moved from file.sh with 100% similarity]
cgilite/html-sh.sed [moved from html-sh.sed with 100% similarity]
cgilite/logging.sh [moved from logging.sh with 100% similarity]
cgilite/markdown.awk [moved from markdown.awk with 100% similarity]
cgilite/session.sh [moved from session.sh with 100% similarity]
cgilite/storage.sh [moved from storage.sh with 100% similarity]
cgilite/users.sh [moved from users.sh with 100% similarity]
index.cgi [new file with mode: 0755]
page_404.sh [new file with mode: 0755]
page_channel.sh [new file with mode: 0755]
rawnet.css [new file with mode: 0644]

index 5c9950ae1c74eb4a290c3887873f567f85c3de4d..e3c57b41d263e10579e1ee021547c205327d796b 100644 (file)
@@ -1,3 +1,3 @@
-cgilite
-serverkey
+channels.db
 users.db
+serverkey
diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..24781a9
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,9 @@
+.PHONY: _subtrees
+
+_subtrees: _cgilite
+
+cgilite:
+       git subtree add --squash -P $@ https://git.plutz.net/git/$@ master
+
+_cgilite: cgilite
+       git subtree pull --squash -P $< https://git.plutz.net/git/$< master
diff --git a/cgilite/.gitignore b/cgilite/.gitignore
new file mode 100644 (file)
index 0000000..5c9950a
--- /dev/null
@@ -0,0 +1,3 @@
+cgilite
+serverkey
+users.db
similarity index 100%
rename from cgilite.sh
rename to cgilite/cgilite.sh
similarity index 100%
rename from common.css
rename to cgilite/common.css
similarity index 100%
rename from file.sh
rename to cgilite/file.sh
similarity index 100%
rename from html-sh.sed
rename to cgilite/html-sh.sed
similarity index 100%
rename from logging.sh
rename to cgilite/logging.sh
similarity index 100%
rename from markdown.awk
rename to cgilite/markdown.awk
similarity index 100%
rename from session.sh
rename to cgilite/session.sh
similarity index 100%
rename from storage.sh
rename to cgilite/storage.sh
similarity index 100%
rename from users.sh
rename to cgilite/users.sh
diff --git a/index.cgi b/index.cgi
new file mode 100755 (executable)
index 0000000..1a8914d
--- /dev/null
+++ b/index.cgi
@@ -0,0 +1,77 @@
+#!/bin/sh
+
+USER_REQUIREEMAIL=false
+
+. "${_EXEC:-${0%/*}}"/cgilite/cgilite.sh
+. "$_EXEC"/cgilite/session.sh nocookie
+. "$_EXEC"/cgilite/users.sh
+
+PATH_INFO="$(PATH "/${PATH_INFO#${_BASE}}")"
+
+export MD_HTML="false"
+if [ "$(which awk)" ]; then
+  markdown() { awk -f "$_EXEC/cgilite/markdown.awk"; }
+else
+  markdown() { busybox awk -f "$_EXEC/cgilite/markdown.awk"; }
+fi
+
+yield_page(){
+  title="${1:-RAW:NET}" page="$2"
+  printf '%s\r\n' 'Content-Type: text/html; charset=utf-8' \
+                  "Content-Security-Policy: script-src 'none'" \
+                  ''
+  { cat <<-EOF
+       [!DOCTYPE HTML]
+       [html [head
+         [meta name="viewport" content="width=device-width"]
+         [link rel="stylesheet" type="text/css" href="$_BASE/cgilite/common.css"]
+         [link rel="stylesheet" type="text/css" href="$_BASE/rawnet.css"]
+         [title . $(HTML "$title")]
+       ] [body class="$page"
+         [header
+           [form method=POST action="$_BASE/search/"
+             [input name=search placeholder="Search"]
+           ]
+           $( [ ! "$USER_ID" ] \
+               && printf '[div #user_login [a href="%s/login/" Login]]' "$_BASE" \
+               || w_user_login
+            )
+         ][main
+       EOF
+  cat
+  printf ']]]'
+  } |"$_EXEC/cgilite/html-sh.sed" -u
+}
+
+case ${PATH_INFO} in
+  /favicon.ico) printf '%s\r\n' 'Content-Length: 0' '';;
+  *.css)
+    . "${_EXEC}/cgilite/file.sh"
+    FILE "${_EXEC}/${PATH_INFO}"
+    ;;
+  /login/)
+    if [ "$USER_ID" ]; then
+      REDIRECT "${_BASE}/"
+    else
+      yield_page 'RAW:NET Login' login <<-EOF
+       $(w_user_login)
+       EOF
+    fi
+    ;;
+  /register/)
+    yield_page 'RAW:NET Register User' register <<-EOF
+       $(w_user_register)
+       EOF
+    ;;
+  /recover/)
+    yield_page 'RAW:NET Recover Account' recover <<-EOF
+       $(w_user_recover)
+       EOF
+    ;;
+  /|/channel/*) . "${_EXEC}/page_channel.sh";;
+  /playlist/*) . "${_EXEC}/page_playlist.sh";;
+  /search/*) . "${_EXEC}/page_search.sh";;
+  *) . "${_EXEC}/page_404.sh";;
+esac
+
+exit 0
diff --git a/page_404.sh b/page_404.sh
new file mode 100755 (executable)
index 0000000..a4acce8
--- /dev/null
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+printf 'Status: 404 Not Found\r\n'
+
+yield_page '' 404 <<-EOF
+[h1 404][p
+[span Page not found or nevermore]
+[span Quoth the server: 404]
+]
+EOF
diff --git a/page_channel.sh b/page_channel.sh
new file mode 100755 (executable)
index 0000000..d12f417
--- /dev/null
@@ -0,0 +1,183 @@
+#!/bin/sh
+
+chan_db="$_DATA/channels.db"
+
+channel='' video='' action=''
+path_info="$PATH_INFO"
+path_info="${path_info#/channel/}"
+if [ "$(checkid "${path_info%%/*}")" ]; then
+  channel="${path_info%%/*}"
+  path_info="${path_info#*/}"
+fi
+if [ "$(checkid "${path_info%%/*}")" ]; then
+  video="${path_info%%/*}"
+  path_info="${path_info#*/}"
+fi
+action="${path_info}"
+unset path_info
+
+# Channel
+# ID   NAME    DESCRIPTION     LOGO    THEME   AUTHORS DESCR_CACHE FUTUREUSE
+
+if [ "$channel" -a -f "$chan_db" -a -r "$chan_db" ]; then
+  read -r CHANNEL_ID CHANNEL_NAME CHANNEL_DESCRIPTION CHANNEL_LOGO \
+          CHANNEL_THEME CHANNEL_AUTHORS CHANNEL_DESCR_CACHE \
+          CHANNEL_FUTUREUSE <<-EOF
+       $(grep "^${channel}     " "${chan_db}")
+       EOF
+  if [ "$CHANNEL_ID" ]; then
+           CHANNEL_NAME="$(UNSTRING "${CHANNEL_NAME}")"
+    CHANNEL_DESCRIPTION="$(UNSTRING "$CHANNEL_DESCRIPTION")"
+        CHANNEL_AUTHORS="$(UNSTRING "$CHANNEL_AUTHORS")"
+    CHANNEL_DESCR_CACHE="$(UNSTRING "$CHANNEL_DESCR_CACHE")"
+    vid_db="${_DATA}/${CHANNEL_ID}/videos.db"
+  else
+    channel=''
+  fi
+fi
+
+update_channel(){
+  local id="${1}" name="${2}" description="${3}" logo="${4}" theme="${5}" \
+        authors="${6}" descr_cache="${7}" futureuse="${8}"
+  local ID INFO
+  if LOCK "$chan_db"; then
+    while read -r ID INFO; do
+      if [ "$id" = "$ID" ]; then
+       printf '%s      %s      %s      %s      %s      %s      %s      %s\n' \
+               "$id" "$(STRING "$name")" "$(STRING "$description")" \
+               "${logo:-\\}" "${theme:-\\}" "$(STRING "$authors")" \
+               "$(printf %s "$description" |markdown |STRING)" \
+               "${futureuse:-\\}"
+      else
+       printf '%s      %s\n' "$ID" "$INFO"
+      fi
+    done <"$chan_db" >"${chan_db}.$$"
+    mv -- "${chan_db}.$$" "${chan_db}"
+    RELEASE "$chan_db"
+  else
+    return 1
+  fi
+}
+
+# Video
+# ID   NAME    DESCRIPTION     RESX    RESY    LENGTH  COVER   STATUS  UPLOADER        HITS
+
+[ "$REQUEST_METHOD" = POST ] && case "$(POST action)" in
+  newchannel)
+    channel="$(POST channel |checkid)"
+    if [ ! "$USER_ID" ]; then
+      REDIRECT "${_BASE}/channel/#ERROR_NEWCHANNEL_NOTALLOWED"
+    elif LOCK "$chan_db"; then
+      if grep -q '^${channel}  ' "$chan_db"; then
+        RELEASE "$chan_db"
+        REDIRECT "${_BASE}/channel/#ERROR_NEWCHANNEL_EXISTS"
+      else
+       printf '%s      \\      \\      \\      \\      %s      \\      \\\n' \
+               "$channel" "$(STRING "$USER_ID")" \
+               >>"$chan_db"
+        RELEASE "$chan_db"
+        REDIRECT "${_BASE}/channel/${channel}/edit"
+      fi
+    else
+      REDIRECT "${_BASE}/channel/#ERROR_NEWCHANNEL_NOLOCK"
+    fi
+    ;;
+  update_channel)
+    if [ ! "$channel" ]; then
+      REDIRECT "${_BASE}/channel/#ERROR_NOCHANNEL"
+    elif [ ! "$USER_ID" ]; then
+      REDIRECT "${_BASE}/channel/${channel}/#ERROR_NOTLOGGEDIN"
+    elif [ "${CHANNEL_AUTHORS##*${USER_ID}*}" ]; then
+      REDIRECT "${_BASE}/channel/${channel}/#ERROR_UPDATE_NOTALLOWED"
+    elif update_channel "$channel" "$(POST name)" "$(POST description)" \
+                        "" "" "$USER_ID" "" ""; then
+      REDIRECT "${_BASE}/channel/${channel}/"
+    else
+      REDIRECT "${_BASE}/channel/${channel}/#ERROR_UPDATE_NOLOCK"
+    fi
+    ;;
+  newvideo)
+    video="$(POST video |checkid)"
+    # database video create
+    REDIRECT "${_BASE}/channel/${channel}/${video}/"
+    ;;
+esac
+
+w_video(){
+  local CID="$1" thumb
+  local ID NAME DESCRIPTION RESX RESY LENGTH COVER STATUS UPLOADER HITS FUTUREUSE
+  if read -r ID NAME DESCRIPTION RESX RESY LENGTH COVER STATUS UPLOADER HITS FUTUREUSE; then
+    thumb="${_BASE}/${CID}/thumb_${ID}.jpg"
+    cat <<-EOF
+       [div .video
+         [h3 . $(UNSTRING "$NAME" |HTML)]
+         [img href="${thumb}" alt="$(UNSTRING "$DESCRIPTION" |HTML)"]
+       ]
+       EOF
+  else
+    return 1
+  fi
+}
+
+w_channel(){
+  local vid_db
+  local ID NAME DESCRIPTION LOGO THEME AUTHORS DESCR_CACHE FUTUREUSE
+  if read -r ID NAME DESCRIPTION LOGO THEME AUTHORS DESCR_CACHE FUTUREUSE; then
+    vid_db="${_DATA}/${ID}/videos.db"
+    [ "$NAME" = \\ ] && NAME="(UNNAMED CHANNEL)"
+    cat <<-EOF
+       [div .channel
+         [h2 [a href="${_BASE}/channel/${ID}/" $(UNSTRING "${NAME}" |HTML)]]
+         [div .description . $(UNSTRING "$DESCR_CACHE")]
+         $( [ -f "$vid_db" -a -r "$vid_db" ] \
+            && while w_video "$ID"; do :; done <"$vid_db"
+         )
+       ]
+       EOF
+  else
+    return 1
+  fi
+}
+
+w_channel_list(){
+  if [ $USER_ID ]; then
+    printf '
+    [form .channel .newchannel method=POST
+      [hidden "channel" "%s"]
+      [submit "action" "newchannel" New Channel]
+    ]' "$(timeid)"
+  fi
+  [ -f "$chan_db" -a -r "$chan_db" ] \
+  && while w_channel; do :; done <"$chan_db"
+}
+
+if [ "$channel" -a "$video" ]; then
+  . ${_EXEC}/page_video.sh
+elif [ "$channel" -a "$action" = edit ]; then
+  [ "$USER_ID" -a ! "${CHANNEL_AUTHORS##*${USER_ID}*}" ] \
+  || REDIRECT "${_BASE}/${channel}/#ERROR_EDIT_NOTALLOWED"
+  yield_page "$CHANNEL_NAME - Edit" "channel edit" <<-EOF
+       [form .channel .edit method=POST
+         [input name="name" value="$(HTML "$CHANNEL_NAME")" placeholder="Channel Name"]
+         [textarea name="description" placeholder="Description" . $(HTML "$CHANNEL_DESCRIPTION")]
+         [submit "action" "update_channel" . Update]
+       ]
+       EOF
+elif [ "$channel" ]; then
+  yield_page "$CHANNEL_NAME" "channel" <<-EOF
+       [h1 .name $(HTML "$CHANNEL_NAME")]
+       $( [ "$USER_ID" -a ! "${CHANNEL_AUTHORS##*${USER_ID}*}" ] \
+           && printf '[a href="edit" edit]'
+        )
+       [div .description . ${CHANNEL_DESCR_CACHE}]
+       [div .videos
+         $( [ -f "$vid_db" -a -r "$vid_db" ] \
+            && while w_video "$ID"; do :; done <"$vid_db"
+         )
+       ]
+       EOF
+else
+  yield_page "Channels" "channels" <<-EOF
+       $(w_channel_list)
+       EOF
+fi
diff --git a/rawnet.css b/rawnet.css
new file mode 100644 (file)
index 0000000..93de0da
--- /dev/null
@@ -0,0 +1,64 @@
+body {
+  background-size: 4pt 4pt;
+  background-image: /* #6AF #6FF */
+    linear-gradient( 0deg, transparent 25%, rgba(128,128,128,.5) 25% 50%, transparent 50% 75%, rgba(192,192,192,.5) 75%),
+    linear-gradient(90deg, transparent 25%, rgba(128,128,128,.5) 25% 50%, transparent 50% 75%, rgba(192,192,192,.5) 75%);
+}
+
+header {
+  background-color: rgba(0,0,0,.75);
+  padding: .25em;
+  border-bottom: 1pt solid;
+  box-shadow: #000 0 .25em .5em;
+  text-align: center;
+}
+header > * {
+  display: inline-block;
+}
+
+header #user_login {
+  float: right;
+  margin: .125em .5em;
+}
+header #user_login > p {
+  display: inline-block;
+  color: #EEE;
+  font-size: .875em; line-height: 1.125em;
+  max-width: 12em;
+}
+
+main {
+  background-color: rgba(255,255,255,.75);
+  margin: 1em; padding: 1em;
+  box-shadow: #000 .125em .125em 1em;
+}
+
+body.channel main h1.name {
+  text-align: center;
+}
+body.channel main .description,
+body.channel main form.edit.channel {
+  max-width: 40em;
+  margin: auto;
+}
+
+body.channel main form.edit.channel input[name=name],
+body.channel main form.edit.channel textarea[name=description] {
+  display: block;
+  width: 100%;
+  margin-bottom: .5em;
+}
+
+body.channels main .channel {
+  border: 1pt solid;
+  border-radius: 4pt;
+  padding: .5em;
+  margin-bottom: .5em;
+}
+
+body.channels main .channel > h2,
+body.channels main .channel > .description {
+  margin: 0;
+  width: 140pt;
+  background-color: #FFF;
+}