mailops 0.2.4__tar.gz → 0.2.5__tar.gz
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.
- {mailops-0.2.4 → mailops-0.2.5}/PKG-INFO +3 -2
- {mailops-0.2.4 → mailops-0.2.5}/README.md +2 -1
- {mailops-0.2.4 → mailops-0.2.5}/pyproject.toml +1 -1
- {mailops-0.2.4 → mailops-0.2.5}/src/mailops.egg-info/PKG-INFO +3 -2
- {mailops-0.2.4 → mailops-0.2.5}/src/mailops.egg-info/SOURCES.txt +1 -0
- {mailops-0.2.4 → mailops-0.2.5}/src/mailops.egg-info/top_level.txt +1 -0
- {mailops-0.2.4 → mailops-0.2.5}/src/sync163.py +37 -32
- mailops-0.2.5/src/sync_account.py +240 -0
- {mailops-0.2.4 → mailops-0.2.5}/setup.cfg +0 -0
- {mailops-0.2.4 → mailops-0.2.5}/src/maildl.py +0 -0
- {mailops-0.2.4 → mailops-0.2.5}/src/mailfwd.py +0 -0
- {mailops-0.2.4 → mailops-0.2.5}/src/mailops/__init__.py +0 -0
- {mailops-0.2.4 → mailops-0.2.5}/src/mailops/backend/__init__.py +0 -0
- {mailops-0.2.4 → mailops-0.2.5}/src/mailops/backend/imap.py +0 -0
- {mailops-0.2.4 → mailops-0.2.5}/src/mailops/backend/maildir.py +0 -0
- {mailops-0.2.4 → mailops-0.2.5}/src/mailops/cli.py +0 -0
- {mailops-0.2.4 → mailops-0.2.5}/src/mailops/config.py +0 -0
- {mailops-0.2.4 → mailops-0.2.5}/src/mailops/downloader.py +0 -0
- {mailops-0.2.4 → mailops-0.2.5}/src/mailops/forwarder.py +0 -0
- {mailops-0.2.4 → mailops-0.2.5}/src/mailops/operations.py +0 -0
- {mailops-0.2.4 → mailops-0.2.5}/src/mailops/organizer.py +0 -0
- {mailops-0.2.4 → mailops-0.2.5}/src/mailops/sync.py +0 -0
- {mailops-0.2.4 → mailops-0.2.5}/src/mailops/workflow.py +0 -0
- {mailops-0.2.4 → mailops-0.2.5}/src/mailops.egg-info/dependency_links.txt +0 -0
- {mailops-0.2.4 → mailops-0.2.5}/src/mailops.egg-info/entry_points.txt +0 -0
- {mailops-0.2.4 → mailops-0.2.5}/src/mailops.egg-info/requires.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mailops
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.5
|
|
4
4
|
Summary: 邮件操作工具箱 — 下载、统计、搜索、转发、附件管理、发送
|
|
5
5
|
Author: Song Wupei
|
|
6
6
|
License-Expression: MIT
|
|
@@ -186,7 +186,8 @@ accounts:
|
|
|
186
186
|
|--------|--------|
|
|
187
187
|
| `maildl.py` | `mailops download-docs` |
|
|
188
188
|
| `mailfwd.py` | `mailops forward` |
|
|
189
|
-
| `sync163.py` | `
|
|
189
|
+
| `sync163.py` | `sync_account.py 163` (IMAP → Maildir,索引去重) + `mailops organize` |
|
|
190
|
+
| `mbsync` | `sync_account.py QQ` (IMAP → Maildir,索引去重,本地删除不重下) |
|
|
190
191
|
| `sync163.py` | `mailops fetch -m 163` |
|
|
191
192
|
| `run-wf.py` | `mailops workflow` |
|
|
192
193
|
| `mailx` (系统命令) | `mailops send` |
|
|
@@ -165,7 +165,8 @@ accounts:
|
|
|
165
165
|
|--------|--------|
|
|
166
166
|
| `maildl.py` | `mailops download-docs` |
|
|
167
167
|
| `mailfwd.py` | `mailops forward` |
|
|
168
|
-
| `sync163.py` | `
|
|
168
|
+
| `sync163.py` | `sync_account.py 163` (IMAP → Maildir,索引去重) + `mailops organize` |
|
|
169
|
+
| `mbsync` | `sync_account.py QQ` (IMAP → Maildir,索引去重,本地删除不重下) |
|
|
169
170
|
| `sync163.py` | `mailops fetch -m 163` |
|
|
170
171
|
| `run-wf.py` | `mailops workflow` |
|
|
171
172
|
| `mailx` (系统命令) | `mailops send` |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mailops
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.5
|
|
4
4
|
Summary: 邮件操作工具箱 — 下载、统计、搜索、转发、附件管理、发送
|
|
5
5
|
Author: Song Wupei
|
|
6
6
|
License-Expression: MIT
|
|
@@ -186,7 +186,8 @@ accounts:
|
|
|
186
186
|
|--------|--------|
|
|
187
187
|
| `maildl.py` | `mailops download-docs` |
|
|
188
188
|
| `mailfwd.py` | `mailops forward` |
|
|
189
|
-
| `sync163.py` | `
|
|
189
|
+
| `sync163.py` | `sync_account.py 163` (IMAP → Maildir,索引去重) + `mailops organize` |
|
|
190
|
+
| `mbsync` | `sync_account.py QQ` (IMAP → Maildir,索引去重,本地删除不重下) |
|
|
190
191
|
| `sync163.py` | `mailops fetch -m 163` |
|
|
191
192
|
| `run-wf.py` | `mailops workflow` |
|
|
192
193
|
| `mailx` (系统命令) | `mailops send` |
|
|
@@ -22,19 +22,23 @@ PASS_ENV = "MAIL163_SMTP_PASS_AERC"
|
|
|
22
22
|
|
|
23
23
|
|
|
24
24
|
def load_index():
|
|
25
|
-
"""加载已知 Message-ID
|
|
25
|
+
"""加载已知 Message-ID 集合。"""
|
|
26
26
|
if INDEX_FILE.exists():
|
|
27
27
|
try:
|
|
28
|
-
|
|
28
|
+
data = json.loads(INDEX_FILE.read_text())
|
|
29
|
+
# 兼容旧格式(dict → 取 keys;新格式是 list)
|
|
30
|
+
if isinstance(data, dict):
|
|
31
|
+
return set(data.keys())
|
|
32
|
+
return set(data)
|
|
29
33
|
except (json.JSONDecodeError, OSError):
|
|
30
34
|
pass
|
|
31
|
-
return
|
|
35
|
+
return set()
|
|
32
36
|
|
|
33
37
|
|
|
34
38
|
def save_index(idx):
|
|
35
|
-
"""
|
|
39
|
+
"""保存索引到磁盘(Message-ID 集合)。"""
|
|
36
40
|
INDEX_FILE.parent.mkdir(parents=True, exist_ok=True)
|
|
37
|
-
INDEX_FILE.write_text(json.dumps(idx))
|
|
41
|
+
INDEX_FILE.write_text(json.dumps(sorted(idx)))
|
|
38
42
|
|
|
39
43
|
|
|
40
44
|
def extract_message_id(msg_bytes):
|
|
@@ -55,23 +59,30 @@ def extract_message_id(msg_bytes):
|
|
|
55
59
|
|
|
56
60
|
|
|
57
61
|
def backfill_index(known):
|
|
58
|
-
"""首次运行:从已有 Maildir
|
|
62
|
+
"""首次运行:从已有 Maildir 文件重建索引(递归扫描所有子文件夹)。
|
|
63
|
+
|
|
64
|
+
不仅扫描 INBOX,也扫描 organize 移入的 GitHub/、Archive/ 等子文件夹。
|
|
65
|
+
"""
|
|
59
66
|
existing = 0
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
for
|
|
65
|
-
|
|
67
|
+
maildir_root = MAILDIR.parent # ~/Mail/163/
|
|
68
|
+
for maildir_root, dirs, files in os.walk(maildir_root):
|
|
69
|
+
# 跳过 tmp/ 目录
|
|
70
|
+
dirs[:] = [d for d in dirs if d != "tmp"]
|
|
71
|
+
for sub in ["cur", "new"]:
|
|
72
|
+
folder = Path(maildir_root) / sub
|
|
73
|
+
if not folder.is_dir():
|
|
66
74
|
continue
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
+
for fpath in folder.iterdir():
|
|
76
|
+
if not fpath.is_file() or fpath.name.startswith("."):
|
|
77
|
+
continue
|
|
78
|
+
try:
|
|
79
|
+
# 只读前 8KB 足以包含所有头部
|
|
80
|
+
mid = extract_message_id(fpath.read_bytes()[:8192])
|
|
81
|
+
if mid and mid not in known:
|
|
82
|
+
known.add(mid)
|
|
83
|
+
existing += 1
|
|
84
|
+
except OSError:
|
|
85
|
+
pass
|
|
75
86
|
if existing:
|
|
76
87
|
print(f"从本地 Maildir 重建索引: +{existing} 封")
|
|
77
88
|
return known
|
|
@@ -130,9 +141,9 @@ def sync(limit=None):
|
|
|
130
141
|
|
|
131
142
|
# ---- 先通过只下载 HEADER 来获取 Message-ID(轻量级) ----
|
|
132
143
|
# 批量获取所有邮件的 Message-ID,用于判断哪些是新的
|
|
133
|
-
ids =
|
|
144
|
+
ids = all_ids # 保持原始顺序(升序)
|
|
134
145
|
if limit:
|
|
135
|
-
ids = ids[-limit:]
|
|
146
|
+
ids = ids[-limit:] # 取最后 N 封(最新)
|
|
136
147
|
|
|
137
148
|
# 分批处理,每批 200 封
|
|
138
149
|
BATCH = 200
|
|
@@ -141,7 +152,9 @@ def sync(limit=None):
|
|
|
141
152
|
|
|
142
153
|
for i in range(0, len(ids), BATCH):
|
|
143
154
|
batch = ids[i : i + BATCH]
|
|
144
|
-
|
|
155
|
+
# 确保范围升序(min:max),修复倒序范围导致 163 返回异常
|
|
156
|
+
nums = sorted(int(x) for x in batch)
|
|
157
|
+
id_range = f"{nums[0]}:{nums[-1]}"
|
|
145
158
|
status, hdr_data = conn.fetch(
|
|
146
159
|
id_range, "(BODY.PEEK[HEADER.FIELDS (MESSAGE-ID)])"
|
|
147
160
|
)
|
|
@@ -190,7 +203,7 @@ def sync(limit=None):
|
|
|
190
203
|
fpath.write_bytes(msg_bytes)
|
|
191
204
|
|
|
192
205
|
# 更新索引
|
|
193
|
-
known
|
|
206
|
+
known.add(msg_id)
|
|
194
207
|
|
|
195
208
|
new_count += 1
|
|
196
209
|
# 快速预览主题
|
|
@@ -208,14 +221,6 @@ def sync(limit=None):
|
|
|
208
221
|
# ---- 保存索引 ----
|
|
209
222
|
save_index(known)
|
|
210
223
|
|
|
211
|
-
# ---- 清理索引中已经不存在的文件 ----
|
|
212
|
-
stale = [mid for mid, fname in known.items() if not (MAILDIR / "new" / fname).exists() and not (MAILDIR / "cur" / fname).exists()]
|
|
213
|
-
if stale:
|
|
214
|
-
for mid in stale:
|
|
215
|
-
del known[mid]
|
|
216
|
-
save_index(known)
|
|
217
|
-
print(f" (清理了 {len(stale)} 条过期索引记录)")
|
|
218
|
-
|
|
219
224
|
print(f"\n同步完成,新增 {new_count} 封 → {MAILDIR}")
|
|
220
225
|
|
|
221
226
|
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""IMAP → Maildir 同步(通用版,索引去重,支持 163/QQ 等)。
|
|
3
|
+
|
|
4
|
+
用法: python3 sync_account.py 163
|
|
5
|
+
python3 sync_account.py QQ --limit 50
|
|
6
|
+
python3 sync_account.py 163 --limit 10
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import imaplib
|
|
10
|
+
import json
|
|
11
|
+
import os
|
|
12
|
+
import re
|
|
13
|
+
import ssl
|
|
14
|
+
import sys
|
|
15
|
+
import time
|
|
16
|
+
from pathlib import Path
|
|
17
|
+
|
|
18
|
+
# ---- 账号配置 ----
|
|
19
|
+
ACCOUNTS = {
|
|
20
|
+
"163": {
|
|
21
|
+
"host": "imap.163.com",
|
|
22
|
+
"user": "songwupei@163.com",
|
|
23
|
+
"pass_file": Path.home() / ".config" / "aerc" / "163-pass",
|
|
24
|
+
"maildir": Path.home() / "Mail" / "163" / "INBOX",
|
|
25
|
+
"need_id": True, # 163 需要 IMAP ID 命令
|
|
26
|
+
},
|
|
27
|
+
"QQ": {
|
|
28
|
+
"host": "imap.qq.com",
|
|
29
|
+
"user": "songwupei@qq.com",
|
|
30
|
+
"pass_file": Path.home() / ".config" / "aerc" / "qq-pass",
|
|
31
|
+
"maildir": Path.home() / "Mail" / "QQ" / "INBOX",
|
|
32
|
+
"need_id": False,
|
|
33
|
+
},
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
CACHE_DIR = Path.home() / ".cache" / "aerc"
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def index_path(account: str) -> Path:
|
|
40
|
+
return CACHE_DIR / f"sync-{account}-index.json"
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def load_index(account: str) -> set:
|
|
44
|
+
path = index_path(account)
|
|
45
|
+
if path.exists():
|
|
46
|
+
try:
|
|
47
|
+
data = json.loads(path.read_text())
|
|
48
|
+
if isinstance(data, dict):
|
|
49
|
+
return set(data.keys())
|
|
50
|
+
return set(data)
|
|
51
|
+
except (json.JSONDecodeError, OSError):
|
|
52
|
+
pass
|
|
53
|
+
return set()
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def save_index(account: str, idx: set):
|
|
57
|
+
path = index_path(account)
|
|
58
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
59
|
+
path.write_text(json.dumps(sorted(idx)))
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def extract_message_id(msg_bytes):
|
|
63
|
+
"""从邮件字节中快速提取 Message-ID。"""
|
|
64
|
+
header_end = msg_bytes.find(b"\r\n\r\n")
|
|
65
|
+
if header_end == -1:
|
|
66
|
+
header_end = msg_bytes.find(b"\n\n")
|
|
67
|
+
if header_end == -1:
|
|
68
|
+
header_end = len(msg_bytes)
|
|
69
|
+
header = msg_bytes[:header_end].decode("utf-8", errors="replace")
|
|
70
|
+
m = re.search(r"(?im)^Message-ID:\s*(.+)", header)
|
|
71
|
+
if m:
|
|
72
|
+
return m.group(1).strip().strip("<>")
|
|
73
|
+
return None
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def backfill_index(maildir: Path, known: set) -> set:
|
|
77
|
+
"""从已有 Maildir 递归重建索引。"""
|
|
78
|
+
existing = 0
|
|
79
|
+
root = maildir.parent # ~/Mail/<account>/
|
|
80
|
+
if not root.is_dir():
|
|
81
|
+
return known
|
|
82
|
+
for walk_root, dirs, files in os.walk(root):
|
|
83
|
+
dirs[:] = [d for d in dirs if d != "tmp"]
|
|
84
|
+
for sub in ["cur", "new"]:
|
|
85
|
+
folder = Path(walk_root) / sub
|
|
86
|
+
if not folder.is_dir():
|
|
87
|
+
continue
|
|
88
|
+
for fpath in folder.iterdir():
|
|
89
|
+
if not fpath.is_file() or fpath.name.startswith("."):
|
|
90
|
+
continue
|
|
91
|
+
try:
|
|
92
|
+
mid = extract_message_id(fpath.read_bytes()[:8192])
|
|
93
|
+
if mid and mid not in known:
|
|
94
|
+
known.add(mid)
|
|
95
|
+
existing += 1
|
|
96
|
+
except OSError:
|
|
97
|
+
pass
|
|
98
|
+
if existing:
|
|
99
|
+
print(f" 从本地 Maildir 重建索引: +{existing} 封")
|
|
100
|
+
return known
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def sync(account: str, limit: int = None):
|
|
104
|
+
cfg = ACCOUNTS.get(account)
|
|
105
|
+
if not cfg:
|
|
106
|
+
print(f"错误: 未知账号 '{account}',可用: {', '.join(ACCOUNTS)}")
|
|
107
|
+
sys.exit(1)
|
|
108
|
+
|
|
109
|
+
host = cfg["host"]
|
|
110
|
+
user = cfg["user"]
|
|
111
|
+
maildir = cfg["maildir"]
|
|
112
|
+
pass_file = cfg["pass_file"]
|
|
113
|
+
need_id = cfg.get("need_id", False)
|
|
114
|
+
|
|
115
|
+
# ---- 密码 ----
|
|
116
|
+
if pass_file.exists():
|
|
117
|
+
password = pass_file.read_text().strip()
|
|
118
|
+
else:
|
|
119
|
+
print(f"错误: 密码文件不存在: {pass_file}")
|
|
120
|
+
sys.exit(1)
|
|
121
|
+
if not password:
|
|
122
|
+
print(f"错误: 密码为空: {pass_file}")
|
|
123
|
+
sys.exit(1)
|
|
124
|
+
|
|
125
|
+
# ---- 初始化 Maildir ----
|
|
126
|
+
for sub in ["cur", "new", "tmp"]:
|
|
127
|
+
(maildir / sub).mkdir(parents=True, exist_ok=True)
|
|
128
|
+
|
|
129
|
+
# ---- 加载/重建索引 ----
|
|
130
|
+
known = load_index(account)
|
|
131
|
+
if not known:
|
|
132
|
+
known = backfill_index(maildir, known)
|
|
133
|
+
save_index(account, known)
|
|
134
|
+
|
|
135
|
+
print(f"[{account}] 服务器连接中...")
|
|
136
|
+
|
|
137
|
+
# ---- 连接 ----
|
|
138
|
+
ctx = ssl.create_default_context()
|
|
139
|
+
with imaplib.IMAP4_SSL(host, 993, ssl_context=ctx) as conn:
|
|
140
|
+
conn.login(user, password)
|
|
141
|
+
|
|
142
|
+
# 163.com 必须的 ID 命令
|
|
143
|
+
if need_id:
|
|
144
|
+
try:
|
|
145
|
+
conn.socket().send(
|
|
146
|
+
b'a001 ID ("name" "mail-dl" "version" "1.0")\r\n'
|
|
147
|
+
)
|
|
148
|
+
conn.socket().recv(1024)
|
|
149
|
+
except Exception:
|
|
150
|
+
pass
|
|
151
|
+
|
|
152
|
+
conn.select("INBOX")
|
|
153
|
+
status, data = conn.search(None, "ALL")
|
|
154
|
+
if status != "OK":
|
|
155
|
+
print(" 搜索失败")
|
|
156
|
+
return
|
|
157
|
+
|
|
158
|
+
all_ids = data[0].split()
|
|
159
|
+
if not all_ids:
|
|
160
|
+
print(" 收件箱为空")
|
|
161
|
+
return
|
|
162
|
+
|
|
163
|
+
total = len(all_ids)
|
|
164
|
+
print(f" 服务器 {total} 封,索引 {len(known)} 封")
|
|
165
|
+
|
|
166
|
+
ids = all_ids
|
|
167
|
+
if limit:
|
|
168
|
+
ids = ids[-limit:]
|
|
169
|
+
|
|
170
|
+
BATCH = 200
|
|
171
|
+
to_fetch = []
|
|
172
|
+
seen_msgids = set()
|
|
173
|
+
|
|
174
|
+
for i in range(0, len(ids), BATCH):
|
|
175
|
+
batch = ids[i : i + BATCH]
|
|
176
|
+
nums = sorted(int(x) for x in batch)
|
|
177
|
+
id_range = f"{nums[0]}:{nums[-1]}"
|
|
178
|
+
status, hdr_data = conn.fetch(
|
|
179
|
+
id_range, "(BODY.PEEK[HEADER.FIELDS (MESSAGE-ID)])"
|
|
180
|
+
)
|
|
181
|
+
if status != "OK":
|
|
182
|
+
continue
|
|
183
|
+
|
|
184
|
+
for item in hdr_data:
|
|
185
|
+
if isinstance(item, tuple):
|
|
186
|
+
header_bytes = item[1]
|
|
187
|
+
if header_bytes:
|
|
188
|
+
msg_id = extract_message_id(header_bytes)
|
|
189
|
+
if msg_id and msg_id not in known and msg_id not in seen_msgids:
|
|
190
|
+
marker = item[0].decode() if isinstance(
|
|
191
|
+
item[0], bytes
|
|
192
|
+
) else str(item[0])
|
|
193
|
+
m = re.match(r"(\d+)", marker)
|
|
194
|
+
if m:
|
|
195
|
+
to_fetch.append((m.group(1).encode(), msg_id))
|
|
196
|
+
seen_msgids.add(msg_id)
|
|
197
|
+
|
|
198
|
+
new_count = 0
|
|
199
|
+
for num_bytes, msg_id in to_fetch:
|
|
200
|
+
status, msg_data = conn.fetch(num_bytes, "(RFC822)")
|
|
201
|
+
if status != "OK":
|
|
202
|
+
continue
|
|
203
|
+
|
|
204
|
+
msg_bytes = msg_data[0][1]
|
|
205
|
+
if msg_bytes is None:
|
|
206
|
+
continue
|
|
207
|
+
|
|
208
|
+
ts = int(time.time())
|
|
209
|
+
fname = f"{ts}.{num_bytes.decode()}.{new_count}.{os.uname().nodename}"
|
|
210
|
+
fpath = maildir / "new" / fname
|
|
211
|
+
fpath.write_bytes(msg_bytes)
|
|
212
|
+
|
|
213
|
+
known.add(msg_id)
|
|
214
|
+
new_count += 1
|
|
215
|
+
|
|
216
|
+
subject = "(无主题)"
|
|
217
|
+
try:
|
|
218
|
+
s = re.search(rb"(?im)^Subject:\s*(.+)", msg_bytes[:4096])
|
|
219
|
+
if s:
|
|
220
|
+
subject = s.group(1).decode("utf-8", errors="replace").strip()
|
|
221
|
+
except Exception:
|
|
222
|
+
pass
|
|
223
|
+
print(f" [{new_count}] {subject}")
|
|
224
|
+
|
|
225
|
+
save_index(account, known)
|
|
226
|
+
print(f" 完成,新增 {new_count} 封\n")
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
if __name__ == "__main__":
|
|
230
|
+
if len(sys.argv) < 2:
|
|
231
|
+
print(f"用法: python3 sync_account.py <163|QQ> [--limit N]")
|
|
232
|
+
print(f"可用账号: {', '.join(ACCOUNTS)}")
|
|
233
|
+
sys.exit(1)
|
|
234
|
+
|
|
235
|
+
account = sys.argv[1]
|
|
236
|
+
limit = None
|
|
237
|
+
if len(sys.argv) > 2 and sys.argv[2] == "--limit":
|
|
238
|
+
limit = int(sys.argv[3]) if len(sys.argv) > 3 else 50
|
|
239
|
+
|
|
240
|
+
sync(account, limit)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|