import os import time import zipfile import shutil import threading from supabase import create_client, Client # Configuration SUPABASE_URL = os.environ.get("SUPABASE_URL") SUPABASE_KEY = os.environ.get("SUPABASE_KEY") BUCKET_NAME = "moltbot-memory" MEMORY_DIR = "/root/.molt" ZIP_FILENAME = "memory.zip" ZIP_PATH = os.path.join("/app", ZIP_FILENAME) # Working in /app SYNC_INTERVAL = 300 # 5 minutes def get_supabase_client(): if not SUPABASE_URL or not SUPABASE_KEY: print("Error: SUPABASE_URL or SUPABASE_KEY not set.") return None try: return create_client(SUPABASE_URL, SUPABASE_KEY) except Exception as e: print(f"Error connecting to Supabase: {e}") return None def download_and_extract_memory(): client = get_supabase_client() if not client: return print(f"Attempting to download {ZIP_FILENAME} from bucket {BUCKET_NAME}...") try: # Check if bucket exists? We assume yes. # Download file with open(ZIP_PATH, "wb") as f: res = client.storage.from_(BUCKET_NAME).download(ZIP_FILENAME) f.write(res) print("Download successful. Extracting...") # Create destination dir if not exists os.makedirs(MEMORY_DIR, exist_ok=True) with zipfile.ZipFile(ZIP_PATH, 'r') as zip_ref: zip_ref.extractall(MEMORY_DIR) print(f"Extracted memory to {MEMORY_DIR}") except Exception as e: print(f"Download/Extraction failed (Normal on first run if no memory exists): {e}") def zip_and_upload_memory(): client = get_supabase_client() if not client: return if not os.path.exists(MEMORY_DIR): print(f"Memory directory {MEMORY_DIR} does not exist. Skipping upload.") return print(f"Zipping {MEMORY_DIR}...") try: # Create a zip file # shutil.make_archive creates file with .zip extension, so we pass base name base_name = os.path.join("/app", "memory_upload") shutil.make_archive(base_name, 'zip', MEMORY_DIR) upload_zip_path = base_name + ".zip" print(f"Uploading {upload_zip_path} to {BUCKET_NAME}/{ZIP_FILENAME}...") with open(upload_zip_path, "rb") as f: # Upsert=true to overwrite client.storage.from_(BUCKET_NAME).upload(ZIP_FILENAME, f, file_options={"upsert": "true"}) print("Upload successful.") except Exception as e: print(f"Upload failed: {e}") def sync_loop(): while True: time.sleep(SYNC_INTERVAL) zip_and_upload_memory() if __name__ == "__main__": # 1. On Startup: Download download_and_extract_memory() # 2. Start Loop # We run the loop in the main thread? # The CMD will run this script in background (&). # So this script should block (run loop forever). sync_loop()