feat: add config validation and init check, create full README

首先实现了配置文件存在性检查,当config.ini不存在时给出明确提示并退出程序。接着添加了完整的必填配置项校验逻辑,会列出所有缺失的配置节和配置项并终止运行。同时新增了完整的项目说明文档README.md,包含功能特性、使用流程、配置说明、API细节等完整内容。
This commit is contained in:
2026-06-04 15:45:06 +08:00
parent ea094dc949
commit a61bb7bb34
2 changed files with 211 additions and 1 deletions

180
README.md Normal file
View File

@@ -0,0 +1,180 @@
# 洛克王国远行商人商品定时邮件推送
自动获取洛克王国远行商人商品数据,并在每个时段开始时通过邮件通知收件人。
## 功能特性
- **定时推送**每天4个时段自动发送商品信息邮件
- **智能重试**API未返回商品数据时每分钟自动重试最多30次
- **延迟触发**时段开始后延迟2分钟再请求API确保数据已更新
- **配置校验**:启动时检查配置文件完整性和必要性
- **HTML邮件**:包含商品图片、价格、限购信息的美观邮件模板
- **多收件人**:支持同时发送给多个邮箱地址
## 时段说明
远行商人商品按时段轮换每天共4个时段
| 时段 | 时间范围 | 邮件发送时间 |
|------|----------|--------------|
| 上午场 | 08:00 - 12:00 | 08:02 |
| 下午场 | 12:00 - 16:00 | 12:02 |
| 傍晚场 | 16:00 - 20:00 | 16:02 |
| 夜间场 | 20:00 - 24:00 | 20:02 |
## 快速开始
### 1. 安装依赖
```bash
pip install -r requirements.txt
```
### 2. 配置
复制示例配置文件并填写你的邮箱信息:
```bash
copy config.example.ini config.ini
```
编辑 `config.ini`,填写以下必要配置:
```ini
[smtp]
# SMTP 服务器地址QQ邮箱为 smtp.qq.com
host = smtp.qq.com
# SMTP 端口SSL通常为465STARTTLS通常为587
port = 465
# 是否使用 SSL
use_ssl = true
# 发件人邮箱
sender = your_email@qq.com
# 发件人邮箱授权码(非登录密码,需在邮箱设置中生成)
password = your_authorization_code
# 收件人邮箱(多个用逗号分隔)
recipients = recipient1@example.com, recipient2@example.com
[api]
# API 地址(使用默认值即可)
url = https://rocom-api.ovofish.com/api/shop
# API Key使用公开免费的Key即可
key = sk-f2141ba4be3a9832106d2dc4042454666e354414d3ed0ce9
```
### 3. 运行
```bash
python main.py
```
程序启动后会:
1. 检查配置文件完整性
2. 显示当前配置信息
3. 注册定时任务
4. 如果当前处于营业时段且已过2分钟缓冲立即执行一次推送
5. 持续运行,按 `Ctrl+C` 退出
## API说明
本项目使用洛克王国远行商人商品API
- **接口地址**`https://rocom-api.ovofish.com/api/shop`
- **认证方式**Header中携带 `X-API-Key`
- **公开Key**`sk-f2141ba4be3a9832106d2dc4042454666e354414d3ed0ce9`(免费使用)
### API响应状态
| 状态 | 说明 | 程序行为 |
|------|------|----------|
| `success` | 成功获取商品数据 | 发送邮件 |
| `loading` | 前置引擎工作中时段前2分钟 | 等待1分钟后重试 |
| `closed` | 未营业00:00-08:00 | 等待1分钟后重试 |
| `error` | 获取商品信息失败 | 等待1分钟后重试 |
| 空商品列表 | 无商品数据 | 等待1分钟后重试 |
## 邮件效果
邮件包含以下信息:
- 商品图片
- 商品名称
- 价格(洛克贝)
- 限购数量
- 下架时间
示例邮件主题:`洛克王国远行商人 - 下午场 商品提醒`
## 配置说明
### 邮箱配置
| 配置项 | 说明 | 示例 |
|--------|------|------|
| `host` | SMTP服务器地址 | `smtp.qq.com` |
| `port` | SMTP端口 | `465`SSL`587`STARTTLS |
| `use_ssl` | 是否使用SSL | `true` |
| `sender` | 发件人邮箱 | `your_email@qq.com` |
| `password` | 邮箱授权码 | `xxxxxxxxxxxx` |
| `recipients` | 收件人邮箱(逗号分隔) | `a@example.com, b@example.com` |
### 获取QQ邮箱授权码
1. 登录QQ邮箱
2. 进入「设置」→「账户」
3. 找到「POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务」
4. 开启「IMAP/SMTP服务」
5. 生成授权码16位字符串
## 错误处理
### 配置文件缺失
```
[ERROR] 配置文件 config.ini 不存在
[HINT] 请复制 config.example.ini 为 config.ini 并填写配置
```
### 配置项缺失
```
[ERROR] 配置文件缺少以下必要配置项:
- [smtp] password
- [api] url
[HINT] 请检查 config.ini 并补充缺失的配置
```
### API请求失败
程序会自动重试每分钟尝试一次最多重试30次
```
[INFO] 第 1 次尝试: status=loading, 商品数=01分钟后重试...
```
## 日志输出
程序运行时会输出详细日志:
- `[时间] 执行任务: 下午场` - 任务开始
- `[INFO] 第 1 次尝试: status=success, 商品数=3` - API请求结果
- `[OK] 邮件已发送 -> recipient@example.com` - 邮件发送成功
- `[ERROR] 邮件发送失败: ...` - 邮件发送失败
## 注意事项
1. **邮箱授权码**:不是邮箱登录密码,需要在邮箱设置中单独生成
2. **网络环境**:确保能访问 `rocom-api.ovofish.com`
3. **程序持续运行**:需要保持程序运行才能按时发送邮件
4. **时区设置**程序使用系统时区Asia/Shanghai
5. **安全提示**`config.ini` 包含敏感信息,已在 `.gitignore` 中忽略
## 依赖
- Python 3.6+
- requests - HTTP请求库
- schedule - 定时任务库
## 许可证
MIT License

