#!/bin/sh
# Command line upload to quickshare + tinyURL support
# by Minas Dasygenis, http://arch.ece.uowm.gr
#
# Check the latest update of this tool at 
# http://arch.ece.uowm.gr/mdasyg/misc/quickshare.sh
#
# Plug and Play install with:
# wget -q http://arch.ece.uowm.gr/mdasyg/misc/quickshare.sh -O /usr/local/bin/quickshare.sh && chmod 755 /usr/local/bin/quickshare.sh
#
#for UOWM: ln -s /scripts/system/quickshare.sh /usr/local/bin/sharelsi4
#for UOWM: ln -s /scripts/system/quickshare.sh /usr/local/bin/share
#for UOWM: ln -s /scripts/system/quickshare.sh /usr/local/bin/sharedirect
#
version=23

# Enable the nanyfying of the URL using lsi.gr . If set to 0 then no minimization will happen.
# Note that minimizing the URL involves storing the URL on an external database, other than share.uowm.gr
# which maybe a security issue if you do not want your file to be logged on a third party database.
# If you do not like minimizing the URL then set the following value to 0.
shorturl=1

# Select either to display the directURL (directURLshow=1) or the landing page url of http://share.uowm.gr (directURLshow=2)
if [ x"$directURLshow" != "x" ] ; then
	directURLshow=$directURLshow
	echo "Setting override for directURLshow to [$directURLshow]"
else
	directURLshow=0
fi


# Apple Indicate String:
# Darwin XXXX-Pro-2.local 22.6.0 Darwin Kernel Version 22.6.0: Wed Jul  5 22:22:05 PDT 2023; root:xnu-8796.141.3~6/RELEASE_ARM64_T6000 arm64
theuname=`uname -a`
echo $theuname | grep -q -i Darwin > /dev/null 2>&1
if [ $? -eq 0 ] ; then
	macos=1
else
	macos=0
fi


# Lets locate the timeout
which timeout > /dev/null 2>&1
if [ $? -eq 0 ] ; then
	tmexec=timeout
	tmexecparam=8
fi
which gtimeout > /dev/null 2>&1
if [ -z "$tmexec" -a $? -eq 0 ] ; then
	tmexec=gtimeout
	tmexecparam=8
fi

if [ -z "$tmexec" ] ; then
	tmexec=""
	tmexecparam=""
fi



#Set enviromental variable LANG to en or el with: 
# setenv QUICKSHARE_LANG en ;export  QUICKSHARE_LANG=en
if [ x"$QUICKSHARE_LANG" = x"en" -o x"$QUICKSHARE_LANG" = x"EN" ] ; then
    lang="en"
else
	lang=`locale | grep CTYPE | cut -d= -f2 | tr -d '"'  |  cut -d_ -f1`
fi

# Lets figure out if the name has the lsi4 which means we will use a minized 4 numbers name
echo $0 | grep -q lsi4
if [ $? -eq 0 ] ; then
	hashsize=4
	charset=1
else
	if [ $directURLshow -eq 0 ] ; then
		hashsize=8
		charset=0
	else
		hashsize=4
		charset=1
	fi
fi
	
echo $0 | grep -q direct
if [ $? -eq 0 ] ; then
	directURLshow=1
	shorturl=0
fi

if [ $directURLshow -eq 1 ] ; then
	echo "====> WARNING: DirectURL is enabled (possible spam detection at mail filter) <====="
fi


if [ "$lang" = "el" ] ; then
file="Το αρχείο"
size="με μέγεθος"
available="θα είναι διαθέσιμο έως"
url="στην παρακάτω διεύθυνση URL:"
direct="Απευθείας δεσμός μεταφόρτωσης αρχείου:"
motd="Πρόγραμμα μεταφόρτωσης φλοιού στο share.uowm.gr έκδοσης $version"
uploading="Μεταφόρτωση του"
wsize="με μέγεθος"
printing="Εκτυπώνονται '*' κάθε"
packets="πακέτα"
form=" για "
slots="θέσεις"
slot1="θέση"
done="Ολοκληρώθηκε η μεταφόρτωση"
seconds="δευτερόλεπτα"
speedmsg="ταχύτητα"
or="ή στο συντομευμένο ισοδύναμο:"
missing="Δε βρέθηκε το προαπαιτούμενο πρόγραμμα"
else
file="The file"
size="with size"
available="will be available until"
url="at the following URL:"
direct="Direct URL File Download:"
motd="share.uowm.gr version $version command line upload script"
uploading="Uploading file"
wsize="with size"
printing="Printing '*' every"
packets="packets"
form=" for "
slots="slots"
slot1="slot"
done="Done Uploading"
seconds="seconds"
speedmsg="speed"
or="or the tinyfied alias:"
missing="I could not find the required program"
fi


