Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save nis267/74c6315f6dbd24a0b8889acdd08789e6 to your computer and use it in GitHub Desktop.
Save nis267/74c6315f6dbd24a0b8889acdd08789e6 to your computer and use it in GitHub Desktop.
### BY: MUNFAQQIHA ####################################################################################################################################
######################### A BASH SHELL SCRIPT FOR LINUX AND WINDOWS TO AUTOMATICALLY NON-STOP UPLOAD FILES TO WWW.TERABOX.COM #########################
#######################################################################################################################################################
### ----------------------------------------------------------------------------------------------------------------------------------------------- ###
### | sample of successful upload: on linux: https://s.id/teraupnix || on windows: https://s.id/teraupwin | ###
### ----------------------------------------------------------------------------------------------------------------------------------------------- ###
### it is possible to upload multiple different types of files recursively, except 0-byte file size, in a folder where you run it. The maximum size ###
### of a single uploaded file allowed by terabox is 2147483648 Bytes (2.00 GiB). if a file exceeds that, this script will split it into pieces, and ###
### 120MiB is the upper limit of a single segment size allowed for multipart upload. however, terabox limits the maximum size of a single file that ###
### can be stored on their server. the total size of a single file for premium user is limited to 21474836479 Bytes (20.00 GiB), & 4294967296 Bytes ###
### (4.00 GiB) for a free member - https://s.id/1IMx2. ###
### ----------------------------------------------------------------------------------------------------------------------------------------------- ###
### ###
### catch the following steps to make it successful (run it on VPS / RDP for faster speed): ###
### ###
### 1. install jq: ###
### ###
### a. on linux do as usual. ###
### b. on windows: choose one of the following: ###
### (1). install linux with WSL: ubuntu or debian (highly recommended). ###
### (2). install gitforwindows (gitforwindows.org). ###
### (*). choose all of its default options. ###
### (*). run this on its shell: curl -Lo /usr/bin/jq.exe https://github.com/stedolan/jq/releases/latest/download/jq-win64.exe && jq -V ###
### ###
### 2. set the value for each of the following variables: ###
### ###
### it is all those little steps to get the value of the following 3 variables jt (jsToken), bt (bdstoken), and co (cookie): ###
### ###
### a. login to terabox account via chrome on desktop. ###
### b. press CTRL + R, then F12, next type "getinfo" in the "Filter" column ###
### c. so click "Networks" tab, right-click the url that says "getinfo" ###
### d. select copy >> Copy as cURL (bash), and don't event miss to paste it into your text editor. its usage is below: ###
### ###
### (1). for "jt" value, copy from "jsToken" section after "=" sign and before "&". ###
### (2). for "bt" value, copy from "bdstoken" section after as "jt" above. ###
### (3). for "co" value, copy from "cookie" section as usually. ###
### ###
### jt="" ###
### bt="" ###
### co="" ###
### ###
### e. the next let you go to fill out all variables (pay attention to text case): ###
### ###
### (1). full location path of a folder containing the files to be uploaded to terabox. ###
### ###
### # sample output of pwd command on linux shell. ###
### fl="/home/munfaqqiha/Pilem/Jadul" ###
### ###
### # sample output of pwd command on gitforwindows shell. ###
### fl="/c/Pilem/Jadul" ###
### ###
### (2). full path of your terabox folder where you'd like to store your files. ###
### ###
### rf="/Pilem/Jadul" ###
### ###
### (3). do you wanna move your files to another place after they're uploaded?: <yes/no>. ###
### ###
### mv="no" ###
### ###
### (4). if you decide that, please specify a full path of a backup folder to move them. ###
### ###
### # sample output of pwd command on linux shell. ###
### bu="/home/munfaqqiha/Pilem/Backup" ###
### ###
### # sample output of pwd command on gitforwindows shell. ###
### bu="/c/Pilem/Backup" ###
### ###
### (5). would you like to get a shared & download link of each uploaded file?: <yes/no>. all will be saved into a text file named "link.id". ###
### ###
### ds="yes" ###
### ###
### (6). while you'd agree to the points above, set its expiration date either 7, 30 (days), or 0 (forever). ###
### ###
### on="0" ###
### ###
### (7). please decide whether files may be deleted from the folder after they're uploaded: <yes/no>. ###
### ###
### rm="no" ###
### (9). amount of files to upload simultaneously (default 1) ###
### ###
### max_files_uploading="1" ###
### ###
#######################################################################################################################################################
### ALERT: ###
### .... After you've obtained your credentials, DO NOT press the "Sign Out" on the terabox.com when leaving it. It is enough to clear your cookies ###
### .... via the browser's built-in feature. If you do, then you'll not be able to upload files. You'll get an error something like: "need verify". ###
### ###
### NOTES: ###
### (*). it is also possible to run the code with the command: "bash yours.sh". if you picking on this, please include all variables in your file. ###
### (*). don't forget to watch a sample of successful upload on linux & windows at here: https://cuty.io/teraput. ###
### (*). for the multiple lines bash command code get it at here: https://cuty.io/linuxwintera. ###
#######################################################################################################################################################
### THE CODE STARTS FROM HERE #########################################################################################################################
set +H
jt="your stuffing"
bt="............."
co="............."
fl="............."
rf="............."
mv="............."
bu="............."
ds="............."
on="............."
rm="............."
max_files_uploading="1"
# Define a function to process a batch of files
process_file_upload() {
yu="$1"
nfo=$(curl -sL "${bo}" -A "${ua}" -b "${co}" -e "${bo}/" | perl -pe 's/\%(\w\w)/chr hex $1/ge' | sed "s#\"#\\n#g;s|:||g;s|,||g" | awk 'NF') &&
jt=$(echo "$nfo" | grep -i 'jstok.*' -A1 | tail -1) &&
bt=$(echo "$nfo" | grep -i 'bdsto.*' -A1 | tail -1) &&
sz=$(du -b "${yu}" 2>&- | awk '{print $1}') && fn="${yu}" &&
qt=$(curl -s "${bo}/api/quota?checkexpire=1&checkfree=1&app_id=250528&jsToken=${jt}" -A "${ua}" -b "${co}" -e "${bo}/") &&
to=$(echo "$qt" | jq -r '.total') && us=$(echo "$qt" | jq -r '.used') &&
if [[ ! ($(grep -s '[[:digit:]]' <<<${to})) || ! ($(grep -s '[[:digit:]]' <<<${on})) ||
(-z ${rf} || -z ${mv} || -z ${bu} || -z ${ds} || -z ${on} || -z ${rm} || -z ${max_files_uploading}) ]]; then
echo -e "\n$(echo "# recheck: the value of your variables, and don't forget to paste all on the shell." |
sed 's/# re.*ck:/\o033[1;41m&\o033[0m/I')" && exit 1
elif [[ $((to - us)) -lt ${sz} ]]; then
echo -e "\n$(echo "# quota: is smaller than the size of the current file ($(numfmt --to=iec-i --suffix=B --format='%.2f' ${sz} |
sed 's/[0-9]\+/& /2')). your remaining space is $(numfmt --to=iec-i --suffix=B --format='%.2f' $((to - us)) |
sed 's/[0-9]\+/& /2')." | sed 's/# quota:/\o033[1;41m&\o033[0m/I')" && exit 1
elif [[ -z "${sz/[ ]*\n/}" ]]; then
echo -e "\n$(echo '# notice: please double-check whether your file exists or not!.' |
sed 's/# notice:/\o033[1;41m&\o033[0m/I')" && return
else
echo -e "\n$(echo '### TERABOX: preparing..! ||' "$(echo "QUOTA:" $(numfmt --to=iec-i --suffix=B --format='%.2f' "$us" |
sed 's/[0-9]\+/& /2') / $(numfmt --to=iec-i --suffix=B --format='%.2f' "$to" | sed 's/[0-9]\+/& /2'))" \
$(printf "%$(tput cols)s" | tr " " "#") | cut -c -$COLUMNS |
sed -E 's/t.*x:|q.*:/\o033[1;41m&\o033[0m/Ig')\n" &&
if [[ (${vi} -eq 1 && ${sz} -le 21474836479) || (${vi} -eq 0 && ${sz} -le 4294967296) ]]; then
[[ ${sz} -ge 2147483648 ]] &&
echo -e "$(echo "# info: your file is larger than 2147483648 bytes (2.00 GiB). please wait it will be splitted into pieces!." |
sed 's/# info:/\o033[1;41m&\o033[0m/I')\n" &&
(split --verbose -b 120M "${yu}" --suffix-length=3 --numeric-suffixes=0 piece"${yu}" &&
echo -e $(ls -1 *piece"${yu}"[[:digit:]]* > "piece${yu}0a")) || echo "${yu}" > "piece${yu}0a"
else
echo -e "$(echo "# info: size limit exceeded!. the total size of a single file for a VIP user is limited to 21474836479 bytes, \
and 4294967296 bytes for a non." | sed 's/# info:/\o033[1;41m&\o033[0m/I')\n" && return
fi &&
cat "piece${yu}0a" | while read md; do
md5sum <<<"${md}" | md5sum | cut -d ' ' -f1 >>"piece${yu}0b"
done &&
md5=$(cat "piece${yu}0b" | sed -n 's/^/"/;s/$/"/;H;${x;s/\n/,/g;s/^,//;p}' | awk '{print "["$0"]"}') &&
fp=$(echo "${rf}/${yu}" | jq -Rr @uri) &&
tp=$(echo "${rf}/" | sed 's#/*$##;${s|$|/|}') &&
pc=$(curl -s "${bo}/api/precreate?app_id=250528&jsToken=${jt}" -A "${ua}" -b "${co}" -H "Origin: ${bo}" -e "${bo}/" \
--data-raw "path=${fp}&size=${sz}&autoinit=1&rtype=3&target_path=${tp}&block_list=${md5}") &&
echo "$pc" | jq -C --arg fs "$(numfmt --to=iec-i --suffix=B --format='%.2f' <<<${sz} | sed 's/[0-9]\+/& /2') (${sz} Bytes)" \
'.filesize = $fs | .block_list |= tostring' 2>&- || true &&
if grep -Eiq 'uploadid.*' <<<${pc}; then
echo -e "\n$(echo '### TERABOX: uploading..!' $(printf "%$(tput cols)s" | tr " " "#") | cut -c -$COLUMNS |
sed "s,t.*:,\o033[1;41m&\o033[0m,I")" &&
ui=$(echo $pc | jq -r '.uploadid') &&
bl=$(cat "piece${yu}0a" | wc -l) &&
pr=0 || pr=1 && ps=0 &&
while read mi; do
ls -1 *piece"${yu}"[[:digit:]]* &>/dev/null &&
echo -e "\n$(echo "# uploading: piece #${pr} of #${bl} left | file: ${mi} | md5: $(cat "piece${yu}0b" | head -1 &&
sed -i '1d' "piece${yu}0b")" | sed -e 's/# up.*ng:/\o033[1;41m&\o033[0m/Ig' -Ee 's/piece\s|left|file:|md5:/\x1b[32m&\x1b[0m/Ig')\n" ||
echo -e "$(true)" &&
up=$(curl -iF "file=@${mi}" "$(echo $bo | sed 's/www/c-jp/')/rest/2.0/pcs/superfile2?method=upload&type=tmpfile&app_id=250528&path=${fp}&uploadid=${ui}&partseq=${ps}" -A "${ua}" -b "${co}" -H "Origin: ${bo}" -e "${bo}/") &&
echo -e "\n$(echo "${up}" | tail -1 | jq -C 2>&-)" &&
echo "${up}" | sed '$!d' | jq -r '.md5' >>"piece${yu}0c" &&
((bl--)) && pr=$((pr + 1)) && ps=$(expr $ps + 1)
done < "piece${yu}0a" &&
md5=$(cat "piece${yu}0c" | sed -n 's/^/"/;s/$/"/;H;${x;s/\n/,/g;s/^,//;p}' | awk '{print "["$0"]"}') &&
if grep -Eiq 'md5.*' <<<${up}; then
echo -e "\n$(echo '### TERABOX: finishing..!' $(printf "%$(tput cols)s" | tr " " "#") | cut -c -$COLUMNS |
sed "s,t.*:,\o033[1;41m&\o033[0m,I")\n" &&
if [[ "${mv}" == *"yes"* ]]; then
mkdir -p "${bu}" && mv -f "${yu}" "${bu}"
elif [[ "${rm}" == *"yes"* ]]; then
rm -rf "${yu}"
fi &&
create=$(curl -s "${bo}/api/create?isdir=0&rtype=1&bdstoken=${bt}&app_id=250528&jsToken=${jt}" -A "${ua}" -b "${co}" -H "Origin: ${bo}" -e "${bo}/" \
--data-raw "path=${fp}&size=${sz}&uploadid=${ui}&target_path=${tp}&block_list=${md5}") &&
fi=$(echo -e "$(echo ${create} | jq --arg fs "$(numfmt --to=iec-i --suffix=B --format='%.2f' <<<${sz} | sed 's/[0-9]\+/& /2') (${sz} Bytes)" \
'.size = $fs | {"uploaded": "Glory to God for His great work!"} + .')") &&
grep -Eiq 'yes' <<<${ds} &&
pl=$(echo ${create} | jq '.path' | jq -Rr @uri) &&
pl=$(echo $pl | sed -n 'H;${x;s/\n/,/g;s/^,//;p}' | awk '{print "["$0"]"}') &&
sl=$(curl -s "${bo}/share/pset?app_id=250528&bdstoken=${bt}" -A "${ua}" -b "${co}" -e "${bo}/" \
--data-raw "schannel=0&channel_list=[0]&period=${on}&path_list=${pl}&public=1" | jq -r '.link') &&
ma=$(echo $sl | awk -F 's/1' '{print $2}') &&
dl=$(curl -s "${bo}/share/list?shorturl=${ma}&root=1&app_id=250528&jsToken=${jt}" -A "${ua}" -b "${co}" -e "${bo}/" | jq -r '.list[].dlink') &&
echo "$fi" | jq -C '.sharedlink="'"${sl}"'" | .downloadlink="'"${dl}"'"' &&
echo -e "Storedname: ${yu}\nSharedlink: ${sl}\nD/loadlink: ${dl}\n" >>link.id ||
echo "$fi" | jq -C && rm -rf *piece"${yu}"[[:digit:]]*
else
echo -e "\n$(echo '# notice: look at the uploading log above..!' $(echo "${up}" | grep -oi 'http.*' |
head -1 | sed 's/\s$//') | sed -e 's/# notice:/\o033[1;41m&\o033[0m/I' -e 's/http.*/\x1b[91m&\x1b[0m/Ig')"
fi
else
echo -e "\n$(echo '# notice: please, look at the precreate section..!' |
sed 's/# notice:/\o033[1;41m&\o033[0m/I')\n"
fi
fi
}
[[ -n ${fl} && -d ${fl} ]] && cd "${fl}" && ua='okhttp/7.4' && bo='https://www.terabox.com' && set +H &&
find . -name "*piece*[[:digit:]]*" ! -regex ".*\.\(sh\|id\)" -delete &&
echo -e "\n$(ls 2>&- --color -Ss1pq --block-size=1 "${PWD}/"*)" &&
readarray -t mi <<<"$(find . -type f ! -regex ".*\.\(sh\|id\)" -size +0 -printf "%f\n")" &&
[ $(echo "${mi[@]}" | wc -w) -gt 0 ] &&
vi=$(curl -s "${bo}/rest/2.0/membership/proxy/user?method=query" -A "${ua}" -b "${co}" -e "${bo}/" | jq -r '.data.member_info.is_vip') &&
# Process files
for yu in "${mi[@]}"; do
process_file_upload "${yu}" &
# Wait until the number of background jobs is less than the maximum allowed
while [ "$(jobs -r | wc -l)" -ge "$max_files_uploading" ]; do
sleep 1
done
done &&
wait &&
echo -e "\n$(ls 2>&- --color -Ss1pq --block-size=1 *)" ||
echo -e "\n$(echo "# notice: check the variable values of your file source directory and its existence or not!." |
sed 's/# notice:/\o033[1;41m&\o033[0m/I')\n"
### CODE ENDS HERE ####################################################################################################################################
@VigramK
Copy link

