feat(ci): 接入论坛发帖步骤(默认关闭)
工作流新增 "Post to forum" 步骤,位于建站之后、提交之前: 读同一次运行生成的 data/deals.json 发帖,不重复抓取。 默认关闭 - LDR_FORUM_ENABLED 默认 false,该步骤只打印「已关闭」并退出 - LDR_FORUM_DRY_RUN 默认 true,即使开启也只演练 - 想真正发帖:仓库 Variables 设 LDR_FORUM_ENABLED=true 且 LDR_FORUM_DRY_RUN=false 关键修正:把 data/forum_posted.json 纳入提交 这是幂等依据 —— 不提交的话每次运行都读不到记录, 同一活动会被反复搬运到论坛。 CLI 新增 --forum-only:只读现有 deals.json 发帖, 不抓取也不建站,便于与抓取步骤解耦。 验证:178 测试通过;YAML 解析正常(10 个步骤)。
This commit is contained in:
1 parent
0ed581e551
commit
7db5d526e7
2 files changed
+69
-2
No files matched your search
@@ -80,11 +80,33 @@ jobs:
|
||||
retention-days: 7
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Post to forum
|
||||
# 把优惠帖搬运到 LowSeek 论坛。
|
||||
#
|
||||
# 默认关闭:LDR_FORUM_ENABLED 未设置时该步骤只打印「已关闭」并退出,
|
||||
# 不会发布任何内容。想开启时在仓库 Variables 里设:
|
||||
# LDR_FORUM_ENABLED = true
|
||||
# LDR_FORUM_DRY_RUN = false (先设 true 可只看演练日志)
|
||||
# 并在 Secrets 里配置 LDR_FORUM_API_KEY。
|
||||
env:
|
||||
LDR_FORUM_ENABLED: ${{ vars.LDR_FORUM_ENABLED || 'false' }}
|
||||
LDR_FORUM_DRY_RUN: ${{ vars.LDR_FORUM_DRY_RUN || 'true' }}
|
||||
LDR_FORUM_API_KEY: ${{ secrets.LDR_FORUM_API_KEY }}
|
||||
LDR_FORUM_URL: ${{ vars.LDR_FORUM_URL || 'https://lowseek.ai' }}
|
||||
LDR_FORUM_TAG_ID: ${{ vars.LDR_FORUM_TAG_ID || '21' }}
|
||||
LDR_FORUM_MAX_PER_RUN: ${{ vars.LDR_FORUM_MAX_PER_RUN || '3' }}
|
||||
LDR_FORUM_MAX_AGE_DAYS: ${{ vars.LDR_FORUM_MAX_AGE_DAYS || '3' }}
|
||||
LDR_FORUM_MIN_PERCENT: ${{ vars.LDR_FORUM_MIN_PERCENT || '30' }}
|
||||
# 读上一步生成的 deals.json,不重复抓取
|
||||
run: python -m letdeals --forum-only
|
||||
|
||||
- name: Commit refreshed data
|
||||
run: |
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||||
git add data/deals.json data/deals.md site/
|
||||
# 注意:forum_posted.json 必须提交 —— 它是幂等依据,
|
||||
# 丢了会导致同一活动被重复搬运到论坛。
|
||||
git add data/deals.json data/deals.md site/ data/forum_posted.json
|
||||
if git diff --staged --quiet; then
|
||||
echo "无变化,跳过提交"
|
||||
exit 0
|
||||
@@ -97,7 +119,7 @@ jobs:
|
||||
# 在其之上重新提交,从而始终是快进推送。
|
||||
git fetch origin main
|
||||
git reset --soft origin/main
|
||||
git add data/deals.json data/deals.md site/
|
||||
git add data/deals.json data/deals.md site/ data/forum_posted.json
|
||||
if git diff --staged --quiet; then
|
||||
echo "与远端一致,无需提交"
|
||||
else
|
||||
|
||||
@@ -52,6 +52,8 @@ def build_parser() -> argparse.ArgumentParser:
|
||||
# ---- 论坛发帖(旁路功能,默认关闭且默认演练)----
|
||||
ap.add_argument("--post-forum", action="store_true",
|
||||
help="把优惠帖搬运到论坛(需 LDR_FORUM_ENABLED=true)")
|
||||
ap.add_argument("--forum-only", action="store_true",
|
||||
help="只发帖:读现有 data/deals.json,不抓取也不建站")
|
||||
ap.add_argument("--forum-dry-run", action="store_true",
|
||||
help="演练:只打印将要发布的内容,不提交")
|
||||
ap.add_argument("--forum-limit", type=int, default=0,
|
||||
@@ -61,6 +63,43 @@ def build_parser() -> argparse.ArgumentParser:
|
||||
return ap
|
||||
|
||||
|
||||
def _forum_only(args, verbose: bool) -> int:
|
||||
"""只发帖:读 data/deals.json,不抓取也不建站。"""
|
||||
import json
|
||||
from . import forum
|
||||
|
||||
path = args.json_out or str(config.DEALS_JSON)
|
||||
if not os.path.exists(path):
|
||||
print("!! 找不到 %s;请先运行一次抓取。" % path)
|
||||
return 1
|
||||
|
||||
with open(path, encoding="utf-8") as f:
|
||||
payload = json.load(f)
|
||||
|
||||
recs = payload.get("records") or []
|
||||
if not recs:
|
||||
print("!! %s 里没有记录。" % path)
|
||||
return 1
|
||||
|
||||
if verbose:
|
||||
print("=" * 72)
|
||||
print("论坛发帖(只发帖模式)")
|
||||
print("=" * 72)
|
||||
print(" 数据来源:%s(%d 条)" % (path, len(recs)))
|
||||
|
||||
try:
|
||||
forum.post_deals(
|
||||
recs,
|
||||
limit=args.forum_limit or None,
|
||||
dry_run=True if args.forum_dry_run else None,
|
||||
verbose=verbose,
|
||||
)
|
||||
except Exception as e: # 不让发帖失败影响整体
|
||||
print(" !! 论坛发帖出错:%r" % e)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
def main(argv: list[str] | None = None) -> int:
|
||||
if hasattr(sys.stdout, "reconfigure"):
|
||||
sys.stdout.reconfigure(encoding="utf-8")
|
||||
@@ -68,6 +107,12 @@ def main(argv: list[str] | None = None) -> int:
|
||||
args = build_parser().parse_args(argv)
|
||||
verbose = not args.quiet
|
||||
|
||||
# ---- 只发帖模式:读现有 deals.json,不抓取也不建站 ----
|
||||
# 用于把发帖与抓取解耦:工作流先更新数据并提交,
|
||||
# 再由单独的步骤读同一份 JSON 发帖,避免重复抓取。
|
||||
if args.forum_only:
|
||||
return _forum_only(args, verbose)
|
||||
|
||||
sources = tuple(s.strip() for s in args.sources.split(",") if s.strip())
|
||||
offline = {}
|
||||
if args.offline_let:
|
||||
|
||||
Reference in new issue
Block a user