import os
import requests
from datetime import datetime
credits="""
This program is made and maintained by Andrew
This program is open source and free to use
MIT @ 2025
Support me by Starring the project & following me on Github:
- https://github.com/Andrewgxgx/catbox.moe
- https://github.com/Andrewgxgx
"""
api = "https://catbox.moe/user/api.php"
api_litterbox="https://litterbox.catbox.moe/resources/internals/api.php"
os_unix="/"
os_windows="\\"
control=0
start=0
formatting = 2 # Default formatting
user_os = os_unix # Default OS
def get_user_preferences():
global user_os, control
while True:
print("""Please choose your OS:
1. Windows
2. Unix (Linux, MacOS)
3. Temple OS
4. Other
Type the number of your choice.
""")
Preferences = input("Enter a number 1 to 4: ")
if Preferences == "1":
user_os = os_windows
break
elif Preferences == "2":
user_os = os_unix
break
elif Preferences == "3":
print("Hello Terry Davis, We currently don't support Temple OS")
print("Exiting...")
control = 1
exit()
elif Preferences == "4":
user_os = os_unix
print("Using Unix-style paths as default")
break
else:
print("Please type 1, 2, 3, or 4")
def format():
global formatting, start
print("""
How would you like to format your links?
1. <file path>: <link>
2. <link>
3. <numbered list>. <link>
4. <Timestamp (hh:mm:ss)> : <File path> : <Link>
5. <custom string (user input)> : <link>
""")
try:
formatting = int(input("Enter a number 1 to 5: "))
start = 0
except ValueError:
print("Invalid input, using default format (link only)")
formatting = 2
def check_upload_folder():
"""Check if upload folder exists and warn if empty"""
folder_path = f".{user_os}upload"
if not os.path.exists(folder_path):
print(f"Warning: Folder '{folder_path}' does not exist!")
create = input("Create it now? (Y/N): ")
if create.upper() in ["Y", "YES", "YE"]:
os.makedirs(folder_path)
print(f"Created {folder_path}. Please add files to upload and run again.")
exit()
else:
print("Exiting...")
exit()
return folder_path
def save_links_to_file(content):
"""Save links, ALWAYS overwriting the existing file"""
try:
with open("uploaded_links.txt", "w", encoding='utf-8') as f:
f.write(content)
print("✅ Links saved to uploaded_links.txt (file overwritten)")
except Exception as e:
print(f"❌ Error saving to file: {str(e)}")
def get_files_from_folder():
"""Get list of files from upload folder"""
folder_path = check_upload_folder()
files_to_upload = []
print("\nScanning for files...")
for root, dirs, files in os.walk(folder_path):
for file in files:
file_path = os.path.join(root, file)
print(f"Found: {file_path}")
files_to_upload.append(file_path)
if not files_to_upload:
print("No files found in upload folder!")
return []
print(f"\nFound {len(files_to_upload)} file(s)")
confirm = input("Upload these files? (Y/N): ")
if confirm.upper() in ["Y", "YES", "YE", "YEAH"]:
return files_to_upload
return []
def upload_to_service(api_url, data, files):
"""Wrapper for requests.post"""
try:
return requests.post(api_url, data=data, files=files)
except Exception as e:
print(f"Network error: {str(e)}")
return None
def process_uploads(files_to_upload, upload_function, additional_data=None):
"""Generic upload processor"""
global start, formatting
all_links = ""
total_files = len(files_to_upload)
for idx, file_path in enumerate(files_to_upload, 1):
print(f"Uploading [{idx}/{total_files}]: {file_path}")
try:
with open(file_path, "rb") as item:
files = {"fileToUpload": item}
data = {"reqtype": "fileupload"}
if additional_data:
data.update(additional_data)
response = upload_function(data, files)
if response and response.status_code == 200:
link = response.text.strip()
if formatting == 1:
formatting_write = f'"{file_path}" : {link}\n'
elif formatting == 2:
formatting_write = f"{link}\n"
elif formatting == 3:
start += 1
formatting_write = f"{start}. {link}\n"
elif formatting == 4:
current_time = datetime.now().strftime("%H:%M:%S")
formatting_write = f"[{current_time}]: {file_path} : {link}\n"
elif formatting == 5:
write = input("Put text before the link: ")
formatting_write = f"{write} : {link}\n"
else:
formatting_write = f"{link}\n"
all_links += formatting_write
print(f"✓ Uploaded: {link}")
else:
print(f"✗ Failed to upload: {file_path}")
except Exception as e:
print(f"✗ Error uploading {file_path}: {str(e)}")
if all_links:
save_links_to_file(all_links)
print(f"\n✅ Successfully uploaded {len(files_to_upload)} files")
else:
print("\n❌ No files were uploaded successfully")
def upload_links():
"""Handle URL uploads - ALWAYS OVERWRITES the file"""
all_links = ""
print("\nEnter links to upload (type 'done' when finished):")
while True:
enter_links = input("Link: ")
if enter_links.lower() == "done":
break
data = {"reqtype": "urlupload", "url": enter_links}
response = upload_to_service(api, data, None)
if response and response.status_code == 200:
print(f"✓ Uploaded: {response.text}")
all_links += f"{response.text}\n"
else:
print("✗ Failed to upload link")
if all_links:
save_links_to_file(all_links)
else:
print("No links were uploaded")
def upload_links_with_account(account):
"""Handle URL uploads with account - ALWAYS OVERWRITES the file"""
all_links = ""
print("\nEnter links to upload (type 'done' when finished):")
while True:
enter_links = input("Link: ")
if enter_links.lower() == "done":
break
data = {
"reqtype": "urlupload",
"userhash": account,
"url": enter_links
}
response = upload_to_service(api, data, None)
if response and response.status_code == 200:
print(f"✓ Uploaded: {response.text}")
all_links += f"{response.text}\n"
else:
print("✗ Failed to upload link")
if all_links:
save_links_to_file(all_links)
else:
print("No links were uploaded")
def catbox_no_acc():
linkornot = input("Upload via link? (Y/N): ")
if linkornot.upper() in ["Y", "YE", "YES"]:
upload_links()
else:
files_to_upload = get_files_from_folder()
if files_to_upload:
format()
process_uploads(
files_to_upload,
lambda d, f: upload_to_service(api, d, f)
)
def catbox_with_acc():
account = input("Enter your account hash: ")
if not account:
print("Account hash required!")
return
linkornot = input("Upload via link? (Y/N): ")
if linkornot.upper() in ["Y", "YE", "YES"]:
upload_links_with_account(account)
else:
files_to_upload = get_files_from_folder()
if files_to_upload:
format()
process_uploads(
files_to_upload,
lambda d, f: upload_to_service(api, d, f),
{"userhash": account}
)
def litterbox():
files_to_upload = get_files_from_folder()
if not files_to_upload:
return
time_options = {"1h", "12h", "24h", "72h"}
while True:
time = input("Upload duration? (1h, 12h, 24h, 72h): ").lower()
if time in time_options:
break
print("Invalid duration. Please enter 1h, 12h, 24h, or 72h")
format()
process_uploads(
files_to_upload,
lambda d, f: upload_to_service(api_litterbox, d, f),
{"time": time}
)
def menu():
global control
print(f"""
{credits}
=========
Welcome to CATBOX & Litterbox Uploader!
Choose your options!
1. Upload to Catbox.moe (No account)
2. Upload to Catbox.moe (with account)
3. Upload to Litterbox
4. Exit / Stop program
====
Note: uploaded_links.txt will be OVERWRITTEN each time you upload!
""")
try:
opt = int(input("Type 1,2,3 or 4: "))
if opt == 1:
print("Catbox - no account")
catbox_no_acc()
elif opt == 2:
print("Catbox - with account")
catbox_with_acc()
elif opt == 3:
print("Upload to LitterBox")
litterbox()
elif opt == 4:
print("Exiting...")
control = 1
else:
print("Invalid option. Please enter 1-4")
except ValueError:
print("Please enter a valid number")
# Main program
if __name__ == "__main__":
print(credits)
print("Welcome to the Catbox Uploader")
print("Please choose your OS first, before getting started")
get_user_preferences()
folder_path = f".{user_os}upload"
if not os.path.exists(folder_path):
os.makedirs(folder_path)
print(f"Created upload folder: {folder_path}")
print("Please add files to upload and run again.")
exit()
while control == 0:
menu()
if control != 1:
input("\nPress Enter to continue...")
print("\n" + credits)
print("Thank you for using the Catbox Uploader")
print("Exiting...")