VigramK commented Jan 16, 2024

@nis267 Hi, i tried this script and it fails after the files are split. This is the error message i am getting

creating file 'File1.rar.piece039'
creating file 'File2.rar.piece040'
creating file 'File2.rar.piece041'
ls: cannot access 'pieceFile1.rar[[:digit:]]': No such file or directory
cat: pieceFile1.rar0b: No such file or directory
ls: cannot access 'pieceFile2.rar[[:digit:]]': No such file or directory
cat: pieceFile2.rar0b: No such file or directory

@nis267
Copy link
Author

nis267 commented Jan 26, 2024

Hello @VigramK Sorry for the late reply I will look into this weekend and let you know when I fixed it.

@munfaqqiha
Copy link

Hello, nis267

I have replied to your comments.

@nis267
Copy link
Author

nis267 commented Feb 7, 2024

I fixed it can you check if it's working now @VigramK ?

@VigramK
Copy link

VigramK commented Feb 10, 2024

I fixed it can you check if it's working now @VigramK ?

HI, i tried it and it is working now, but are the files after being split supposed to only upload one at a time? I thought it would be uploading multiple parts concurrently.

@nis267
Copy link
Author

nis267 commented Feb 11, 2024

I fixed it can you check if it's working now @VigramK ?

HI, i tried it and it is working now, but are the files after being split supposed to only upload one at a time? I thought it would be uploading multiple parts concurrently.

