#!/usr/bin/env python3 """Extrait les points d'accès de l'API des apps Boti Education depuis les chunks JS décompilés. Usage : python3 extract_endpoints.py [--markdown] Cherche dans les *.js la signature d'appel de l'ApiService Angular : .post(, "endpoint") / .get(, "endpoint") et produit une table endpoint -> méthodes dédupliquée. """ import re import sys import glob import os import argparse APPEL = re.compile( r'\.(post|get|getBlob)\(\s*' r'(?:"[^"]*"|`[^`]*`|[A-Za-z_$][\w$]*(?:\s*\.\s*[\w$]+)*(?:\([^()]*\))?|\{[^{}]*\})' r'\s*,\s*"([^"]*)"' ) def scanner(dossier): trouves = {} # endpoint -> {méthode: [chunks]} for chemin in sorted(glob.glob(os.path.join(dossier, '*.js'))): chunk = os.path.basename(chemin) src = open(chemin, encoding='utf8', errors='replace').read() for m in APPEL.finditer(src): methode, ep = m.group(1), m.group(2) d = trouves.setdefault(ep, {}) d.setdefault(methode, []).append(chunk) return trouves def principal(): ap = argparse.ArgumentParser() ap.add_argument('dossier') ap.add_argument('--markdown', action='store_true') args = ap.parse_args() trouves = scanner(args.dossier) if not trouves: sys.exit('aucun point d\'accès trouvé, mauvais dossier ?') if args.markdown: print(f'# Points d\'accès extraits de {os.path.basename(args.dossier)}') print() print(f'{len(trouves)} points d\'accès uniques (non filtrés, voir docs/endpoints.md pour la liste nettoyée).') print() print('| endpoint | méthodes | chunk(s) |') print('|---|---|---|') for ep in sorted(trouves): methodes = ', '.join(sorted(trouves[ep])) chunks = ', '.join(sorted({c for ms in trouves[ep].values() for c in ms})[:3]) print(f'| {ep} | {methodes} | {chunks} |') else: for ep in sorted(trouves): print(ep, sorted(trouves[ep])) print(f'TOTAL points d\'accès : {len(trouves)}', file=sys.stderr) if __name__ == '__main__': principal()