1
1
Fork 0
mirror of https://github.com/tonydamage/nux-env.git synced 2025-12-11 13:24:28 +01:00

Legacy sync

Signed-off-by: Tony Tkacik <tonydamage@gmail.com>
This commit is contained in:
Tony Tkáčik 2020-03-05 12:20:11 +01:00
parent 851914ff75
commit 4c4bb238a0
13 changed files with 1026 additions and 7 deletions

98
inc/nuweb.nuxsh.sh Normal file
View file

@ -0,0 +1,98 @@
## #nuweb - Server-side HTTP scripting library for BASH
##
## *nuweb* is set of BASH function to ease implementation of CGI scripts using
## BASH. Idea behind it, is to allow for reuse of existing shell scripts
## and command-line utilities, without need to duplicate functionality.
##
## *nuweb* is based on *nux-env*, which allows large code-share with *nux-env*
## command line tools and use of *nux-env* libraries.
##
## *nuweb* is separated into several components:
##
## nuweb::
## this library, base functionality
## nuweb/router:: router support functionality - dispatch of code
## based on path and query parameters
## nuweb/html::
## basic support for generating HTML content
##
## #Public functions:
## nuweb.status:: <code>
## Sets HTTP response status code.
## NOTE: If any content was already returned this function does not work.
##
@namespace nuweb {
function :status {
local code=$1;shift;
local message=$@;
echo "HTTP/1.1 $code $message"
}
## nuweb.content_type:: <content-type>
## Sets HTTP response content type
## NOTE: If any content was already returned this function does not work.
function :content_type {
echo "Content-Type: $@"
}
## nuweb.redirect:: [--relative] <path>
##
function :redirect {
local prefix="";
if [ "$1" == "--relative" ]; then
shift;
prefix="$(dirname "$SCRIPT_NAME")/"
fi
nux.log debug "Redirecting to:" "$@"
if [ -z "$@" ]; then
:status 404 NOT FOUND
else
echo Location: "$prefix$@"
echo
echo
fi
}
## nuweb.redirect.exec::
##
function :redirect.exec {
if [ "$1" == "--relative" ]; then
args="--relative";
shift;
fi
fn=$1; shift;
nuweb.redirect $args "$($fn $@)"
}
## nuweb.http.query.var:: <param> [defaultValue]
## Reads HTTP query string from variable *QUERY_STRING*, parses it and returns
## value of parameter *param* or *defaultValue*.
##
## NOTE: Currently does not perform urldecode
}
@namespace nuweb.http.query {
function :var() {
local to_read=$1;
local line_separrated=$(sed "s/&/\n/g" <<< $QUERY_STRING)
while IFS="=" read -r var value; do
if [ "$var" = "$to_read" ]; then
echo "$value"
return;
fi
done <<< "$line_separrated"
echo $2
}
## nuweb.http.query.to_var::
##
function :to_var() {
local line_separrated=$(sed "s/&/\n/g" <<< $QUERY_STRING)
while IFS="=" read -r var value; do
declare -x "nuweb_QUERY_$var"="$value"
done <<< "$line_separrated"
}
}

View file

@ -0,0 +1,5 @@
@namespace block.rewrite {
:call nuweb.html.html '+e html' '-e html'
:call nuweb.html.head '+e html' '-e html'
}

View file

@ -0,0 +1,23 @@
@prefix statement nux.nuxsh.statement
@prefix block nux.nuxsh.block
@namespace nuweb.html.syntax {
function :element {
for tag in "$@" ; do
block:rewrite.call nuweb.html.$tag "nuweb.html.element $tag" "nuweb.html.element.end $tag"
statement:rewrite.call nuweb.html.$tag "nuweb.html.element --close $tag"
done
}
:element html body head title
:element style link meta script
:element header main nav
:element span div p pre
:element a img
:element h1 h2 h3 h4 h5 h6
:element form input submit button textarea select label
}

View file

@ -0,0 +1,16 @@
@namespace app. {
function :color.primary {
echo teal
}
function :color.accent {
echo cyan
}
function :header {
:
}
}

