#!/usr/bin/env python3
import base64, hashlib, hmac, json, time, urllib.request, urllib.error, uuid
from pathlib import Path

cfg={}
for line in Path.home().joinpath('.cosmos/credentials').read_text().splitlines():
    if line.strip() and not line.lstrip().startswith('#') and '=' in line:
        k,v=line.split('=',1); cfg[k.strip()]=v.strip()
local=cfg.get('GHOST_LOCAL_URL','http://127.0.0.1:2368')
public=cfg.get('GHOST_PUBLIC_URL','https://www.cosmosluminosity.com')
host=public.split('://',1)[-1].rstrip('/')
key_id,secret=cfg['GHOST_ADMIN_API_KEY'].split(':',1)

def token():
    now=int(time.time())
    def b64(o): return base64.urlsafe_b64encode(json.dumps(o,separators=(',',':')).encode()).rstrip(b'=')
    si=b64({'alg':'HS256','typ':'JWT','kid':key_id})+b'.'+b64({'iat':now,'exp':now+300,'aud':'/admin/'})
    return (si+b'.'+base64.urlsafe_b64encode(hmac.new(bytes.fromhex(secret),si,hashlib.sha256).digest()).rstrip(b'=')).decode()

def upload_theme():
    path='/tmp/cosmos-theme-experiment-v2-20261027.zip'
    boundary=uuid.uuid4().hex
    content=Path(path).read_bytes()
    body=(f'--{boundary}\r\nContent-Disposition: form-data; name="file"; filename="clean.zip"\r\nContent-Type: application/zip\r\n\r\n'.encode()+content+f'\r\n--{boundary}--\r\n'.encode())
    req=urllib.request.Request(local+'/ghost/api/admin/themes/upload/',data=body,method='POST')
    headers={'Authorization':'Ghost '+token(),'Accept-Version':'v6.0','Host':host,'X-Forwarded-Proto':'https','Origin':public,'Content-Type':f'multipart/form-data; boundary={boundary}'}
    for k,v in headers.items(): req.add_header(k,v)
    try:
        with urllib.request.urlopen(req,timeout=120) as r:
            data=r.read().decode(errors='replace')
            print('theme upload',r.status,data[:1200])
    except urllib.error.HTTPError as e:
        print('theme upload HTTP',e.code,e.read().decode(errors='replace'))
        raise

upload_theme()
