# -*- coding: utf-8 -*- """Batch fix for 课评汇总 class pages: 1) Remove the 评星 (star rating) feature: strip each
…
block, delete star/metric CSS rules, and remove the dead star JS functions. 2) Fix the 翻页卡死 (pagination freeze) on carousel pages: switch slides from absolute-stacked opacity to display:none for inactive cards (only the active card is ever laid out/painted), and remove backdrop-filter blur (compositing cost). Only applied to the first-week pages when is the folder. """ import os, re, sys # ------------- balanced
removal ------------- def remove_metrics(html): marker = '
' res = [] i = 0 n = len(html) while True: idx = html.find(marker, i) if idx == -1: res.append(html[i:]) break res.append(html[i:idx]) depth = 1 j = idx + len(marker) while depth > 0 and j < n: oi = html.find('', j) if ci == -1: j = n break if oi != -1 and oi < ci: depth += 1 j = oi + 4 else: depth -= 1 j = ci + 6 i = j return ''.join(res) # ------------- balanced CSS block parser ------------- def strip_css(css, is_carousel): out = [] i = 0 n = len(css) while i < n: m = re.match(r'\s+', css[i:]) if m: out.append(m.group(0)); i += m.end(); continue m = re.match(r'/\*.*?\*/', css[i:], re.S) if m: out.append(m.group(0)); i += m.end(); continue brace = css.find('{', i) if brace == -1: out.append(css[i:]); break sel = css[i:brace] depth = 1 j = brace + 1 while depth > 0 and j < n: if css[j] == '{': depth += 1 elif css[j] == '}': depth -= 1 j += 1 body = css[brace+1:j-1] full = css[i:j] selnorm = sel.strip() if selnorm.startswith('@media') or selnorm.startswith('@supports'): out.append(selnorm + '{' + strip_css(body, is_carousel) + '}') elif re.search(r'\.(?:metric|star)', selnorm): pass # drop star / metric rules elif is_carousel and re.match(r'^\.student-card', selnorm): if '.prev' in selnorm: pass # drop the now-unneeded prev-state rule elif '.active' in selnorm: out.append('.student-card.active { display: block; position: relative; pointer-events: auto; }') elif re.match(r'^\.student-card\s*$', selnorm): out.append('.student-card { display: none; }') else: out.append(full) # .student-card:hover else: out.append(full) i = j return ''.join(out) def process_styles(html, is_carousel): def repl(m): css = strip_css(m.group(2), is_carousel) css = re.sub(r'backdrop-filter\s*:\s*blur\([^)]*\);?', '', css) return m.group(1) + css + m.group(3) return re.sub(r'(]*>)(.*?)()', repl, html, flags=re.S) # ------------- dead star JS removal ------------- def remove_function(js, name): pat = re.compile(r'function\s+' + re.escape(name) + r'\s*\(') m = pat.search(js) if not m: return js brace = js.find('{', m.end()) if brace == -1: return js depth = 1 j = brace + 1 n = len(js) while depth > 0 and j < n: if js[j] == '{': depth += 1 elif js[j] == '}': depth -= 1 j += 1 return js[:m.start()] + js[j:] def remove_call(js, name): return re.sub(r'^[ \t]*' + re.escape(name) + r'\(\).*?$', '', js, flags=re.M) def fix(html): is_carousel = 'id="cardsSlider"' in html html = remove_metrics(html) html = process_styles(html, is_carousel) if 'function initStarRatings' in html and 'initStarRatings' in html: html = remove_call(html, 'initStarRatings') html = remove_function(html, 'initStarRatings') html = remove_function(html, 'setStarRating') return html def main(files): for path in files: with open(path, encoding='utf-8') as f: html = f.read() out = fix(html) changed = out != html with open(path, 'w', encoding='utf-8') as f: f.write(out) print(('CHANGED ' if changed else 'same ') + os.path.basename(path)) if __name__ == '__main__': main(sys.argv[1:])