pixelarraylib 1.0.0__py3-none-any.whl
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.
- arraylib/__init__.py +36 -0
- arraylib/__main__.py +126 -0
- arraylib/aliyun/__init__.py +0 -0
- arraylib/aliyun/aliyun_email.py +130 -0
- arraylib/aliyun/billing.py +477 -0
- arraylib/aliyun/content_scanner.py +253 -0
- arraylib/aliyun/domain.py +434 -0
- arraylib/aliyun/eci.py +47 -0
- arraylib/aliyun/ecs.py +68 -0
- arraylib/aliyun/fc.py +142 -0
- arraylib/aliyun/oss.py +649 -0
- arraylib/aliyun/sms.py +59 -0
- arraylib/aliyun/sts.py +124 -0
- arraylib/db_utils/mysql.py +544 -0
- arraylib/db_utils/redis.py +373 -0
- arraylib/decorators/__init__.py +13 -0
- arraylib/decorators/decorators.py +194 -0
- arraylib/gitlab/__init__.py +0 -0
- arraylib/gitlab/code_analyzer.py +344 -0
- arraylib/gitlab/pypi_package_manager.py +61 -0
- arraylib/monitor/__init__.py +0 -0
- arraylib/monitor/feishu.py +132 -0
- arraylib/net/request.py +143 -0
- arraylib/scripts/__init__.py +22 -0
- arraylib/scripts/collect_code_to_txt.py +327 -0
- arraylib/scripts/create_test_case_files.py +100 -0
- arraylib/scripts/nginx_proxy_to_ecs.py +119 -0
- arraylib/scripts/remove_empty_lines.py +120 -0
- arraylib/scripts/summary_code_count.py +430 -0
- arraylib/system/__init__.py +0 -0
- arraylib/system/common.py +390 -0
- pixelarraylib-1.0.0.dist-info/METADATA +141 -0
- pixelarraylib-1.0.0.dist-info/RECORD +37 -0
- pixelarraylib-1.0.0.dist-info/WHEEL +5 -0
- pixelarraylib-1.0.0.dist-info/entry_points.txt +2 -0
- pixelarraylib-1.0.0.dist-info/licenses/LICENSE +21 -0
- pixelarraylib-1.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,430 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
每日提交代码行数统计脚本
|
|
4
|
+
该脚本用于统计Git仓库中master分支每天提交的代码行数,包括新增行数、删除行数和净变化行数
|
|
5
|
+
|
|
6
|
+
使用方法:
|
|
7
|
+
1. 作为命令行工具:
|
|
8
|
+
arraylib summary_code_count --since="2025-05-09"
|
|
9
|
+
arraylib summary_code_count --author="张三"
|
|
10
|
+
arraylib summary_code_count --output=stats.csv
|
|
11
|
+
arraylib summary_code_count --file-types="py,js,vue"
|
|
12
|
+
|
|
13
|
+
2. 作为Python模块:
|
|
14
|
+
from arraylib.scripts.summary_code_count import main
|
|
15
|
+
main()
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
import os
|
|
19
|
+
import subprocess
|
|
20
|
+
import argparse
|
|
21
|
+
from datetime import datetime, timedelta
|
|
22
|
+
from collections import defaultdict
|
|
23
|
+
import pandas as pd
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class GitCommitStatsAnalyzer:
|
|
27
|
+
def __init__(self, repo_path="."):
|
|
28
|
+
self.repo_path = repo_path
|
|
29
|
+
self.daily_stats = defaultdict(
|
|
30
|
+
lambda: {
|
|
31
|
+
"commits": 0,
|
|
32
|
+
"added_lines": 0,
|
|
33
|
+
"deleted_lines": 0,
|
|
34
|
+
"net_lines": 0,
|
|
35
|
+
"authors": set(),
|
|
36
|
+
"files_changed": 0,
|
|
37
|
+
}
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
def is_git_repo(self):
|
|
41
|
+
"""检查是否为git仓库"""
|
|
42
|
+
return os.path.exists(os.path.join(self.repo_path, ".git"))
|
|
43
|
+
|
|
44
|
+
def run_git_command(self, command):
|
|
45
|
+
"""执行git命令并返回结果"""
|
|
46
|
+
try:
|
|
47
|
+
result = subprocess.run(
|
|
48
|
+
command,
|
|
49
|
+
shell=True,
|
|
50
|
+
cwd=self.repo_path,
|
|
51
|
+
capture_output=True,
|
|
52
|
+
text=True,
|
|
53
|
+
check=True,
|
|
54
|
+
)
|
|
55
|
+
return result.stdout.strip()
|
|
56
|
+
except subprocess.CalledProcessError as e:
|
|
57
|
+
# 对于某些预期的错误(如第一个提交),不打印错误信息
|
|
58
|
+
if "unknown revision" in e.stderr or "ambiguous argument" in e.stderr:
|
|
59
|
+
return ""
|
|
60
|
+
else:
|
|
61
|
+
print(f"Git命令执行失败: {command}")
|
|
62
|
+
print(f"错误信息: {e.stderr}")
|
|
63
|
+
return ""
|
|
64
|
+
|
|
65
|
+
def get_commit_list(self, since_date=None, until_date=None, author=None):
|
|
66
|
+
"""获取master分支的提交列表"""
|
|
67
|
+
command = 'git log master --oneline --pretty=format:"%H|%ad|%an" --date=short'
|
|
68
|
+
|
|
69
|
+
if since_date:
|
|
70
|
+
command += f' --since="{since_date}"'
|
|
71
|
+
if until_date:
|
|
72
|
+
command += f' --until="{until_date}"'
|
|
73
|
+
if author:
|
|
74
|
+
command += f' --author="{author}"'
|
|
75
|
+
|
|
76
|
+
output = self.run_git_command(command)
|
|
77
|
+
commits = []
|
|
78
|
+
|
|
79
|
+
for line in output.split("\n"):
|
|
80
|
+
if line:
|
|
81
|
+
parts = line.split("|")
|
|
82
|
+
if len(parts) >= 3:
|
|
83
|
+
commit_hash = parts[0]
|
|
84
|
+
commit_date = parts[1]
|
|
85
|
+
commit_author = parts[2]
|
|
86
|
+
commits.append(
|
|
87
|
+
{
|
|
88
|
+
"hash": commit_hash,
|
|
89
|
+
"date": commit_date,
|
|
90
|
+
"author": commit_author,
|
|
91
|
+
}
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
return commits
|
|
95
|
+
|
|
96
|
+
def get_commit_stats(self, commit_hash, file_types=None):
|
|
97
|
+
"""获取单个提交的统计信息"""
|
|
98
|
+
# 首先检查是否有父提交
|
|
99
|
+
parent_check = self.run_git_command(f"git rev-parse {commit_hash}^ 2>/dev/null || echo 'NO_PARENT'")
|
|
100
|
+
|
|
101
|
+
if parent_check.strip() == "NO_PARENT":
|
|
102
|
+
# 这是第一个提交,没有父提交,使用空树作为比较基准
|
|
103
|
+
command = f"git diff --numstat 4b825dc642cb6eb9a060e54bf8d69288fbee4904 {commit_hash}"
|
|
104
|
+
else:
|
|
105
|
+
# 有父提交,正常比较
|
|
106
|
+
command = f"git diff --numstat {commit_hash}^..{commit_hash}"
|
|
107
|
+
|
|
108
|
+
output = self.run_git_command(command)
|
|
109
|
+
|
|
110
|
+
added_lines = 0
|
|
111
|
+
deleted_lines = 0
|
|
112
|
+
files_changed = 0
|
|
113
|
+
|
|
114
|
+
for line in output.split("\n"):
|
|
115
|
+
if line:
|
|
116
|
+
parts = line.split("\t")
|
|
117
|
+
if len(parts) >= 3:
|
|
118
|
+
try:
|
|
119
|
+
added = int(parts[0]) if parts[0] != "-" else 0
|
|
120
|
+
deleted = int(parts[1]) if parts[1] != "-" else 0
|
|
121
|
+
filename = parts[2]
|
|
122
|
+
|
|
123
|
+
# 如果指定了文件类型过滤
|
|
124
|
+
if file_types:
|
|
125
|
+
file_ext = filename.split(".")[-1].lower()
|
|
126
|
+
if file_ext not in file_types:
|
|
127
|
+
continue
|
|
128
|
+
|
|
129
|
+
added_lines += added
|
|
130
|
+
deleted_lines += deleted
|
|
131
|
+
files_changed += 1
|
|
132
|
+
except (ValueError, IndexError):
|
|
133
|
+
continue
|
|
134
|
+
|
|
135
|
+
return {
|
|
136
|
+
"added_lines": added_lines,
|
|
137
|
+
"deleted_lines": deleted_lines,
|
|
138
|
+
"net_lines": added_lines - deleted_lines,
|
|
139
|
+
"files_changed": files_changed,
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
def analyze_commits(
|
|
143
|
+
self, since_date=None, until_date=None, author=None, file_types=None
|
|
144
|
+
):
|
|
145
|
+
"""分析master分支的提交统计"""
|
|
146
|
+
if not self.is_git_repo():
|
|
147
|
+
print("错误:当前目录不是Git仓库")
|
|
148
|
+
return False
|
|
149
|
+
|
|
150
|
+
print("正在分析Git master分支的提交历史...")
|
|
151
|
+
commits = self.get_commit_list(since_date, until_date, author)
|
|
152
|
+
|
|
153
|
+
if not commits:
|
|
154
|
+
print("没有找到符合条件的提交")
|
|
155
|
+
return False
|
|
156
|
+
|
|
157
|
+
total_commits = len(commits)
|
|
158
|
+
print(f"找到 {total_commits} 个提交,正在统计...")
|
|
159
|
+
|
|
160
|
+
for i, commit in enumerate(commits):
|
|
161
|
+
# 显示进度
|
|
162
|
+
if i % 10 == 0 or i == total_commits - 1:
|
|
163
|
+
progress = (i + 1) / total_commits * 100
|
|
164
|
+
print(f"进度: {progress:.1f}% ({i + 1}/{total_commits})")
|
|
165
|
+
|
|
166
|
+
commit_date = commit["date"]
|
|
167
|
+
commit_author = commit["author"]
|
|
168
|
+
|
|
169
|
+
stats = self.get_commit_stats(commit["hash"], file_types)
|
|
170
|
+
|
|
171
|
+
# 累加到日统计
|
|
172
|
+
day_stats = self.daily_stats[commit_date]
|
|
173
|
+
day_stats["commits"] += 1
|
|
174
|
+
day_stats["added_lines"] += stats["added_lines"]
|
|
175
|
+
day_stats["deleted_lines"] += stats["deleted_lines"]
|
|
176
|
+
day_stats["net_lines"] += stats["net_lines"]
|
|
177
|
+
day_stats["authors"].add(commit_author)
|
|
178
|
+
day_stats["files_changed"] += stats["files_changed"]
|
|
179
|
+
|
|
180
|
+
print("分析完成!")
|
|
181
|
+
return True
|
|
182
|
+
|
|
183
|
+
def print_stats(self):
|
|
184
|
+
"""使用pandas DataFrame打印统计结果"""
|
|
185
|
+
if not self.daily_stats:
|
|
186
|
+
print("没有统计数据")
|
|
187
|
+
return
|
|
188
|
+
|
|
189
|
+
# 准备DataFrame数据
|
|
190
|
+
data = []
|
|
191
|
+
all_authors = set()
|
|
192
|
+
|
|
193
|
+
# 按日期排序
|
|
194
|
+
sorted_dates = sorted(self.daily_stats.keys())
|
|
195
|
+
|
|
196
|
+
for date in sorted_dates:
|
|
197
|
+
stats = self.daily_stats[date]
|
|
198
|
+
all_authors.update(stats["authors"])
|
|
199
|
+
|
|
200
|
+
data.append(
|
|
201
|
+
{
|
|
202
|
+
"Date": date,
|
|
203
|
+
"Commits": stats["commits"],
|
|
204
|
+
"Added": stats["added_lines"],
|
|
205
|
+
"Deleted": stats["deleted_lines"],
|
|
206
|
+
"Net": stats["net_lines"], # 保持为数字类型
|
|
207
|
+
"Authors": len(stats["authors"]),
|
|
208
|
+
"Files": stats["files_changed"],
|
|
209
|
+
"Author List": ", ".join(sorted(stats["authors"])),
|
|
210
|
+
}
|
|
211
|
+
)
|
|
212
|
+
|
|
213
|
+
# 创建DataFrame
|
|
214
|
+
df = pd.DataFrame(data)
|
|
215
|
+
|
|
216
|
+
if df.empty:
|
|
217
|
+
print("没有统计数据")
|
|
218
|
+
return
|
|
219
|
+
|
|
220
|
+
# 设置pandas显示选项
|
|
221
|
+
pd.set_option("display.max_columns", None)
|
|
222
|
+
pd.set_option("display.width", None)
|
|
223
|
+
pd.set_option("display.max_colwidth", 50)
|
|
224
|
+
|
|
225
|
+
# 定义每列的宽度(调整为更合适的宽度)
|
|
226
|
+
column_widths = {
|
|
227
|
+
"Date": 15, # 增加宽度,确保日期完整显示
|
|
228
|
+
"Commits": 12, # 增加宽度,考虑标题长度
|
|
229
|
+
"Added": 12, # 增加宽度,考虑大数字
|
|
230
|
+
"Deleted": 12, # 增加宽度,考虑大数字
|
|
231
|
+
"Net": 12, # 增加宽度,考虑符号和大数字
|
|
232
|
+
"Authors": 10, # 增加宽度,考虑标题长度
|
|
233
|
+
"Files": 10, # 增加宽度,考虑标题长度
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
# 打印主表格(不包含作者列表)
|
|
237
|
+
display_df = df.drop("Author List", axis=1).copy()
|
|
238
|
+
|
|
239
|
+
# 格式化净变化列,添加正负号
|
|
240
|
+
display_df["Net"] = display_df["Net"].apply(
|
|
241
|
+
lambda x: f"+{x}" if x > 0 else str(x)
|
|
242
|
+
)
|
|
243
|
+
|
|
244
|
+
# 计算总宽度(包括列之间的空格)
|
|
245
|
+
total_width = sum(column_widths.values()) + len(column_widths) - 1
|
|
246
|
+
|
|
247
|
+
# 打印表头
|
|
248
|
+
print("\n" + "=" * total_width)
|
|
249
|
+
print(f"{'每日代码提交统计 (master分支)':^{total_width}}") # 居中显示标题
|
|
250
|
+
print("=" * total_width)
|
|
251
|
+
|
|
252
|
+
# 打印列标题
|
|
253
|
+
header = ""
|
|
254
|
+
for col, width in column_widths.items():
|
|
255
|
+
header += f"{col:^{width}} " # 使用^实现居中对齐
|
|
256
|
+
print(header.rstrip())
|
|
257
|
+
print("-" * total_width)
|
|
258
|
+
|
|
259
|
+
# 打印数据行
|
|
260
|
+
for _, row in display_df.iterrows():
|
|
261
|
+
line = ""
|
|
262
|
+
for col, width in column_widths.items():
|
|
263
|
+
value = str(row[col]) # 转换为字符串
|
|
264
|
+
if col == "Date":
|
|
265
|
+
# 日期左对齐
|
|
266
|
+
line += f"{value:<{width}} "
|
|
267
|
+
elif col == "Net":
|
|
268
|
+
# 净变化右对齐,确保符号对齐
|
|
269
|
+
line += f"{value:>{width}} "
|
|
270
|
+
else:
|
|
271
|
+
# 其他数字右对齐
|
|
272
|
+
line += f"{value:>{width}} "
|
|
273
|
+
print(line.rstrip())
|
|
274
|
+
|
|
275
|
+
# 计算总计
|
|
276
|
+
total_commits = df["Commits"].sum()
|
|
277
|
+
total_added = df["Added"].sum()
|
|
278
|
+
total_deleted = df["Deleted"].sum()
|
|
279
|
+
total_net = df["Net"].sum()
|
|
280
|
+
total_authors = len(all_authors)
|
|
281
|
+
total_files = df["Files"].sum()
|
|
282
|
+
|
|
283
|
+
# 打印总计行
|
|
284
|
+
print("-" * total_width)
|
|
285
|
+
total_net_str = f"+{total_net}" if total_net > 0 else str(total_net)
|
|
286
|
+
total_line = (
|
|
287
|
+
f"{'总计':<{column_widths['Date']}} "
|
|
288
|
+
f"{total_commits:>{column_widths['Commits']}} "
|
|
289
|
+
f"{total_added:>{column_widths['Added']}} "
|
|
290
|
+
f"{total_deleted:>{column_widths['Deleted']}} "
|
|
291
|
+
f"{total_net_str:>{column_widths['Net']}} "
|
|
292
|
+
f"{total_authors:>{column_widths['Authors']}} "
|
|
293
|
+
f"{total_files:>{column_widths['Files']}}"
|
|
294
|
+
)
|
|
295
|
+
print(total_line)
|
|
296
|
+
|
|
297
|
+
# 统计摘要
|
|
298
|
+
print("\n📊 统计摘要 (master分支):")
|
|
299
|
+
print(f" 📅 统计天数: {len(df)} 天")
|
|
300
|
+
print(f" 🔄 总提交数: {total_commits:,}")
|
|
301
|
+
print(f" ➕ 总新增行数: {total_added:,}")
|
|
302
|
+
print(f" ➖ 总删除行数: {total_deleted:,}")
|
|
303
|
+
print(f" 📈 净变化行数: {total_net:+,}")
|
|
304
|
+
print(f" 👥 参与作者数: {total_authors}")
|
|
305
|
+
|
|
306
|
+
if len(df) > 0:
|
|
307
|
+
print(f" 📊 平均每天提交: {total_commits/len(df):.1f}")
|
|
308
|
+
print(f" 📈 平均每天净增: {total_net/len(df):+.1f} 行")
|
|
309
|
+
|
|
310
|
+
# 显示TOP统计
|
|
311
|
+
if len(df) > 1:
|
|
312
|
+
print("\n🏆 TOP统计 (master分支):")
|
|
313
|
+
# 最活跃的一天
|
|
314
|
+
max_commits_day = df.loc[df["Commits"].idxmax()]
|
|
315
|
+
print(
|
|
316
|
+
f" 🥇 最多提交日: {max_commits_day['Date']} ({max_commits_day['Commits']} 次提交)"
|
|
317
|
+
)
|
|
318
|
+
|
|
319
|
+
# 代码变化最大的一天
|
|
320
|
+
max_lines_day = df.loc[df["Added"].idxmax()]
|
|
321
|
+
print(
|
|
322
|
+
f" 📝 最多新增日: {max_lines_day['Date']} (+{max_lines_day['Added']} 行)"
|
|
323
|
+
)
|
|
324
|
+
|
|
325
|
+
# 净增长最大的一天(使用原始数值)
|
|
326
|
+
max_net_day = df.loc[df["Net"].idxmax()]
|
|
327
|
+
net_change_str = (
|
|
328
|
+
f"+{max_net_day['Net']}"
|
|
329
|
+
if max_net_day["Net"] > 0
|
|
330
|
+
else str(max_net_day["Net"])
|
|
331
|
+
)
|
|
332
|
+
print(f" 🚀 最大净增日: {max_net_day['Date']} ({net_change_str} 行)")
|
|
333
|
+
|
|
334
|
+
if all_authors:
|
|
335
|
+
print(f"\n👥 参与作者 (master分支): {', '.join(sorted(all_authors))}")
|
|
336
|
+
|
|
337
|
+
# 如果数据量不大,显示详细的作者分布
|
|
338
|
+
if len(df) <= 10:
|
|
339
|
+
print(f"\n📋 详细作者分布 (master分支):")
|
|
340
|
+
for _, row in df.iterrows():
|
|
341
|
+
if row["Author List"]:
|
|
342
|
+
print(f" {row['Date']}: {row['Author List']}")
|
|
343
|
+
|
|
344
|
+
def get_dataframe(self):
|
|
345
|
+
"""返回pandas DataFrame格式的统计数据"""
|
|
346
|
+
if not self.daily_stats:
|
|
347
|
+
return pd.DataFrame()
|
|
348
|
+
|
|
349
|
+
data = []
|
|
350
|
+
sorted_dates = sorted(self.daily_stats.keys())
|
|
351
|
+
|
|
352
|
+
for date in sorted_dates:
|
|
353
|
+
stats = self.daily_stats[date]
|
|
354
|
+
data.append(
|
|
355
|
+
{
|
|
356
|
+
"日期": date,
|
|
357
|
+
"提交数": stats["commits"],
|
|
358
|
+
"新增行数": stats["added_lines"],
|
|
359
|
+
"删除行数": stats["deleted_lines"],
|
|
360
|
+
"净变化": stats["net_lines"],
|
|
361
|
+
"作者数": len(stats["authors"]),
|
|
362
|
+
"文件数": stats["files_changed"],
|
|
363
|
+
"作者列表": ", ".join(sorted(stats["authors"])),
|
|
364
|
+
}
|
|
365
|
+
)
|
|
366
|
+
|
|
367
|
+
return pd.DataFrame(data)
|
|
368
|
+
|
|
369
|
+
def export_to_csv(self, filename):
|
|
370
|
+
"""导出统计结果到CSV文件"""
|
|
371
|
+
df = self.get_dataframe()
|
|
372
|
+
if df.empty:
|
|
373
|
+
print("没有统计数据可导出")
|
|
374
|
+
return
|
|
375
|
+
|
|
376
|
+
df.to_csv(filename, index=False, encoding="utf-8")
|
|
377
|
+
print(f"📁 统计结果已导出到: {filename}")
|
|
378
|
+
|
|
379
|
+
|
|
380
|
+
def main():
|
|
381
|
+
parser = argparse.ArgumentParser(
|
|
382
|
+
description="Git每日代码提交统计工具 (仅统计master分支)",
|
|
383
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
384
|
+
epilog=__doc__,
|
|
385
|
+
)
|
|
386
|
+
|
|
387
|
+
parser.add_argument("--since", "-s", help="开始日期 (格式: YYYY-MM-DD,默认30天前)")
|
|
388
|
+
parser.add_argument("--until", "-u", help="结束日期 (格式: YYYY-MM-DD,默认今天)")
|
|
389
|
+
parser.add_argument("--author", "-a", help="指定作者名称")
|
|
390
|
+
parser.add_argument("--output", "-o", help="输出CSV文件名")
|
|
391
|
+
parser.add_argument(
|
|
392
|
+
"--file-types", "-t", help="指定文件类型,用逗号分隔 (如: py,js,vue)"
|
|
393
|
+
)
|
|
394
|
+
parser.add_argument(
|
|
395
|
+
"--repo-path", "-p", default=".", help="Git仓库路径 (默认当前目录)"
|
|
396
|
+
)
|
|
397
|
+
|
|
398
|
+
args = parser.parse_args()
|
|
399
|
+
|
|
400
|
+
# 设置默认日期范围(最近30天)
|
|
401
|
+
if not args.since:
|
|
402
|
+
args.since = (datetime.now() - timedelta(days=30)).strftime("%Y-%m-%d")
|
|
403
|
+
|
|
404
|
+
# 处理文件类型过滤
|
|
405
|
+
file_types = None
|
|
406
|
+
if args.file_types:
|
|
407
|
+
file_types = [ft.strip().lower() for ft in args.file_types.split(",")]
|
|
408
|
+
|
|
409
|
+
# 创建分析器实例
|
|
410
|
+
analyzer = GitCommitStatsAnalyzer(args.repo_path)
|
|
411
|
+
|
|
412
|
+
# 执行分析
|
|
413
|
+
success = analyzer.analyze_commits(
|
|
414
|
+
since_date=args.since,
|
|
415
|
+
until_date=args.until,
|
|
416
|
+
author=args.author,
|
|
417
|
+
file_types=file_types,
|
|
418
|
+
)
|
|
419
|
+
|
|
420
|
+
if success:
|
|
421
|
+
# 显示统计结果
|
|
422
|
+
analyzer.print_stats()
|
|
423
|
+
|
|
424
|
+
# 导出CSV(如果指定)
|
|
425
|
+
if args.output:
|
|
426
|
+
analyzer.export_to_csv(args.output)
|
|
427
|
+
|
|
428
|
+
|
|
429
|
+
if __name__ == "__main__":
|
|
430
|
+
main()
|
|
File without changes
|