- 27 Apr, 2026 1 commit
-
-
Stefy Lanza (nextime / spora ) authored
-
- 25 Apr, 2026 9 commits
-
-
Stefy Lanza (nextime / spora ) authored
Co-Authored-By:Claude Sonnet 4.6 <noreply@anthropic.com>
-
Stefy Lanza (nextime / spora ) authored
-
Stefy Lanza (nextime / spora ) authored
-
Stefy Lanza (nextime / spora ) authored
-
Stefy Lanza (nextime / spora ) authored
-
Stefy Lanza (nextime / spora ) authored
-
Stefy Lanza (nextime / spora ) authored
-
Stefy Lanza (nextime / spora ) authored
-
Stefy Lanza (nextime / spora ) authored
-
- 24 Apr, 2026 28 commits
-
-
Stefy Lanza (nextime / spora ) authored
fix: use importlib.metadata.version() for version check — avoids import aisbf crash before config is set up
-
Stefy Lanza (nextime / spora ) authored
-
Stefy Lanza (nextime / spora ) authored
fix: copy config/ files to share dir on bootstrap; preserve existing user-customised configs on re-bootstrap
-
Stefy Lanza (nextime / spora ) authored
-
Stefy Lanza (nextime / spora ) authored
fix: use importlib.util.find_spec instead of import aisbf to avoid __init__.py crash on missing providers.json
-
Stefy Lanza (nextime / spora ) authored
fix: dynamically register all _share/ files in package_data — '**' globs in static list were silently dropped by setuptools
-
Stefy Lanza (nextime / spora ) authored
-
Stefy Lanza (nextime / spora ) authored
--system-site-packages only includes system-wide packages (/usr/lib/…); it does NOT include user-installed packages (~/.local/lib/…). When aisbf is installed with pip --user (or auto-detected user mode with --break-system-packages), import aisbf fails inside the venv and the server cannot start. Add _link_user_site_packages() to aisbf.sh: - Determines the user site-packages path via python3 -m site --user-site - Writes a .pth file into the venv's site-packages directory pointing there - Called on venv creation AND on every subsequent run (refresh after upgrades) Also sync aisbf/aisbf.sh (the package-bundled bootstrap copy) to match.
-
Stefy Lanza (nextime / spora ) authored
pip's data_files extraction is unreliable for user installs with --break-system-packages: files either land in the wrong prefix or are silently dropped from the wheel entirely. Fix: build_py hook in setup.py copies main.py, aisbf.sh, requirements.txt, templates/, static/, and config/ into aisbf/_share/ at wheel-build time. These are declared as package_data so pip always installs them to site-packages/aisbf/_share/ regardless of install mode. cli.py now: - Checks all sysconfig-derived paths for a complete share directory - Falls back to bootstrapping: copies the full aisbf/_share/ bundle to ~/.local/share/aisbf/ on first run if data_files were not installed - Works for both wheel installs (uses _share/) and editable installs (uses the project root directly as the bundle source) - Prints a clear error with checked paths and reinstall instructions if bootstrap also fails aisbf/_share/ is gitignored (generated at build time).
-
Stefy Lanza (nextime / spora ) authored
cli.py: - Replace hardcoded paths with sysconfig.get_path('data', scheme) covering all pip install modes (venv, posix_user, posix_prefix, posix_home, system) - Fall back to legacy hardcoded paths for extra safety - Last-resort bootstrap: copy bundled aisbf/aisbf.sh to ~/.local/share/aisbf/ when data_files were not installed by pip (known pip/wheel limitation) - Improved error message with all checked paths and reinstall instructions aisbf.sh: - Replace hardcoded /usr/share/aisbf check (wrong: setup.py installs to /usr/local/share/aisbf) with a Python sysconfig lookup that checks the actual pip data prefix across all known schemes - Derive LOG_DIR from SHARE_DIR instead of duplicating the detection logic Packaging: - Add aisbf/aisbf.sh as package_data so it is always present in the installed aisbf package regardless of data_files extraction success - Add recursive-include aisbf *.sh to MANIFEST.in for sdist - Add aisbf/aisbf.sh to setup.py data_files share/aisbf/aisbf listing -
Stefy Lanza (nextime / spora ) authored
Replace DashboardBlockingMiddleware + APIBlockingMiddleware with a single GenocidalBlockingMiddleware that blocks ALL routes (not just dashboard or API) under any of three conditions: 1. Server's own public IP resolves to Israel — detected once at startup via api.ipify.org + geolocation lookup, stored in _server_ip_blocked flag 2. Host header domain ends with .il (port stripped before check) 3. Connecting client IP resolves to Israel (per-request geolocation lookup) /blocked is always allowed through to avoid redirect loops. API/MCP routes return JSON 403; all other routes redirect to /blocked.
-
Stefy Lanza (nextime / spora ) authored
- Move geolocation.py from repo root into aisbf/ package (correct location) - Fix NameError: call geolocation.get_ip_country() with module prefix in APIBlockingMiddleware - Fix middleware execution order: register DashboardBlockingMiddleware and APIBlockingMiddleware before ProxyHeadersMiddleware so proxy headers are decoded first (last added = first executed in Starlette) - Fix typo: is_ip_genocidial -> is_ip_genocidal in aisbf/geolocation.py - Fix tests: update import path to aisbf.geolocation and use AsyncMock so httpx coroutines are properly awaitable - Add aisbf/geolocation.py and templates/blocked.html to setup.py data_files - Add trailing newlines to geolocation.py, blocked.html, and test file - Add static/i18n.js and static/i18n/*.json locale files
-
Stefy Lanza (nextime / spora ) authored
-
Stefy Lanza (nextime / spora ) authored
-
Stefy Lanza (nextime / spora ) authored
- Cache None for non-200 HTTP status codes to avoid repeated failed API calls - Move exception handling cache to except block for consistency
-
Stefy Lanza (nextime / spora ) authored
- Test invalid IP validation returns None without API call - Test caching behavior for repeated calls - Test error handling for API failures
-
Stefy Lanza (nextime / spora ) authored
-
Stefy Lanza (nextime / spora ) authored
-
Stefy Lanza (nextime / spora ) authored
-
Stefy Lanza (nextime / spora ) authored
-
Stefy Lanza (nextime / spora ) authored
-
Stefy Lanza (nextime / spora ) authored
fix: response cache stats missing enabled field; tor status reads from JSON config instead of Pydantic singleton
-
Stefy Lanza (nextime / spora ) authored
-
Stefy Lanza (nextime / spora ) authored
-
Stefy Lanza (nextime / spora ) authored
-
Stefy Lanza (nextime / spora ) authored
-
Stefy Lanza (nextime / spora ) authored
-
Stefy Lanza (nextime / spora ) authored
-
- 23 Apr, 2026 2 commits
-
-
Stefy Lanza (nextime / spora ) authored
When a card was added via billing page, it was only stored in the DB — never attached to the Stripe customer. This meant every charge was on an unattached PM, which Stripe processes differently. For subscription upgrades the user is actively present, so off_session=True was incorrect: it marks the charge as a Merchant-Initiated Transaction (MIT) which settles slower than Customer-Initiated (CIT). Other sites that use Stripe's frontend SDK do CITs, which is why their charges clear faster. - dashboard_add_payment_method_stripe: attach PM to Stripe customer and set as customer default immediately when the card is added - auto_charge: add off_session parameter (default True for existing auto top-up/renewal callers); document the distinction - dashboard_subscribe_tier: pass off_session=False so the upgrade charge is processed as a CIT and settles at normal speed
-
Stefy Lanza (nextime / spora ) authored
- auto_charge: verify payment_intent.status is succeeded/processing before returning success; add description/metadata params so subscription charges are labeled correctly in Stripe - pricing: redirect to ?success= after upgrade/downgrade so the persistent server-side banner shows instead of a 1.5s toast that disappears on reload - pricing GET endpoint: pass success/error query params to template context - base modal: support html:true option in open() so showConfirm can render HTML content; update showConfirm signature to accept html flag - pricing: pass html=true to showConfirm so the upgrade confirmation renders bold/colored text instead of raw tags
-