Hi @VigramK ! It's uploading multiple files concurrently but not multiple parts of a file yet. I can add this feature also. I will let you know when I am doing it 👍.

@VigramK
Copy link

VigramK commented Feb 11, 2024

Hey @nis267, It doesn't seem to be uploading multiple files concurrently for me though. I set max_files_uploading="2" and the two files were above 2 GB, so it split the files and started uploading, but the way it uploaded was something like this

File1.Chunk1
File2.Chunk1
File1.Chunk2
File2.Chunk2
...

Each chunk only started uploading after the previous one has finished and it was the same even if the chunks were of different files. I have added a screenshot.
https://imgur.com/a/pU6Clyj

Perhaps i could be mistaken and the chunks are uploaded in the background, but the output is only shown after one chunk is uploaded. I will try to test further and let you know.

@nis267
Copy link
Author

nis267 commented Feb 11, 2024

But I think it's correct no?

File1 and File2 started uploading the parts?

File1.Chunk2 will only start after File1.Chunk1 is uploaded no?

Or you mean that File2.Chunk1 started uploading only after File1.Chunk1 was uploaded?

@VigramK
Copy link

VigramK commented Feb 11, 2024

Or you mean that File2.Chunk1 started uploading only after File1.Chunk1 was uploaded?

Yep, that's what i meant. I edited my previous comment with a screenshot, and i will try to test further and let you know.

