Compare commits

...

90 Commits

Author SHA1 Message Date
fbt 0238da5820 Refuse to upload empty files
Signed-off-by: fbt <fbt@fleshless.org>
2026-09-13 00:50:30 +00:00
fbt 67dc431aa2 Add a step that converts files if asked to
Signed-off-by: fbt <fbt@fleshless.org>
2025-05-25 11:14:31 +00:00
fbt 19f6c5249a remove debug stuff
Signed-off-by: fbt <fbt@fleshless.org>
2022-12-28 04:19:58 +00:00
fbt 823a2847c8 encode all the stuff
Signed-off-by: fbt <fbt@fleshless.org>
2022-12-28 04:16:26 +00:00
fbt 6e2c506e72 alignment
Signed-off-by: fbt <fbt@fleshless.org>
2022-04-18 10:25:48 +00:00
fbt 3f094a2b47 xclip selector selector :>
Signed-off-by: fbt <fbt@fleshless.org>
2021-10-06 13:49:35 +03:00
fbt cd5f695936 clipboard option
Signed-off-by: fbt <fbt@fleshless.org>
2021-10-06 13:40:45 +03:00
fbt 8aea6446bb forgot this one
Signed-off-by: fbt <fbt@fleshless.org>
2021-10-06 13:22:17 +03:00
fbt fb38496fe9 just return 1
Signed-off-by: fbt <fbt@fleshless.org>
2021-04-19 16:14:19 +03:00
fbt df4e1d0370 Smarter args
Signed-off-by: fbt <fbt@fleshless.org>
2020-10-03 19:44:19 +03:00
fbt b63ae67204 it's actually just format
Signed-off-by: fbt <fbt@fleshless.org>
2020-08-21 15:42:52 +03:00
fbt f103e564dc readme
Signed-off-by: fbt <fbt@fleshless.org>
2020-05-24 04:36:13 +03:00
fbt 176b80fcf6 Actually, to hell with this sugar stuff
Signed-off-by: fbt <fbt@fleshless.org>
2020-05-24 04:21:39 +03:00
fbt 3ac25bbeb2 simpler sugar
Signed-off-by: fbt <fbt@fleshless.org>
2020-05-24 03:57:17 +03:00
fbt 522dc0e1f6 group curl settings and make em configurable at the same time
Signed-off-by: fbt <fbt@fleshless.org>
2020-05-24 03:43:39 +03:00
fbt 6e9046367f wut
Signed-off-by: fbt <fbt@fleshless.org>
2019-12-04 14:14:13 +03:00
fbt 67ddff1306 indentation
Signed-off-by: fbt <fbt@fleshless.org>
2019-12-04 14:13:03 +03:00
fbt c89d90f67c Just use this in a wrapper; this was a bad idea
Signed-off-by: fbt <fbt@fleshless.org>
2019-12-04 14:12:01 +03:00
fbt 2beb1c0638 these have no reason not to be flags
Signed-off-by: fbt <fbt@fleshless.org>
2019-11-26 01:53:22 +03:00
fbt 8804a855b3 and some other stuff
Signed-off-by: fbt <fbt@fleshless.org>
2019-11-26 01:49:12 +03:00
fbt 7858829ec4 support setting the secret in env vars
Signed-off-by: fbt <fbt@fleshless.org>
2019-11-26 01:46:00 +03:00
fbt bfbd899554 Forgot to change this
Signed-off-by: fbt <fbt@fleshless.org>
2019-11-25 04:39:24 +03:00
fbt 4e1d3a7bcd A better way
Signed-off-by: fbt <fbt@fleshless.org>
2019-11-24 14:00:32 +03:00
fbt 03e0fda896 A better way
Signed-off-by: fbt <fbt@fleshless.org>
2019-11-24 13:59:08 +03:00
fbt 146f06e7c5 alternate config file
Signed-off-by: fbt <fbt@fleshless.org>
2019-11-24 13:50:24 +03:00
fbt d2529e32bd Let the script get its own damn token
Signed-off-by: fbt <fbt@fleshless.org>
2019-11-24 13:18:22 +03:00
fbt bb704f4856 fix the doc
Signed-off-by: fbt <fbt@fleshless.org>
2019-11-24 08:46:22 +03:00
fbt fadba21791 void
Signed-off-by: fbt <fbt@fleshless.org>
2019-11-24 08:41:53 +03:00
fbt 3cfdcb1209 How long has that been there, wtf
Signed-off-by: fbt <fbt@fleshless.org>
2019-11-23 22:45:55 +03:00
fbt ad256e83e3 Use jq
Signed-off-by: fbt <fbt@fleshless.org>
2019-11-23 09:58:19 +03:00
fbt 3a48f36d43 Use jq
Signed-off-by: fbt <fbt@fleshless.org>
2019-11-23 09:57:58 +03:00
fbt 01478630e8 no more api/2
Signed-off-by: fbt <fbt@fleshless.org>
2019-11-23 09:37:09 +03:00
fbt a31d8b8963 album control also moved
Signed-off-by: fbt <fbt@fleshless.org>
2019-11-23 08:19:12 +03:00
fbt 0dafaaf15b The upload endpoint moved
Signed-off-by: fbt <fbt@fleshless.org>
2019-11-23 07:18:51 +03:00
fbt 466050972d shrink moved too
Signed-off-by: fbt <fbt@fleshless.org>
2019-11-23 06:52:41 +03:00
fbt 99735444f3 notification control
Signed-off-by: fbt <fbt@fleshless.org>
2019-11-22 14:43:04 +03:00
fbt d73f41e2de ip moved
Signed-off-by: fbt <fbt@fleshless.org>
2019-11-22 12:52:07 +03:00
fbt 52f5ea9028 support tags
Signed-off-by: fbt <fbt@fleshless.org>
2019-11-20 07:38:10 +03:00
fbt 83bbe70c80 Fix: ufw does nothing without a positional argument even if it's not required
Signed-off-by: fbt <fbt@fleshless.org>
2019-11-18 04:07:42 +03:00
fbt 47fe62a7c8 duh
Signed-off-by: fbt <fbt@fleshless.org>
2019-06-03 02:21:56 +03:00
fbt 639a97f43e I SAID NO MORE
Signed-off-by: fbt <fbt@fleshless.org>
2019-05-20 15:31:06 +03:00
fbt 784ad95215 There is no scan anymore
Signed-off-by: fbt <fbt@fleshless.org>
2019-05-20 15:30:35 +03:00
fbt 58e1b63fb7 Support multiple workdirs
Signed-off-by: fbt <fbt@fleshless.org>
2019-05-20 15:28:03 +03:00
fbt 65fdd688bf That was poorly researched
Signed-off-by: fbt <fbt@fleshless.org>
2019-05-13 22:57:40 +03:00
fbt 488fdc0a5a oops-driven development
Signed-off-by: fbt <fbt@fleshless.org>
2019-05-10 00:18:29 +03:00
fbt 14af6b720f oops
Signed-off-by: fbt <fbt@fleshless.org>
2019-05-09 23:55:03 +03:00
fbt c22e34afb2 aaaand fork for every file
Signed-off-by: fbt <fbt@fleshless.org>
2019-05-09 23:50:33 +03:00
fbt d7f1104f82 use inotifywait; clipboard
Signed-off-by: fbt <fbt@fleshless.org>
2019-05-09 23:31:25 +03:00
fbt e2c6143c8c use maim instead of scrot
Signed-off-by: fbt <fbt@fleshless.org>
2016-12-04 16:58:19 +03:00
fbt b5331d8c93 code shuffle; quiet flag
Signed-off-by: fbt <fbt@fleshless.org>
2016-03-12 20:45:19 +03:00
fbt 59fb4b81eb -l: request a login token
Signed-off-by: fbt <fbt@fleshless.org>
2016-03-08 00:39:48 +03:00
fbt 97701825bd deps
Signed-off-by: fbt <fbt@fleshless.org>
2016-03-06 16:55:09 +03:00
fbt c6e43448ca clear the delimiter for read
Signed-off-by: fbt <fbt@fleshless.org>
2016-03-06 09:01:49 +03:00
fbt 9b3516951c code cleanup
Signed-off-by: fbt <fbt@fleshless.org>
2016-03-06 08:43:05 +03:00
fbt 91a5d9bec2 Line breaks
Signed-off-by: fbt <fbt@fleshless.org>
2016-03-06 08:33:20 +03:00
fbt 40c1767aae I'm tired of updating the help in README
Signed-off-by: fbt <fbt@fleshless.org>
2016-03-06 08:32:52 +03:00
fbt 7c9d85e8c0 Some options overhaul and 8fw json support
Signed-off-by: fbt <fbt@fleshless.org>
2016-03-06 08:28:33 +03:00
fbt e610dce293 * Fix README
* Create the album ourselves.

