@@ -250,6 +250,39 @@ def extract_name_from_row(row):
250250 return parts [1 ].strip ()
251251 return None
252252
253+ def extract_allowed_leave_quota (content , default_quota = 2 ):
254+ """
255+ 从 README 内容中解析“请假规则”下的“每周请假 X 次”并返回 X 作为每周可请假次数。
256+ 若未解析到,返回默认值 default_quota(保持向后兼容,默认为 2)。
257+ """
258+ try :
259+ # 定位到“## 请假规则”标题所在的段落
260+ header_pattern = re .compile (r"^##\s*请假规则\s*$" , re .MULTILINE )
261+ header_match = header_pattern .search (content )
262+ if not header_match :
263+ logging .info ("请假规则标题未找到,使用默认请假次数" )
264+ return default_quota
265+
266+ section_start = header_match .end ()
267+ # 找到下一个以“## ”开头的标题,作为本节结束位置
268+ next_header_pattern = re .compile (r"^##\s+" , re .MULTILINE )
269+ next_header_match = next_header_pattern .search (content , section_start )
270+ section_end = next_header_match .start () if next_header_match else len (content )
271+ section_text = content [section_start :section_end ]
272+
273+ # 解析“每周请假 3 次”中的数字,允许可选空格
274+ quota_match = re .search (r"每周请假\s*([0-9]+)\s*次" , section_text )
275+ if quota_match :
276+ quota = int (quota_match .group (1 ))
277+ logging .info (f"解析到每周请假次数: { quota } " )
278+ return quota
279+
280+ logging .info ("未在请假规则中解析到具体次数,使用默认请假次数" )
281+ return default_quota
282+ except Exception as e :
283+ logging .error (f"解析请假规则失败: { str (e )} ,使用默认请假次数" )
284+ return default_quota
285+
253286def update_readme (content ):
254287 try :
255288 start_index = content .find (TABLE_START_MARKER )
@@ -258,6 +291,9 @@ def update_readme(content):
258291 logging .error ("Error: Couldn't find the table markers in README.md" )
259292 return content
260293
294+ # 读取README中的请假次数配置
295+ allowed_leave_quota = extract_allowed_leave_quota (content , default_quota = 2 )
296+
261297 new_table = [
262298 f'{ TABLE_START_MARKER } \n ' ,
263299 f'| { FIELD_NAME } | ' + ' | ' .join (date .strftime ("%m.%d" ).lstrip ('0' )
@@ -272,14 +308,14 @@ def update_readme(content):
272308 user_name = extract_name_from_row (row )
273309 if user_name :
274310 existing_users .add (user_name )
275- new_table .append (generate_user_row (user_name ))
311+ new_table .append (generate_user_row (user_name , allowed_leave_quota ))
276312 else :
277313 logging .warning (f"Skipping invalid row: { row } " )
278314
279315 new_users = set (get_all_user_files ()) - existing_users
280316 for user in new_users :
281317 if user .strip ():
282- new_table .append (generate_user_row (user ))
318+ new_table .append (generate_user_row (user , allowed_leave_quota ))
283319 logging .info (f"Added new user: { user } " )
284320 else :
285321 logging .warning (f"Skipping empty user: '{ user } '" )
@@ -289,7 +325,7 @@ def update_readme(content):
289325 logging .error (f"Error in update_readme: { str (e )} " )
290326 return content
291327
292- def generate_user_row (user ):
328+ def generate_user_row (user , allowed_leave_quota ):
293329 user_status = get_user_study_status (user )
294330 owner , repo = get_repo_info ()
295331 if owner and repo :
@@ -355,8 +391,8 @@ def generate_user_row(user):
355391 # 获取当前日期的状态
356392 current_status = user_status .get (start_utc , "⭕️" )
357393
358- # 如果当前周期缺席超过2天 ,标记为失败
359- if absent_count > 2 :
394+ # 如果当前周期缺席超过配置的请假次数 ,标记为失败
395+ if absent_count > allowed_leave_quota :
360396 is_eliminated = True
361397 new_row += " ❌ |"
362398 else :
0 commit comments