- Add SERVICE_INVENTORY_V1.0.0.md (25 source-verified tools, 3.7GB) - Add ERP_SELECTION_REPORT.md (Odoo CE vs ERPNext comparison) - Add SFTPGO_ODOO_REPLACEMENT.md (SFTPGo migration plan) - Add SERVICE_GO_GITEA_BUILD.md (Go compiler + Gitea build report) - Add release visualize command (face trace heatmap + identity filter) - Add sqlite-vec integration (160MB SQLite with vec0 vector tables) - Add export_identities.py, export_sqlite.py, render_face_heatmap.py - Add Go, Gitea, Rust/Cargo, Swift, yt-dlp, SQLite, sqlite-vec to service CLI - Fix package to include identities and identity_bindings in data.sql - Update release list to show all deployed video stats - Add V1.0.0 YAML frontmatter to all docs (DOCS_STANDARD compliant)
75 lines
2.5 KiB
Python
75 lines
2.5 KiB
Python
#!/opt/homebrew/bin/python3.11
|
|
"""
|
|
Export identity data for a video UUID as JSON (for offline analysis).
|
|
Usage: python3 export_identities.py <file_uuid> [output.json]
|
|
"""
|
|
import sys, json, psycopg2
|
|
|
|
UUID = sys.argv[1] if len(sys.argv) > 1 else "aeed71342a899fe4b4c57b7d41bcb692"
|
|
OUT = sys.argv[2] if len(sys.argv) > 2 else f"/Users/accusys/momentry/output_dev/{UUID}.identities.json"
|
|
|
|
conn = psycopg2.connect("dbname=momentry user=accusys")
|
|
cur = conn.cursor()
|
|
|
|
# Get identities referenced by this file's face_detections
|
|
cur.execute("""
|
|
SELECT DISTINCT i.id, i.name, i.uuid, i.identity_type, i.source, i.status,
|
|
i.face_embedding, i.voice_embedding, i.reference_data, i.tmdb_id, i.tmdb_profile
|
|
FROM dev.identities i
|
|
INNER JOIN dev.face_detections fd ON fd.identity_id = i.id
|
|
WHERE fd.file_uuid = %s
|
|
ORDER BY i.id
|
|
""", (UUID,))
|
|
rows = cur.fetchall()
|
|
|
|
identities = []
|
|
for r in rows:
|
|
identities.append({
|
|
"id": r[0],
|
|
"name": r[1],
|
|
"uuid": str(r[2]) if r[2] else None,
|
|
"identity_type": r[3],
|
|
"source": r[4],
|
|
"status": r[5],
|
|
"tmdb_id": r[9],
|
|
"tmdb_profile": r[10],
|
|
})
|
|
|
|
# Get identity_bindings for these identities' traces
|
|
cur.execute("""
|
|
SELECT DISTINCT ib.identity_id, ib.identity_type, ib.identity_value, ib.confidence
|
|
FROM dev.identity_bindings ib
|
|
WHERE ib.identity_id IN (
|
|
SELECT DISTINCT fd.identity_id FROM dev.face_detections fd WHERE fd.file_uuid = %s
|
|
)
|
|
""", (UUID,))
|
|
bindings = [{"identity_id": r[0], "identity_type": r[1], "identity_value": r[2], "confidence": float(r[3])} for r in cur.fetchall()]
|
|
|
|
# Get trace-to-identity mapping from face_detections
|
|
cur.execute("""
|
|
SELECT DISTINCT trace_id, identity_id, COUNT(*) as face_count
|
|
FROM dev.face_detections
|
|
WHERE file_uuid = %s AND identity_id IS NOT NULL AND trace_id IS NOT NULL
|
|
GROUP BY trace_id, identity_id ORDER BY trace_id
|
|
""", (UUID,))
|
|
trace_map = [{"trace_id": r[0], "identity_id": r[1], "face_count": r[2]} for r in cur.fetchall()]
|
|
|
|
cur.close(); conn.close()
|
|
|
|
output = {
|
|
"file_uuid": UUID,
|
|
"identity_count": len(identities),
|
|
"binding_count": len(bindings),
|
|
"trace_mapping_count": len(trace_map),
|
|
"identities": identities,
|
|
"bindings": bindings,
|
|
"trace_to_identity": trace_map,
|
|
}
|
|
|
|
with open(OUT, 'w') as f:
|
|
json.dump(output, f, indent=2, ensure_ascii=False)
|
|
|
|
size_kb = len(json.dumps(output)) / 1024
|
|
print(f"Exported {len(identities)} identities, {len(bindings)} bindings, {len(trace_map)} trace mappings")
|
|
print(f" → {OUT} ({size_kb:.0f}KB)")
|