human_readable_size() {
    if [ -z "$1" ]; then
        echo "Usage: human_readable_size <number of bytes>"
        return
    fi

    bytes=$1
    if [ "$bytes" -lt 0 ]; then
        echo "Error: Input must be a positive number."
        return
    fi

    unit_index=0

    while [ "$bytes" -ge 1000 ]; do
        bytes=$(echo "scale=1; $bytes / 1024" | bc)
        unit_index=$((unit_index + 1))
    done

    case $unit_index in
        0) unit="B";;
        1) unit="KB";;
        2) unit="MB";;
        3) unit="GB";;
        4) unit="TB";;
    esac

    printf "%.1f %s\n" "$bytes" "$unit"
}

# Function to check if the short url service is online
check_short_url()
{
# Check if the nanyfying web site is reachable from us
# If it is not reachable just skip it
ok=1
$tmexec $tmexecparam curl -s http://lsi.gr -o /dev/null
if [ $? -ne 0 -a $shorturl -eq 1 ] ; then
	#echo "[lsi.gr seems inaccessible (curl returned $?)]"
	msg="[share] lsi.gr seems inaccessible (curl returned $?)"
	logger $msg
	shorturl=0
	export shorturl
	ok=0
fi

# if the previous version activated and disabled the shorturl
# lets perform one more check
if [ $ok -eq 0 ] ;then
	$tmexec $tmexecparam curl -s http://arch.ece.uowm.gr -o /dev/null
	if [ $? -ne 0 ] ; then
		msg="[share] arch.ece.uowm.gr seems inaccessible (curl returned $?)"
	else
		msg="[share] arch.ece.uowm.gr is online"
		shorturl=1
		export shorturl
	fi
fi
echo $shorturl
return $shorturl
}




short_url()
{
myurl=$1



if [ $shorturl -eq 1 ]; then
# If we have perl and curl we can sorten the url a bit
which perl > /dev/null 2>&1
r1=$?
if [ $r1 -ne 0 ] ; then
	echo $missing " perl "
	sleep 3
	if [ `uname -s` = "FreeBSD" ] ; then
		pkg install -f -y net/p5-URI
	fi
which perl > /dev/null 2>&1
r1=$?
fi

which curl > /dev/null 2>&1
r2=$?
if [ $r1 -eq 0 -a $r2 -eq 0  ] ; then
	urlNEW=$1
	perl -MURI::Escape -e 'help' > /dev/null 2>&1
	if [ $? -ne 0 ] ; then
	echo $missing " URI/Escape Perl module "
	sleep 3
	if [ `uname -s` = "FreeBSD" ] ; then
		pkg install -y -f net/p5-URI
	fi
	fi

	directURL="$(perl -MURI::Escape -e 'print uri_escape($ARGV[0]);' "$urlNEW")" > /dev/null 2>&1
	urlNEW=$directURL
	directURL=`$tmexec $tmexecparam curl -s http://lsi.gr/create.php\?hashsize=${hashsize}\&charset=${charset}\&key=76111\&url=$urlNEW || $tmexec $tmexecparam curl -s http://arch.ece.uowm.gr/lsi/create.php\?hashsize=${hashsize}\&charset=${charset}\&key=76111\&url=$urlNEW`
	if [ -z "$directURL" -o $? -ne 0 ] ; then
		#curl failed, resort to normal url
		directURL=$myurl
	fi
fi
else
	#User has not specified for minimization, so just return whatever he gave us
	directURL=$myurl
fi

echo $directURL;
}



#entry point main()

#Set enviromental variable silent with: setenv QUICKSHARE_SILENT YES;export  QUICKSHARE_SILENT=YES
if [ x"$QUICKSHARE_SILENT" = x"YES" ] ; then
	silent=1
else
	silent=0
fi

logfile=$HOME/.quickshare.log
logging=0
if [ -w "$logfile" ] ; then
	#change this option if you do not want any logging
	logging=1
