#!/usr/bin/env python3 """Upload 'The Digital Waqif: Waqf, Faraid, and the Architecture of Legacy' to BookStack.""" import os, sys, json, subprocess, time, urllib.request BS_ID = "is2FJhIWpKEIY13qxHsmboYqukpgRn0U" BS_SECRET = "yQdxQaAKtTatZEeOLAS92umUfRNBqQFq" BS_BASE = "https://docs.falahos.my/api" CHAPTERS_DIR = os.path.expanduser("~/odysseus_book/digital_waqif/chapters") PDF_PATH = os.path.expanduser("~/odysseus_book/digital_waqif/pdf/The_Digital_Waqif.pdf") CHAPTERS = [ "Clause 1: The Wasiyyah — The Will That God Commanded", "Clause 2: The Faraid Matrix — The Fixed Shares Decoded", "Clause 3: The Waqf — The Three Exits of Wealth", "Clause 4: The Digital Kingdom — Inventorying the Invisible Estate", "Clause 5: The Keys — Custody and the Executor Who Cannot Be Bribed", "Clause 6: The Amil — Choosing the Executor of the Digital Estate", "Clause 7: The Purification — Debt, Zakat, and Cleaning the Estate", "Clause 8: The Token — Smart-Contract Faraid and On-Chain Waqf", "Clause 9: The Successor — Business Continuity for the Digital Kingdom", "Clause 10: The Perpetuity — The Eternal Contract of the Digital Waqif", ] def api_call(method, path, data=None): url = f"{BS_BASE}/{path}" headers = { "Authorization": f"Token {BS_ID}:{BS_SECRET}", "User-Agent": "curl/7.88.1", "Content-Type": "application/json", } body = json.dumps(data).encode() if data else None req = urllib.request.Request(url, data=body, headers=headers, method=method) with urllib.request.urlopen(req, timeout=30) as r: return json.loads(r.read()) def markdown_to_html(md): text = md parts = text.split('**') for i in range(1, len(parts), 2): parts[i] = f'{parts[i]}' text = ''.join(parts) parts = text.split('*') for i in range(1, len(parts), 2): parts[i] = f'{parts[i]}' text = ''.join(parts) text = text.replace('\n', '
\n') return text def main(): print("📚 Creating BookStack book...") book_data = { "name": "The Digital Waqif: Waqf, Faraid, and the Architecture of Legacy", "description": "Will & Testament Playbook — Clause-Driven Legacy Architecture. Dual Mentors: FARADI (Ilm al-Faraid) + WAQIF (Waqf builder). 10 Clauses of the Digital Will & Endowment: Wasiyyah, Faraid Matrix, Waqf, Digital Inventory, Keys, Executor, Purification, Tokenization, Successor, Perpetuity. By Jauhari Che Wan.", "tags": [ {"name": "Series", "value": "Faradi × Waqif Playbook"}, {"name": "Author", "value": "Jauhari Che Wan"}, {"name": "Shelf", "value": "721"} ] } result = api_call("POST", "books", book_data) book_id = result.get("id") print(f" Book ID: {book_id}") print("📖 Uploading chapters...") for i, title in enumerate(CHAPTERS): fname = f"Clause_0{i+1}.md" if i < 9 else f"Clause_{i+1}.md" fpath = os.path.join(CHAPTERS_DIR, fname) if not os.path.exists(fpath): print(f" WARNING: {fname} not found") continue with open(fpath) as f: content = f.read() lines = content.split('\n') body_start = 0 for j, line in enumerate(lines): if line.startswith('# ') or line.startswith('## ') or line.strip() == '': continue else: body_start = j break body = '\n'.join(lines[body_start:]) html_body = markdown_to_html(body) page_name = f"Clause #{i+1}: {title}" print(f" Uploading {page_name}...") data = { "book_id": book_id, "name": page_name, "html": html_body, "priority": i + 1, "tags": [{"name": "Part", "value": f"Clause #{i+1}"}] } try: page_result = api_call("POST", "pages", data) print(f" Page ID: {page_result.get('id')}") except Exception as e: print(f" Error: {str(e)[:100]}") time.sleep(0.3) print(f"\n✅ BookStack upload complete! Book ID: {book_id}") if __name__ == "__main__": main()