XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFEEDToolBox

【WinUI】XFE精英危险工具箱

公开
关注 0 Fork 0 Star 0
UTF-8
"""Run SQLite's official recovery on the forensic copy, never the live database."""
import hashlib
import json
import pathlib
import re
import subprocess
import sys
import urllib.request
import zipfile

sys.stdout.reconfigure(encoding="utf-8")
root = pathlib.Path(sys.argv[1]).resolve()
tools = root / "sqlite-tools"
tools.mkdir(exist_ok=True)
page = urllib.request.urlopen("https://www.sqlite.org/download.html", timeout=30).read().decode()
product = next(line for line in page.splitlines() if line.startswith("PRODUCT,") and "/sqlite-tools-win-x64-" in line)
_, version, url, size, digest, *_ = product.split(",")
archive = tools / pathlib.Path(url).name
if not archive.exists():
    with urllib.request.urlopen("https://www.sqlite.org/" + url, timeout=30) as source, archive.open("xb") as target:
        while chunk := source.read(1024 * 1024):
            target.write(chunk)
if hashlib.sha3_256(archive.read_bytes()).hexdigest() != digest:
    raise RuntimeError("Official SQLite tool checksum mismatch")
with zipfile.ZipFile(archive) as package:
    package.extract("sqlite3.exe", tools)
cli = tools / "sqlite3.exe"
source = root / "markets.db"
recovered = root / "recovered.db"
if recovered.exists():
    raise RuntimeError("Choose a fresh recovered database")
with (root / "recovery-stderr.log").open("wb") as errors, (root / "import-stderr.log").open("wb") as import_errors:
    producer = subprocess.Popen([str(cli), "-readonly", str(source), ".recover --ignore-freelist"], stdout=subprocess.PIPE, stderr=errors)
    consumer = subprocess.Popen([str(cli), str(recovered)], stdin=producer.stdout, stdout=subprocess.DEVNULL, stderr=import_errors)
    producer.stdout.close()
    recover_code = producer.wait()
    import_code = consumer.wait()
report = {"sqlite_version": version, "tool_sha3_256": digest, "recover_exit": recover_code, "import_exit": import_code, "bytes": recovered.stat().st_size}
check = subprocess.run([str(cli), "-readonly", "-json", str(recovered), "PRAGMA integrity_check; SELECT name FROM sqlite_schema WHERE type='table'; SELECT COUNT(*) AS stations FROM stations; SELECT COUNT(*) AS snapshots FROM snapshots; SELECT COUNT(*) AS quotes FROM quotes;"], capture_output=True, text=True, encoding="utf-8")
report["check_exit"] = check.returncode
report["check_output"] = check.stdout
report["check_error"] = check.stderr
(root / "recovery-report.json").write_text(json.dumps(report, ensure_ascii=False, indent=2), encoding="utf-8")
print(json.dumps(report, ensure_ascii=False), flush=True)