fi

if [ $silent -eq 0 ] ; then
echo "----------------------------------------------------"
echo $motd
echo "by Dr Minas Dasygenis"
echo "http://arch.ece.uowm.gr , 2016-2020"
if [ $logging -eq 1 ] ; then 
	echo Logging Enabled because I discovered $logfile; else
	echo If you create $logfile, URLs will be logged there; fi
fi
echo "----------------------------------------------------"
echo " "

which python > /dev/null 2>&1
if  [ $? -ne 0 ] ; then
	which python3
	if  [ $? -ne 0 ] ; then
		echo $missing " python "
		if [ `uname -s` = "FreeBSD" ] ; then
			pkg install -y -f lang/python
		fi
		exit 4
	else
	executable=python3
	fi
else
	executable=python
fi


blocksize=1024
countpackets=1000
packetbytes=`expr $blocksize \* $countpackets`

if [ "$#" -eq 0 ] ; then
	echo 'Quickshare one or more files'
	echo Usage: $0 file0 file1 ....
	echo 'If you set the enviromental variable SILENT, only basic messages will appear:'
	echo 'setenv QUICKSHARE_SILENT YES;export  QUICKSHARE_SILENT=YES'
	echo 'Set the language to en or el with:'
	echo 'setenv QUICKSHARE_LANG en ;export  QUICKSHARE_LANG=en'
	exit 45
fi





which curl > /dev/null 2>&1
if [ $? -ne 0 ] ; then
	echo Requisite program curl not found
	exit 4
fi

