Skip to content

Instantly share code, notes, and snippets.

@thiswillbeyourgithub
Last active April 13, 2025 18:14
Show Gist options
  • Save thiswillbeyourgithub/53befc8223f37aa929b35c6ebf8e6365 to your computer and use it in GitHub Desktop.
Save thiswillbeyourgithub/53befc8223f37aa929b35c6ebf8e6365 to your computer and use it in GitHub Desktop.
Zsh scripts for edgevpn to send and receive files
#!/bin/zsh
#
# Note : I will probably not be using this script anymore, I made wormrot.sh : https://github.com/thiswillbeyourgithub/wormrot
#
# USAGE:
# 0. Create a new folder
# 1. Install edgevpn via 'curl -s https://raw.githubusercontent.com/mudler/edgevpn/master/install.sh | sudo sh'
# 2. Put this script in the same folder, with name "edge_vpn_file_scripts.sh"
# 3. Run "chmod +x edge_vpn_file_scripts.sh"
# 4. Put your edgevpn token inside the environment variable called EDGEVPNTOKEN
# 5. add those alias to your shell:
# alias edge_send="path_to_here/edge_vpn_file_scripts.sh send"
# alias edge_receive="path_to_here/edge_vpn_file_scripts.sh receive"
# 6. Repeat for every device you want to be able to exchange files.
#
# Now, to send a file from deviceA to deviceB, do:
# 1. On deviceA run `edge_send path_to_file` (optional: add `--compress` at the end)
# 2. On deviceB simply run `edge_receive`
# 3. When the second command exits, you can stop the first one.
#
# Note:
# - it can take some time for each device to find each other. I've had even 10-20 minutes!
# - the temporary file is stored in /tmp so normally is only taking up ram, not disk space
get_mnemonic() {
# note: this function turns the token into words reversibly
# source: https://github.com/thiswillbeyourgithub/HumanReadableSeed
uvx HumanReadableSeed@latest toread "$@"
}
# extra_args="" # default values
# # extra_args="$extra_args --low-profile=false" # true
# # extra_args="$extra_args --discovery-interval=10" # 720
# extra_args="$extra_args --ledger-announce-interval=10" # 10
# # extra_args="$extra_args --autorelay-discovery-interval=1m" # 5m
# extra_args="$extra_args --ledger-synchronization-interval=10" # 10
# # extra_args="$extra_args --aliveness-healthcheck-interval=30" # 120
# extra_args="$extra_args --log-level=debug" # info
# # extra_args="$extra_args --libp2p-log-level=debug" # info
edge_send() {
local compress=1
local pathoffile=""
# Parse arguments
for arg in "$@"; do
if [[ "$arg" == "-c" || "$arg" == "--compress" ]]; then
compress=1
elif [[ "$pathoffile" == "" && "$arg" != "send" ]]; then
pathoffile="$arg"
fi
done
# check if a file or a non empty dir
if [ ! -f "$pathoffile" ] && ( [ ! -d "$pathoffile" ] || [ ! "$(ls -A "$pathoffile")" ] )
then
echo "File not found at '""$pathoffile""'"
exit 1
fi
local human=$(get_mnemonic $EDGEVPNTOKEN)
local name="EdgeVPN_file_$(echo $human | cut -c-30 | paste -sd ' ' - | sed 's/ /_/g')"
echo "\n"
echo "File to send: $pathoffile"
echo "Human readable token:\n---\n$human\n---"
echo "\n"
if [[ -z "$pathoffile" ]]
then
echo "Error: Must supply a path"
else
echo "Creating metadata..."
local metadata_file=$(mktemp --suffix="_metadata_${name}.json")
filename=$(basename $pathoffile)
metadata_filename=$(basename $metadata_file)
if [[ "$compress" == "1" ]]
then
echo "Using file compression"
local tar_file=$(mktemp --suffix="_${name}.tar.gz")
tararg="-cvzf"
else
echo "Not using file compression"
local tar_file=$(mktemp --suffix="_${name}.tar")
tararg="-cvf"
fi
echo '{"filename": "'"$filename"'", "timestamp": "'$(date -Iseconds)'"}' > "$metadata_file"
echo "Tar archive location: $tar_file"
if [[ -d "$pathoffile" ]]; then
echo "Creating tar for dir $pathoffile ..."
# Get the directory containing the target
parent_dir=$(dirname "$pathoffile")
target_name=$(basename "$pathoffile")
tar --transform="s/$filename/file/" --transform="s/$metadata_filename/metadata.json/" $tararg "$tar_file" -C "$parent_dir" "$target_name" -C "$(dirname $metadata_file)" "$(basename $metadata_file)"
else
echo "Creating tar for file $pathoffile ..."
# Get the directory containing the target
parent_dir=$(dirname "$pathoffile")
target_name=$(basename "$pathoffile")
tar --transform="s/$filename/file/" --transform="s/$metadata_filename/metadata.json/" $tararg "$tar_file" -C "$parent_dir" "$target_name" -C "$(dirname $metadata_file)" "$(basename $metadata_file)"
fi
echo "Done creating tar archive"
echo "Cleaning up metadata file..."
trash -v -- "$metadata_file"
if [ ! -f "$tar_file" ]
then
echo "Tar output not found at '" "$tar_file" "', something went wrong"
exit 1
fi
echo "Sending the tar archive..."
start_time=$(date +%s)
expect -c "set timeout -1; spawn edgevpn file-send $extra_args --name \"$name\" --path \"$tar_file\" ; expect \") Done handling \" {puts \"File successfully sent\"; sleep 3; exit 0}"
end_time=$(date +%s)
duration=$((end_time - start_time))
echo "File transfer took $duration seconds."
echo "Cleaning up tar archive..."
trash -v -- "$tar_file"
echo "File transfer complete."
fi
}
edge_receive() {
local human=$(get_mnemonic $EDGEVPNTOKEN)
local name="EdgeVPN_file_$(echo $human | cut -c-30 | paste -sd ' ' - | sed 's/ /_/g')"
local pathoffile=$(mktemp --suffix="_EdgeVPN_received_file.tar.gz")
echo "\n"
echo "Temporary file location: $pathoffile"
echo "Human readable token:\n---\n$human\n---"
echo "\n"
echo "Waiting for file..."
# retry as long as the file is of size 0
while true; do
edgevpn file-receive $extra_args --name "$name" --path "$pathoffile"
if [[ -s "$pathoffile" ]]; then
echo "File received successfully."
break
elif [[ -z "$pathoffile" ]]; then
echo "Didn't receive a file. Crashing"
return
else
echo "Received file is empty. Deleting and retrying..."
echo ""
echo ""
trash -v -- "$pathoffile"
sleep 1 # Wait for X seconds before retrying
fi
done
echo "Extracting contents..."
local extract_dir=$(mktemp -d --suffix="_extracted_$(basename "$pathoffile" .tar.gz)")
mkdir -p "$extract_dir"
# Check if file is compressed using the file command
if file "$pathoffile" | grep -q "gzip"; then
echo "Detected gzip compressed file, untaring with compression..."
tar -vxzf "$pathoffile" -C "$extract_dir"
else
echo "Detected uncompressed file, untaring without compression..."
tar -vxf "$pathoffile" -C "$extract_dir"
fi
echo "Done untaring $pathoffile into $extract_dir. Content of that dir:"
ls -lvaAR "$extract_dir"
echo "Content of metadata file:"
cat "$extract_dir/metadata.json"
filename=$(cat "$extract_dir/metadata.json" | jq -r '.["filename"]')
trash -v -- "$extract_dir/metadata.json"
echo "Moving file to ./$filename ..." && \
mv -v "$extract_dir"/file ./$filename &&\
echo "Cleaning up temporary files..." &&\
trash -v -- "$extract_dir" &&\
trash -v -- "$pathoffile" &&\
echo "File transfer and extraction complete."
}
# parse arguments
eval $(uvx ShellArgParser@latest $@)
if [[ "$ARGS_1" == "send" ]]
then
edge_send "$@"
elif [[ "$ARGS_1" == "receive" ]]
then
edge_receive
else
echo "Unexpected first argument, not 'send' nor 'receive'"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment