From 7b0c9d0ad2ebc4ae964c793f2a429da50f41a911 Mon Sep 17 00:00:00 2001 From: Q Date: Sat, 19 Aug 2023 21:10:45 +0300 Subject: [PATCH] the script --- code/templates/mfl | 255 ++++++++++++++++++++++++++++++++++++++++++++ code/utils/files.py | 1 + test/run-tests.sh | 21 ++++ 3 files changed, 277 insertions(+) create mode 100755 code/templates/mfl diff --git a/code/templates/mfl b/code/templates/mfl new file mode 100755 index 0000000..2563e38 --- /dev/null +++ b/code/templates/mfl @@ -0,0 +1,255 @@ +#!/bin/bash + +set -e +_help() { + SELF=$( basename "$0" ) + echo "MFL CLI v.{{ version }} + Commands: + + (l)ist [default] List names of files + (w)rite Save to share, read from stdin/file/folder + (d)elete Delete an entry + upload Get URL for uploads [no arguments] + autocomplete Get Bash autocompletion script + update Update self + + -d max days to keep (default 30) + -m max downloads to keep (default 9999, -1 to disable) + + Filename: + When writing to share: + File or folder to read from. If omitted: stdin. + + Usage: + echo my data | $SELF w file.ext # writes data with name: file.ext + $SELF w file.ext # sends file keeping its name + + Config: + set: MFL_ROOTURL, MFL_TOKEN +" + exit +} + + +_load_config() { + MFL_TOKEN="${MFL_TOKEN:-{{ token }}}" + MFL_ROOTURL="${MFL_ROOTURL:-{{ rooturl }}}" +} + +_update_client() { + echo "Current version:" + "$0" --help | head -n 1 + echo "Updating from $MFL_ROOTURL" + curl -fLo "$0" -H "Secret: $MFL_TOKEN" "$MFL_ROOTURL/script/mfl" + err=$? + chmod +x "$0" + echo "Downloaded version:" + "$0" --help | head -n 1 + exit $err +} + +_list() { + curl -fL -w "\n" -s -H "Secret: $MFL_TOKEN" "$MFL_ROOTURL"/ls +} + +#~ _simple_list() { + #~ curl -fL -w "\n" -s -H "Secret: $MFL_TOKEN" "$MFL_ROOTURL"/ls | sed 's/.*http/http/' | tail -n +3 +#~ } + +_write() { + # stdin is open + [ -t 0 ] || { + stream_in=1 + [[ -z "$NAME" ]] && { + _msg Output filename not set + exit 1 + } + } + # no file mentioned, use the name as file + [[ -z "$FILE" ]] && { + [[ -e "$NAME" ]] && { + # NAME is actually the file, reverse roles + FILE="${NAME}" + NAME=$( basename "${NAME}" ) + } + } + [[ -e "$FILE" ]] && { + # Input file exists, dont use stream + stream_in=0 + } + + [[ $stream_in -ne 1 ]] && [[ -z "$FILE" ]] && { + _msg File to read needed, or use stdin + exit 1 + } + _msg "Writing $NAME" + [[ "$stream_in" -eq 1 ]] && { + _write_stdin "$NAME" + return $? + } + + [[ -d "$FILE" ]] && { + [[ "${NAME,,}" = *".tar" ]] || NAME="${NAME}".tar + _write_folder "$NAME" "$FILE" + return $? + } + + [[ -f "$FILE" ]] || { + _msg "No such file" + exit 1 + } + _write_file "$NAME" "$FILE" +} + +_write_folder() { # name, file + tar c "$2" | \ + curl -fL -w "\n" -F file="@-" -X POST \ + -H "Name: $1" \ + -H "Max-Downloads: $MAXDL" \ + -H "Expires-Days: $MAXDAYS" \ + -H "Secret: $MFL_TOKEN" \ + "$MFL_ROOTURL"/upload +} +_write_file() { # name, file + curl -fL -w "\n" -F file="@$2" -X POST \ + -H "Name: $1" \ + -H "Max-Downloads: $MAXDL" \ + -H "Expires-Days: $MAXDAYS" \ + -H "Secret: $MFL_TOKEN" \ + "$MFL_ROOTURL"/upload +} +_write_stdin() { # name + cat - \ + curl -fL -w "\n" -F file="@-" -X POST \ + -H "Name: $1" \ + -H "Max-Downloads: $MAXDL" \ + -H "Expires-Days: $MAXDAYS" \ + -H "Secret: $MFL_TOKEN" \ + "$MFL_ROOTURL"/upload +} +#~ _link_format() { + #~ sed -e 's/^http:/https:/' -e 'p;' | sed -e "2s|$MFL_ROOTURL|&/dl|" +#~ } + +_delete() { # name + read -p "Sure to delete: $1 ? Break to exit " foo + curl -fL -w "\n" \ + -H "Secret: $MFL_TOKEN" \ + "$MFL_ROOTURL"/delete/"$1" +} + +#~ _upload_url() { + #~ echo "This information is a security risk, watch where it's shared" + #~ echo "curl -fL -w \"\\n\" -H \"Max-Days: $MAXDAYS\" -u \"${USER}:${PASSWORD}\" $MFL_ROOTURL/[FILENAME] --upload-file [FILENAME]" + #~ exit +#~ } + +#~ _self_url() { + #~ echo "This information is a security risk, watch where it's shared" + #~ echo "curl -L -H \"Token: $PASSWORD\" \"${MFL_ROOTURL}/xfer.sh\"" + #~ exit +#~ } + +_msg() { + echo "$@" >&2 +} + + +_get_completer() { + self=$( basename $( readlink -f "$0" ) ) + echo '_MFL_EXEC_complete() { +local curr_arg +curr_arg=${COMP_WORDS[COMP_CWORD]} +if [[ $COMP_CWORD -eq 1 ]]; then + COMPREPLY=( $(compgen -W "help autocomplete list write delete update" -- $curr_arg ) ); +fi +if [[ $COMP_CWORD -eq 2 ]]; then + case ${COMP_WORDS[$(( $COMP_CWORD - 1 ))]} in + delete) + local remotelist=$( eval MFL_EXEC simplelist ) + COMPREPLY=( $(compgen -W "$remotelist" -- $curr_arg ) ); + ;; + w*) + COMPREPLY=( $(compgen -f -d -- $curr_arg ) ); + ;; + esac +fi +if [[ $COMP_CWORD -eq 3 ]]; then + COMPREPLY=( $(compgen -f -d -- $curr_arg ) ); +fi +} +complete -F _MFL_EXEC_complete MFL_EXEC +# Run me as: source <( MFL_EXEC autocomplete ) +' | sed "s,MFL_EXEC,$self,g" + exit 0 +} + +_load_config +for (( i=1; i<=$#; i++ )); do + [[ "${!i}" = "-h" ]] && _help + [[ "${!i}" = "--help" ]] && _help +done + +MAXDL=9999 +MAXDAYS=30 +CMD=list +# if stdin comes from stream, default to write +[ -t 0 ] || CMD=help +for (( i=2; i<=$#; i++ )); do + j=$(( i + 1 )) + [[ "${!i}" = "-m" ]] && { MAXDL=${!j}; i=$j; continue; } + [[ "${!i}" = "-d" ]] && { MAXDAYS=${!j}; i=$j; continue; } + if [[ -z "$FILE" ]]; then + FILE="${!i}" + continue + fi + if [[ -z "$NAME" ]]; then + NAME="${!i}" + fi +done +if [[ -z "$NAME" ]]; then + if [[ -n "$FILE" ]]; then + NAME="$( basename ${FILE} )" + fi +fi + +[[ "$1" = "w" || "$1" = "write" ]] && { CMD=write; ARG1=$CMD; } +[[ "$1" = "d" || "$1" = "delete" || "$1" = "del" ]] && { CMD=delete; ARG1=$CMD; } +[[ "$1" = "l" || "$1" = "list" ]] && { CMD=list; ARG1=$CMD; } +[[ "$1" = "simplelist" ]] && { CMD=simple_list; ARG1=$CMD; } +[[ "$1" = "autocomplete" ]] && { _get_completer; } +[[ "$1" = "update" ]] && { _update_client; } +[[ "$1" = "upload" ]] && { _upload_url; } +[[ "$1" = "self" ]] && { _self_url; } +[[ "$1" = "h" || "$1" = "help" ]] && CMD=help + +[[ "$CMD" = help ]] && { + _help + exit $? +} + +[[ "$CMD" = list ]] && { + _list + exit $? +} + +[[ "$CMD" = simple_list ]] && { + _simple_list + exit $? +} + +[[ "$CMD" = delete ]] && { + if [[ -z "$NAME" ]]; then + echo Missing key / file name + _simple_list | sed 's,^'${ROOTURL}/',,' + echo Add secret key as argument + exit + fi + + _delete "$NAME" + exit $? +} +[[ "$CMD" = write ]] && { + _write + exit $? +} diff --git a/code/utils/files.py b/code/utils/files.py index 2252c3b..9ae2332 100644 --- a/code/utils/files.py +++ b/code/utils/files.py @@ -45,6 +45,7 @@ def db_get_files(): SELECT token,name,added,expires,downloads,max_downloads FROM files WHERE expires > ? and (downloads < max_downloads or max_downloads = -1) + ORDER BY added """, (time.time(),), ) diff --git a/test/run-tests.sh b/test/run-tests.sh index aa39c3d..8680445 100755 --- a/test/run-tests.sh +++ b/test/run-tests.sh @@ -232,6 +232,27 @@ function t10-maintenance-post() { "$FLASK_PUBLIC_URL"/ls } +function t11-get-mfl() { + curl -fL \ + -H "Secret: $FLASK_ACCESS_TOKEN" \ + "$FLASK_PUBLIC_URL"/script/mfl > mfl + chmod +x mfl + +} +function t12-mfl-update() { + ./mfl update +} +function t13-mfl-list() { + ./mfl list + ./mfl +} +function t14-mfl-upload() { + ./mfl w mfl + ./mfl w -d 1 -m 1 mfl +} + + + _getlist() { declare -F | awk '{ print $3 }' | grep -v ^_ echo exit