151 lines
4.6 KiB
Python
Executable file
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()
|