Signed-off-by: fbt <fbt@fleshless.org>
2016-03-06 07:35:25 +03:00
fbt 634b11c3b4 forgot about --
Signed-off-by: fbt <fbt@fleshless.org>
2016-03-06 07:19:40 +03:00
fbt f05682e9a7 new README
Signed-off-by: fbt <fbt@fleshless.org>
2016-03-06 07:18:59 +03:00
fbt 71744b6325 api tweaks
Signed-off-by: fbt <fbt@fleshless.org>
2016-03-06 06:57:47 +03:00
fbt b33e57e886 fastfix
Signed-off-by: fbt <fbt@fleshless.org>
2016-03-03 21:55:51 +03:00
fbt 3fe0d59815 album 2016-03-03 21:49:49 +03:00
fbt ef3cd20dfc Add file to an album on upload 2016-03-03 19:00:39 +03:00
fbt fd208cff1e pass keys to ufw
Signed-off-by: fbt <fbt@fleshless.org>
2016-02-22 23:43:04 +03:00
fbt 776217ab00 8fw now marks new files as private unless stated otherwise
Signed-off-by: fbt <fbt@fleshless.org>
2016-02-22 23:19:06 +03:00
fbt 2d7e65682f eh 2016-01-01 17:16:03 +03:00
fbt baa483e7cc notification support 2015-12-20 15:46:24 +03:00
fbt e13f062037 sup -> ufw 2015-11-19 18:59:09 +03:00
fbt 81c636d2fc Merge branch 'master' of builder:git/ufw-tools 2015-11-19 18:33:05 +03:00
fbt 68a8550c1c o hai 2015-11-19 18:32:58 +03:00
fbt 6a42269dbc README 2015-11-13 05:14:26 +03:00
fbt 84ac5fb315 actually not in megabytes 2015-11-13 05:13:45 +03:00
fbt b264c94a85 taaaabs 2015-11-13 05:13:12 +03:00
fbt 8befbdf3da max filesize 2015-11-13 05:08:55 +03:00
fbt a4e0a119a8 Another default domain change 2015-10-20 21:38:29 +03:00
fbt ee819a8629 8fw.eu 2015-10-19 00:35:04 +03:00
fbt af0b52e575 always remove temporary files 2015-10-13 13:57:56 +03:00
fbt 1809fde7c9 use XDG! 2015-10-13 13:52:26 +03:00
fbt e3d642a730 /ip support 2015-10-12 17:59:33 +03:00
fbt b118e40f72 rm didn't work if the file was already uploaded 2015-07-05 17:14:27 +03:00
fbt 76952ee309 description support 2015-06-23 23:25:48 +03:00
fbt 828e6a3c53 support for getting shortlinks on upload 2015-06-22 03:13:44 +03:00
fbt 78b17aa234 actually return the proper url 2015-06-22 02:44:11 +03:00
fbt d3e99ec189 hehe 2015-06-22 02:29:57 +03:00
fbt 9424b975ed Support for the new shortlink feature. 2015-06-21 16:05:12 +03:00
fbt 30c57c8685 clienside hash check 2015-06-21 09:52:29 +03:00
fbt 75897a38f7 New tool: supd
supd is a very simple tool that uploads everything from a directory to zfh.
Also some refactoring on sup.
2015-04-17 00:42:06 +03:00
fbt 5e8960d376 README 2015-03-08 19:49:37 +03:00
fbt eece601793 sup usage function 2015-03-08 19:48:26 +03:00
5 changed files with 600 additions and 192 deletions
+17 -13
View File
@@ -1,23 +1,27 @@
LICENSE
=======
All scripts here are released uder the ISC permissive free software license (http://en.wikipedia.org/wiki/ISC_license).
It basically says that you can do whatever you like with the code as long as you credit the author and provide the license with it.
Also see LICENSE in the repo.
ufw-tools
=========
ufw-tools are two simple-ish scripts for uploading files to 8fw.me.
Support
=======
I do not promise any support for any of the provided scripts. That said, I'll do what I can for you if I'm not too busy and/or drunk.
General information
===================
The paths are all configurable of course.
The help information that the scripts give is dynamic and is provided here only for reference.
Scripts
=======
sup
ufw
---
A very simple tool to upload files to the zfh.so file hosting
Usage: sup [-RsF] [-D num] [file/url]
ufw can upload files to 8fw.me, shorten urls and show you your ip.
Call ufw -h for help.
Dependencies: curl, jq
The config goes into `$XDG_CONFIG_DIR/ufw`.
ufwd
----
ufwd periodically checks a directory of your choosing (defaults to $XDG_RUNTIME DIR/ufwd) and invokes ufw to upload the files and remove them.
Call ufwd -h for help.
+11
View File
@@ -0,0 +1,11 @@
# Put your actual secret here, this is just a random string
secret='rooxoosh7Aese7phiPh3Choh3uthiTha'
# Override the default common curl behaviour:
#curl() { command curl -sL "$@"; }
#cfg_tmp_dir="$XDG_RUNTIME_DIR/ufw"
#cfg_service_url='https://8fw.me'
#cfg_max_filesize='200M' # Local limit, doesn't affect the server one :)
#flag_shortlink=0 # Display short links
#flag_directlink=1 # Display direct file links
-179
View File
@@ -1,179 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) 2012 fbt <fbt@fleshless.org>
#
# About:
# A simple upload script for ZFH (http://zerofiles.org)
_self="${0##*/}"
cfg_url_regex='^[A-Za-z]([A-Za-z0-9+.-]+)?://.+'
cfg_tmp_dir="/tmp/$USER/sup"; TEMPDIR="$cfg_tmp_dir"
cfg_script_url='https://zfh.so/upload'
cfg_screenshot_ext='png'
[[ -f $HOME/.suprc ]] && { source "$HOME/.suprc"; }
sup.msg() { printf '%s\n' "[sup] $1"; }
sup.err() { sup.msg "(error) $1" >&2; }
sup.usage() {
printf '%s\n' "Usage: ${_self} [-RsF] [-D num] [file/url]"
}
sup.env() {
for i in "$cfg_tmp_dir"; do
[[ -d "$i" ]] || { mkdir -p "$i"; }
done
}
sup.upload() {
curl -F file="@$file" \
-F upload_mode='api' \
-F flag_private="$flag_private" \
-F secret="$secret" \
-F submit="" \
"$cfg_script_url" -sL -A 'zerofiles.org upload script' || { return 1; }
(( "$flag_rm" )) && { rm "$file"; }
return 0
}
sup.mktemp() {
>"$1" || {
sup.err "Cannot create $1!"
return 1
}
printf '%s\n' "$1"
}
sup.scrot() {
declare tmp_file
[[ "$scrot_exec" ]] || { scrot_exec=$(type -P scrot); }
[[ "$scrot_exec" ]] || {
sup.err "Please install scrot to use this function"
return 1
}
(( "$flag_scrot_fullscreen" )) || { scrot_args+=( '-s' ); }
[[ "$cfg_scrot_delay" ]] && { scrot_args+=( "-d $cfg_scrot_delay" ); }
tmp_file="$(sup.mktemp "${cfg_tmp_dir}" ".${cfg_screenshot_ext}")"
scrot "${scrot_args[@]}" "$tmp_file" || {
sup.err "Failed to take a screenshot."
return 1
}
printf '%s\n' "$tmp_file"
}
sup.if_url() { printf '%s\n' "$1" | grep -oE "$cfg_url_regex" &>/dev/null; }
sup.mktemp() {
declare tmp_file_name tmp_file_name_extra="$2" tmp_dir="$1"
[[ -d "$tmp_dir" ]] || {
sup.err "${tmp_dir} does not exist or is not a directory."
return 1
}
until [[ ! -e "${tmp_dir}/${tmp_file_name}" ]]; do
tmp_file_name="${RANDOM}${RANDOM}${tmp_file_name_extra}"
done
printf '%s\n' "${tmp_dir}/${tmp_file_name}"
}
sup.set_argv() {
declare arg opt c
declare -g argv
while (( $# )); do
unset -v arg opt c
case "$1" in
(--) argv+=( "$1" ); break;;
(--*)
IFS='=' read arg opt <<< "$1"
argv+=( "$arg" )
[[ "$opt" ]] && {
argv+=( "$opt" )
}
;;
(-*)
while read -n1 c
do
case "$c" in
-|'') :;;
*) argv+=( "-$c" );;
esac
done <<< "$1"
;;
(*) argv+=( "$1" );;
esac
shift
done
}
main() {
declare args file target flag_private flag_rm flag_scrot flag_scrot_fullscreen cfg_scrot_delay
while [[ "$1" ]]; do
case "$1" in
-p|--private) flag_private='true';;
-R|--remove-file) flag_rm='1';;
-s|--screenshot) flag_scrot='1';;
-F|--fullscreen) flag_scrot_fullscreen='1';;
-D|--screenshot-delay) cfg_scrot_delay="$2"; shift;;
-h|--help|--usage) sup.usage; return;;
--) shift; break;;
*) break;;
esac
shift
done
sup.env
if (( flag_scrot )); then
file=$(sup.scrot) || { return 1; }
else
(( $# )) || {
sup.usage
return 1
}
target="$1"
if sup.if_url "$target"; then
file=$(sup.mktemp "$cfg_tmp_dir")
curl -skL "$target" > "$file" || {
sup.err "Could not download file."
return 1
}
else
file="$target"
[[ -f "$file" ]] || {
sup.err "No such file: ${file}"
return 1
}
fi
fi
sup.upload
}
sup.set_argv "$@"
main "${argv[@]}"
Executable
+471
View File
@@ -0,0 +1,471 @@
#!/usr/bin/bash
# Copyright (c) 2012 fbt <fbt@fleshless.org>
# License: ISC
#
# About:
# A simple upload script for UFW (http://zerofiles.org)
_cat() {
while read; do
printf '%s\n' "$REPLY"
done
}
is_url() {
[[ "$1" =~ $cfg_url_regex ]]
}
msg() {
if ! (( flag_quiet )); then
printf '%s\n' "$1"
fi
}
err() { printf '(error) %s\n' "$*" >&2; }
curl() { command curl -sL "$@"; }
usage() {
_cat <<- EOF
Usage: ufw [-RsF] [-D num] [file/url]
Flags:
-R|--remove-file # Remove the file after uploading.
-d|--description # Supply a description.
-p|--public # Make the file public.
-n|--no-notify # Don't send immediate notifications for this upload.
--notify # Force a notification for this upload.
-u|--shorten <URL> # Generate a shortlink from URL.
-S|--short-url # Get a shortlink when uploading a file.
-P|--page-url # Get a link to the file page instead of a direct one.
-m|--max-filesize <num>[suf] # Maximum filesize (takes K, M and G suffixes).
-a|--album-id # Add the file to an album.
-A|--album-name # Add the file to an album by name. The album will be created, if necessary.
-t|--tags "<tag1[, tag2,..]>" # Add tags to the file.
-q|--quiet # Be quiet.
-v|--void # Don't add the file to my files.
-c|--clipboard # Throw the result into the clipboard
Config options (~/.config/ufw):
secret # Your personal token. Get it at https://zfh.so/settings_form
cfg_max_filesize # Maximum filesize (takes K, M and G suffixes).
# Others are self-explanatory:
cfg_url_regex
cfg_tmp_dir
cfg_service_url
Environment variables:
UFW_CFG_FILE # Config file to read, defaults to \$XDG_CONFIG_DIR/ufw
UFW_SECRET # Your API secret
UFW_TMP_DIR
UFW_URL
EOF
}
get_file_hash() {
read file_hash _ < <( sha1sum "$1" )
}
get_max_filesize() {
if [[ $cfg_max_filesize =~ ^[0-9]+[BKMG]?$ ]]; then
max_filesize_base="${cfg_max_filesize//[BKMG]/}"
case "$cfg_max_filesize" in
*K) max_filesize_bytes=$(( max_filesize_base * 1024 ));;
*M) max_filesize_bytes=$(( max_filesize_base * 1024 * 1024 ));;
*G) max_filesize_bytes=$(( max_filesize_base * 1024 * 1024 * 1024 ));;
*) max_filesize_bytes=$max_filesize_base;;
esac
else
err "Wrong cfg_max_filesize: $cfg_max_filesize"
return 1
fi
}
get_album_id() {
declare api_response api_status api_status_message
api_response=$( curl --get \
--data-urlencode "name=$1" \
--data-urlencode "secret=$secret" \
"$cfg_service_url/albumctl.json?m=new" )
get_api_status <<< "$api_response"
if (( api_status == 200 )); then
album_id=$( jq -r '.data.album.id' <<< "$api_response" )
misc_curl_args+=( -F album_id="$album_id" )
else
printf 'Error [album]: %s %s\n' "$api_status" "$api_status_message"
return 1
fi
}
upload() {
declare api_response api_status api_status_message
(( $# )) || {
usage
return 1
}
target="$1"
if is_url "$target"; then
flag_rm=1
file=$(_mktemp "$cfg_tmp_dir")
get_max_filesize || { return 1; }
curl --max-filesize "$max_filesize_bytes" "$target" > "$file"
curl_result=$?
if (( curl_result )); then
case "$curl_result" in
63) err "File exceeds cfg_max_filesize";;
*) err "Could not download file.";;
esac
return 1
fi
else
file="$target"
[[ -f "$file" ]] || {
err "No such file: ${file}"
return 1
}
fi
get_file_hash "$file"
if [[ "$album_name" ]]; then
get_album_id "$album_name"
fi
api_response=$( curl \
-F file="@$file" \
-F format='json' \
-F flag_private="$flag_private" \
-F secret="$secret" \
-F tags="$tags" \
-F notify="$flag_notify" \
-F void="${flag_void:-0}" \
-F submit="" \
"${misc_curl_args[@]}" \
-A 'zerofiles.org upload script' \
"$cfg_service_url/maw.json" )
if (( flag_shortlink )); then
if (( flag_directlink )); then
file_url_request='short_url'
else
file_url_request='page_short_url'
fi
else
file_url_request='url'
fi
get_api_status <<< "$api_response"
if (( api_status == 200 )); then
file_link=$( jq -r ".data.${file_url_request}" <<< "$api_response" )
(( flag_shortlink )) || {
(( flag_directlink )) || file_link="${file_link#*.}"
}
(( flag_clipboard )) && xclip "${xclip_args[@]}" <<< "$file_link"
printf '%s\n' "$file_link"
if (( flag_rm )); then
msg "Removing file: $file"
rm "$file"
fi
else
printf 'Error: %s %s\n' "$api_status" "$api_status_message"
return 1
fi
}
get_shortlink() {
declare url=$1 api_response api_status api_status_message
api_response=$( curl --data-urlencode "url=$url" \
--data-urlencode "secret=$secret" \
"$cfg_service_url/shrink.json" )
get_api_status <<< "$api_response"
if (( api_status == 200 )); then
read -r short_url real_url < <(
jq -r '.data.short_url' <<< "$api_response"
)
(( flag_clipboard )) && xclip "${xclip_args[@]}" <<< "$short_url"
printf '%s\n' "$short_url"
else
printf 'Error: %s %s\n' "$api_status" "$api_status_message"
fi
}
get_api_status() {
read -d '' -r api_status api_status_message < <(
jq -r '.status.code, .status.message'
)
if (( api_status >= 400 )); then
return 1
fi
}
_mktemp() {
declare tmp_file_name tmp_file_name_extra="$2" tmp_dir="$1"
[[ -d "$tmp_dir" ]] || {
err "${tmp_dir} does not exist or is not a directory."
return 1
}
until [[ ! -e "${tmp_dir}/${tmp_file_name}" ]]; do
tmp_file_name="${RANDOM}${RANDOM}${tmp_file_name_extra}"
done
printf '%s\n' "${tmp_dir}/${tmp_file_name}"
}
get_my_ip() {
declare api_response api_status api_status_message my_ip
api_response=$( curl "$cfg_service_url/ip.json" )
get_api_status <<< "$api_response"
if (( api_status == 200 )); then
my_ip=$( jq -r '.data.ip' <<< "$api_response" )
(( flag_clipboard )) && xclip "${xclip_args[@]}" <<< "$my_ip"
printf '%s\n' "$my_ip"
else
printf 'Error: %s %s\n' "$api_status" "$api_status_message"
fi
}
login() {
declare api_response
api_response=$( curl "$cfg_service_url/token_request.json?login=$login" )
if get_api_status <<< "$api_response"; then
printf 'Check your email.\n'
else
printf 'Error: %s %s\n' "$api_status" "$api_status_message"
fi
}
get_token() {
[[ $secret ]] && return 0
[[ -f $cfg_file ]] && return 1
declare api_response login password
printf "First-time setup...\n"
read -p 'Username: ' login
read -sp 'Password: ' password
printf '\n'
login_response=$(curl -c "$cfg_file.cookiejar" -d "login=$login" -d "password=$password" -sl "$cfg_service_url/login.json")
get_api_status <<< "$login_response" || {
jq -r '.status.message' <<< "$login_response"
return 1
}
api_response=$(curl -b "$cfg_file.cookiejar" -sl "$cfg_service_url/api_token.json")
rm -f "$cfg_file.cookiejar"
if get_api_status <<< "$api_response"; then
secret=$(jq -r '.data.token' <<< "$api_response")
printf 'export secret="%s"' "$secret" >> "$cfg_file"
chmod 600 "$cfg_file"
printf 'Done\n'
else
printf 'Error: %s %s\n' "$api_status" "$api_status_message"
return 1
fi
}
set_argv() {
declare arg opt c
declare -g argv
while (( $# )); do
unset -v arg opt c
case "$1" in
(--) argv+=( "$1" ); shift; break;;
(--*)
IFS='=' read arg opt <<< "$1"
argv+=( "$arg" )
[[ "$opt" ]] && {
argv+=( "$opt" )
}
;;
(-*)
while read -n1 c
do
case "$c" in
-|'') :;;
*) argv+=( "-$c" );;
esac
done <<< "$1"
;;
(*) argv+=( "$1" );;
esac
shift
done
if (( $# )); then
argv+=( "$@" )
fi
}
main() {
declare args file target flag_private flag_rm flag_notify
declare flag_shortlink
# Defaults for XDG
if ! [[ "$XDG_RUNTIME_DIR" ]]; then
XDG_RUNTIME_DIR="/run/user/$UID"
fi
if ! [[ "$XDG_CONFIG_DIR" ]]; then
XDG_CONFIG_DIR="$HOME/.config"
fi
cfg_url_regex='^[A-Za-z]([A-Za-z0-9+.-]+)?://.+'
cfg_file=${UFW_CFG_FILE:-"$XDG_CONFIG_DIR/ufw"}
[[ $UFW_SECRET ]] && secret=$UFW_SECRET
[[ $UFW_TMP_DIR ]] && cfg_tmp_dir=$UFW_TMP_DIR
[[ $UFW_URL ]] && cfg_service_url=$UFW_URL
[[ $1 ]] || { usage; return 1; }
if [[ -f "$cfg_file" ]]; then
if ! source "$cfg_file"; then
printf 'Failed to source configuration file: %s\n' "$cfg_file"
return 1
fi
fi
# Defaults
: ${cfg_file:="$XDG_CONFIG_DIR/ufw"}
: ${cfg_tmp_dir:="$XDG_RUNTIME_DIR/ufw"}
: ${cfg_service_url:='https://8fw.me'}
: ${cfg_max_filesize:='200M'}
: ${flag_shortlink:=0}
: ${flag_directlink:=1}
: ${flag_clipboard:=0}
: ${xclip_selector:='clipboard'}
while [[ "$1" ]]; do
case "$1" in
(-h|--help|--usage) usage; return;;
(-m|--max-filesize) cfg_max_filesize=$2; shift;;
(-A|--album-name) album_name=$2; shift;;
(-t|--tags) tags=$2; shift;;
(--tmp-dir) cfg_tmp_dir=$2; shift;;
(--url) cfg_service_url=$2; shift;;
(--max-filesize) cfg_max_filesize=$2; shift;;
(-i|--my-ip) action='getmyip';;
(-u|--shorten) action='url';;
(-p|--public) flag_private='false';;
(-R|--remove-file) flag_rm='1';;
(-S|--short-url) flag_shortlink=1;;
(-P|--page-url) flag_directlink=0;;
(-q|--quiet) flag_quiet=1;;
(-v|--void) flag_void=1;;
# Clipboard
(-c|--clipboard) flag_clipboard=1;;
(-C|--xclip-selector) xclip_selector=$2; shift;;
(--notify) flag_notify=1;;
(--no-notify|-n) flag_notify=0;;
(-a|--album-id)
misc_curl_args+=( -F "album_id=$2" )
shift
;;
(-d|--description)
misc_curl_args+=( -F "description=$2" )
shift
;;
--) shift; break;;
-*)
err "Unknown flag: $1"
usage
return 1
;;
*) args+=( "$1" );;
esac
shift
done
xclip_args+=( -selection "$xclip_selector" )
# Catch the args after --
if (( $# )); then
args+=( "$@" )
shift
fi
TEMPDIR="$cfg_tmp_dir"
for i in "$cfg_tmp_dir"; do
[[ -d "$i" ]] || { mkdir -p "$i"; }
done
case "${action:-upload}" in
upload)
get_token || return $?
(( ${#args[@]} )) || return 1
for t in "${args[@]}"; do
if [[ -s "$t" ]]; then
upload "$t"
else
if [[ -f "$t" ]]; then
err "$t is empty"
else
err "$t not found"
fi
fi
done
;;
url)
get_token || return $?
for t in "${args[@]}"; do
get_shortlink "$t"
done
;;
getmyip) get_my_ip;;
login) login;;
esac
}
set_argv "$@"
main "${argv[@]}"
Executable
+101
View File
@@ -0,0 +1,101 @@
#!/usr/bin/env bash
shopt -s nullglob
# Defaults for XDG
if ! [[ "$XDG_RUNTIME_DIR" ]]; then
XDG_RUNTIME_DIR="/run/user/$UID"
fi
msg() { printf '%s\n' "$*"; }
err() { echo "$*" >&2; }
usage() {
printf 'Usage: ufwd [-hn] [-d workdir] -D [check delay]\n'
printf ' -h # Show this message.\n'
printf ' -n # Enable notifications with notify-send. Must be installed.\n'
printf ' -d [path] # Set the dir that is to be watched.\n'
printf ' -s # Push the file url into the clipboard.\n'
printf ' --magick <type:format> # Convert files of `type` into `format` with magick.\n'
}
upload() {
declare file=$1 file_type _type _target upload_output upload_return
shift
if [[ $cfg_magick ]]; then
file_type=$(file -ib "$file")
file_type="${file_type%;*}"
for x in "${cfg_magick[@]}"; do
_type="${x%:*}"
_target="${x#*:}"
[[ $_type == "$file_type" ]] && {
magick "$file" "${file%.*}.$_target"
rm -v "$file"
exit 0 # The next instance of the script will pick the file up.
}
done
fi
upload_output=$( ufw -R "$@" "$file" )
upload_return=$?
if (( flag_enable_notifications )); then
if (( $upload_return )); then
notify-send 'ufwd' "File upload failed: $upload_output"
else
notify-send 'ufwd' "File uploaded: $upload_output"
fi
fi
if (( flag_enable_clipboard )); then
read -r fl <<< "$upload_output"
xclip <<< "$fl"
fi
printf '%s\n' "$upload_output"
}
main() {
while (( $# )); do
case "$1" in
(--help|-h) usage; return 0;;
(--notify|-n) flag_enable_notifications=1;;
(--clipboard|-c) flag_enable_clipboard=1;;
(--workdir|-d) cfg_workdir+=( "$2" ); shift;;
(--magick) cfg_magick+=( "$2" ); shift;;
(--) shift; break;;
(-*) err "Unknown key: $1"; usage; return 1;;
(*) break;;
esac
shift
done
[[ $cfg_workdir ]] || cfg_workdir="$XDG_RUNTIME_DIR/ufwd"
if (( flag_enable_notifications )); then
if type -P notify-send &>/dev/null; then
msg "Found notify-send."
else
err "notify-send not found in PATH, disabling notifications."
flag_enable_notifications=0
fi
fi
for p in "${cfg_workdir[@]}"; do
[[ -d "$p" ]] || return 1
done
printf 'Working in:\n'
printf ' - %s\n' "${cfg_workdir[@]}"
while read -r d e f; do
upload "$d$f" "$@" &
done < <( inotifywait -m -e close_write "${cfg_workdir[@]}" )
}
main "$@"