Download code/yahbible_main.py from OhBeOneKeyNoBe/YahBible: direct link, hf CLI and curl.
- Browser
- Download file 9.55 kB
-
https://huggingface.co/OhBeOneKeyNoBe/YahBible/resolve/main/code/yahbible_main.py
- Command line
-
hf download hf://OhBeOneKeyNoBe/YahBible/code/yahbible_main.py
-
curl -L -o yahbible_main.py https://huggingface.co/OhBeOneKeyNoBe/YahBible/resolve/main/code/yahbible_main.py
9.55 kB
| #!/usr/bin/env python | |
| r"""YahBible launcher -- the entry point PyInstaller freezes into YahBible.exe. | |
| Out of the box: double-click. On first run it downloads the study library from Hugging Face | |
| (OhBeOneKeyNoBe/YahBible) into a local folder, then starts the local server and opens the app | |
| in your browser. Subsequent runs are instant. Works run-in-place OR installed -- the library | |
| lives in %LOCALAPPDATA%\YahBible so it persists either way. | |
| The library mirrors the app's expected layout under one BASE dir, and YAHBIBLE_BASE points the | |
| server at it (the server falls back to D:\ only on the dev machine). | |
| """ | |
| import os | |
| import sys | |
| import threading | |
| import time | |
| import webbrowser | |
| REPO = "OhBeOneKeyNoBe/YahBible" | |
| PORT = 41537 | |
| # study library: HF path -> subpath under BASE (mirrors the app's expected tree) | |
| LIB = { | |
| "data/watchman.db": "watchman/watchman.db", | |
| "data/reflected_red_basic.sqlite": "Holorites_data/daeos/reflected_red_basic.sqlite", | |
| "data/reflected_red.sqlite": "Holorites_data/reflected_red.sqlite", | |
| "data/taviel_versions.sqlite": "Holorites_data/daeos/taviel_versions.sqlite", | |
| "data/taviel_corpus.sqlite": "Holorites_data/daeos/taviel_corpus.sqlite", | |
| "data/english_dict.sqlite": "Holorites_data/daeos/english_dict.sqlite", | |
| "data/piper/en_US-lessac-medium.onnx": "Holorites_data/daeos/piper/en_US-lessac-medium.onnx", | |
| "data/piper/en_US-lessac-medium.onnx.json": "Holorites_data/daeos/piper/en_US-lessac-medium.onnx.json", | |
| "data/reflected_vocal.sqlite": "Holorites/torus_upgrades/reflected_vocal.sqlite", | |
| "data/elaniel_yt.sqlite": "Holorites_data/daeos/elaniel_yt.sqlite", | |
| "data/taviel_redletter.sqlite": "Holorites_data/daeos/taviel_redletter.sqlite", | |
| "data/taviel_doctrine.sqlite": "Holorites_data/daeos/taviel_doctrine.sqlite", | |
| } | |
| # the big lexicon (interlinear + Strong's + dictionary). Optional first-run: it is 70GB, so we | |
| # fetch it in the background after the app is already usable, unless YAHBIBLE_SKIP_LEX is set. | |
| BIG = "data/reflected_red.sqlite" | |
| # --- CODE auto-update ------------------------------------------------------- | |
| # The app CODE (server + UI + study data) lives in the HF repo under code/ and is pulled on every | |
| # launch so fixes reach users WITHOUT shipping a new exe. Downloaded modules are loaded over the | |
| # frozen copies; any failure falls back to the frozen build, so the app always starts. | |
| CODE_FILES = ["o_taviel_ui.py", "o_taviel_server.py", | |
| "taviel_commandments.json", "taviel_repentance.json", "taviel_news.json", | |
| # the Gauntlet: served by o_taviel_server, so installed desktops pull these too | |
| "taviel_apologetics.py", "taviel_reason.py", "gauntlet_kb.json", | |
| "taviel_doctrine.py", | |
| # THE JEV FRONT DOOR. taviel_reason.serve() routes through these | |
| # when the decision server and the embedder are both reachable, | |
| # answering identity, vetted, verse, clarify and decline with no | |
| # generated tokens at all. Uploading them to the repo was not | |
| # enough: this list is what an installed desktop actually | |
| # fetches, so a module missing from here is a module that never | |
| # arrives, and the front door would sit in the repo doing | |
| # nothing. They are SAFE to ship to a desktop with no fork | |
| # binary -- serve() gates on a cheap probe and falls back to the | |
| # verbatim gauntlet exactly as before. | |
| "taviel_frontdoor.py", "taviel_decide.py", "taviel_person.py", | |
| "taviel_contrast.py", "taviel_verify.py", | |
| # completed interlinear for verses the lexicon lacks (KJV<->MT versification | |
| # divergences + NT doxologies) -- so installed desktops match web/mobile | |
| "canon_fill.sqlite", | |
| # BlackBox split-key auth: o_taviel_server imports these to publish the two | |
| # encrypted credential halves (HF + GitHub) on signup / password change | |
| "yahbible_auth.py", "auth_sync.py"] | |
| def ensure_code(base): | |
| cdir = os.path.join(base, "code") | |
| os.makedirs(cdir, exist_ok=True) | |
| try: | |
| from huggingface_hub import hf_hub_download | |
| except Exception: | |
| return cdir | |
| import shutil | |
| for fn in CODE_FILES: | |
| for _ in range(3): | |
| try: | |
| cached = hf_hub_download(repo_id=REPO, filename="code/" + fn, repo_type="model") | |
| tmp = os.path.join(cdir, fn + ".tmp") | |
| shutil.copy2(cached, tmp) | |
| os.replace(tmp, os.path.join(cdir, fn)) | |
| break | |
| except Exception as e: | |
| print(" code sync skip %s (%s)" % (fn, str(e)[:40]), flush=True) | |
| time.sleep(2) | |
| return cdir | |
| def load_updated_code(cdir): | |
| """Load the freshly-downloaded o_taviel_ui / o_taviel_server over the frozen copies.""" | |
| import importlib.util | |
| for mod in ("o_taviel_ui", "o_taviel_server"): | |
| p = os.path.join(cdir, mod + ".py") | |
| if not (os.path.exists(p) and os.path.getsize(p) > 0): | |
| continue | |
| try: | |
| spec = importlib.util.spec_from_file_location(mod, p) | |
| m = importlib.util.module_from_spec(spec) | |
| sys.modules[mod] = m | |
| spec.loader.exec_module(m) | |
| print(" updated %s loaded from repo" % mod, flush=True) | |
| except Exception as e: | |
| print(" updated %s failed, using built-in (%s)" % (mod, str(e)[:60]), flush=True) | |
| sys.modules.pop(mod, None) | |
| def base_dir(): | |
| b = os.environ.get("YAHBIBLE_BASE") | |
| if b: | |
| return b | |
| root = os.environ.get("LOCALAPPDATA") or os.path.expanduser("~") | |
| b = os.path.join(root, "YahBible", "library") | |
| os.makedirs(b, exist_ok=True) | |
| return b | |
| def have(base, sub): | |
| p = os.path.join(base, sub.replace("/", os.sep)) | |
| return os.path.exists(p) and os.path.getsize(p) > 0 | |
| def fetch(base, hf_path, sub): | |
| from huggingface_hub import hf_hub_download | |
| dst = os.path.join(base, sub.replace("/", os.sep)) | |
| os.makedirs(os.path.dirname(dst), exist_ok=True) | |
| print(" downloading %s ..." % sub, flush=True) | |
| cached = hf_hub_download(repo_id=REPO, filename=hf_path, repo_type="model") | |
| # copy out of the HF cache into our mirrored layout (hardlink if possible) | |
| import shutil | |
| try: | |
| if os.path.exists(dst): | |
| os.remove(dst) | |
| os.link(cached, dst) | |
| except Exception: | |
| shutil.copy2(cached, dst) | |
| def ensure_library(base): | |
| small = {k: v for k, v in LIB.items() if k != BIG} | |
| missing = [(k, v) for k, v in small.items() if not have(base, v)] | |
| if missing: | |
| print("First run: fetching the YahBible study library (~1.2 GB) ...", flush=True) | |
| for k, v in missing: | |
| for _ in range(4): | |
| try: | |
| fetch(base, k, v) | |
| break | |
| except Exception as e: | |
| print(" retry (%s)" % str(e)[:60], flush=True) | |
| time.sleep(4) | |
| # the 70GB lexicon: fetch in the background so the app is usable immediately | |
| if not have(base, LIB[BIG]) and not os.environ.get("YAHBIBLE_SKIP_LEX"): | |
| def _bg(): | |
| for _ in range(6): | |
| try: | |
| print("Background: fetching the full lexicon (interlinear + Strong's, ~70 GB)...", flush=True) | |
| fetch(base, BIG, LIB[BIG]) | |
| print("Lexicon ready -- interlinear + Strong's now enabled.", flush=True) | |
| break | |
| except Exception as e: | |
| print(" lexicon retry (%s)" % str(e)[:60], flush=True) | |
| time.sleep(10) | |
| threading.Thread(target=_bg, daemon=True).start() | |
| def main(): | |
| # when frozen, our bundled modules sit next to the exe / in the PyInstaller temp | |
| here = os.path.dirname(os.path.abspath(sys.argv[0])) | |
| if getattr(sys, "_MEIPASS", None): | |
| here = sys._MEIPASS | |
| if here not in sys.path: | |
| sys.path.insert(0, here) | |
| base = base_dir() | |
| os.environ["YAHBIBLE_BASE"] = base | |
| print("YahBible -- library at:", base, flush=True) | |
| ensure_library(base) | |
| # pull the latest app code from the repo so fixes apply without a new exe | |
| try: | |
| cdir = ensure_code(base) | |
| os.environ["YAHBIBLE_CODE"] = cdir # so the server's _res() finds updated study data | |
| if cdir not in sys.path: | |
| sys.path.insert(0, cdir) | |
| load_updated_code(cdir) | |
| except Exception as e: | |
| print(" code auto-update skipped (%s)" % str(e)[:60], flush=True) | |
| # start the server (import after YAHBIBLE_BASE is set so its path constants resolve) | |
| import o_taviel_server as S | |
| threading.Thread(target=S.main, daemon=True).start() | |
| # wait for it to bind, then open the browser | |
| import socket | |
| for _ in range(120): | |
| s = socket.socket(); s.settimeout(0.4) | |
| try: | |
| s.connect(("127.0.0.1", PORT)); s.close(); break | |
| except Exception: | |
| time.sleep(0.5) | |
| webbrowser.open("http://127.0.0.1:%d/" % PORT) | |
| print("YahBible is running at http://127.0.0.1:%d/ (close this window to quit)" % PORT, flush=True) | |
| try: | |
| while True: | |
| time.sleep(3600) | |
| except KeyboardInterrupt: | |
| pass | |
| if __name__ == "__main__": | |
| main() | |