wimotek-chromium-sync 1.0.8 → 1.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,176 +4,264 @@
4
4
  [![npm version](https://img.shields.io/npm/v/wimotek-chromium-sync.svg?style=flat-square)](https://www.npmjs.com/package/wimotek-chromium-sync)
5
5
  [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg?style=flat-square)](LICENSE)
6
6
 
7
- 专为 Chromium / Chrome 设计的现代化会话与 Cookie 集群同步调度工具。
7
+ 专为 Chromium / Chrome 设计的生产级会话与 Cookie 集群同步调度引擎。支持 1对1 与 1对多集群、域名白/黑名单过滤、会话级连接池复用、Cookie 指纹变更差量同步 (Diff Sync)、本地免密直连及 SSH 私钥文本(PEM)/路径与密码认证。
8
8
 
9
9
  ---
10
10
 
11
- ## 🌟 核心特性
12
-
13
- * **统一节点模型 (1对1 / 1对多集群)**:采用纯粹现代的节点架构,同时支持 1对1 穿透与任意规模的 1对多 节点集群分发。
14
- * **本地免密直连与全能 SSH 认证**:
15
- * **本地节点**:指定本地端口即可直接直连 CDP,免登录、免配置、零 SSH 开销。
16
- * **远程节点**:支持自定义 SSH 用户名 (`ssh_user`)、私钥认证 (`ssh_key_path` / `ssh_key_data`) 与密码认证 (`ssh_password`)。
17
- * **端口自愈防撞**:自动为各远程节点分配互不冲突的本地隧道映射端口,已存在的活跃隧道自动复用。
18
- * **两类高效同步策略**:
19
- * **`merge` (全节点凭证智能融合)**:汇总所有在线节点的 Cookie,若存在同名/同域/同路径冲突,**无条件保留有效期最新(expires 更长)的记录**,同时融合 LocalStorage 状态并向集群节点广播热刷新。
20
- * **`sync` (单源广播同步)**:将指定源节点 (`source`) 的全部会话凭据镜像推送至一个或多个目标节点。
21
- * **极简调用,免建数据库表**:
22
- * 代码层面提供 `get_cookies()`、`inspect()` 与 `get_summary_table()`,**仅需 1 行代码即可获取任何节点或全集群的 Cookie 列表与状态**。
23
- * 命令行提供 `--status` (ASCII 表格) 与 `--json` (标准 JSON 格式),随取随用。
11
+ ## 🌟 核心工程特性
12
+
13
+ 1. **统一现代节点模型 (1对1 / 1对多集群)**:
14
+ * 原生支持任意规模的节点集群管理与多隧道并发映射。
15
+ * **本地节点免密直连**:配置本地端口即可直接直连 CDP 探针,跳过 SSH 隧道拉起。
16
+ 2. **域名白名单 / 黑名单过滤机制 (Domain Filter)**:
17
+ * **`include_domains`**:仅提取与同步关注的关键业务域名(如 `['.google.com', '.github.com', '.twitter.com']`),剔除海量无关噪音。
18
+ * **`exclude_domains`**:自动过滤广告、统计追踪类垃圾 Cookie(如 `['doubleclick.net', 'google-analytics.com']`),大幅提升同步速率并防止从端污染。
19
+ 3. **会话级连接池复用 (Connection Pooling)**:
20
+ * 原生支持异步与同步上下文管理器:`async with ChromiumSync(...) as syncer:`。
21
+ * 在高频周期调度、定时巡检场景下,复用底层常驻 WebSocket CDP 会话与 SSH 隧道,避免重复握手建立与销毁,消除网络与 CPU 抖动。
22
+ 4. **Cookie 指纹变更差量同步 (Diff / Delta Sync)**:
23
+ * 默认开启 `diff=True`:自动比对目标端与待同步 Cookie 的核心指纹 `(name, domain, path, value)`。
24
+ * **仅对产生实质变动的凭据执行写入**,若完全一致则直接跳过,并避免无意义触发浏览器页面重载,**极大保护从属节点的磁盘与 SSD IO 寿命**。
25
+ 5. **原生私钥内容 (PEM String) / 路径与密码认证**:
26
+ * `ssh_key`: 原生支持**私钥 PEM 文本内容字符串**或**私钥文件绝对路径**,调用方无需配置环境变量中转。
27
+ * `ssh_password`: 直接支持 SSH 密码认证,支持集群级默认凭证与单节点自定义。
28
+ 6. **结构化执行指标返回 (Structured Return Dict)**:
29
+ * 执行后返回包含 `status`、`transferred_count`、`diff_skipped_count`、`duration` 等度量指标的标准字典,Web 控制台可直接消费展示。
30
+ 7. **全量纯函数工具方法开箱即用**:
31
+ * 模块顶级导出 `merge_cookies`、`filter_cookies`、`compute_cookie_delta` 等独立纯函数工具,无需 CDP 环境亦可直接处理和计算 Cookie 差量。
24
32
 
25
33
  ---
26
34
 
27
35
  ## 📦 安装
28
36
 
29
- ### Python 环境 (PyPI)
37
+ ### Python (PyPI)
30
38
  ```bash
31
39
  pip install wimotek-chromium-sync
32
40
  playwright install chromium
33
41
  ```
34
42
 
35
- ### Node.js 环境 (npm)
43
+ ### Node.js (npm)
36
44
  ```bash
37
45
  npm install -g wimotek-chromium-sync
38
46
  ```
39
47
 
40
48
  ---
41
49
 
42
- ## 🚀 极简使用指南
43
-
44
- ### 1. Python 代码调用
50
+ ## 🚀 极简开发示例
45
51
 
46
- #### (1) 1 行代码获取节点状态与 Cookie 详情 (无需数据库)
52
+ ### 1. 会话级连接池复用 (高频周期调度推荐)
53
+ 使用 `async with` 上下文管理器常驻复用 CDP 连接与隧道,杜绝频繁断连与握手损耗:
47
54
  ```python
55
+ import asyncio
48
56
  from chromium_sync import ChromiumSync
49
57
 
50
- syncer = ChromiumSync(nodes=[
51
- {"id": "local", "name": "本机容器", "cdp_port": 9222},
52
- {"id": "kr2", "name": "韩国节点", "ssh_host": "kr2.wimotek.com", "ssh_user": "root", "ssh_key_path": "~/.ssh/id_rsa", "cdp_port": 9222}
53
- ])
54
-
55
- # 打印美观的终端状态表格
56
- print(syncer.get_summary_table())
57
-
58
- # 获取指定节点或全集群的 Cookie 明细列表 (无需创建外部数据库表)
59
- all_cookies = syncer.get_cookies() # {"local": [...], "kr2": [...]}
60
- local_cookies = syncer.get_cookies("local") # 获取单个节点的 Cookie 列表
61
- print(f"本地有效 Cookie 数: {len(local_cookies)}")
58
+ async def periodic_sync_task():
59
+ # 进入上下文时自动预热连接池与隧道
60
+ async with ChromiumSync(
61
+ nodes=[
62
+ {"id": "local", "cdp_port": 9222},
63
+ {"id": "kr2", "ssh_host": "kr2.wimotek.com", "ssh_key": "~/.ssh/id_rsa", "cdp_port": 9222}
64
+ ],
65
+ mode="merge",
66
+ include_domains=["google.com", "github.com"], # 仅同步核心业务域名
67
+ diff=True # 开启差量比对,保护磁盘
68
+ ) as syncer:
69
+ for round_idx in range(5):
70
+ # 复用已建立的 WebSocket 会话执行热同步
71
+ result = await syncer.sync_async()
72
+ print(f"第 {round_idx + 1} 轮同步完成: 写入 {result['transferred_count']} 条, 跳过一致凭据 {result['diff_skipped_count']} 条")
73
+ await asyncio.sleep(60)
74
+
75
+ asyncio.run(periodic_sync_task())
62
76
  ```
63
77
 
64
- #### (2) 全节点 Cookie 智能 Merge (合并最新有效期)
78
+ ---
79
+
80
+ ### 2. 域名过滤与差量同步 (Diff Sync)
65
81
  ```python
66
82
  from chromium_sync import ChromiumSync
67
83
 
68
84
  syncer = ChromiumSync(
69
85
  nodes=[
70
86
  {"id": "local", "cdp_port": 9223},
71
- {"id": "kr2", "ssh_host": "kr2.wimotek.com", "ssh_user": "root", "ssh_key_path": "~/.ssh/id_rsa", "cdp_port": 9222},
87
+ {"id": "kr2", "ssh_host": "kr2.wimotek.com", "ssh_user": "root", "ssh_key": "~/.ssh/id_rsa", "cdp_port": 9222},
72
88
  {"id": "sg1", "ssh_host": "sg1.wimotek.com", "ssh_user": "ubuntu", "ssh_password": "YourPassword", "cdp_port": 9222}
73
89
  ],
74
- mode="merge"
90
+ mode="merge",
91
+ # 白名单:仅同步以下业务站点的 Cookie
92
+ include_domains=["google.com", "twitter.com", "x.com", "github.com"],
93
+ # 黑名单:过滤广告与追踪类 Cookie
94
+ exclude_domains=["doubleclick.net", "google-analytics.com"],
95
+ # 差量比对 (默认 True)
96
+ diff=True
75
97
  )
76
- syncer.run()
98
+
99
+ result = syncer.run()
100
+ print(result)
77
101
  ```
102
+ **结构化返回值示例**:
103
+ ```python
104
+ {
105
+ "status": "success", # "success" | "failed"
106
+ "mode": "merge",
107
+ "transferred_count": 8, # 本次真正变动并写入的 Cookie 数量
108
+ "diff_skipped_count": 34, # 指纹完全相同、跳过写入以保护磁盘的 Cookie 数量
109
+ "source_total": 42, # 过滤后的业务凭证总数
110
+ "target_total": 42,
111
+ "nodes_synced": ["local", "kr2", "sg1"],
112
+ "duration": 0.85, # 耗时(秒)
113
+ "details": "全节点 Merge 成功: 融合并向 ['local', 'kr2', 'sg1'] 写入 8 条凭证 (跳过一致指纹 34 条)",
114
+ "error": None
115
+ }
116
+ ```
117
+
118
+ ---
78
119
 
79
- #### (3) 单源广播同步 (例如将本机状态推送到所有云端节点)
120
+ ### 3. 轻量静态探针(无需实例化集群)
121
+ 单点探测某个节点时,直接 1 行静态调用:
80
122
  ```python
81
123
  from chromium_sync import ChromiumSync
82
124
 
83
- syncer = ChromiumSync(
84
- nodes=[
85
- {"id": "local", "cdp_port": 9222},
86
- {"id": "node_a", "ssh_host": "10.0.0.1", "cdp_port": 9222},
87
- {"id": "node_b", "ssh_host": "10.0.0.2", "cdp_port": 9222}
88
- ],
89
- mode="sync",
90
- source="local"
91
- )
92
- syncer.run()
125
+ # 1. 单点探测节点在线状态与页面信息
126
+ info = ChromiumSync.probe(port=9222)
127
+ print(info)
128
+ # {'online': True, 'cookie_count': 42, 'page_title': 'GitHub', 'page_url': 'https://github.com', ...}
129
+
130
+ # 2. 单点直接提取 Cookie (支持域名过滤)
131
+ cookies = ChromiumSync.get_cookies(port=9222, include_domains=["github.com"])
132
+
133
+ # 3. 单点写入 Cookie 并启用差量检测
134
+ ChromiumSync.set_cookies(cookies, port=9223, reload=True, diff=True)
93
135
  ```
94
136
 
95
137
  ---
96
138
 
97
- ### 2. 命令行 (CLI) 快速执行
139
+ ### 4. 导出顶级独立纯函数工具
140
+ 即使没有运行中的 CDP 浏览器,亦可使用顶级导出的纯函数对 Cookie 结构做离线处理:
141
+ ```python
142
+ from chromium_sync import merge_cookies, filter_cookies, compute_cookie_delta
143
+
144
+ raw_cookies = [
145
+ {"name": "token", "value": "val1", "domain": ".github.com", "path": "/", "expires": 1700000000},
146
+ {"name": "_ad", "value": "track", "domain": ".doubleclick.net", "path": "/", "expires": 1700000000}
147
+ ]
148
+
149
+ # 1. 独立过滤域名
150
+ filtered = filter_cookies(raw_cookies, include_domains=["github.com"])
151
+
152
+ # 2. 独立比对两组 Cookie 差量
153
+ delta, skipped = compute_cookie_delta(incoming_cookies=filtered, existing_cookies=[])
154
+
155
+ # 3. 多端 Cookie 离线融合 (优先保留最新过期时间)
156
+ merged = merge_cookies([[c1, c2], [c3]])
157
+ ```
158
+
159
+ ---
98
160
 
99
- #### (1) 终端直接传入多个节点 (内联精简语法)
161
+ ### 5. 命令行 (CLI) 快速执行
162
+
163
+ #### (1) 带域名过滤与差量比对的同步
100
164
  ```bash
101
- # 智能合并多节点最新 Cookie
102
165
  chromium-sync \
103
- --node id=local,port=9223 \
104
- --node id=kr2,ssh=root@kr2.wimotek.com,port=9222,key=~/.ssh/id_rsa \
105
- --node id=sg1,ssh=ubuntu@sg1.wimotek.com,port=9222,pass=SecretPassword \
166
+ --config cluster.json \
167
+ --include-domains google.com github.com twitter.com \
168
+ --exclude-domains doubleclick.net google-analytics.com \
106
169
  --mode merge
107
170
  ```
108
171
 
109
- #### (2) 仅查看状态与 Cookie 统计 (ASCII 报表)
172
+ #### (2) 仅查看过滤后的节点状态表格 (ASCII 报表)
110
173
  ```bash
111
174
  chromium-sync \
112
- --node id=local,port=9223 \
113
- --node id=kr2,ssh=root@kr2.wimotek.com,port=9222,key=~/.ssh/id_rsa \
175
+ --config cluster.json \
176
+ --include-domains google.com github.com \
114
177
  --status
115
178
  ```
116
179
  输出样例:
117
180
  ```text
118
- ==========================================================================================
119
- 节点 ID | 节点名称 | 类型 | CDP端口/映射 | Cookie数 | 当前页面状态
120
- ------------------------------------------------------------------------------------------
121
- local | 本地容器 | 本地直连 | 9223 | 42 条 | [Google] https://google.com
122
- kr2 | 韩国节点 | SSH远程 | 19222 | 38 条 | [GitHub] https://github.com
123
- ==========================================================================================
181
+ ============================================================================================
182
+ 节点 ID | 节点名称 | 类型 | CDP端口/映射 | Cookie有效数 | 当前页面状态
183
+ --------------------------------------------------------------------------------------------
184
+ local | 本地容器 | 本地直连 | 9223 | 18 条 | [GitHub] https://github.com
185
+ kr2 | 韩国生产服 | SSH远程 | 19222 | 16 条 | [Google] https://google.com
186
+ --------------------------------------------------------------------------------------------
187
+ 过滤规则: [白名单: google.com, github.com]
188
+ ============================================================================================
124
189
  ```
125
190
 
126
- #### (3) 导出 Cookie 详情为 JSON (便于程序与定时脚本直接提取)
191
+ #### (3) 导出指标 JSON (供 CI/CD 或自动化运维捕获)
127
192
  ```bash
128
- chromium-sync --config cluster.json --status --json > /tmp/cluster_cookies.json
193
+ chromium-sync --config cluster.json --mode merge --json
129
194
  ```
130
195
 
131
- #### (4) 使用 JSON 配置文件运行集群同步
132
- 准备配置文件 `cluster.json`:
133
- ```json
134
- [
135
- { "id": "local", "name": "本地开发机", "cdp_port": 9222 },
136
- { "id": "sg1", "name": "新加坡服", "ssh_host": "sg.host.com", "ssh_user": "ubuntu", "ssh_key_path": "~/.ssh/id_rsa", "cdp_port": 9222 },
137
- { "id": "kr2", "name": "韩国服", "ssh_host": "kr.host.com", "ssh_user": "root", "ssh_password": "SafePassword123", "cdp_port": 9222 }
138
- ]
139
- ```
140
- 单源广播或合并:
196
+ #### (4) 命令行内联多节点语法
141
197
  ```bash
142
- # 合并所有节点最新有效凭据
143
- chromium-sync --config cluster.json --mode merge
144
-
145
- # 本地向所有云端广播
146
- chromium-sync --config cluster.json --mode sync --source local
198
+ chromium-sync \
199
+ --node id=local,port=9223 \
200
+ --node id=kr2,ssh=root@kr2.wimotek.com,port=9222,key=~/.ssh/id_rsa \
201
+ --node id=sg1,ssh=ubuntu@sg1.wimotek.com,port=9222,pass=SecretPassword \
202
+ --mode merge
147
203
  ```
148
204
 
149
205
  ---
150
206
 
151
- ## ⚙️ 节点配置字段规范 (NodeConfig)
207
+ ## ⚙️ 核心参数与配置规范
208
+
209
+ ### `cluster.json` 配置文件结构
210
+ ```json
211
+ [
212
+ {
213
+ "id": "local",
214
+ "name": "本机容器",
215
+ "cdp_port": 9222
216
+ },
217
+ {
218
+ "id": "kr2",
219
+ "name": "韩国服",
220
+ "ssh_host": "kr2.wimotek.com",
221
+ "ssh_port": 22,
222
+ "ssh_user": "root",
223
+ "ssh_key": "-----BEGIN RSA PRIVATE KEY-----\n...\n-----END RSA PRIVATE KEY-----",
224
+ "cdp_port": 9222
225
+ },
226
+ {
227
+ "id": "sg1",
228
+ "name": "新加坡服",
229
+ "ssh_host": "sg1.wimotek.com",
230
+ "ssh_user": "ubuntu",
231
+ "ssh_password": "Password123",
232
+ "cdp_port": 9222
233
+ }
234
+ ]
235
+ ```
236
+
237
+ ### `ChromiumSync` 初始化参数
152
238
 
153
- | 字段 | 类型 | 默认值 | 详细说明 |
239
+ | 参数字段 | 类型 | 默认值 | 详细说明 |
154
240
  | :--- | :--- | :--- | :--- |
155
- | `id` | str | 必填 | 节点唯一标识符 (例如 `local`, `sg1`, `kr2`) |
156
- | `name` | str | `id` | 节点显示名称 |
157
- | `is_local` | bool | 自动识别 | 是否为本地节点 (不填 `ssh_host` 或填回环地址自动为 True,免密直连) |
158
- | `cdp_host` | str | `127.0.0.1` | 节点 CDP 服务监听的主机地址 |
159
- | `cdp_port` | int | `9222` | 节点暴露的 CDP 端口 |
160
- | `ssh_host` | str | `None` | 远程服务器 IP 或主机名 (提供该字段时识别为远程 SSH 节点) |
161
- | `ssh_port` | int | `22` | 远程服务器 SSH 端口 |
162
- | `ssh_user` | str | `root` | 远程 SSH 用户名 |
163
- | `ssh_key_path` | str | `None` | SSH 私钥文件路径 (例如 `~/.ssh/id_rsa`) |
164
- | `ssh_key_data` | str | `None` | SSH 私钥内容字符串 |
165
- | `ssh_password` | str | `None` | SSH 登录密码 (无外部依赖纯原生环境自动适配) |
166
- | `tunnel_port` | int | 自动分配 | 本地用于映射隧道的端口 (集群环境下自动递增分配防冲突) |
241
+ | `nodes` | list | 必填 | 节点配置列表 (支持 `NodeConfig` 或 dict) |
242
+ | `mode` | str | `'sync'` | 同步策略: `'merge'`(全端融合最新凭证) 或 `'sync'`(单源广播) |
243
+ | `include_domains` | list | `None` | **域名白名单**:仅同步匹配列表的 Cookie (如 `['google.com']`) |
244
+ | `exclude_domains` | list | `None` | **域名黑名单**:排除广告/统计类 Cookie (如 `['doubleclick.net']`) |
245
+ | `diff` | bool | `True` | **指纹差量同步**:相同凭据跳过写入,避免频繁刷盘并保护磁盘 IO |
246
+ | `source` | str | 第一个节点 | `'sync'` 模式下的源节点 ID |
247
+ | `targets` | list | 其余节点 | `'sync'` 模式下的目标节点 ID 列表 |
248
+ | `ssh_key` | str | `None` | 集群默认 SSH 私钥 (支持私钥文件绝对路径 或 私钥 PEM 文本内容) |
249
+ | `ssh_password` | str | `None` | 集群默认 SSH 密码认证 |
250
+ | `auto_close_tunnel` | bool | `False` | 任务完成后是否自动关闭创建的 SSH 隧道 |
251
+ | `verbose` | bool | `True` | 是否输出详细调度日志 |
167
252
 
168
253
  ---
169
254
 
170
- ## 🤖 定时任务配置示例 (Crontab)
255
+ ## 📚 模块导出接口一览 (`__all__`)
171
256
 
172
- 配合 Linux Crontab,每天凌晨定时执行全节点凭证智能融合:
173
- ```bash
174
- crontab -e
175
- # 每天凌晨 3:00 自动融合多节点最新有效凭证并释放隧道
176
- 0 3 * * * /usr/local/bin/chromium-sync --config /etc/chromium/cluster.json --mode merge --auto-close >> /var/log/chromium_sync.log 2>&1
257
+ ```python
258
+ from chromium_sync import (
259
+ ChromiumSync, # 主集群调度器与连接池上下文
260
+ NodeConfig, # 统一节点配置数据类
261
+ merge_cookies, # 多节点 Cookie 智能融合纯函数
262
+ filter_cookies, # 域名白名单/黑名单过滤纯函数
263
+ compute_cookie_delta # Cookie 指纹变更差量计算纯函数
264
+ )
177
265
  ```
178
266
 
179
267
  ---
@@ -2,7 +2,7 @@
2
2
  wimotek-chromium-sync Package
3
3
  Universal Chromium Session & Cookie Synchronizer with SSH Tunnel and Cluster Support
4
4
  """
5
- from .core import ChromiumSync, NodeConfig, merge_cookies
5
+ from .core import ChromiumSync, NodeConfig, merge_cookies, filter_cookies, compute_cookie_delta
6
6
 
7
- __version__ = "1.1.0"
8
- __all__ = ["ChromiumSync", "NodeConfig", "merge_cookies"]
7
+ __version__ = "1.3.0"
8
+ __all__ = ["ChromiumSync", "NodeConfig", "merge_cookies", "filter_cookies", "compute_cookie_delta"]
@@ -53,7 +53,7 @@ def parse_node_str(val: str) -> dict:
53
53
  elif k in ("user", "ssh_user"):
54
54
  res["ssh_user"] = v
55
55
  elif k in ("key", "ssh_key", "ssh_key_path"):
56
- res["ssh_key_path"] = v
56
+ res["ssh_key"] = v
57
57
  elif k in ("pass", "password", "ssh_pass", "ssh_password"):
58
58
  res["ssh_password"] = v
59
59
  elif k in ("id", "name"):
@@ -72,23 +72,20 @@ def main():
72
72
  formatter_class=argparse.RawDescriptionHelpFormatter,
73
73
  epilog="""
74
74
  使用示例:
75
- # 1. 快速查看节点状态与 Cookie 数量 (ASCII 表格)
75
+ # 1. 过滤仅同步指定业务域名 (如 google, twitter, github)
76
+ chromium-sync --config cluster.json --include-domains google.com twitter.com github.com --mode merge
77
+
78
+ # 2. 排除广告/统计类无关域名 (如 doubleclick, google-analytics)
79
+ chromium-sync --config cluster.json --exclude-domains doubleclick.net google-analytics.com --mode merge
80
+
81
+ # 3. 快速查看过滤后的节点状态与 Cookie 数量 (ASCII 表格)
76
82
  chromium-sync --node id=local,port=9222 --node id=kr2,ssh=root@kr2.wimotek.com,port=9222,key=~/.ssh/id_rsa --status
77
83
 
78
- # 2. 导出节点状态与 Cookie 详情为 JSON (便于程序直接提取 Cookie 列表)
84
+ # 4. 导出节点状态与 Cookie 详情为 JSON (便于程序直接提取 Cookie 列表)
79
85
  chromium-sync --config cluster.json --status --json
80
86
 
81
- # 3. 全节点 Cookie 智能 Merge (合并所有节点并保留最新有效期)
87
+ # 5. 全节点 Cookie 智能 Merge (合并所有节点并保留最新有效期,默认启用指纹差量 Diff)
82
88
  chromium-sync --config cluster.json --mode merge
83
-
84
- # 4. 指定单源节点广播同步到所有其他节点
85
- chromium-sync --config cluster.json --mode sync --source local
86
-
87
- # 5. 极简命令行多节点直接同步
88
- chromium-sync \\
89
- --node id=local,port=9223 \\
90
- --node id=kr2,ssh=root@kr2.wimotek.com,port=9222,key=~/.ssh/id_rsa \\
91
- --mode merge
92
89
  """
93
90
  )
94
91
 
@@ -97,6 +94,19 @@ def main():
97
94
  parser.add_argument("--node", action="append", default=[], help="定义节点 (可多次传入,如 id=local,port=9222)")
98
95
  parser.add_argument("--nodes", help="JSON 数组格式的节点配置字符串")
99
96
 
97
+ # 全局默认 SSH 凭据
98
+ parser.add_argument("--ssh-key", help="集群默认 SSH 私钥 (支持私钥文件绝对路径 或 私钥 PEM 文本内容)")
99
+ parser.add_argument("--ssh-password", help="集群默认 SSH 连接密码")
100
+
101
+ # 域名过滤机制
102
+ parser.add_argument("--include-domains", nargs="*", default=None,
103
+ help="域名白名单过滤列表 (如: google.com twitter.com github.com)")
104
+ parser.add_argument("--exclude-domains", nargs="*", default=None,
105
+ help="域名黑名单过滤列表 (如: doubleclick.net google-analytics.com)")
106
+
107
+ # 差量写入策略
108
+ parser.add_argument("--no-diff", action="store_true", help="禁用指纹差量检测,强制全量覆写目标节点 Cookie")
109
+
100
110
  # 同步模式
101
111
  parser.add_argument("--mode", choices=["sync", "merge"], default="sync",
102
112
  help="同步方式: 'merge'(合并所有节点最新Cookie), 'sync'(单源广播同步,默认)")
@@ -105,7 +115,7 @@ def main():
105
115
 
106
116
  # 探测与数据查询
107
117
  parser.add_argument("--status", action="store_true", help="仅探测并输出各节点的 Cookie 数与详情表格,不执行写入")
108
- parser.add_argument("--json", action="store_true", help="以 JSON 格式输出节点完整数据与 Cookie 列表")
118
+ parser.add_argument("--json", action="store_true", help="以 JSON 格式输出节点数据或执行结果指标")
109
119
 
110
120
  # 隧道与连接
111
121
  parser.add_argument("--auto-close", action="store_true", help="任务完成后关闭拉起的 SSH 隧道")
@@ -139,6 +149,11 @@ def main():
139
149
  mode=args.mode,
140
150
  source=args.source,
141
151
  targets=args.targets,
152
+ include_domains=args.include_domains,
153
+ exclude_domains=args.exclude_domains,
154
+ diff=(not args.no_diff),
155
+ ssh_key=args.ssh_key,
156
+ ssh_password=args.ssh_password,
142
157
  auto_close_tunnel=args.auto_close,
143
158
  verbose=args.verbose
144
159
  )
@@ -151,7 +166,9 @@ def main():
151
166
  print(syncer.get_summary_table(report))
152
167
  return
153
168
 
154
- syncer.run()
169
+ result = syncer.run()
170
+ if args.json:
171
+ print(json.dumps(result, ensure_ascii=False, indent=2))
155
172
 
156
173
 
157
174
  if __name__ == "__main__":