# recursion over files with spaces may be problematic here
#
if [ $# -gt 1 ]; then
	massmode=1
else
	massmode=0
fi


for ifile in "$@"
do
	if [ ! -s "$ifile" ] ; then
		echo "File $ifile with 0 Bytes content....Skipping it."
		continue
	fi

	if [ -d "$ifile" ] ; then
		echo "Recursive is not possible into directory $ifile , skipping it."
		continue
	fi

	if [ ! -f "$ifile" ] ; then
		#this file is absent, just skip it
		echo "File $ifile does not seem to exist..."
		exit 7
		continue	
	fi

#lets find out the size
myfilesize=`ls -lHa "$ifile" | awk '{print $5}'`
#myfilesizeh=`human_readable_size $myfilesize`
myfilesizeh=`ls -lHha "$ifile" | awk '{print $5}'`

# If we are sharing multiple files, do not print headers
if [ $massmode -eq 0 ] ; then
if [ $silent -eq 0 ] ; then
	echo -n "$uploading [$ifile] $wsize [$myfilesizeh] Bytes."
	if [ "$logging" -eq 1 ] ; then
		echo -n "|LOG| "
	fi
fi
fi
echo " "


#original starting time
START=$(date +%s)

#lets compute how many POSTS we need
numberposts=`expr $myfilesize / $packetbytes`

#fix for very small
if [ $numberposts -eq 0 ] ; then
	numberposts=1
fi

countersize=`expr $myfilesize / $numberposts`


#if we have too many packets, do limit the max
if [ "$numberposts" -gt 80 ] ; then
	numberposts=80
	countersize=`expr $myfilesize / $numberposts`
fi



mycounter=`echo $countersize  | $executable -c 'from __future__ import print_function;import sys;import re; print(re.sub(r"(?<=.)(?=(?:...)+$)", ",",sys.stdin.read()));' | head -1`


# If we are sharing multiple files, do not print headers
if [ $massmode -eq 0 ] ; then
if [ $silent -eq 0 ] ; then
	if [ $numberposts -eq 1 ] ; then
		theslot=$slot1
	else
		theslot=$slots
	fi
	echo "$printing $mycounter $packets $form $numberposts $theslot."
fi
fi



if [ "$numberposts" -lt 1 ]  ; then numberposts=0 ; fi
counter=0

# If we are sharing multiple files, do not print headers
if [ $massmode -eq 0 ] ; then
		if [ $silent -eq 0 ] ; then
			echo -n "["
		fi
fi

while [ "$counter" -lt "$numberposts" ] ;do
if [ $massmode -eq 0 ] ; then
  if [ $silent -eq 0 ] ; then
	echo -n .
  fi
fi
counter=`expr $counter + 1`
done

if [ $massmode -eq 0 ] ; then
  if [ $silent -eq 0 ] ; then
	echo -n "]"
  fi
fi

counter=`expr $counter + 1`
counter=`expr $counter + 1`



if [ "$silent" -eq 0 ] ; then
	#return the cursor back
	printf "\033[${counter}D" 
	#lets reprint the missing char
	if [ $massmode -eq 0 ] ; then
	 	echo -n "["
	fi
fi



#Generate our key, its simpler to just give our random key, than wait for the server to give us a random key
ourkey=`od -vAn -N4 -tu4  /dev/urandom|tr -d " "`

#upload the file in parts

#initialy we do not skip anything
skip=0
temp_transfered=0
transfered=0
uploading=1
mypackets=0

while [ $uploading = 1 ] ; do
$tmexec $tmexecparam dd if="$ifile" bs=$blocksize count=$countpackets skip=$skip 2> /dev/null  | ( 
response="`$tmexec $tmexecparam curl --retry 3 --retry-delay 5 -s -X POST  --data-binary @- http://share.uowm.gr/bigUpload.php\?action=upload\&key=$ourkey`"
rc=$?
if [ $rc -eq 124 ] ; then
	comment="One more time if timeout has occured"
	response="`$tmexec $tmexecparam curl -s -X POST  --data-binary @- http://share.uowm.gr/bigUpload.php\?action=upload\&key=$ourkey`"
fi

note="Check if the return code of the previous command is not zero"
if [ $rc -ne 0 ] ; then
echo " ";
if [ $rc -eq 124 ] ; then
	echo "UPLOAD Error. Timeout has occured connecting to share.uowm.gr."
else
	echo "UPLOAD Error rc=[$rc]. share.uowm.gr replied:[$response]" ;
fi
sleep 1 ;
printf "\033[0m"
exit 4 ;
fi ;

echo "$response" | grep -q "ERROR"
if [ $? -eq 0 ] ; then
echo " "
echo "UPLOAD Error123. The response is: [$response]";
printf "\033[0m"
exit 6;
fi
)

if [ $? -ne 0 ] ; then
	uploading=0
	sleep 1
	exit
fi

skip=`expr $skip + $countpackets`
transfered=`expr $transfered + $packetbytes`

# If we are sharing multiple files, do not print headers
if [ $massmode -eq 0 ] ; then
if [ $silent -eq 0 ] ;then
	printf "\033[31m" 
fi
fi


# We print a start when we have completed the countersize...
temp_transfered=`expr  $packetbytes +  $temp_transfered`
should_we_print=`expr $temp_transfered / $countersize`
if [ "$should_we_print" -ge 1 ] ; then
	
	# If we are sharing multiple files, do not print headers
	if [ $massmode -eq 0 ] ; then
	if [ $silent -eq 0 ] ; then
		echo -n "*" 
	fi
	fi
	mypackets=`expr $mypackets + 1`
	extra_packets=`expr $countersize \* $should_we_print`
	temp_transfered=`expr $temp_transfered - $extra_packets`
fi


#duration=`echo $((END-START)) | awk '{print int($1/60)":"int($1%60)}'`

if [ "$transfered" -ge "$myfilesize" ] ; then
	END=$(date +%s);
	duration=`echo $((END-START))`
	if [ $duration -eq 0 ] ; then duration=1 ; fi
	speed=`expr $myfilesize / $duration`
	myspeed=`echo $speed |  $executable -c 'from __future__ import print_function;import sys;import re; print(re.sub(r"(?<=.)(?=(?:...)+$)", ",",sys.stdin.read()));' | head -1`
	if [ $massmode -eq 0 ] ; then
	 if [ $silent -eq 0 ] ; then
		echo ''
		echo "$done [$packets: $mypackets][$seconds: $duration][$speedmsg: $myspeed B/second]"
	 fi
	fi
	uploading=0
fi

done
#ok upload finished.

#reset the cursor color
if [ $massmode -eq 0 ] ; then
	if [ $silent -eq 0 ] ; then
		printf "\033[0m\n" 
	fi
fi


#OK, lets close the upload, and fix the filename without spaces
#Remove strange characters, normalize filename
bbname=`basename "$ifile" `
#If the file is .php then /usr/local/bin/quickshare.sh
echo $bbname | grep -q '.php$'
if [ $? -eq 0 ] ; then
	bbname=$bbname."txt"
fi


# Remove characters sets not supported
bname=` echo "$bbname" | sed 's/[^0-9A-Za-zΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩΆΈΉΊΌΎΏαβγδεζηθικλμνξοπρσςτυφχψωάέίύήώό.-]/_/g'`


bbname=$bname
#Replace not supported characters- unknown Chars [Note, some transformations with tr alter dramatically the name, like ΰ •, and thus we use sed there
bname=`echo "$bbname" | tr '#' "_" |  tr "@" "_" | sed 's/ΰ/υ/g' | tr -d "]" | tr "ΐ" "ι" |  tr -d "[" |  tr " ," - | tr -d "'" | tr -d "&" |tr -d '(' | tr -d ')' | sed 's/•//g' | tr -s "-" | tr  '=' '.' |   sed 's/--/-/g'  `

#lets grab the URL
response=`$tmexec $tmexecparam curl -s -d name="$bname" -dkey="$ourkey" http://share.uowm.gr/bigUpload.php\?action=finish`

if [ $? -ne 0 ] ; then
	echo 'Retrying......'
	response=`$tmexec $tmexecparam curl -s -d name="$bname" -dkey="$ourkey" http://share.uowm.gr/bigUpload.php\?action=finish`
fi


if [ $? -ne 0 ] ; then
	echo 'Server did not gave us a URL. Please retry.'
	exit 88
fi



errorstatus=`echo $response  | grep -E -o '"errorStatus":[^"},]*' | cut -f2 -d: | tr -d '"' 2>/dev/null `
errorText=`echo $response  | grep -E -o '"errorText":"[^"},]*' | cut -f2- -d: | tr -d '"' | tr -d '\\' 2>/dev/null `

#NOTE: despite it's name errorText carries the link
#NOTE: https://share.uowm.gr/download/25447b....html


if [ -z "$errorstatus" -o -z "$errorText" ] ; then
	echo "UPLOAD Error. Site replied: [$response]"
	exit 4
fi
#DEBUG: echo $errorText
directURL="https://share.uowm.gr/files/`echo $errorText | sed 's@https://share.uowm.gr/download/@@' | sed  's/.html$//'`/$bname"

shorturl=`check_short_url`
# No need to lsi.gr the big http://share.... URL
# errorTextmini=`short_url "$errorText"`

if [ $directURLshow -eq 1 ] ; then
	directURL=`short_url "$directURL"`
else
	directURL=`short_url "$errorText"`
fi

export directURL

#echo $myurl
if [ "$errorstatus" -ne 0 ] ; then
	echo Server replied with wrong errorstatus: $errorstatus / $errorText
	exit 51
fi
expirydate=`date -v +30d 2>/dev/null || date  -d "+30 days" 2>/dev/null`


echo -n "$file ["

if [ $silent -eq 0 ] ; then
	printf "\033[33m"
fi
echo -n "$bname"
if [ $silent -eq 0 ] ; then
	printf "\033[0m"
fi




#echo -n "]"
echo "]"
echo -n "$size ["
if [ $silent -eq 0 ] ; then
	printf "\033[34m"
fi
echo -n "$myfilesizeh"
if [ $silent -eq 0 ] ; then
	printf "\033[0m"
fi
echo "] Bytes"







echo -n "$available ["
if [ $silent -eq 0 ] ; then
	printf "\033[32m"
fi
echo -n $expirydate
if [ $silent -eq 0 ] ; then
	printf "\033[0m"
fi
#echo "] $url"
echo "]:"





#if [ $shorturl -eq 0 ]; then
#	echo $errorText
#fi


#if [ $shorturl -eq 1 ]; then
#	echo "$or"
#	echo $errorTextmini
#fi

if [ $silent -eq 0 ] ; then
	#echo "-----------------------------------------------------------------------------------"
	#echo "$direct"
	echo "---------------------------"
	echo "$directURL"
	echo "---------------------------"

	if [ $massmode -eq 0 ] ; then
		echo " "
		echo " "
	fi
fi

if [ "$logging" -eq 1 ] ; then
	echo "Original Name: $bbname" >> $logfile
	echo "Link Created: `/bin/date`" >> $logfile
	echo "Link Expires: $expirydate" >> $logfile 
	echo "$directURL" >> $logfile 
	echo " " >> $logfile 
fi

export SHAREDIRECTURL=$errorText

done

exit

