-
-
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 #################################################################################################################################### |
@nis267 Is there some way to upload the files and folders recursively keeping the original folder structure?
@nis267 That would be very helpful when uploading from headless machines.
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.
Hello @nis267 , thank you for what you do.
I run your code on bash.sh.
- 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
- 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.
Hi, thank you for sharing your code! However, it seems that the bdstoken
parameter is no longer present in the cURL. Additionally, I believe the website detects when the browser’s inspect mode is open, causing it to redirect to about:blank
. To capture the getInfo
request, you need to act quickly and copy it before the redirection happens
Hi, thank you for sharing your code! However, it seems that the
bdstoken
parameter is no longer present in the cURL. Additionally, I believe the website detects when the browser’s inspect mode is open, causing it to redirect toabout:blank
. To capture thegetInfo
request, you need to act quickly and copy it before the redirection happens
What browser are you using? I am using Firefox and i can still open developer tools and access the network tab. The getInfo
request found there still includes the bdstoken
along with jsToken
& cookie
parameters.
Hi, thank you for sharing your code! However, it seems that the
bdstoken
parameter is no longer present in the cURL. Additionally, I believe the website detects when the browser’s inspect mode is open, causing it to redirect toabout:blank
. To capture thegetInfo
request, you need to act quickly and copy it before the redirection happens
i have made a tapermonkey script to capture it without any redirects
// ==UserScript==
// @name Capture Terabox GetInfo Request with Cookies
// @namespace http://tampermonkey.net/
// @version 1.2
// @description Capture Terabox getinfo API request and copy as cURL with full headers and cookies
// @author You
// @match *://*.terabox.com/*
// @grant GM_setClipboard
// ==/UserScript==
(function () {
'use strict';
console.log("[Tampermonkey] Script loaded for Terabox!");
// Function to get all cookies as a string
function getCookies() {
return document.cookie.split("; ").map(cookie => `-H "Cookie: ${cookie}"`).join(" ");
}
// Hook into fetch API
const originalFetch = window.fetch;
window.fetch = async function (...args) {
const response = await originalFetch(...args);
if (args[0].includes("/api/user/getinfo")) {
console.log("[Tampermonkey] Intercepted fetch getinfo request:", args);
let headers = "";
if (args[1] && args[1].headers) {
for (const [key, value] of Object.entries(args[1].headers)) {
headers += `-H "${key}: ${value}" `;
}
}
// Get cookies and add them to the headers
const cookieHeader = getCookies();
headers += ` ${cookieHeader}`;
const curlCommand = `curl -X GET "${args[0]}" ${headers}`;
console.log("[Tampermonkey] Generated cURL Command:", curlCommand);
GM_setClipboard(curlCommand);
alert("✅ cURL command copied to clipboard!\n\nIncludes authentication cookies.");
}
return response.clone();
};
// Hook into XHR API (for older requests)
const originalOpen = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function (method, url) {
if (url.includes("/api/user/getinfo")) {
console.log("[Tampermonkey] Intercepted XHR getinfo request:", method, url);
const cookieHeader = getCookies();
const curlCommand = `curl -X GET "https://www.terabox.com${url}" ${cookieHeader}`;
console.log("[Tampermonkey] Generated XHR cURL Command:", curlCommand);
GM_setClipboard(curlCommand);
alert("✅ cURL command copied to clipboard!\n\nIncludes authentication cookies.");
}
return originalOpen.apply(this, arguments);
};
})();
@miju12 thanks for posting your script, it works like a charm. However, it seems like there is no cookie
token in the copied cURL command. It only contains jsToken
, pcftoken
& bdstoken
as url parameters and csrfToken
inside a Cookie:
-H "Cookie: csrfToken=..."
What exactly do i have to assign as "co" value?
@miju12 thanks for posting your script, it works like a charm. However, it seems like there is no
cookie
token in the copied cURL command. It only containsjsToken
,pcftoken
&bdstoken
as url parameters andcsrfToken
inside a Cookie. What exactly do i have to assign as "co" value?
- Install Mozilla Firefox and Fiddler Classic.
- Open your Firefox then Fiddler Classic (make sure the
File > Capture Traffic
is checked). - Sign in to your terabox.com account on Firefox.
- Back to Fiddler Classic, press
CTR + F
then paste and searchgetinfo
. - Right click on one of yellow highlighted text and select
Copy > Headers only
. - Paste the copied text into text editor like notepad.
- Find and copy only the
ndus
part (it has 45 characters), i.e.ndus=SftCdCQeWuHQ6aSRDUliAGd8etw2cj076wXtYe6p
. - You can then assign it as
co
value, i.e.co="ndus=SftCdCQeWuHQ6aSRDUliAGd8etw2cj076wXtYe6p"
.
Hope this helps. Thank you.
@miju12 thanks for posting your script, it works like a charm. However, it seems like there is no
cookie
token in the copied cURL command. It only containsjsToken
,pcftoken
&bdstoken
as url parameters andcsrfToken
inside a Cookie. What exactly do i have to assign as "co" value?1. Install [Mozilla Firefox](https://www.mozilla.org/en-US/firefox) and [Fiddler Classic](https://api.getfiddler.com/fc/latest). 2. Open your Firefox then Fiddler Classic (make sure the `File > Capture Traffic` is checked). 3. Sign in to your terabox.com account on Firefox. 4. Back to Fiddler Classic, press `CTR + F` then paste and search `getinfo`. 5. Right click on one of yellow highlighted text and select `Copy > Headers only`. 6. Paste the copied text into text editor like notepad. 7. Find and copy only the `ndus` part (it has 45 characters), i.e. `ndus=SftCdCQeWuHQ6aSRDUliAGd8etw2cj076wXtYe6p`. 8. You can then assign it as `co` value, i.e. `co="ndus=SftCdCQeWuHQ6aSRDUliAGd8etw2cj076wXtYe6p"`.
Hope this helps. Thank you.
Para conseguir obter os dados do site do terabox, que está em HTTPs, sigao tutorial abaixo:
https://docs.telerik.com/fiddler/configure-fiddler/tasks/firefoxhttps
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.