Initial SQL-only 1C adapter baseline
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Index exported 1C ConfigCAS files for GUID/string lookup.
|
||||
|
||||
This is a mechanical content index: decompress, decode when possible, collect
|
||||
GUIDs and string hits. It does not infer semantic object kinds.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
from inspect_1c_sql_files import GUID_RE, try_decode, try_decompress
|
||||
|
||||
|
||||
def inspect_cas_file(path: Path, target_guids: set[str], target_strings: list[str]) -> dict[str, Any]:
|
||||
data = path.read_bytes()
|
||||
payload, compression = try_decompress(data)
|
||||
text, encoding = try_decode(payload)
|
||||
item: dict[str, Any] = {
|
||||
"file_name": path.name,
|
||||
"bytes": len(data),
|
||||
"payload_bytes": len(payload),
|
||||
"compression": compression,
|
||||
"encoding": encoding,
|
||||
"guid_count": 0,
|
||||
"target_guid_hits": [],
|
||||
"target_string_hits": [],
|
||||
"guids_sample": [],
|
||||
"text_preview": "",
|
||||
}
|
||||
if text is None:
|
||||
return item
|
||||
clean = text.replace("\x00", "").replace("\ufeff", "")
|
||||
guids = sorted(set(match.lower() for match in GUID_RE.findall(clean)))
|
||||
item["guid_count"] = len(guids)
|
||||
item["guids_sample"] = guids[:50]
|
||||
item["target_guid_hits"] = sorted(target_guids.intersection(guids))
|
||||
item["target_string_hits"] = [value for value in target_strings if value and value in clean]
|
||||
if item["target_guid_hits"] or item["target_string_hits"]:
|
||||
item["text_preview"] = clean[:2000]
|
||||
else:
|
||||
item["text_preview"] = clean[:300]
|
||||
return item
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(description="Index exported ConfigCAS files.")
|
||||
parser.add_argument("cas_dir", type=Path)
|
||||
parser.add_argument("--output", type=Path, required=True)
|
||||
parser.add_argument("--target-guid", action="append", default=[])
|
||||
parser.add_argument("--target-string", action="append", default=[])
|
||||
args = parser.parse_args()
|
||||
|
||||
target_guids = {value.lower() for value in args.target_guid}
|
||||
files = sorted(path for path in args.cas_dir.iterdir() if path.is_file())
|
||||
items = [inspect_cas_file(path, target_guids, args.target_string) for path in files]
|
||||
guid_hits = [item for item in items if item["target_guid_hits"]]
|
||||
string_hits = [item for item in items if item["target_string_hits"]]
|
||||
compression_counts: dict[str, int] = {}
|
||||
encoding_counts: dict[str, int] = {}
|
||||
for item in items:
|
||||
compression_counts[item["compression"]] = compression_counts.get(item["compression"], 0) + 1
|
||||
encoding = item["encoding"] or "<binary>"
|
||||
encoding_counts[encoding] = encoding_counts.get(encoding, 0) + 1
|
||||
report = {
|
||||
"schema": "onec_sql_cas_index.v1",
|
||||
"cas_dir": str(args.cas_dir),
|
||||
"file_count": len(items),
|
||||
"target_guids": sorted(target_guids),
|
||||
"target_strings": args.target_string,
|
||||
"compression_counts": dict(sorted(compression_counts.items())),
|
||||
"encoding_counts": dict(sorted(encoding_counts.items())),
|
||||
"target_guid_hit_count": len(guid_hits),
|
||||
"target_string_hit_count": len(string_hits),
|
||||
"target_guid_hits": guid_hits,
|
||||
"target_string_hits": string_hits,
|
||||
"files": items,
|
||||
}
|
||||
args.output.parent.mkdir(parents=True, exist_ok=True)
|
||||
args.output.write_text(json.dumps(report, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
|
||||
print(
|
||||
json.dumps(
|
||||
{
|
||||
"output": str(args.output),
|
||||
"files": len(items),
|
||||
"guid_hits": len(guid_hits),
|
||||
"string_hits": len(string_hits),
|
||||
"compression_counts": report["compression_counts"],
|
||||
},
|
||||
ensure_ascii=False,
|
||||
)
|
||||
)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in New Issue
Block a user