View file

@ -0,0 +1,207 @@
@syntax nuweb/html
nux.use nuweb/mdlio
nux.use nuweb/mdlio.app.defaults
nux.use nuweb/router
nux.use nux.mime
@prefix h nuweb.html
@prefix router nuweb.router
@block:rewrite:call2 e +e -e ;
@namespace mdlio.app {
function mdlio.app {
nux.exec.optional app.init
mdlio.app.html "$@"
}
function :custom func {
nux.exec.or $func app.$func "$@";
}
function :html {
nuweb.content_type text/html
echo
local spec="$1"; shift;
$spec "$@";
local app_uri="${NUWEB_SCRIPT_URI}";
local appName=$(nux.exec.optional app.name);
local title="$(nux.exec.optional title)";
echo "<!doctype html>"
h:html {
h:head {
h:meta @charset utf-8
h:meta @http-equiv x-ua-compatible @content ie=edge
h:meta @name "viewport" @content "width=device-width, initial-scale=1.0, minimum-scale=1.0"
mdlio.css $(mdlio.app.custom color.primary) $(mdlio.app.custom color.accent)
h:link @rel stylesheet @href "$NUWEB_SCRIPT_URI/action:asset/mdlio-app.css"
h:link @rel stylesheet @href "https://unpkg.com/simplelightbox@1.11.0/dist/simplelightbox.css"
nux.exec.optional app.custom.head
h:title "$(app.title) - $appName"
}
h:body .mdl-base {
+mdlio.layout .mdl-layout--fixed-header
e.mdlio.header++ "$appName"
mdlio.app.custom header
-e div
-e header
if nux.check.function app.drawer ; then
h:div .mdl-layout__drawer {
app.drawer
nux.exec.optional drawer
}
fi
+mdlio.main
nux.exec.optional app.main.start
nux.exec.or app.template-main app.content "$@"
-e main
-e div
mdlio.app.photoswipe.html
h:div .scripts {
h:script @src "https://code.jquery.com/jquery-3.2.1.min.js"
h:script @src "https://unpkg.com/masonry-layout@4/dist/masonry.pkgd.js"
h:script @src "https://unpkg.com/photoswipe@4.1.2/dist/photoswipe.js"
h:script @src "https://unpkg.com/photoswipe@4.1.2/dist/photoswipe-ui-default.js"
h:link @rel stylesheet @href https://unpkg.com/photoswipe@4.1.2/dist/photoswipe.css
h:link @rel stylesheet @href https://unpkg.com/photoswipe@4.1.2/dist/default-skin/default-skin.css
h:script @src "https://unpkg.com/infinite-scroll@3/dist/infinite-scroll.pkgd.js"
h:script @src "$NUWEB_SCRIPT_URI/action:asset/mdlio-app.js"
h:script @src "https://code.getmdl.io/1.3.0/material.min.js"
nux.exec.optional scripts
}
}
}
}
function :grid-sizer {
h:div @id scooter {
h:div .mdl-grid @id sizer {
h:div @id gutter .gutter .mdl-cell .mdl-cell--1-col .mdl-cell--1-col-phone .mdl_cell--1-col-tablet
h:div @id gutter .gutter .mdl-cell .mdl-cell--1-col .mdl-cell--1-col-phone .mdl_cell--1-col-tablet
h:div @id gutter .gutter .mdl-cell .mdl-cell--1-col .mdl-cell--1-col-phone .mdl_cell--1-col-tablet
h:div @id gutter .gutter .mdl-cell .mdl-cell--1-col .mdl-cell--1-col-phone .mdl_cell--1-col-tablet
h:div @id gutter .gutter .mdl-cell .mdl-cell--1-col .mdl-cell--1-col-phone .mdl_cell--1-col-tablet
h:div @id gutter .gutter .mdl-cell .mdl-cell--1-col .mdl-cell--1-col-phone .mdl_cell--1-col-tablet
h:div @id gutter .gutter .mdl-cell .mdl-cell--1-col .mdl-cell--1-col-phone .mdl_cell--1-col-tablet
h:div @id gutter .gutter .mdl-cell .mdl-cell--1-col .mdl-cell--1-col-phone .mdl_cell--1-col-tablet
}
}
}
function :infinity container item nextPage {
local outlayer="";
e script """
var infScroll = new InfiniteScrolldocument.querySelector('$container'); grid, {
path: '$nextPage',
append: '$item',
$outlayer
status: '.page-load-status',
elementScroll: '.mdl-layout__content'
});
"""
}
function :masonry grid gridItem lightBoxItem gutter nextPage {
e script """
var gallery = new mdlio.cardsGallery(document.querySelector('$grid'), '$gridItem', '$lightBoxItem');
"""
}
function :action.uri action path args {
echo "$NUWEB_SCRIPT_URI/action:${action}${path}${args}"
}
function :thumb.uri filename mimetype {
local thumb_name="$(thumby.name.shared "$filename")"
local dirname=$(dirname "$filename")
local thumb_path="$dirname/.sh_thumbnails/large/$thumb_name"
if thumby.thumb.can.generate "$filename" "$mimetype"; then
if thumby.thumb.should.generate "$filename" "$mimetype"; then
:action.uri thumb "$NUWEB_REQUEST_PATH/$filename"
return 0;
fi
fi
if [ -e "$thumb_path" ] ; then
nux.dirty.urlencode "$thumb_path"
fi
}
function :thumb.get {
img_path="${@##/}"
nux.log info "Generating thumb for" $(pwd) "$img_path"
thumb_path="$(thumby.thumb.get "${DOCUMENT_ROOT}/$img_path")";
if [ -n "$thumb_path" ]; then
nux.dirty.urlencode "${thumb_path#$DOCUMENT_ROOT}";
fi
}
function :run {
nuweb.router.exec mdlio.app.routes
}
function :routes {
function :post uri_spec {
router:post "$uri_spec" mdlio.app "$@"
}
function :get uri_spec {
router:get "$uri_spec" mdlio.app "$@"
}
function :get.paginate {
function app.content {
#nux.exec.optional before "$@";
before=before after=after nuweb.paginate div .gallery .mdl-grid items per-item next-page 20;
#nux.exec.optional after "$@";
}
function next-page {
h:div .mdl-grid {
h:div .mdl-cell .mdl-cell--11-col .mdl-cell--col-3-phone .mdl-cell--col-7-tablet
h:div .mdl-cell .mdl-cell--1-col {
h:a .next-page .mdl-button.mdl-button--colored @href "${REQUEST_URI%%?*}?page=$1&per_page=$2" Next
}
}
}
:get "$@"
}
#nuweb.get "/action:zip:serve/@+" mdlio.action.zip.serve
router:get "/action:thumb/@+" nuweb.redirect.exec mdlio.app.thumb.get
router:get "/action:asset/@" mdlio.app.asset
nux.exec.optional app.routes;
:get "/" app.main;
}
function :asset name {
local file="$NUX_ENV_DIR/assets/nuweb/$name";
if [ -e "$file" ]; then
mime=$(nux.mime "$file");
echo Content-Type: $mime
echo
cat "$file"
fi
}
function :photoswipe.html {
echo "<div></div>"
}
}