@nis267
Copy link
Author

nis267 commented Feb 11, 2024

When uploading multiples files concurrently the output is mixed up because each file is uploaded in background. Maybe that is misleading but I think it's correctly uploading multiple files. I will also try again when I have time.

@Banaune
Copy link

Banaune commented Feb 17, 2024

@nis267 Is there some way to upload the files and folders recursively keeping the original folder structure?

@nis267
Copy link
Author

nis267 commented Feb 19, 2024

@nis267 Is there some way to upload the files and folders recursively keeping the original folder structure?

@Banaune with the actual script no for that I need to implement this feature.

@Banaune
Copy link

Banaune commented Feb 28, 2024

@nis267 That would be very helpful when uploading from headless machines.

@arnelap
Copy link

arnelap commented Mar 3, 2024

This is awesome, thanks to both developers!

Any chance more file management features will be added i the future, especially deleting files?
That way I could upload a backup and then delete the older version of that backup.

@Namlee123
Copy link

Namlee123 commented Mar 4, 2024

Hello @nis267 , thank you for what you do.
I run your code on bash.sh.

  1. Error: I get an error with the filename being too long and containing a comma:
  • Comma: curl: (26) Failed to open/read local data from file/application.
    --> I fixed it by inserting: "file=@\"${mi}\"" and it worked.
  • The name is too long: it will report that the file/folder does not exist and delete the file, regardless of "rm=no".
    --> Hope you can fix this error.
    File name: (Guzheng, Instrumental, Chinese) [CD] VA - High Mountains, Flowing Water (高山流水) (Selection of Masterpieces by Chinese Masters of Guzheng) - 2011, FLAC (image+.cue), lossless.zip
  1. Improvements:
  • If a file (F1) is larger than 2G, it will be split into 120M size files: F1.Chunk1, F1.Chunk2, F1.Chunk3... It uploads each file in turn. Do not upload simultaneously.
    --> I want the split files F1.Chunk1, F1.Chunk2, F1.Chunk3 to be uploaded simultaneously in the background, just like uploading files F1, F2, F3... As this will be extremely economical meantime.
  • With a Free account, the size of a file does not exceed 4G. But I have a 5G file.
    --> So you can create an additional subroutine, combined with zip or rar to separate the 5G file into 4G and 1G and then upload it.
    For example:
    File: xyz.zip (9G)
    linux zip: zip -s=4G -0 "xyz.zip.zip" "xyz.zip"
    result: xyz.zip.z01(4G), xyz.zip.z02 (4G), xyz.zip.zip (1G)
    ->start uploading those 3 files

Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment