1
1
"""
2
- hooks/committer.py – 使用源码文件 git 时间增量缓存,
2
+ hooks/committer.py – 使用源码文件 git 时间增量缓存(时间戳版)
3
3
支持 URL 编码字符(Two%20Sum → Two Sum)
4
4
"""
5
5
@@ -26,7 +26,13 @@ def _log(msg: str, level: str = "INFO"):
26
26
print (f"{ _now ()} [{ level } ] { msg } " )
27
27
28
28
29
- # ───────────────────────── 工具函数 ───────────────────────── #
29
+ # ───────────────────────── 时间工具 ───────────────────────── #
30
+ def _ts (dt : datetime ) -> int :
31
+ """datetime → Unix 时间戳(秒,UTC)"""
32
+ return int (dt .timestamp ())
33
+
34
+
35
+ # ───────────────────────── 其他工具函数 ───────────────────────── #
30
36
def _exclude (src_path : str , globs : List [str ]) -> bool :
31
37
for g in globs :
32
38
if fnmatch .fnmatchcase (src_path , g ):
@@ -51,7 +57,7 @@ def _file_git_datetime(repo_path: str) -> datetime:
51
57
执行前后都打印完整命令与结果,便于排查。
52
58
"""
53
59
cmd = ["git" , "log" , "-1" , "--format=%ct" , "--" , repo_path ]
54
- cmd_str = " " .join (shlex .quote (c ) for c in cmd ) # 可粘贴到终端复现
60
+ cmd_str = " " .join (shlex .quote (c ) for c in cmd )
55
61
_log (f"_file_git_datetime: run → { cmd_str } " )
56
62
57
63
try :
@@ -67,7 +73,6 @@ def _file_git_datetime(repo_path: str) -> datetime:
67
73
_log (f"_file_git_datetime: success stdout='{ ts } '" )
68
74
return datetime .fromtimestamp (int (ts ), tz = timezone .utc )
69
75
70
- # 非 0 或无输出,打印全部信息
71
76
_log (
72
77
f"_file_git_datetime: git log failed "
73
78
f"(code={ result .returncode } ) "
@@ -96,22 +101,36 @@ def __init__(self):
96
101
def on_pre_build (self , _cfg ):
97
102
if self .cache_path .exists ():
98
103
try :
99
- self .page_authors = json .loads (self .cache_path .read_text ())["page_authors" ]
104
+ raw = json .loads (self .cache_path .read_text ())["page_authors" ]
105
+ # 过滤旧式错误键;并对 retrieved 做向下兼容
106
+ for k , v in list (raw .items ()):
107
+ if k .startswith ("https://" ):
108
+ continue # 丢弃早期错误的 “全 URL” 键
109
+ rt = v .get ("retrieved" )
110
+ if isinstance (rt , str ):
111
+ try :
112
+ raw [k ]["retrieved" ] = _ts (datetime .fromisoformat (rt ))
113
+ except Exception :
114
+ raw [k ].pop ("retrieved" , None )
115
+ self .page_authors = raw
100
116
_log (f"Loaded committer cache from { self .cache_path } " )
101
117
except Exception as e :
102
118
_log (f"Failed to read cache, ignore: { e } " , "WARN" )
103
119
104
120
def on_post_build (self , _cfg ):
105
121
out = {
106
- "cache_date" : datetime .now (tz = timezone .utc ). isoformat ( ),
122
+ "cache_date" : _ts ( datetime .now (tz = timezone .utc )),
107
123
"page_authors" : self .page_authors ,
108
124
}
109
125
self .cache_path .write_text (json .dumps (out , ensure_ascii = False , indent = 2 ))
110
126
_log (f"Saved committer cache to { self .cache_path } " )
111
127
112
128
_log ("========= Committer Summary =========" )
113
129
for k , v in sorted (self .page_authors .items ()):
114
- _log (f"[SUMMARY] { k } | retrieved: { v .get ('retrieved' , 'N/A' )} " )
130
+ rt = v .get ("retrieved" , "N/A" )
131
+ if isinstance (rt , int ):
132
+ rt = datetime .fromtimestamp (rt , tz = timezone .utc ).isoformat ()
133
+ _log (f"[SUMMARY] { k } | retrieved: { rt } " )
115
134
_log ("=====================================" )
116
135
117
136
def on_page_context (self , context , page , _cfg , _nav ):
@@ -130,26 +149,24 @@ def on_page_context(self, context, page, _cfg, _nav):
130
149
@staticmethod
131
150
def _repo_path_from_edit_url (edit_url : str ) -> str :
132
151
"""
152
+ 把 GitHub edit URL 转成 repo 内部相对路径。
133
153
例:
134
- edit_url =
135
154
https://github.com/doocs/leetcode/edit/main/solution/0000-0099/0001.Two%20Sum/README.md
136
- 返回:
137
- solution/0000-0099/0001.Two Sum/README.md
155
+ → solution/0000-0099/0001.Two Sum/README.md
138
156
"""
139
157
raw_path = edit_url .split ("/edit/main/" )[- 1 ]
140
158
return urllib .parse .unquote (raw_path )
141
159
142
160
@staticmethod
143
161
def _api_url_from_repo_path (repo_path : str ) -> str :
144
- # 重新进行 URL 编码,确保空格等字符合法
145
162
quoted = urllib .parse .quote (repo_path )
146
163
return (
147
164
"https://api.github.com/repos/doocs/leetcode/commits"
148
165
f"?path={ quoted } &sha=main&per_page=100"
149
166
)
150
167
151
168
def _get_authors_with_cache (self , api_url : str , repo_path : str ) -> List [Dict ]:
152
- git_mtime = _file_git_datetime (repo_path ). isoformat ()
169
+ git_mtime = _ts ( _file_git_datetime (repo_path )) # int
153
170
154
171
cached = self .page_authors .get (repo_path )
155
172
cached_time = cached .get ("retrieved" ) if cached else None
@@ -195,7 +212,7 @@ def _get_authors_with_cache(self, api_url: str, repo_path: str) -> List[Dict]:
195
212
196
213
self .page_authors [repo_path ] = {
197
214
"authors" : authors ,
198
- "retrieved" : datetime .now (tz = timezone .utc ). isoformat (),
215
+ "retrieved" : _ts ( datetime .now (tz = timezone .utc )), # int
199
216
}
200
217
_log (f"[CACHE UPDATE] { repo_path } new authors: { len (authors )} " )
201
218
return authors
0 commit comments