View file

@ -0,0 +1,49 @@
@syntax nuweb/html
@prefix statement nux.nuxsh.statement
@prefix block nux.nuxsh.block
@prefix hs nuweb.html.syntax
nux.use nuweb/html.syntax
@namespace nuweb.mdlio.syntax {
function :element name tag {
block:rewrite.call nuweb.mdlio.tag.$name "nuweb.html.element $tag $@" "nuweb.html.element.end $tag"
statement:rewrite.call nuweb.mdlio.tag.$name "nuweb.html.element --close $tag $@"
}
function :block-as-function fqn {
block:rewrite.call $fqn "function $fqn {" "}"
}
function :statement-as-echo-function fqn {
statement:rewrite.call $fqn "function $fqn() { echo " ";}"
}
:element card div .mdl-card.mdl-shadow--2dp
:element card-media div .mdl-card_media
:element card-title div .mdl-card_title
:element nav nav .mdl-navigation
:block-as-function app.name
:block-as-function app.main
:block-as-function app.content
:block-as-function app.drawer
:block-as-function app.page-title
:block-as-function app.title
:block-as-function app.scripts
:block-as-function app.template-main
:block-as-function app.routes
#:statement-as-echo-function app.page-title
#:statement-as-echo-function app.content
}
function .block.app.start.plan {
identifier=app .match.namespace_block_start.plan
}
function .block.app.end.plan {
.block.rule.namespace.end.plan
}