32
main.py
View File

@@ -16,7 +16,9 @@
import configparser import configparser
import datetime import datetime
import json import json
import os
import smtplib import smtplib
import sys
import time import time
from email.mime.multipart import MIMEMultipart from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText from email.mime.text import MIMEText
@@ -28,8 +30,36 @@ import schedule
# 配置加载 # 配置加载
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
CONFIG_FILE = "config.ini"
if not os.path.exists(CONFIG_FILE):
print(f"[ERROR] 配置文件 {CONFIG_FILE} 不存在")
print(f"[HINT] 请复制 config.example.ini 为 {CONFIG_FILE} 并填写配置")
sys.exit(1)
config = configparser.ConfigParser() config = configparser.ConfigParser()
config.read("config.ini", encoding="utf-8") config.read(CONFIG_FILE, encoding="utf-8")
REQUIRED_KEYS = {
"smtp": ["host", "port", "use_ssl", "sender", "password", "recipients"],
"api": ["url", "key"],
}
missing = []
for section, keys in REQUIRED_KEYS.items():
if not config.has_section(section):
missing.append(f"[{section}] 整个配置节缺失")
else:
for key in keys:
if not config.has_option(section, key):
missing.append(f"[{section}] {key}")
if missing:
print("[ERROR] 配置文件缺少以下必要配置项:")
for m in missing:
print(f" - {m}")
print(f"[HINT] 请检查 {CONFIG_FILE} 并补充缺失的配置")
sys.exit(1)
SMTP_HOST = config.get("smtp", "host") SMTP_HOST = config.get("smtp", "host")
SMTP_PORT = config.getint("smtp", "port") SMTP_PORT = config.getint("smtp", "port")