fix 一键组合只上传邮箱列表,服务端再从数据库加载完整账号
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Create a sanitized BitBrowser database while preserving extensions and kernels."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import sqlite3
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def quote_identifier(value: str) -> str:
|
||||
return '"' + value.replace('"', '""') + '"'
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--source", required=True)
|
||||
parser.add_argument("--output", required=True)
|
||||
args = parser.parse_args()
|
||||
|
||||
source_path = Path(args.source).resolve()
|
||||
output_path = Path(args.output).resolve()
|
||||
if source_path == output_path:
|
||||
raise RuntimeError("The output database must differ from the source database")
|
||||
if not source_path.is_file():
|
||||
raise FileNotFoundError(source_path)
|
||||
output_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
if output_path.exists():
|
||||
output_path.unlink()
|
||||
|
||||
source = sqlite3.connect(f"file:{source_path.as_posix()}?mode=ro", uri=True)
|
||||
target = sqlite3.connect(str(output_path))
|
||||
try:
|
||||
source.backup(target)
|
||||
target.execute("PRAGMA foreign_keys = OFF")
|
||||
|
||||
tables = [
|
||||
row[0]
|
||||
for row in target.execute(
|
||||
"SELECT name FROM sqlite_master "
|
||||
"WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name"
|
||||
)
|
||||
]
|
||||
|
||||
extension_rows = []
|
||||
if "local_extensions" in tables:
|
||||
extension_rows = target.execute(
|
||||
"SELECT name, desc, extension_id, icon, version, is_use "
|
||||
"FROM local_extensions ORDER BY id"
|
||||
).fetchall()
|
||||
|
||||
chrome_rows = []
|
||||
if "chrome_versions" in tables:
|
||||
chrome_rows = target.execute(
|
||||
"SELECT chrome, version FROM chrome_versions ORDER BY id"
|
||||
).fetchall()
|
||||
|
||||
firefox_rows = []
|
||||
if "firefox_versions" in tables:
|
||||
firefox_rows = target.execute(
|
||||
"SELECT firefox, version FROM firefox_versions ORDER BY id"
|
||||
).fetchall()
|
||||
|
||||
for table in tables:
|
||||
target.execute(f"DELETE FROM {quote_identifier(table)}")
|
||||
target.execute("DELETE FROM sqlite_sequence")
|
||||
|
||||
if extension_rows:
|
||||
target.executemany(
|
||||
"INSERT INTO local_extensions "
|
||||
"(name, desc, extension_id, icon, version, is_use, cloud_id, main_user_id) "
|
||||
"VALUES (?, ?, ?, ?, ?, ?, NULL, NULL)",
|
||||
extension_rows,
|
||||
)
|
||||
if chrome_rows:
|
||||
target.executemany(
|
||||
"INSERT INTO chrome_versions (chrome, version) VALUES (?, ?)",
|
||||
chrome_rows,
|
||||
)
|
||||
if firefox_rows:
|
||||
target.executemany(
|
||||
"INSERT INTO firefox_versions (firefox, version) VALUES (?, ?)",
|
||||
firefox_rows,
|
||||
)
|
||||
|
||||
target.commit()
|
||||
target.execute("VACUUM")
|
||||
target.execute("PRAGMA optimize")
|
||||
|
||||
counts = {
|
||||
table: target.execute(
|
||||
f"SELECT COUNT(*) FROM {quote_identifier(table)}"
|
||||
).fetchone()[0]
|
||||
for table in tables
|
||||
}
|
||||
allowed_nonempty = {"local_extensions", "chrome_versions", "firefox_versions"}
|
||||
unexpected = {
|
||||
table: count
|
||||
for table, count in counts.items()
|
||||
if count and table not in allowed_nonempty
|
||||
}
|
||||
if unexpected:
|
||||
raise RuntimeError(f"Sanitization failed; unexpected rows remain: {unexpected}")
|
||||
|
||||
integrity = target.execute("PRAGMA integrity_check").fetchone()[0]
|
||||
if integrity != "ok":
|
||||
raise RuntimeError(f"SQLite integrity check failed: {integrity}")
|
||||
|
||||
report = {
|
||||
"source": str(source_path),
|
||||
"output": str(output_path),
|
||||
"extensions": [
|
||||
{
|
||||
"name": row[0],
|
||||
"extension_id": row[2],
|
||||
"version": row[4],
|
||||
"enabled": bool(row[5]),
|
||||
}
|
||||
for row in extension_rows
|
||||
],
|
||||
"chrome_versions": [
|
||||
{"chrome": row[0], "version": row[1]} for row in chrome_rows
|
||||
],
|
||||
"firefox_versions": [
|
||||
{"firefox": row[0], "version": row[1]} for row in firefox_rows
|
||||
],
|
||||
"table_counts": counts,
|
||||
"integrity_check": integrity,
|
||||
"size_bytes": os.path.getsize(output_path),
|
||||
}
|
||||
print(json.dumps(report, ensure_ascii=False, indent=2))
|
||||
finally:
|
||||
target.close()
|
||||
source.close()
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in New Issue
Block a user