habitica-xp/costume.py
2026-09-09 21:27:09 -07:00

151 lines
4.6 KiB
Python
Executable file

#!/usr/bin/env python3
import argparse
import json
import os
import sys
import requests
API_URL = "https://habitica.com/api/v3/user"
def get_habitica_headers():
user_id = os.getenv("HABITICA_USER_ID")
api_token = os.getenv("HABITICA_API_TOKEN")
if not user_id or not api_token:
print("Error: Environment variables HABITICA_USER_ID and HABITICA_API_TOKEN must be set.", file=sys.stderr)
sys.exit(1)
return {
"x-api-user": user_id,
"x-api-key": api_token,
"x-client": f"{user_id}-CustomizationScript"
}
def fetch_habitica_gear():
"""Fetches only the costume, background, pet, and mount from the user profile."""
try:
response = requests.get(API_URL, headers=get_habitica_headers())
response.raise_for_status()
except requests.exceptions.RequestException as e:
print(f"Error communicating with Habitica API: {e}", file=sys.stderr)
sys.exit(1)
data = response.json().get("data", {})
# Extract specific fields
items = data.get("items", {})
gear = items.get("gear", {})
costume = gear.get("costume", {})
background = data.get("preferences", {}).get("background", "default")
pet = items.get("currentPet", "")
mount = items.get("currentMount", "")
customizations = {
"costume": costume,
"background": background,
"pet": pet,
"mount": mount
}
print(customizations)
return customizations
def save_costume(filename):
# print("Fetching equipment and costume data from Habitica...")
gear_data = fetch_habitica_gear()
with open(filename, "w", encoding="utf-8") as f:
json.dump(gear_data, f, indent=4)
def equip(type, name):
try:
response = requests.post(f"{API_URL}/equip/{type}/{name}",
headers=get_habitica_headers())
response.raise_for_status()
print(f"Successfully equiped '{name}'.")
except requests.exceptions.RequestException as e:
print(f"Error communicating with Habitica API: {e}", file=sys.stderr)
if hasattr(e, 'response') and e.response is not None:
print(f"Server response: {e.response.text}", file=sys.stderr)
sys.exit(1)
def set_background(name):
bg_payload = {
"preferences.background": name
}
try:
res = requests.put(f"{API_URL}",
headers=get_habitica_headers(), json=bg_payload)
res.raise_for_status()
print(f"Successfully set background to: {name}")
except requests.exceptions.RequestException as e:
print(f"Error setting background: {e}", file=sys.stderr)
if hasattr(e, 'response') and e.response is not None:
print(f"Server response: {e.response.text}", file=sys.stderr)
def set_costume(data):
for k,v in data.get("costume").items():
if v and not v.endswith("base_0"):
equip("costume", v)
if "pet" in data:
equip("pet", data.get("pet"))
# if "mount" in data:
# equip("mount", data.get("mount"))
# TODO: Not sure how to set the background!
if "background" in data:
set_background(data["background"])
def load_costume(filename):
if os.path.exists(filename):
with open(filename, "r", encoding="utf-8") as f:
gear_data = json.load(f)
# Update defaults with values from the file
set_costume(gear_data)
def store_all(filename):
try:
response = requests.get(API_URL, headers=get_habitica_headers())
response.raise_for_status()
except requests.exceptions.RequestException as e:
print(f"Error communicating with Habitica API: {e}", file=sys.stderr)
sys.exit(1)
data = response.json().get("data", {})
with open(filename, "w", encoding="utf-8") as f:
json.dump(data, f, indent=4)
def parse_arguments():
parser = argparse.ArgumentParser(description="Costume configuration script")
parser.add_argument(
"--load",
type=str,
help="Path to a JSON file containing saved costume values"
)
parser.add_argument(
"--save",
type=str,
help="Path to a JSON file to save your costume values"
)
parser.add_argument(
"-a", "--all",
action=argparse.BooleanOptionalAction,
help="Download and store all data in 'all.json'"
)
return parser.parse_args()
def main():
args = parse_arguments()
if args.save:
save_costume(args.save)
elif args.load:
load_costume(args.load)
elif args.all:
store_all("all.json")
if __name__ == "__main__":
main()