-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathextract.py
More file actions
99 lines (81 loc) · 3.76 KB
/
Copy pathextract.py
File metadata and controls
99 lines (81 loc) · 3.76 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
from bs4 import BeautifulSoup, Tag
import datetime, json, pathlib, re
# ------------------------------------------------------------------
# 1. Parse one “week N” HTML file ➜ { Monday: {meat/…}, … Friday }
# ------------------------------------------------------------------
def _extract_line(block, label):
p = block.find(
lambda t: t.name == "p" and t.find("strong") and label in t.find("strong").text
)
if not p:
return None
return p.get_text(" ", strip=True).replace(label, "").strip()
def parse_week(file_path: str):
soup = BeautifulSoup(pathlib.Path(file_path).read_text(encoding="utf-8"),
"html.parser")
menu = {}
for h2 in soup.find_all("h2"):
day = h2.get_text(strip=True)
if day not in ("Monday", "Tuesday", "Wednesday", "Thursday", "Friday"):
continue
# the two blocks that follow each <h2> always have this class
blocks = []
candidate = h2
while len(blocks) < 2:
candidate = candidate.find_next("div", class_="well alternate-blue")
if not candidate:
break
blocks.append(candidate)
meatfree_block = next(b for b in blocks if "Meat-free" in b.h3.text)
meat_block = next(b for b in blocks if "Meat option" in b.h3.text)
menu[day] = {
"meat": _extract_line(meat_block, "Main course"),
"meatfree": _extract_line(meatfree_block, "Main course"),
"desert": _extract_line(meatfree_block, "To finish"),
}
return menu
# Parse every weekly pattern we have (order is important!)
WEEK_FILES = ["week1.html", "week2.html", "week3.html"] # adjust paths if needed
WEEK_PATTERNS = [parse_week(f) for f in WEEK_FILES]
# -----------------------------------------------------------
# 2. Build the calendar between 21 Apr 2025 and 24 Oct 2025
# -----------------------------------------------------------
START_DATE = datetime.date(2025, 4, 21) # first Monday on the menus
END_DATE = datetime.date(2025,10,24) # last Friday requested
# School / public-holiday breaks where NO menu is served (inclusive)
BREAKS = [
(datetime.date(2025, 5, 26), datetime.date(2025, 5, 30)), # May half-term
(datetime.date(2025, 7, 24), datetime.date(2025, 8, 31)), # Summer holidays
]
def in_break(day):
return any(start <= day <= end for start, end in BREAKS)
def build_full_menu(start_idx=1):
"""
start_idx tells us which WEEK_PATTERNS element applies to the very first
teaching week (0 = week1.html, 1 = week2.html, 2 = week3.html).
From the JSON you verified, the 21 Apr 2025 menu is Week-2, so offset 1.
"""
full = {}
week_idx = start_idx
current = START_DATE
while current <= END_DATE:
if in_break(current): # skip whole holiday weeks
current += datetime.timedelta(days=7)
continue
pattern = WEEK_PATTERNS[week_idx % len(WEEK_PATTERNS)]
for offset, weekday in enumerate(("Monday","Tuesday","Wednesday","Thursday","Friday")):
day = current + datetime.timedelta(days=offset)
if day > END_DATE or in_break(day):
continue
full[day.isoformat()] = pattern[weekday]
week_idx += 1
current += datetime.timedelta(days=7)
return full
TERM_MENU = build_full_menu(start_idx=1) # <- matches your examples
# -----------------------------------------------------------
# 3. Use it – print / write / import …
# -----------------------------------------------------------
if __name__ == "__main__":
# Optionally dump to JSON file
with open("term_menu.json", "w", encoding="utf-8") as f:
json.dump(TERM_MENU, f, indent=2, ensure_ascii=False)