de25dcee57
installer/:
- build_usb.py: dev tool — builds Flutter + AR-ECDIS, assembles USB pendrive
image with serial.key, autorun.inf, and START_INSTALLER.bat
- serial_generator.py: generates AR-XXXX-XXXX-XXXX serial numbers (48-bit
entropy), logs to CSV for CRM integration
- src/license.py: hardware fingerprint (Windows MachineGuid + primary MAC),
serial validation, online activation POST, local cache with 30-day offline
grace period
- src/sysconfig.py: HKCU autostart registry entries, .lnk shortcuts (desktop
+ Start Menu via WScript.Shell), firewall rules (netsh), COM port detection
- src/install.py: tkinter installer GUI — 9 sequential steps with per-step
progress indicators, threaded execution, error dialogs, and silent mode
license_server/ (FastAPI service — deploy to arelectronics.com VPS):
- POST /api/v1/activate: first activation accepted; same-HW re-activation
refreshes heartbeat; different-HW rejected with 409
- GET /api/v1/validate/{serial}: heartbeat endpoint to refresh offline cache
- Admin endpoints (X-Admin-Key): issue, list, revoke licenses
- SQLAlchemy models: License (serial registry) + Activation (per-machine rows)
- SQLite default, PostgreSQL-ready via DATABASE_URL env var
AR_electronics — AR-Autopilot Project
34 lines
1007 B
Python
34 lines
1007 B
Python
# =============================================================================
|
|
# license_server/database.py — SQLAlchemy engine + session factory
|
|
# =============================================================================
|
|
|
|
import os
|
|
from sqlalchemy import create_engine
|
|
from sqlalchemy.orm import DeclarativeBase, sessionmaker
|
|
|
|
# Default: SQLite in same directory. Set DATABASE_URL env var for PostgreSQL.
|
|
DATABASE_URL = os.getenv(
|
|
"DATABASE_URL",
|
|
"sqlite:///./ar_licenses.db",
|
|
)
|
|
|
|
# connect_args only needed for SQLite (allows multi-threaded use by FastAPI)
|
|
_connect_args = {"check_same_thread": False} if DATABASE_URL.startswith("sqlite") else {}
|
|
|
|
engine = create_engine(DATABASE_URL, connect_args=_connect_args)
|
|
|
|
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
|
|
|
|
|
|
class Base(DeclarativeBase):
|
|
pass
|
|
|
|
|
|
def get_db():
|
|
"""FastAPI dependency that yields a database session."""
|
|
db = SessionLocal()
|
|
try:
|
|
yield db
|
|
finally:
|
|
db.close()
|