-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathmain.py
More file actions
150 lines (124 loc) · 4.81 KB
/
main.py
File metadata and controls
150 lines (124 loc) · 4.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
"""GitHub Commit History 3D Visualization Tool."""
import sys
import os
from pathlib import Path
import click
from loguru import logger
from dotenv import load_dotenv
from github_api import get_commit_stats, get_daily_commits_for_year
from model_generator import generate_commit_visualization
# 加载.env文件
load_dotenv()
@click.command()
@click.argument('username')
@click.argument('year', type=int)
@click.option(
'-m',
'--margin',
type=float,
default=2.0,
help='阵列到底盘边缘的距离,单位mm (默认: 2.0)',
)
@click.option('-b', '--base-height', type=float, default=2.5, help='底板高度,单位mm (默认: 2.5)')
@click.option('-v', '--verbose', is_flag=True, help='显示详细日志')
def main(username: str, year: int, margin: float, base_height: float, verbose: bool):
"""将GitHub用户的contribution历史可视化为3D STL模型。
使用GitHub GraphQL API获取contribution数据。
\b
配置要求:
在项目根目录创建 .env 文件,添加:
GITHUB_TOKEN=your_token_here
\b
获取Token:
访问 https://github.com/settings/tokens
创建 Personal Access Token (不需要任何权限)
\b
输出位置:
文件将保存到: output/<year>/<username>_<year>.3mf
\b
自定义参数:
--margin: 阵列到底盘边缘的距离 (默认1mm)
--base-height: 底板高度 (默认1mm)
\b
示例:
python main.py torvalds 2025
python main.py octocat 2024 -v
python main.py user 2023 --margin 2 --base-height 1.5
"""
# 配置日志
logger.remove() # 移除默认handler
if verbose:
logger.add(
sys.stderr,
level='DEBUG',
format='<green>{time:HH:mm:ss}</green> | <level>{level: <8}</level> | <level>{message}</level>',
)
else:
logger.add(sys.stderr, level='INFO', format='<level>{message}</level>')
# 从环境变量获取GitHub Token
github_token = os.getenv('GITHUB_TOKEN')
if not github_token:
logger.error('未找到GitHub Token!')
logger.error('')
logger.error('请在项目根目录创建 .env 文件,并添加:')
logger.error(' GITHUB_TOKEN=your_token_here')
logger.error('')
logger.error('获取token步骤:')
logger.error(' 1. 访问 https://github.com/settings/tokens')
logger.error(' 2. 生成新的 Personal Access Token (classic)')
logger.error(' 3. 不需要选择任何权限')
logger.error(' 4. 复制token到 .env 文件')
sys.exit(1)
# 验证年份
if year < 2008 or year > 2100:
logger.error(f'年份 {year} 不合理')
sys.exit(1)
# 验证参数范围
if margin < 0 or margin > 10:
logger.error(f'边距 {margin}mm 不合理,应在 0-10mm 之间')
sys.exit(1)
if base_height < 0.1 or base_height > 10:
logger.error(f'底板高度 {base_height}mm 不合理,应在 0.1-10mm 之间')
sys.exit(1)
# 创建输出目录结构: output/year/
output_dir = Path('output') / str(year)
output_dir.mkdir(parents=True, exist_ok=True)
# 设置输出文件名: output/year/username_year.3mf
output_file = output_dir / f'{username}_{year}.3mf'
logger.info('=' * 60)
logger.info('GitHub Commit 3D 可视化工具')
logger.info('=' * 60)
logger.info(f'用户名: {username}')
logger.info(f'年份: {year}')
logger.info(f'边距: {margin}mm')
logger.info(f'底板高度: {base_height}mm')
logger.info(f'输出文件: {output_file}')
logger.info('=' * 60)
logger.info('')
try:
# 1. 获取contribution统计数据(使用GraphQL)
logger.info('步骤 1/3: 查询GitHub contribution历史...')
commit_stats = get_commit_stats(username, year, github_token)
if not commit_stats:
logger.warning(f'未找到用户 {username} 在 {year} 年的任何contributions')
logger.info('仍将生成空白模型...')
# 2. 转换为每日数据
logger.info('步骤 2/3: 处理数据...')
daily_commits = get_daily_commits_for_year(year, commit_stats)
# 3. 生成STL文件(传递自定义参数)
logger.info('步骤 3/3: 生成3D模型...')
generate_commit_visualization(
daily_commits, str(output_file), username=username, year=year, margin=margin, base_height=base_height
)
logger.info('')
logger.info('=' * 60)
logger.success('✓ 完成!')
logger.info('=' * 60)
logger.info('')
logger.info('您可以使用3D打印切片软件或在线STL查看器打开该文件:')
logger.info(f' {output_file.absolute()}')
except Exception as e:
logger.exception(f'发生错误: {e}')
sys.exit(1)
if __name__ == '__main__':
main()