Files
tianxuan/analysis/tls_ref.py
T
PM-pinou 8fa36b774e v7: 19 issues fixed — SQLite storage, new clustering pipeline, display_id, globe rewrite, Chinese tools
Key changes:
- New: data_loader.py SQLite persistence with drop_sqlite_table
- New: db_utils.py retry_on_lock decorator (3 retries, exponential backoff)
- New: tool_registry.py with 27 MCP tools (filter_and_cluster, compute_scores, etc.)
- New: tls_ref.py for TLS cipher/reference data
- New: import_tlsdb.py management command
- New: scripts/start_server.py for portable runtime
- New: migrations 0003-0007 for SQLite table, display_id, llm fields
- Changed: views.py unified pipeline worker, retry_run, display_id everywhere
- Changed: models.py with display_id auto-assignment, run_type, sqlite_table, llm_thinking, tool_calls_json
- Changed: urls.py added retry_run route
- Changed: session_store.py robust JSON persistence
- Changed: AGENTS.md v7 fix summary added
- Changed: templates — globe rewrite (inertia/polar flip), auto.html (thinking/tool accordions), base.html (toast/config), all pages use display_id
- Changed: run.bat PYTHONUTF8=1
- Deleted: entity_detector.py, entity_aggregator.py (replaced by filter_and_cluster clustering pipeline)
- Test: 92/92 unit tests passing
2026-07-20 13:33:13 +08:00

95 lines
2.9 KiB
Python

"""SQLite-backed TLS reference data access — replaces ``TlsDB.csv``.
Provides functions to query the ``tls_ref_data`` table (populated by
the ``import_tlsdb`` management command) instead of reading the
now-deprecated ``TlsDB.csv`` file.
Usage::
from analysis.tls_ref import get_tls_ref_data, get_tls_field, get_tls_ref_dict
# All rows as list of dicts
all_fields = get_tls_ref_data()
# Single field
field = get_tls_field('0ver')
# -> {'field_code': '0ver', 'meaning': 'TLS版本', 'data_type': '2字节'}
# Dict lookup (cached in memory after first call)
lookup = get_tls_ref_dict()
# -> {'0ver': {'meaning': 'TLS版本', 'data_type': '2字节'}, ...}
"""
from functools import lru_cache
from typing import Optional
from django.db import connection
def get_tls_ref_data() -> list[dict[str, str]]:
"""Return all rows from ``tls_ref_data`` as a list of dicts.
Returns:
Each dict has keys ``field_code``, ``meaning``, ``data_type``.
Returns an empty list if the table does not exist (e.g. before
migration).
"""
if not _table_exists():
return []
with connection.cursor() as cursor:
cursor.execute(
'SELECT field_code, meaning, data_type FROM tls_ref_data ORDER BY id'
)
columns = [col[0] for col in cursor.description]
return [dict(zip(columns, row)) for row in cursor.fetchall()]
def get_tls_field(field_code: str) -> Optional[dict[str, str]]:
"""Return a single TLS field definition by its code.
Args:
field_code: e.g. ``'0ver'``, ``':ips'``, ``'cipher-suite'``.
Returns:
Dict with keys ``field_code``, ``meaning``, ``data_type``, or
``None`` if not found.
"""
if not _table_exists():
return None
with connection.cursor() as cursor:
cursor.execute(
'SELECT field_code, meaning, data_type FROM tls_ref_data WHERE field_code = %s',
[field_code],
)
row = cursor.fetchone()
if row is None:
return None
return {
'field_code': row[0],
'meaning': row[1],
'data_type': row[2],
}
@lru_cache(maxsize=1)
def get_tls_ref_dict() -> dict[str, dict[str, str]]:
"""Return a dict mapping ``field_code -> {meaning, data_type}``.
The result is cached in memory after the first call. Call
``get_tls_ref_dict.cache_clear()`` to invalidate if the
underlying table is modified at runtime.
"""
rows = get_tls_ref_data()
return {r['field_code']: {'meaning': r['meaning'], 'data_type': r['data_type']} for r in rows}
def _table_exists() -> bool:
"""Check if the ``tls_ref_data`` table exists in the database."""
with connection.cursor() as cursor:
cursor.execute(
"SELECT name FROM sqlite_master WHERE type='table' AND name='tls_ref_data'"
)
return cursor.fetchone() is not None