Python 49.6%
TypeScript 25.5%
CSS 24.1%
1#!/usr/bin/env python32# -----------------------------------------------------------------------------3# Home-Ka — US real-estate aggregator (Groupe KA)4# Author: Simon-Pierre Boucher — contact@spboucher.ai5# run.py : entry point — sync, watch, serve, discovery, brokerage seed6# -----------------------------------------------------------------------------7"""Usage:8 python run.py sync [source ...] # sync listings from all/selected sources9 python run.py watch [minutes] # sync loop (default 60 min)10 python run.py serve [port] # start the API + frontend (default 8099)11 python run.py list # list registered connectors & sources12 python run.py seed [file] # load data/brokerages_seed.json13 python run.py discover [n] # inspect the next n brokerages (default 25)14 python run.py rescore # recompute brokerage priority scores15 python run.py geocode [n] # geocode listings without coordinates16 python run.py quality # re-run the quality gate17 python run.py dedup # re-run the dedup pass18"""19from __future__ import annotations2021import os22import sys23from pathlib import Path2425# Load .env (feed credentials, SCRAPFLY_KEY, HOMEKA_ADMIN_TOKEN...) without26# any external dependency27_env = Path(__file__).parent / ".env"28if _env.exists():29 for line in _env.read_text().splitlines():30 line = line.strip()31 if line and not line.startswith("#") and "=" in line:32 k, _, v = line.partition("=")33 os.environ.setdefault(k.strip(), v.strip())343536def main() -> None:37 cmd = sys.argv[1] if len(sys.argv) > 1 else "serve"38 if cmd == "sync":39 from homeka import ingest40 ingest.run(sys.argv[2:] or None)41 elif cmd == "watch":42 from homeka import ingest43 minutes = int(sys.argv[2]) if len(sys.argv) > 2 else 6044 ingest.watch(minutes * 60)45 elif cmd == "list":46 from homeka import db47 from homeka.connectors import CUSTOM, FAMILIES48 print("families:", ", ".join(sorted(FAMILIES)))49 for sid in sorted(CUSTOM):50 print(f"custom {sid}")51 con = db.connect()52 for s in db.get_sources(con):53 flag = "on " if s["enabled"] else "off"54 print(f"source [{flag}] {s['id']:28s} type={s['connector_type']}")55 con.close()56 elif cmd == "seed":57 from homeka import brokerages58 res = brokerages.load_seed(sys.argv[2] if len(sys.argv) > 2 else None)59 print(f"[home-ka] brokerage seed: {res}")60 elif cmd == "discover":61 from homeka import discovery62 n = int(sys.argv[2]) if len(sys.argv) > 2 else 2563 print(discovery.run_batch(limit=n))64 elif cmd == "rescore":65 from homeka import brokerages66 print(f"[home-ka] rescored {brokerages.rescore()} brokerage(s)")67 elif cmd == "geocode":68 from homeka import geocode69 print(geocode.run_batch(int(sys.argv[2]) if len(sys.argv) > 2 else None))70 elif cmd == "quality":71 from homeka import db, quality72 con = db.connect()73 print(quality.refresh(con))74 con.close()75 elif cmd == "dedup":76 from homeka import db77 con = db.connect()78 print(f"[home-ka] dedup: {db.refresh_dedup(con)} hidden")79 con.close()80 elif cmd == "serve":81 import uvicorn82 port = int(sys.argv[2]) if len(sys.argv) > 2 else 809983 uvicorn.run("homeka.web:app", host="0.0.0.0", port=port)84 else:85 print(__doc__)86 sys.exit(1)878889if __name__ == "__main__":90 main()91