46
inc/nuweb/mdlio.nuxsh.sh Normal file
View file

@ -0,0 +1,46 @@
@syntax nuweb/html
@prefix h nuweb.html
nux.use nuweb/html
function mdlio.css() {
e.link stylesheet "https://fonts.googleapis.com/css?family=Roboto:regular,bold,italic,thin,light,bolditalic,black,medium&lang=en"
e.link stylesheet "https://fonts.googleapis.com/icon?family=Material+Icons"
e.link stylesheet "https://code.getmdl.io/1.3.0/material.${1}-${2}.min.css"
}
function e.mdlio.header++() {
+e header .mdl-layout__header .mdl-color--primary
+e div .mdl-layout__header-row
e span .mdl-layout-title $1
e div .mdl-layout-spacer
}
@namespace nuweb.mdlio.tag {
function :textfield id type label {
h:div .mdl-textfield.mdl-js-textfield.mdl-textfield--floating-label {
h:input .mdl-textfield__input @type "$type" @id "$id" "$@"
h:label .mdl-textfield__label @for "$id" "$label"
}
}
function :submit name {
h:input @type submit .mdl-button.mdl-js-button.mdl-button--raised.mdl-button--accent @value "$name" "$@"
}
function :nav-link href {
h:a .mdl-navigation__link @href "$href" {
echo "$@"
}
}
}
e.alias mdlio.layout "div" ".mdl-layout .mdl-js-layout"
e.alias mdlio.main "main" ".mdl-layout__content"
e.alias mdlio.card "div" ".mdl-card.mdl-shadow--2dp"
function .mdl_cell() {
echo .mdl-cell.mdl-cell--"$1"-col.mdl-cell--"$2"-col-tablet.mdl-cell--"$2"-col-phone
}

View file

@ -0,0 +1,13 @@
#!/usr/bin/env bash
nux.prep.rewrite() {
}
nux.prep.include() {
}
nux.prep.exec() {
}

130
inc/thumby.nuxsh.sh Normal file
View file

