#!/usr/bin/env python3
import base64, hashlib, hmac, json, os, 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)
now=int(time.time())
def b64(o):
    raw=json.dumps(o,separators=(',',':')).encode()
    return base64.urlsafe_b64encode(raw).rstrip(b'=')
header={'alg':'HS256','typ':'JWT','kid':key_id}; payload={'iat':now,'exp':now+300,'aud':'/admin/'}
si=b64(header)+b'.'+b64(payload)
token=(si+b'.'+base64.urlsafe_b64encode(hmac.new(bytes.fromhex(secret),si,hashlib.sha256).digest()).rstrip(b'=')).decode()
zip_path='/tmp/cosmos-theme-positioning-20261027.zip'
boundary=uuid.uuid4().hex
content=Path(zip_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())
url=local+'/ghost/api/admin/themes/upload/'
req=urllib.request.Request(url,data=body,method='POST')
for k,v in {'Authorization':'Ghost '+token,'Accept-Version':'v6.0','Host':host,'X-Forwarded-Proto':'https','Origin':public,'Content-Type':f'multipart/form-data; boundary={boundary}'}.items(): req.add_header(k,v)
try:
    with urllib.request.urlopen(req,timeout=120) as r:
        print(r.status, r.read().decode()[:1000])
except urllib.error.HTTPError as e:
    print('HTTP',e.code,e.read().decode())
    raise
