@@ -1891,8 +1891,19 @@ def check_assignments_inline(driver_obj, assignments, *, submitted_assignments,
18911891 'due_date_str' : due_date_str ,
18921892 'due_date_obj' : due_dt ,
18931893 }
1894- # 過期的不進 pending(也不顯示)
1895- if not is_expired_assignment (item , now_dt ):
1894+ # 若已繳交或已過期,皆記錄為已處理(寫入 submitted_assignments 以後不要再點進去了)
1895+ if is_expired_assignment (item , now_dt ):
1896+ newly_submitted [key ] = {
1897+ 'course' : a ['course' ],
1898+ 'name' : a ['name' ],
1899+ 'url' : a ['url' ],
1900+ 'assignment_key' : key ,
1901+ 'checked_date' : time .strftime ('%Y-%m-%d %H:%M:%S' ),
1902+ 'status' : 'expired'
1903+ }
1904+ if key in pending_cache :
1905+ pending_cache .pop (key , None )
1906+ else :
18961907 pending_cache [key ] = item
18971908 else :
18981909 # 沒看到繳交按鈕也沒明確狀態:當作已繳交/無需繳交,避免一直卡在 pending
@@ -1916,12 +1927,15 @@ def check_assignments_inline(driver_obj, assignments, *, submitted_assignments,
19161927 return submitted_assignments , pending_cache
19171928
19181929
1919- def recheck_pending_assignments (driver_obj , * , pending_cache , submitted_assignments , limit = 6 ):
1930+ def recheck_pending_assignments (driver_obj , * , pending_cache , submitted_assignments , limit = None ):
19201931 """對少量「已在 pending_cache」的作業做再驗證。
19211932
19221933 原本 pending_cache 內的作業為了加速會被跳過檢查;若使用者已在網頁上完成繳交,
19231934 可能會暫時殘留在未繳交清單。這裡用小額度重新檢查,將已繳交者移出 pending。
19241935 """
1936+ # limit=None 代表全部檢查(最可靠,避免已繳交仍殘留在未繳清單)
1937+ if limit is None :
1938+ limit = len (pending_cache or {})
19251939 try :
19261940 limit = max (0 , int (limit or 0 ))
19271941 except Exception :
@@ -1973,9 +1987,55 @@ def recheck_pending_assignments(driver_obj, *, pending_cache, submitted_assignme
19731987 }
19741988 pending_cache .pop (key , None )
19751989 else :
1976- # 若已過期就移除(避免殘留)
1977- if is_expired_assignment (item , now_dt ):
1978- pending_cache .pop (key , None )
1990+ # 若抓不到狀態文字,改用「是否還能繳交」判斷:
1991+ # 找不到「繳交作業」按鈕,通常代表已繳交/無需繳交,避免一直殘留在未繳清單。
1992+ try :
1993+ has_submit_button = False
1994+ try :
1995+ submit_buttons = driver_obj .find_elements (By .XPATH , "//button[contains(text(), '繳交作業')]" )
1996+ if submit_buttons :
1997+ has_submit_button = True
1998+ except Exception :
1999+ pass
2000+
2001+ if (not has_submit_button ) and status_text and (
2002+ "尚無任何作業繳交" in status_text or "目前尚無" in status_text
2003+ ):
2004+ has_submit_button = True
2005+
2006+ if not has_submit_button :
2007+ submitted_assignments [stable_key ] = {
2008+ 'course' : course ,
2009+ 'name' : name ,
2010+ 'url' : url ,
2011+ 'assignment_key' : stable_key ,
2012+ 'checked_date' : time .strftime ('%Y-%m-%d %H:%M:%S' )
2013+ }
2014+ pending_cache .pop (key , None )
2015+ else :
2016+ # 若已過期就移除(寫入 submitted_assignments 以避免殘留與重複驗證)
2017+ if is_expired_assignment (item , now_dt ):
2018+ submitted_assignments [stable_key ] = {
2019+ 'course' : course ,
2020+ 'name' : name ,
2021+ 'url' : url ,
2022+ 'assignment_key' : stable_key ,
2023+ 'checked_date' : time .strftime ('%Y-%m-%d %H:%M:%S' ),
2024+ 'status' : 'expired'
2025+ }
2026+ pending_cache .pop (key , None )
2027+ except Exception :
2028+ # 若已過期就移除(寫入 submitted_assignments 以避免殘留與重複驗證)
2029+ if is_expired_assignment (item , now_dt ):
2030+ submitted_assignments [stable_key ] = {
2031+ 'course' : course ,
2032+ 'name' : name ,
2033+ 'url' : url ,
2034+ 'assignment_key' : stable_key ,
2035+ 'checked_date' : time .strftime ('%Y-%m-%d %H:%M:%S' ),
2036+ 'status' : 'expired'
2037+ }
2038+ pending_cache .pop (key , None )
19792039
19802040 checked += 1
19812041 except Exception :
@@ -4625,17 +4685,37 @@ def cleanup_driver():
46254685 cleanup_thread .start ()
46264686 close_macos_terminal_and_exit (0 )
46274687
4628- print (f"{ PINK } 開啟未繳交作業(可用空白分隔多個編號):{ RESET } \n " )
4629-
46304688import datetime
46314689
46324690# 1) 從文字檔載入上次未繳交作業(加速)
46334691submitted_assignments = load_submitted_assignments ()
46344692pending_cache = load_pending_assignments ()
46354693
4636- # 清掉已過期(不顯示)
4694+ # 清掉已過期(不顯示),並且把它們加入已處理快取(submitted_assignments)
4695+ # 以避免未來程式又把它們當成新作業點進去驗證!
46374696_now_dt = datetime .datetime .now ()
4638- pending_cache = {k : v for k , v in pending_cache .items () if not is_expired_assignment (v , _now_dt )}
4697+ _new_pending = {}
4698+ _newly_ignored = {}
4699+ for k , v in pending_cache .items ():
4700+ if is_expired_assignment (v , _now_dt ):
4701+ _newly_ignored [k ] = {
4702+ 'course' : v .get ('course' , '' ),
4703+ 'name' : v .get ('name' , '' ),
4704+ 'url' : v .get ('url' , '' ),
4705+ 'assignment_key' : k ,
4706+ 'checked_date' : time .strftime ('%Y-%m-%d %H:%M:%S' ),
4707+ 'status' : 'expired'
4708+ }
4709+ else :
4710+ _new_pending [k ] = v
4711+
4712+ pending_cache = _new_pending
4713+ if _newly_ignored :
4714+ submitted_assignments .update (_newly_ignored )
4715+ try :
4716+ save_submitted_assignments (submitted_assignments )
4717+ except Exception :
4718+ pass
46394719
46404720# 先把「其實已繳交」的從 pending_cache 清掉(用 id 比對,避免課程名變動導致殘留)
46414721try :
@@ -4657,12 +4737,23 @@ def cleanup_driver():
46574737
46584738# 3) 限量檢查新作業(不在 pending/submitted 的),用主 driver 直接進入頁面判斷
46594739try :
4740+ # 預設:全部檢查(只會檢查「不在 pending/submitted」的新作業)。
4741+ # 若要加速,可設定環境變數 ASSIGNMENT_CHECK_LIMIT。
4742+ try :
4743+ _env_check_limit = os .environ .get ('ASSIGNMENT_CHECK_LIMIT' , '' ).strip ()
4744+ except Exception :
4745+ _env_check_limit = ''
4746+ if _env_check_limit :
4747+ _check_limit = int (_env_check_limit )
4748+ else :
4749+ _check_limit = len (all_assignments_found or [])
4750+
46604751 submitted_assignments , pending_cache = check_assignments_inline (
46614752 driver ,
46624753 all_assignments_found ,
46634754 submitted_assignments = submitted_assignments ,
46644755 pending_cache = pending_cache ,
4665- limit = ASSIGNMENT_CHECK_LIMIT
4756+ limit = _check_limit
46664757 )
46674758 save_submitted_assignments (submitted_assignments )
46684759except Exception :
@@ -4671,9 +4762,20 @@ def cleanup_driver():
46714762
46724763# 3.5) 少量 recheck:避免「已繳交但仍殘留在未繳」
46734764try :
4674- recheck_limit = int (os .environ .get ('PENDING_RECHECK_LIMIT' , '6' ) or '6' )
4765+ _env_limit = os .environ .get ('PENDING_RECHECK_LIMIT' , '' ).strip ().lower ()
4766+ if not _env_limit :
4767+ # 預設:全數 recheck(最可靠)
4768+ recheck_limit = None
4769+ elif _env_limit == 'all' :
4770+ recheck_limit = None
4771+ elif _env_limit == 'auto' :
4772+ # 自動模式:pending 不多則全數,過多則只檢查最接近截止的前 N 筆
4773+ _pending_n = len (pending_cache or {})
4774+ recheck_limit = _pending_n if _pending_n <= 30 else 30
4775+ else :
4776+ recheck_limit = int (_env_limit )
46754777except Exception :
4676- recheck_limit = 6
4778+ recheck_limit = None
46774779try :
46784780 submitted_assignments , pending_cache = recheck_pending_assignments (
46794781 driver ,
@@ -4690,6 +4792,17 @@ def cleanup_driver():
46904792empty_assignments = [a for a in empty_assignments if not is_expired_assignment (a , _now_dt )]
46914793empty_assignments .sort (key = lambda x : x .get ('due_date_obj' , datetime .datetime .max ) if x .get ('due_date_obj' ) else datetime .datetime .max )
46924794
4795+ # 如果沒有任何「未繳且未過期」作業:不顯示輸入編號提示,直接結束
4796+ if not empty_assignments :
4797+ try :
4798+ save_pending_assignments (pending_cache )
4799+ except Exception :
4800+ pass
4801+ print (f"{ GREEN } 目前無須繳交作業{ RESET } " )
4802+ close_macos_terminal_and_exit (0 )
4803+
4804+ print (f"{ PINK } 開啟未繳交作業(可用空白分隔多個編號):{ RESET } \n " )
4805+
46934806items_list = []
46944807current_idx = 1
46954808ibxx = 0
0 commit comments