@ -0,0 +1,130 @@
nux.use nux.mime
@namespace thumby {
function :name.shared {
echo $(basename "$1"|md5sum|cut -d " " -f1).png
}
function :noop {
:
}
function :image.size {
raw_str=$(identify "$1")
str=${raw_str#$1 * }
echo ${str%% *}
}
function :mimetype.supported {
local mimetype="$1";
local base="${mimetype%%/*}";
local helper="${mimetype/\//.}";
if [ "$base" == "image" ]; then
return 0;
elif nux.check.function thumby.thumb.source.locator.$helper; then
return 0;
elif nux.check.function thumby.thumb.source.extractor.$helper; then
return 0;
fi
return 1;
}
}
@namespace thumby.thumb {
function :should.generate path mimetype {
local thumbpath=$(thumby.thumb.path "$path");
local source=$(thumby.thumb.source "$path" "$mimetype");
if [ "$source" -nt "$thumbpath" ]; then
return 0;
else
return 1;
fi
}
function :can.generate path mimetype {
local helper="${mimetype/\//.}";
if ! thumby.mimetype.supported "$mimetype" {
return 1;
}
if nux.check.function thumby.thumb.source.locator.$helper {
local source=$(thumby.thumb.source.locator.$helper "$path");
if [ -z "$source" ] {
return 1;
}
}
return 0;
}
function :source path mimetype {
local helper="${mimetype/\//.}";
if nux.check.function thumby.thumb.source.locator.$helper; then
thumby.thumb.source.locator.$helper "$path"
else
echo "$path";
fi
}
function :path path {
local filename=$(basename "$path")
local dirname=$(dirname "$path")
local thumbname="$(thumby.name.shared "$filename")";
echo "$dirname/.sh_thumbnails/large/$thumbname";
}
function :get path mimetype {
nux.log debug "thumby path: $path";
if [ ! -e "$path" ] ; then
return -1;
fi
if [ -z "$mimetype" ] ; then
mimetype=$(nux.mime "$path")
fi
local filename=$(basename "$path")
local dirname=$(dirname "$path")
local thumbname="$(thumby.name.shared "$filename")";
local thumbpath="$dirname/.sh_thumbnails/large/$thumbname";
nux.log debug "Dir: $dirname, File: $filename, thumb: $thumbname"
if thumby.thumb.should.generate "$path" "$mimetype" {
helper="${mimetype/\//.}"
nux.log debug "File $path, type $mimetype does not have thumbnail. Trying to generate using $helper."
local preexec=thumby.noop;
local postexec=thumby.noop;
local source=$path;
local streamer=thumby.noop;
if nux.check.function thumby.thumb.source.locator.$helper ; then
source=$(thumby.thumb.source.locator.$helper "$path");
fi
if nux.check.function thumby.thumb.source.extractor.$helper ; then
echo "Using source helper" >&2
source="-"
streamer=thumby.thumb.source.extractor.$helper;
fi
nux.log debug "File $path, using '$source' as source. Using stremer '$streamer'"
mkdir -p "$dirname/.sh_thumbnails/large" &>/dev/null
mtime=`stat -c '%Y' "$path"`
$preexec "$path"
nux.log info "Source is : $source, Streamer is $streamer";
$streamer "$path" | convert -thumbnail '256x256>' -strip "$source" "$thumbpath" >&2
$postexec "$path"
}
if [ -e "$thumbpath" ]; then
echo $thumbpath;
fi
}
function :generate {
convert -thumbnail '256x256>' -strip "$path" "$thumbpath" >&2
}
}

View file

@ -0,0 +1,46 @@
@namespace thumby.thumb.source {
function :locator.directory {
nux.log info "Using find to find jpg or png"
find -L "$1" -maxdepth 1 -iname "*.jpg" -or -iname "*.png" | sort -n | head -n1
}
function :locator.application.pdf {
echo "$1[0]"
}
function :extractor.application.epub+zip() {
local rootDesc=$(unzip -p "$1" META-INF/container.xml \
| xmlstarlet sel -N od="urn:oasis:names:tc:opendocument:xmlns:container" \
-t -v "/od:container/od:rootfiles/od:rootfile[@media-type='application/oebps-package+xml']/@full-path" -n)
nux.log info "Root description is in: $rootDesc";
local imgDesc=$(unzip -p "$1" "$rootDesc" \
| xmlstarlet sel -N opf="http://www.idpf.org/2007/opf" \
-t -m "/opf:package/opf:manifest/opf:item[@id=/opf:package/opf:metadata/opf:meta[@name='cover']/@content]" \
-v "@href" -o ":" -v "@media-type" -n)
IFS=":" read -r img media <<< "$imgDesc";
nux.log info "Image name is $imgDesc $img";
if [ -n "$img" ]; then
unzip -p "$1" $img
fi
}
function :extractor.application.x-cbr() {
suffix="${1##*.}"
case "$suffix" in
zip) ;&
cbz)
potential=$(unzip -l "$1" | sed -re "s/^ *[0-9]+ +[0-9\\-]+ +[0-9:]+ +//gi" | grep -E '\.((jpg)|(png)|(jpeg))$' | sort -n | head -n 1)
nux.log debug "Potential preview is: $potential";
if [ -n "$potential" ]; then
unzip -p "$1" "$potential"
nux.log debug "Preview extracted."
fi
;;
*) nux.log error "$suffix is not supported."
esac
}
}