automatically fetch lunch info from canteen website and send notification with bark
  • Python 32.9%
  • CSS 28.3%
  • JavaScript 25.4%
  • HTML 12.8%
  • Dockerfile 0.6%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-10-05 17:56:44 +08:00
src Rewrite everything 2026-10-05 17:56:44 +08:00
.dockerignore Rewrite everything 2026-10-05 17:56:44 +08:00
.env.example Rewrite everything 2026-10-05 17:56:44 +08:00
.gitignore Rewrite everything 2026-10-05 17:56:44 +08:00
Dockerfile Rewrite everything 2026-10-05 17:56:44 +08:00
README.md Rewrite everything 2026-10-05 17:56:44 +08:00
requirements.txt Rewrite everything 2026-10-05 17:56:44 +08:00

Lunch Push

从学校食堂系统获取当天订餐信息,通过 Bark 或 Server酱 Turbo 推送。提供中文简约管理页,适合个人、单学校账号的内网部署。

  • 查看早餐、午餐、晚餐,按日期查询订餐或重新抓取后推送今日订餐。
  • 选择查询日期可查看过去或未来的订餐记录;非今日结果只用于查看,不覆盖当天缓存,也不会触发推送。
  • 配置学校账号、推送渠道、每日推送时间;单独测试已保存的渠道配置。
  • 默认每天北京时间 06:30 推送,无订餐不发送;可更改时间或关闭自动推送。
  • 配置和最近 100 条运行记录持久化到 SQLite;首页默认显示 5 条,可展开更多,手机端使用列表。抓取失败保留并标注上次成功数据。
  • 设置页显示未保存修改,保存栏在滚动时保持可见;有未保存修改或渠道未配置时,需先保存配置才能测试。

本地启动

要求 Python 3.11+(Docker 使用 3.14),Linux 或 macOS。

python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env

直接启动,无需管理员密码:

python src/web.py

打开 http://127.0.0.1:8080,在「设置与渠道」中填写学校账号和渠道配置。学校密码和推送密钥留空会保留原值;勾选明确的清除操作才会删除。清除渠道密钥时需要同时关闭该渠道。

局域网访问时设置 HOST=0.0.0.0,通过服务器的局域网 IP 和 8080 端口访问。此模式面向可信内网;如配置 HTTPS 反向代理,设置 COOKIE_SECURE=true。

环境变量与持久化

变量 说明
HOST / PORT 默认 127.0.0.1 / 8080,Docker 默认监听 0.0.0.0
LUNCH_DB 默认 data/lunch.db,Docker 为 /app/data/lunch.db
SCHOOL_USERNAME / SCHOOL_PASSWORD 首次初始化时可选的学校账号和密码
BARK_SERVER_URL / BARK_DEVICE_KEY 首次初始化时可选,完整配置自动启用 Bark
SERVERCHAN_SENDKEY 首次初始化时可选,Server酱默认关闭,在页面手动启用
COOKIE_SECURE HTTPS 时设为 true;本地 HTTP 默认 false

学校账号、渠道及定时设置只在创建数据库时从环境变量导入一次,之后以数据库和页面保存的设置为准。数据库内的学校密码与渠道密钥用于调用服务,保留原文,但不回传浏览器、也不输出到日志;数据库文件权限为 0600,请妥善保管数据卷和备份。

推送渠道

在订餐页选择日期后点击「查询订餐」,默认日期为北京时间当天。「回到今天」会切回当天并重新查询。「推送今日订餐」与定时任务始终重新抓取当天数据,不发送指定日期查询结果。学校页面未提供该日期记录时显示未订餐;学校页面本身的可查询范围决定哪些日期能查到。

POST /api/fetch 接受可选 JSON 参数 date(YYYY-MM-DD),省略则查询当天;返回结果包含本次抓取的 menu,失败时为 null。非法日期返回 400。执行记录标注查询日期。

Bark:在 iPhone 上安装 Bark,填写服务地址(默认 https://api.day.app)和设备 Key。

Server酱 Turbo:从 官方 SendKey 页面与教程 获取 SCT 开头的 SendKey,填入页面并启用。本项目不支持 sctp 开头的 Server酱³ 密钥。接收渠道、额度及频率限制以服务方当前设置为准。

两种渠道可同时启用。测试按钮发送固定消息,使用已保存的配置,因此编辑后应先保存。渠道返回成功表示服务已接受请求,不保证终端已送达;单渠道失败不影响另一渠道,失败不自动重发。

Docker 部署

docker build -t lunch-push .
docker run -d --name lunch-push --restart unless-stopped \
  --env-file .env \
  -e HOST=0.0.0.0 -e LUNCH_DB=/app/data/lunch.db \
  -p 8080:8080 \
  -v lunch-push-data:/app/data \
  lunch-push

打开服务器内网地址的 8080 端口。命名数据卷保留设置、菜单和运行记录;容器使用非 root 用户运行。若使用宿主机目录挂载,需先让目录可供容器用户写入。

Web 服务使用 Waitress 单进程和 APScheduler。只启动一个 Web 实例,不使用多 worker 或 Flask reloader,否则会创建重复调度器。自动任务使用北京时间,服务重启后恢复每日时间,不补发停机期间任务。CLI 与 Web 共用文件锁,运行中重复请求返回冲突。

旧版本迁移与 CLI

旧 .env 的四个学校/Bark 变量仍可导入。升级时保留持久化数据卷,并删除旧外部 cron,避免它与 Web 调度器重复推送;新版 Docker 已移除容器内 cron。

继续支持一次性执行(不启动 Web):

python src/main.py

CLI 使用同一 LUNCH_DB 配置并记录结果;失败或部分成功返回退出码 1。若只使用 CLI 与外部 cron,可不运行 Web,或在 Web 中关闭自动推送。后台抓取失败会记录原因,不发送上次成功的订餐数据,也不发送额外登录失败通知。

手动检查

启动后打开页面,保存学校和渠道设置,再使用「查询订餐」与「测试已保存配置」检查。测试渠道会发送真实通知,需要有效凭证;未配置学校账号时,刷新会显示提示。查询不会发送通知,「推送今日订餐」则会重新抓取当天订餐并向已启用的渠道发送。