aboutsummaryrefslogtreecommitdiff
path: root/sjdbmk/menuparser.py
diff options
context:
space:
mode:
Diffstat (limited to 'sjdbmk/menuparser.py')
-rw-r--r--sjdbmk/menuparser.py136
1 files changed, 136 insertions, 0 deletions
diff --git a/sjdbmk/menuparser.py b/sjdbmk/menuparser.py
new file mode 100644
index 0000000..7413ff0
--- /dev/null
+++ b/sjdbmk/menuparser.py
@@ -0,0 +1,136 @@
+#!/usr/bin/env python3
+#
+# Utility functions to parse the XLSX menu for the Daily Bulletin
+# Copyright (C) 2024 Runxi Yu <https://runxiyu.org>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+#
+
+
+from typing import Optional, Any
+
+import openpyxl
+
+
+def menu_item_fix(s: str) -> Optional[str]:
+ if not s:
+ return None
+ if s == "Condiments Selection\n葱,香菜,榨菜丝,老干妈,生抽,醋":
+ return None
+ return (
+ s.strip()
+ .replace("Biscuit /", "Biscuit/")
+ .replace("Juice /", "Juice/")
+ .replace(" \n", "\n")
+ .replace("\n ", "\n")
+ )
+
+
+def parse_meal_table(
+ rows: list[Any], initrow: int, t: list[str]
+) -> dict[str, dict[str, list[str]]]:
+ assert rows[initrow + 1][1].value is None
+
+ igroups = []
+ i = initrow + 2
+ while True:
+ c = rows[i][1]
+ if not isinstance(c, openpyxl.cell.MergedCell):
+ igroups.append(i)
+ i += 1
+ if len(igroups) >= len(t):
+ break
+ wgroups = dict(zip(igroups + [i], t + [None]))
+
+ ret: dict[str, dict[str, list[str]]] = {}
+ kmap = {}
+ for k in range(2, 7):
+ ret[rows[initrow + 1][k].value[0:3]] = {}
+ kmap[k] = rows[initrow + 1][k].value[0:3]
+
+ i = 0
+ wgroupskeys = list(wgroups.keys())
+ while i < len(wgroupskeys) - 1:
+ wgroup = wgroups[wgroupskeys[i]]
+ assert wgroup is not None
+ for km in ret:
+ ret[km][wgroup] = []
+ for j in range(wgroupskeys[i], wgroupskeys[i + 1]):
+ for k in range(2, 7):
+ v = menu_item_fix(rows[j][k].value)
+ if v:
+ ret[kmap[k]][wgroup].append(v)
+ i += 1
+
+ return ret
+
+
+def parse_menus(filename: str) -> dict[str, dict[str, dict[str, list[str]]]]:
+ wb = openpyxl.load_workbook(filename=filename)
+ ws = wb["菜单"]
+ rows = list(ws.iter_rows())
+
+ final = {}
+
+ i = -1
+ while i < len(rows) - 1:
+ i += 1
+ row = rows[i]
+ if not isinstance(row[1].value, str):
+ continue
+ if "BREAKFAST" in row[1].value:
+ final["Breakfast"] = parse_meal_table(
+ rows,
+ i,
+ [
+ "Taste of Asia",
+ "Eat Global",
+ "Revolution Noodle",
+ "Piccola Italia",
+ "Self Pick-up", # instead of veg and soup
+ "Fruit/Drink",
+ ],
+ )
+ elif "LUNCH" in row[1].value:
+ final["Lunch"] = parse_meal_table(
+ rows,
+ i,
+ [
+ "Taste of Asia",
+ "Eat Global",
+ "Revolution Noodle",
+ "Piccola Italia",
+ "Vegetarian",
+ "Daily Soup",
+ "Dessert/Fruit/Drink",
+ ],
+ )
+ elif "DINNER" in row[1].value:
+ final["Dinner"] = parse_meal_table(
+ rows,
+ i,
+ [
+ "Taste of Asia",
+ "Eat Global",
+ "Revolution Noodle",
+ "Piccola Italia",
+ "Vegetarian",
+ "Daily Soup",
+ "Dessert/Fruit/Drink",
+ ],
+ )
+ # elif "Students Snack" in row[1].value:
+ # parse_meal_table(rows, i)
+
+ return final