BobbySlattery/draft-list-generator

GitHub: BobbySlattery/draft-list-generator

从Toast POS自动生成生啤菜单列表并支持网页和电视实时显示的Python工具。

Stars: 0 | Forks: 0

# Draft 列表生成器 从 Toast POS 拉取当前的 Draft 啤酒列表,并生成: - `draft_list.pdf` — 横向排版,可随时上传到您的 WordPress 网站 - `draft_list.html` — 独立的、可自动刷新的页面,适用于酒吧电视 整个程序是一个单独的 Python 脚本。无需数据库,无需服务器即可测试。只需将其设置在 cron 定时任务中即可完成。 ## 此文件夹中的文件 | 文件 | 用途说明 | |---|---| | `01_TOAST_ACCESS_REQUEST.md` | 获取 Toast API 凭据的详细步骤,以及经理将使用的描述字段规范 | | `generate_draft_list.py` | 生成器脚本 | | `sample_menu.json` | 逼真的 Toast 菜单响应示例 — 当您使用 `--sample` 参数运行时使用 | | `.env.example` | 复制为 `.env` 并填入您的 Toast 凭据 | | `requirements.txt` | Python 依赖项 | | `draft_list.pdf` / `draft_list.html` | 示例输出文件(可随时重新生成) | ## 立即尝试(无需 Toast 访问权限) ``` pip install -r requirements.txt python generate_draft_list.py --sample ``` 这将从打包好的示例菜单生成 `draft_list.pdf` 和 `draft_list.html`。打开它们查看 — 这就是您实际输出的样子,只是使用的是您真实的啤酒列表。 ## 上线运行 1. 获取 Toast API 凭据 — 请参阅 `01_TOAST_ACCESS_REQUEST.md`,了解需要发送给 Toast 支持团队的具体请求内容。 2. 运行 `cp .env.example .env` 并粘贴您的 `TOAST_CLIENT_ID`、`TOAST_CLIENT_SECRET` 和 `TOAST_RESTAURANT_GUID`。 3. 确保经理已将您的 Draft 啤酒移至名为 `Draft Beer` 的 Toast 菜单组中(或者在 `.env` 中设置 `DRAFT_GROUP_NAME` 为您使用的名称)。 4. 确保啤酒详情遵循 `01_TOAST_ACCESS_REQUEST.md` 中描述的描述格式: `风格: West Coast IPA | 酒精度: 6.5% | 酒头: 3` (品鉴笔记可以放在风格之前:`口感清爽。风格: Pilsner | 酒精度: 5.0% | 酒头: 4`) 5. 运行脚本: `python generate_draft_list.py` ## 为两个设施运行 Toast 将所有内容限定在一个餐厅 GUID 内,因此从 API 角度看,您的两个设施(24 头和 16 头)是独立的 Toast 餐厅。最简洁的设置是为每个地点使用单独的 `.env` 文件: ``` draft-list/ generate_draft_list.py westside/ .env # TOAST_RESTAURANT_GUID for the 24-tap, BAR_NAME=On Tap — Westside draft_list.pdf draft_list.html eastside/ .env # TOAST_RESTAURANT_GUID for the 16-tap, BAR_NAME=On Tap — Eastside draft_list.pdf draft_list.html ``` 使用 `--output-dir` 参数来分开输出文件,并为每个地点加载对应的 `.env` 文件: ``` ( set -a; . westside/.env; set +a; python generate_draft_list.py --output-dir westside ) ( set -a; . eastside/.env; set +a; python generate_draft_list.py --output-dir eastside ) ``` 两个设施在同一 cron 任务中运行。布局会自动调整:24 头会使用两列密集排版,16 头会使用两列更宽松的排版,留有更多空间。 ## 设置定时运行 此脚本设计为可按计划重复运行。Toast 的速率限制是每个位置每分钟 1000 次请求 — 您的使用量远远达不到这个限制。 **Cron 定时任务,每 5 分钟一次:** ``` */5 * * * * cd /opt/draft-list && /usr/bin/python3 generate_draft_list.py >> /var/log/draft-list.log 2>&1 ``` **systemd 计时器:** 如果您的系统偏好,可以创建 `draft-list.timer` 并设置 `OnCalendar=*:0/5`。 **GitHub Actions:** 如果您不想运行服务器,可以创建一个使用 5 分钟 `schedule:` 触发器的工作流来运行脚本,并将输出提交到 `gh-pages` 分支 — 这样您就可以在 `https://.github.io//draft_list.html` 免费托管了。请将您的 Toast 凭据存储在仓库的 Secrets 中。 ## 托管输出文件 您需要让这两个文件在稳定的 URL 上可访问。这里有几个简单的选择: | 托管方式 | 设置时间 | 备注 | |---|---|---| | WordPress 媒体库 | 5 分钟 | 手动操作:每次生成后上传 `draft_list.pdf`。如果您希望完全无需操作,请跳过此选项。 | | GitHub Pages | 30 分钟 | 免费,通过 GitHub Actions 自动化。电视加载 `https://.github.io//draft_list.html`。WordPress 链接到同一域名的 PDF。 | | Cloudflare R2 / S3 + Cloudflare | 30 分钟 | 每次运行后通过 `aws s3 cp` cron 任务上传两个文件。支持自定义域名。效果很好。 | | 自托管(酒吧里的树莓派) | 1 小时 | 在路由器后的树莓派上运行 `python -m http.server`。电视加载 `http://192.168.x.x:8000/draft_list.html`。成本最低,电视无需互联网连接。 | ## 接入 WordPress 两种模式: **模式 A — 链接到 PDF(与您当前的工作流程匹配)。** 在您的啤酒页面上添加一个按钮:`下载今日的 Draft 列表 (PDF)`。每次 cron 运行后,将 PDF 复制/上传到媒体库。或者,如果您托管在 GitHub Pages / S3 上,只需链接到公共 URL — 无需上传步骤。 **模式 B — 嵌入实时 HTML 页面。** 使用 ` ``` 从长远来看,模式 B 优于模式 A,因为网站与电视上的显示完全一致,且无需上传步骤。 ## 将电视指向实时页面 无论驱动电视的设备是什么(树莓派、Mac mini、Fire TV 棒、智能电视浏览器),请在全屏 kiosk 模式下打开 HTML URL。 **树莓派(酒吧中最常见):** ``` chromium-browser --kiosk --noerrdialogs --disable-infobars \ --check-for-update-interval=31536000 \ https:///draft_list.html ``` 将其放入 `/etc/xdg/lxsession/LXDE-pi/autostart` 文件中,电视在断电重启后会自动恢复。 **Mac mini:** 在 Chrome 中打开 URL 并按 ⌘+Shift+F 进入全屏。 该页面已内置 `` — 浏览器每 5 分钟自动重新加载一次,因此电视会自动获取下一次 cron 生成的更新。 ## 故障排除 - **"在 'Draft Beer' 组中找到 0 啤酒。"** — Toast 中的组名与 `DRAFT_GROUP_NAME` 不匹配。要么在 Toast 中重命名该组,要么更新 `.env` 文件。 - **"缺少必需的环境变量"** — 您尚未填写 `.env` 文件(或者您在脚本目录外运行)。使用 `--sample` 从示例数据生成。 - **输出中啤酒厂/风格字段为空** — 检查 Toast 中该项目的描述。格式要求严格:`啤酒厂: X | 风格: Y | 酒精度: Z%`。运行 `python -c "from generate_draft_list import parse_description; print(parse_description('您的描述文本'))"` 进行调试。 - **Toast API 返回 401** — 您的客户端密钥错误,或者账户没有 `menus:read` 权限范围。重新检查 Toast 支持发送给您的内容。 - **Toast API 返回 403** — `Toast-Restaurant-External-ID` 头部与您的客户端有权访问的餐厅不匹配。与 Toast 支持确认餐厅 GUID。 ## 此工具*故意不*做的事情 - **回写到 Toast。** 它是只读的。经理仍然以 Toast 作为唯一真实来源进行更新。 - **跟踪库存/剩余酒桶。** Toast 可以单独处理;不在本工具范围内。 - **设置网站本身的样式。** HTML 故意设计为可通过 iframe 直接嵌入。如果您希望它继承您的 WordPress 主题,请将 `