资源抓取 · 转码发布 · 内容管理
IP: --
服务器: --
运行时间: --
从 NordVPN API 实时拉节点, 剔除 1h 内用过/失败的, 切完测 DNS
📧 账户: liuhuangsu@okay-webcursor.com
💡 用途: 流媒体下载时绕过 CDN 地区封锁。如果下载失败显示 451/403,说明当前 IP 被封,点击「换 IP」或切换到其他城市。
选择地区 (点击展开城市列表)
加载中...
⭐ 收藏节点 (点击直连)
聚合搜索日韩AV、国产资源,抓取并直传到服务器
设置每个分类自动抓取数量
暂无抓取记录
加载服务器状态...
-- / --
0
-
0
0
0
0
0
0
0
0
引擎/transcode/ffmpeg.py
→ build_command()
加载中…
源站 IP:— · 激活:—
调度状态加载中…
res.{根域名}/go/r · /go/img
| # | 封面 | 标题 | 分类 | 时长 | 点击 | 状态 | 操作 | |
|---|---|---|---|---|---|---|---|---|
| 加载中... | ||||||||
显示 0 - 0 条,共 0 条
暂无图片
配置 WEB 前端落地站点,每个站点可以部署到独立域名
60s + 事件触发
备用池模式:每个负责人维护 N 个 standby 域名(默认
N=landing_groups.pre_register_count=3),切换瞬时;被百度打风险时立刻自动补一个。
• 购买规则:GNAME 一口价市场 · 仅 .com · < $2 · 长度 4~30 · 聚查 4-in-1 + Google Safe Browsing 安检
• 扫描节奏:每小时一次百度风险扫描(聚查 bdjc + 百度搜索关键词双通道)
• 告警通道:发现风险 → Telegram 推送(1 小时内同域名不重推) + 自动激活备用 + 异步补购 1 个
• CF + SSL:购买后自动加 zone + 改 NS + 等生效 + 配 A 记录 + acme.sh 申请 LE 证书 + nginx
• 紧急停车:LANDING_AUTO_BUY_ENABLED=0 停补购,LANDING_BAIDU_SCAN_ENABLED=0 停扫描
目标库存
—
备用就绪
—
当前活跃
—
缺货 / 被风控
—
购买前 5-in-1 检测: 不通过则跳过,确保域名干净
管理各站点的广告位、素材和展示规则
🎯 功能概述:通过 Telegram Bot 接收广告主发送的替换请求,自动批量替换数据库中的广告内容(链接/图片/文字)。
📨 TG 消息格式(5 种格式自动识别 + 预览确认):
# ━━━━━ 格式 ① 标准「原 + 换」(推荐,最精确)━━━━━ # "位置" 行的第一个词会自动写入 advertiser 字段 # 该广告位的归属就锁定为这个名字,URL 再换也不变 原 564新葡京链接 https://64.p64125228.top 换 564新葡京链接 https://64.p64125627.top 位置 澳门新葡京 横幅+图标 750+150 150+150 # ━━━━━ 格式 ② 仅「换」无「原」(兼容,自动反查)━━━━━ # 没发老链接?没问题,系统按广告主名反查 DB 拿到老 URL 换 澳门新葡京 https://66.p66999999.top # → 自动找出该广告主名下当前的所有 URL,全部替换为新 URL # → 预览会显示「DB 反查老链接: ... 个不同值,全部替换」 # ━━━━━ 格式 ③ 图床批量(含 5 层级联匹配)━━━━━ 564新葡京:更换新图床 横幅:750x150 https://k6t47hu.p2po2o.com/xxx.gif 图标/悬浮 logo:150x150-单 https://k6t47hu.p2po2o.com/yyy.gif 564新葡京链接 https://64.p64125627.top ← 当前跳转链接(用于反查) 位置 澳门新葡京 横幅+图标 750+150 150+150 # ━━━━━ 格式 ④ 兼容旧格式 / 文字广告 ━━━━━ 旧:https://old-domain.com/landing1 新:https://new-domain.com/landing1 原:PG电子 换:澳门赌场 # ━━━━━ 格式 ⑤ 换广告名称(精确改名,不动链接/图片)━━━━━ # 用于把全站某个广告位的「显示名 / 广告主」一并改掉 # 精确匹配 ad_campaigns.name = X 和 advertiser = X,命中后改为新名 # 不会动 url / image / extra_data,纯粹改名 # 写法 A — 行级关键字(推荐,可以多对一起发) 原名 钻石直播 换名 大秀直播 原名 富贵棋牌 换名 极速捕鱼 # 写法 B — 块级关键字(消息开头声明) 换广告名 原 钻石直播 换 大秀直播 # 触发关键字:换名 / 换广告名 / 换广告名称 / 改名 / 名称替换 # 注意:包含 http(s) 链接的行不会识别为名称替换(自动退回 URL 替换逻辑) # 支持一条消息多组替换 + 多组共享同一个"位置"
🎯 智能匹配策略(图床类型 5 层级联,命中即停):
advertiser = X AND width = W AND height = H
— 最快路径
ad_campaigns.url
推出真实 advertiser 再尺寸匹配
(advertiser ILIKE '%X%' OR name ILIKE '%X%')
👀 预览阶段 dry-run(确认前可见全部信息):
🔍 检测到 2 组替换指令 📍 将影响 4 个广告位(确认前请核对) ━━ 第1组 [图床] ━━ 尺寸: 750x150 新图: https://k6t47hu.p2po2o.com/xxx.gif 广告主: BC 匹配策略: 链接反查+位置推断(url匹配) 将替换以下 1 个广告位: ✓ 导航横幅 第6条(OKAY-VIDEO) ━━ 第2组 [图床] ━━ 尺寸: 150x150 新图: ... 将替换以下 3 个广告位: ✓ 图标广告 第3条/第1条/第11条 ⚠️ 核对位置无误后点「确定替换」
🎯 精确选择模式(命中 ≥ 2 条时启用,单选/多选):
❌ 取消 / 🎯 精确选择 /
✅ 全部替换
🎯 精确选择
→ 进入多选模式:每条广告位是一个独立按钮(☑/☐ 切换)
🔁 反选 / ☑ 全选/全不选✅ 确认所选 (N/M)
→ 仅替换勾选位置;其他位置完全不动
🎯 精确选择模式 📍 共 4 个候选广告位,已选 2 个 点击下方按钮切换 ☑/☐,确认后只替换被勾选的位置: [☑ 导航横幅 第5条 (OKAY-VIDEO) [image] ] [☐ 导航横幅 第6条 (OKAY-VIDEO) [image] ] [☑ 导航横幅 第8条 (OKAY-VIDEO) [image] ] [☐ 导航横幅 第12条 (OKAY-VIDEO) [image] ] [🔁 反选] [☑ 全选] [✅ 确认所选 (2/4)] [❌ 取消]
🔧 技术架构:
📝 替换 SQL(按 type 分支):
# auto: 标准跳转 / 图片 / 文字内链
UPDATE ad_campaigns SET url=%s WHERE url=%s
UPDATE ad_campaigns SET image=%s WHERE image=%s
# url_only: 仅广告主名 + 新 URL(自动反查老 URL)
SELECT DISTINCT url FROM ad_campaigns WHERE advertiser ILIKE %s
UPDATE ad_campaigns SET url=%s, advertiser=%s WHERE id = ANY(%s)
# image_by_size: 图床(5 层级联匹配,复用 _dry_run_image_by_size)
UPDATE ad_campaigns SET image=%s WHERE id = ANY(%s)
# text: 文字广告(解析 extra_data JSON 替换 links[].text)
for link in extra_data['links']:
if link['text'] == old_val:
link['text'] = new_val
# name_replace: 换广告名(精确匹配 name 和 advertiser)
UPDATE ad_campaigns SET name=%s WHERE name=%s
UPDATE ad_campaigns SET advertiser=%s WHERE advertiser=%s
🤖 TG Bot 工作流程:
AND id = ANY(selected_ids) 限制
⚡ 缓存与生效机制:
/ad/api/config/cache/clear
可手动清理服务端缓存
⚠️ CF 缓存注意: 如果站点开启了 Cloudflare
CDN,/ad/api/config 接口可能被 CF 边缘节点缓存。建议在 CF
规则中对该路径设置
Cache-Control: bypass
或使用 Page Rules 跳过缓存,否则即使服务端已清理,CF
节点仍可能返回旧数据(最长取决于 CF 的 TTL 设置)。
📂 相关代码文件:
转码时自动检测并去除所有常见水印位置:
转码时在视频画面和封面图上叠加水印 Logo
综合图片 会添加水印并转换为 WebP 格式
AI 会自动清理标题中的数字、日期等干扰,并根据视频分类生成更吸引人的标题。
点击"预览效果"查看 AI 优化建议
同时设置下载和转码的并发数量
💡 降低并发数时,已运行的任务会继续完成,新任务将按新配置调度。
批量上传封面,新小说自动匹配(封面可复用,700+ 张可循环分配)
media_servers.max_*,可后台调)
DAILY_AUTO_CRAWL_ENABLED=0
| 源 | 支持分类 | 下载方式 |
|---|---|---|
| javmenu (JM) | 亚洲无码 / 亚洲AV / 中文字幕 | FF 直流 (m3u8);全分类强制 FF(不走 BT) |
| NjavTV | 国产激情 / 欧美激情 / 成人动漫 | BT (aria2c) |
| 1024(草榴/Discuz) | 国产激情 / 欧美激情 / 成人动漫 / 综合图片 / 综合小说 | BT;小说为文字;cookies 在 PG |
| T66Y | 国产激情 / 欧美激情 / 成人动漫 / 综合小说 / 综合图片 | BT;rmdown 兜底 |
code(番号)/
resource_id(去重唯一键)/
source / category
magnet(BT)/
stream_url(JM m3u8)/ file_size /
expected_duration(转码完整性校验必依赖)
status(pending / downloading / completed
/ failed)/ download_progress /
error_message / downloaded_at /
updated_at
content_type(video /
image_set / novel)
image_urls(jsonb)/
preview_images / text_url /
text_content
pikpak_folder /
pikpak_file_id / folder_path
cleanup_status /
moved_category
tags(普通字符串,非 jsonb)/
views / real_views /
has_chinese / has_hd /
has_preview
country-jp / country-hk
/ country-sg / country-tw 四国轮转。
ProxyManager.get_proxy() 调用都注入 8
字符随机 session_id,IPRoyal 返回新出口 IP,
源站封单 IP 也封不死。
403/429/503) → base URL 进
failed_proxies 冷却 5 分钟 → 自动切下一国 →
4 国全冷却则清空失败记录重试。
INSERT INTO system_config(key,value) VALUES('crawler_proxy_config',
'{"proxies":[..._country-kr...,..._country-us...]}')
crawler_schedule(next_run / interval_minutes /
enabled)/ forum_1024_cookies(持久化论坛
cookies,不是环境变量)
/ad)
| Method | Path | 用途 |
|---|---|---|
| POST | /api/crawler/auto/crawl-download-stream | 主入口:抓取 + 自动下载 SSE 流(utils_13.js 调用) |
| POST | /api/crawler/auto/crawl-stream | 仅抓取不下载(写 history) |
| GET | /api/crawler/auto/subscribe-logs | SSE 订阅实时日志 |
| GET / POST | /api/crawler/auto/{status,stop} | 查状态 / 强制停止 |
| GET / POST | /api/crawler/daily/{status,trigger} | 每日 00:00 自动抓取调度状态 / 手动后端触发 |
| GET | /api/crawler/history | 分页列表 |
| GET / POST | /api/crawler/proxy | 代理读写 |
| GET | /api/image-proxy | 缩略图代理(绕同源 + 缓存) |
| GET | /api/crawler/captcha/status | 1024 验证码状态(封号风控链路) |
⚠️ 文档中曾写过的 POST /ad/api/crawler/start
已不存在,请勿使用。
.m3u8 作
stream_url,_verify_stream_url
过滤死链;磁力来自表格行
href="magnet:..." 按高清/可离线排序。
magnet:?xt=urn:btih:… 收集;论坛会话依赖 PG
system_config.forum_1024_cookies + 验证码流程。
rmdown.com/link.php?hash=261{infohash}
解析后拼出 magnet:。
| 抓取源 | 超时 | 重试 | 备注 |
|---|---|---|---|
| JM | SB 60s / 普通 30s | 3 |
IPRoyal _streaming-1 自动改写为
_session-…_lifetime-30m
|
| T66Y | 列表 15s / 详情 30s | 3 | 分页随机 sleep 1–6s 防风控 |
| 1024 | 30s | 3 | cookies 来自 PG |
| BT 下载器 | metadata 120s / SSH 30s / 远程命令 60s | — |
_START_INTERVAL=5s;60min 未更新视为卡住
|
CLOUDBYPASS_APIKEY — ScrapingBypass V2,请求头
x-cb-apikey
CRAWLER_PROXY_URL /
CRAWLER_SOCKS_PROXY /
CRAWLER_PROXY_POOL — 与「代理管理器」组合使用
DATABASE_URL — PG 连接system_config.forum_1024_cookies)
crawler.html "抓取" 按钮 ↓ POST /ad/api/crawler/auto/crawl-download-stream (SSE) crawler.py 调度器 (旧 crawler_3.py 合并入口) ↓ 走 IPRoyal/ScrapingBypass 代理 → BeautifulSoup 解析 ↓ 写 crawler_history (status=pending, magnet/stream_url) ↓ INSERT media_tasks (type=download / stream_download) 媒体管理器(startup.py) ↓ SSH 流媒体跑 ffmpeg / aria2c ↓ 进度同步:_sync_stream_download_progress ↓ 完成 → 自动创建 transcode 任务 转码调度器 → ffmpeg 切 HLS → /opt/ppvod/hls/ ↓ video_save.py: INSERT videos ↓ 异步触发 cold_migrate(NVMe>80% 时迁移)
JUYU-002(带 -)/ MDHG0022(不带)/
CUS-2433 三种,正则要兼容
[A-Z]{2,6}-?\d{2,5}
_choose_download_mode 与转码完整性校验
content_type=novel 短路,改通用代码时要保留分支
system_config.forum_1024_cookies 用 RealDictCursor
读,row[0] 会报 KeyError,必须
row.get('value')
9c00eeb6 修复 /ad/videos
页面刷新卡 60s+ 根因
5729b7fd javmenu 抓取时验证
m3u8 URL 可达性,跳过死链
a509012e javmenu 全分类强制走
FF 直流(不走 BT)
b13b3c1e
抓取前预检番号,跳过已知重复
35f2f4cd JavMenu 集成
ScrapingBypass API 绕过 Cloudflare
5dc0199a
重写定时抓取系统(间隔循环 + 0 cron)
e622c065
简化定时抓取:前端定时触发,后端只存状态
fc8253df
修复小说抓取被论坛磁力检查拦截
ca3cd804 更新 1024 论坛域名
5ed6c608 njavtv 超时 15s +
重试 2 次,避免 1 分钟一条
bff713ea 套图标题去除
[xxP] + 修复 0 张显示
7f0fda1f
修复 RealDictCursor 下 system_config 读取错误
/ad/api/server-monitor/status 拉取状态
_cache_get /
_cache_set)
df -h / vmstat / nproc /
free -m,结果合并写
media_servers.metrics
media_servers 字段全集
id / name / ip
ssh_port / ssh_user /
ssh_key / ssh_password
resource_domain(视频/图片 CDN)/
web_share_domain
panel_port / panel_password
status(online/offline)/
last_heartbeat_at / metrics(jsonb:
disk / cpu / mem / load)/ max_download /
max_bt_download /
max_transcode
created_at / updated_at/ad)
/api/server-monitor/status
— 服务器实时状态(缓存 5–60s)
/api/server-monitor/browse?path=/data/亚洲AV
— 浏览目录
/api/server-monitor/delete-folder
— 删除孤儿目录
/api/server-monitor/cleanup-orphans
— 一键清理孤儿(DB 没记录但磁盘有的)
/api/media-servers
— 服务器 CRUD(资源域名管理)
/api/system/maint/cold_migrate
— 触发流媒体冷数据迁移(事件驱动,不依赖 cron)
/opt/ppvod/cold_migrate.sh,不装
cron
POST /api/stats/sync_one 触发归档(30s
进程内防抖缓存)
timestamp without time zone,前端
YYYY-MM-DD 直接展示会显示成 UTC 日期(与北京时间差
8 小时);新版 dashboard 用
_fmtDateTimeBJ 显式格式化
8e636ba6 cold_migrate 改用
SSH(不依赖 nginx 转发)
26891d9a cold_migrate
改事件触发 + 移除 stream_progress_reporter cron
a6e91092
清理心跳模式相关代码和注释
b28ab9761
精简跳板机配置(仅留 seo-a 和 seo-g)
/opt/ppvod/hls/<category>/<folder>/video_1/
v_ + md5(category/folder)[:16];
例外:multi_process.py 用
md5(title)[:12](不是 16 位)
_resolve_video_id_collision 改用
v_ + md5(category/folder/uuid4())[:16]
media_tasks.type 完整枚举
| type | 说明 |
|---|---|
| download |
通用下载(BT 或 FF;extra_data.download_source=stream
标记 FF 直流)
|
| stream_download | JM m3u8 直流下载(独立 type,与 download+stream 并存) |
| folder_download | 套图整目录下载 |
| image_download | 单图下载(去重场景) |
| image_watermark | 套图加水印 |
| gallery_video | 套图合成视频 |
| watermark | 视频水印(去 / 加) |
| transcode | HLS 切片(核心入库链路) |
media_tasks.status 完整枚举
pending / processing /
completed / failed /
cancelled / deleted(软删,
videos_2.py)
media_tasks 字段全集
id / type / title /
file_name / folder_name /
file_type(video /
video_folder / folder /
novel)
status / priority /
server_id / retry_count
progress / started_at /
updated_at / completed_at /
created_at / error_message
source_url / target_path
extra_data(jsonb)常见键:category /
code / cover_url /
cover_path / hls_dir /
video_id / expected_duration /
retry_count / source_task_id /
download_source(stream 标记 FF)
watermark_config 字段
type(remove/add)/ delogo_x /
delogo_y / delogo_w /
delogo_h / overlay_image /
enabled
引擎/transcode/executor.py:_构建去水印滤镜 拼接
| 模块 | 关键参数 | 用途 |
|---|---|---|
| executor.py | HLS_TIME=2 / CRF=32 / PRESET=slower / 7200s timeout | 主链路(480p 极致压缩) |
| ffmpeg.py | crf=28 / profile=main / -b:a 64k / -hls_key_info_file |
HLS 加密链路;分片 seg_%03d.ts;
delete_segments+split_by_time
|
| delogo |
delogo=x=…:y=…:w=…:h=…
|
分段 delogo / SUPJAV 角标 |
HLS_BASE_DIR=/opt/ppvod/hls(executor.py
/ scheduler.py / video_save.py)
/data/{category}/{folder_name}(cover_find.py)
/data/downloads(_helpers.py,旧 _helpers_5 已合并)
file_name LIKE '[预览]%' 优先调度TRANSCODE_TIMEOUT=7200s(executor)max_retries=3,间隔 1s6×5s=30s,失败回
pending + error_message='启动超时'
cover_find.py)LIMIT 1 每轮(防风控);max_preview=2
reset_zombie_transcode_tasks
/ad)
/api/media/processor/{start,stop,reload}
— 任务处理器控制
/api/media/processor/status
— 处理器状态
/api/media/concurrent —
并发配置(写入 media_servers.max_*)
/api/media/tasks —
任务列表
/api/media/tasks/<id>/{pause,prioritize}
— 暂停 / 提优先级
/api/videos/<id>/retranscode
— 单条重转码
/api/videos/batch-retranscode
— 批量重转码
crawler 抓到资源 ↓ INSERT media_tasks (type=download / stream_download) manager._check_pending_tasks 调度 ↓ aria2c (BT) / ffmpeg (m3u8) 远程执行(SSH) ↓ 进度同步线程更新 progress / updated_at status=completed ↓ ffprobe 校验 实际时长/expected ≥ 0.8 ↓ 自动创建 type=transcode 任务 转码调度器 transcode/scheduler.py ↓ ffmpeg 切 HLS → /opt/ppvod/hls/ ↓ video_save.py 入库 INSERT videos ↓ 异步触发 cold_migrate (NVMe>80% 时迁移)
startup.py)
type=download AND status=failed AND retry_count<3
重置为 pending
processing AND watermark →
重置(远程进程不会丢,本地状态丢)
completed download 但无 transcode 跟进 → 补建
transcode;新版返回 "created"/"exists"/"failed"
字符串状态(修复 KeyError(0) 静默 bug)
stream_download 容器重启后无恢复 →
已修,避免永久卡死
db_pool.get_db() 默认 RealDictCursor,row[0]
报 KeyError(0)。错误被 except 静默吞,str(e) = "0"。修:用 _tuple_cursor() 或
row.get("col_name")
WHERE title LIKE '%code%' AND status='active'),避免重复转码
[分类]
前缀(引擎/media/task/manager.py:CATEGORY_PREFIXES);下游匹配要兼容
folder_name=like /
extra_data->>'code' /
file_name LIKE
三套兜底
引擎/media/task/manager.py 与
路由/media_3.py
同名两份,改一处要同步
ffprobe 实际时长 / expected ≥ 0.8 才算
completed,否则重置 pending
resume 文件替换为主文件,确保转码读到完整内容(早期
bug)
updated_at,否则 stuck-watcher
会误判僵尸(已修)
e4dc2bd0 补建转码任务静默失败
→ 容器重启反复扫同一批(KeyError(0))
c060d957 Render
重启后转码自动恢复 + 启动时安全重置卡死任务
935616cf
修复部署重启后转码进度不更新
81fa7517
修复转码完成后时长不更新
00761095 修复 stream_download
容器重启后无恢复逻辑导致永久卡死
d5542f00 下载完成时把 resume
文件替换为主文件
d75b05ed
转码检测到源文件不完整时重置下载任务
a56d913e FF
下载进度同步不更新
updated_at
4f96bf77
修复水印管理器 SQL 查询为空 + 容器重启自动重置卡住任务
e36586b8 转码极致压缩 —
480p/CRF32/slower/baseline/64k
7b93f487
修复截图兜底无法读取加密 HLS
e04b8a2a
封面抓取失败时从视频智能截图兜底
45ab1636 扩展 ffmpeg
瞬态网络错误重试白名单 + 本地容器配置统一线上
21d000ab HLS 分片 2 秒 +
关键帧 2 秒,优化拖动响应
v_ + md5(category/folder)[:16]
(multi_process.py
例外:md5(title)[:12])
res.okyskkkk.com(视频)+
img.okyskkkk.com(图片)双 CDN
POST /api/cache/refresh 主动通知流媒体清缓存
videos 表完整字段
id / video_id /
title / safe_title /
source(默认 'pikpak')
category(亚洲无码 等中文)/
folder_name([分类] 番号 标题)/
folder_path / pikpak_folder
video_url
(https://res.okyskkkk.com/hls/{video_id}/video_1/index.m3u8)/
video_urls(jsonb,见下)/
video_count / real_video_count /
duration
cover_url
(https://img.okyskkkk.com/hls/{video_id}/.../cover.webp)/
cover_source(见下)/ server_images
content_type(video /
novel / image_set)/
tags(普通字符串,非 JSON 数组,来自
_lookup_tags)
status(active /
draft / deleted /
pending,videos_4.py 批量发布)
views(模拟)/ real_viewscreated_at(前 3 真实,其他模拟)/
updated_at
video_urls jsonb 结构(多集合并)
{ url, title, duration, index, cover_url }
_merge_video 合并到一条 video
记录的 video_urls,不创建多条
_resolve_video_id_collision 改用
v_ + md5(category/folder/uuid4())[:16]
cover_source 完整枚举(与代码对齐)
| cover_source | 含义 |
|---|---|
| auto | 系统自动选择 |
| task_cover |
任务 extra_data.cover_url
|
| crawler_url / crawler |
抓取器写入 crawler_history 的封面 URL
|
| source_folder | 源目录里发现的封面图 |
| official | 官方封面(pikpak 等) |
| screenshot | ffmpeg 截图兜底(封面抓取失败时) |
枚举来源:引擎/transcode/cover_find.py。文档曾写过的
pikpak / manual 是早期粗分。
/ad)
/api/videos/category-counts
— 各分类视频数
/api/videos?category=... —
列表
/api/videos/<id>/cover/upload
— 替换封面
/api/videos/screenshots/batch-generate
— 批量截图
/api/videos/batch-watermark —
批量水印
/api/videos/<id>/retranscode
/
/api/videos/batch-retranscode
— 重转码
/api/cache/refresh —
即时同步到流媒体(视频 / 图片 / 小说通用)
display_name),DB.category
字段保持原名,搜索 / 过滤都用 DB 原值
/opt/ppvod/hls/<category>/<folder>
物理文件
video_urls
jsonb,不要重复创建多条
_lookup_tags
返回的是普通字符串
7144234f 抓取内容直接发布 +
每类前 3 个用真实日期
d83eba0b
视频/图片/小说即时同步 — /api/cache/refresh
b13270c6 修复小说加载失败 —
恢复 video_id 查询 + 内容路径修复
f48f5401
修复视频封面本地路径导致 image-proxy 400
787bbcc4
小说入库标题去掉 [综合小说] 前缀 +
自动从封面库分配封面
60d3a071 抓取时 HEAD 验证封面
URL,404 跳过
f130b772
修复国产激情/成人动漫封面抓取失败
bbdf2791
封面下载时转换为真正的 WEBP
3a4392b1
前端全面切换到静态 JSON 文件模式(不再查后端)
959771f7 视频列表分页排序加
id DESC 确保稳定
owner 分组(seo-a/c/d
等),「📤 发布页」单独一类
— 它是
landing_sites 中 owner='发布页' 的特殊
site,对应 permanent_domains 的发布页域名(如
okys520.com),默认在「全部」中
不显示,避免与落地混淆。
config.baidu_analytics_id 自动写入页面(无需开关),
列表里不再显示该 badge。
/etc/nginx/ssl/ → reload),列表里再单独申请已无意义。
如需重申,走 POST /ad/api/sites/{id}/auto-cert。
www.X → IP(DNS only),不创建根 A 记录
acme.sh --issue --dns dns_cf -d www.X(单 SAN,ZeroSSL 默认 CA),证书目录
/root/.acme.sh/www.X_ecc/,安装到
/etc/nginx/ssl/www.X.{crt,key}
server_name www.X;(不含根域名)
_normalize_domain 会统一脱掉 www. 前缀,再统一加回。
/etc/nginx/ssl/(不是只靠 CF Universal)
site-template.conf.example)+
landing-common.conf 通用 include
nginx -t && reload
landing-common.conf 引入
okay-defense-landing.conf(CC / DDoS / 扫描 / 后门
/ SQLi / 路径穿越 / 命令执行 / 爬虫伪装)
landing_groups ← 前缀+TLD+CF 账户 + 随机域名生成器
└── landing_domains ← 组内多域名 + active/standby/blocked 状态
(sites.py 不会读它,仅落地自动化用)
landing_sites ← 控制台 site_id / Nginx / SITE_ID 主数据
(sites.py 唯一操作的表)
permanent_domains ← 发布页(okys520.com 类,永不轮换)
⚠️ 三表
无数据库外键、无自动同步代码。同一字符串域名可能同时出现在
landing_sites.domain 与
landing_domains.domain,需人工 / 流程保证一致。
email +
api_key,表内,不是 env)
auto /
manual)
CLOUDFLARE_EMAIL +
CLOUDFLARE_GLOBAL_API_KEY (Global Key,请求头 X-Auth-Email / X-Auth-Key)
landing_cf_accounts.email +
.api_key(不读 env)
CLOUDFLARE_API_TOKEN(Bearer
Token),如运维文档误写需更正
UI 「添加落地」 → POST /ad/api/sites
↓ DB INSERT landing_sites(domain 字段保存原始输入)
POST /ad/api/sites/{id}/auto-cert
↓ _配置CF落地解析 (仅 www.X 一条 A 记录, proxied: false,根域名故意不解析)
↓ SSH 远端 acme.sh --issue --dns dns_cf -d www.X (ZeroSSL,单 SAN,DNS-01)
↓ 证书目录 /root/.acme.sh/www.X_ecc/
↓ install-cert → /etc/nginx/ssl/www.X.crt + .key
POST /ad/api/sites/{id}/configure-nginx
↓ 生成 nginx conf:server_name www.X(不含根域名)
↓ SSH 流媒体:写 /etc/nginx/conf.d/{slug}.conf
↓ 必含 include /etc/nginx/snippets/landing-common.conf;
↓ ↳ 自动 include okay-defense-landing.conf
↓ nginx -t && nginx -s reload
DB UPDATE nginx_configured = true
/ad)
| 模块 | Path | 用途 |
|---|---|---|
| 站点 | /api/sites | CRUD(landing_sites) |
| 站点 | /api/sites/<id>/{auto-cert,configure-nginx} | 证书 / Nginx 部署 |
| 永久域名 | /api/permanent-domains | CRUD(发布页) |
| 落地自动化 | /api/landing/cf-accounts | CF 账号管理 |
| 落地自动化 | /api/landing/groups | 分组 + 备用域名池 |
| 落地自动化 | /api/landing/domains | 域名状态切换 |
| 防御层 | /api/media-servers/blocks/report | Nginx Lua 上报拦截(POST) |
| 防御层 | /api/media-servers/agent/report | 详细 UA / path 上报 |
| 防御层 | /api/media-servers/blocks | GET 列表 / live 实时拉日志 |
| 防御层 | /api/defense/{manual-ban,manual-unban} | 手动封 / 解封 |
| 防御层 | /api/defense/whitelist-self | 把自己加白名单 |
| 防御层 | /api/media-servers/install-nginx-defense | 一键部署防御 conf 到流媒体 |
block_type='manual' 的 IP 进
blocked_ips.list;auto
上报误进会自锁控制台(曾发生过)
_获取落地白名单 从
landing_sites 取所有非空 domain(未按 status 过滤),并附加 resource_domain;permanent_domains
未纳入
landing-common.conf
的 include 守护
POST /ad/api/media-servers/blocks/report → console
写
media_blocked_ips
okay_block.log
永远空。修:postrotate 加
pgrep -f "nginx: master" 兜底
/etc/nginx/ssl/,证书过期排障要走 SSH
pgrep -f "nginx: master" > /run/nginx.pid 再
reload
landing_cf_accounts 表 —
改一处不影响另一处
landing_sites 与
landing_domains 之间手工对齐;删除时容易遗漏
status 过滤;改一处要同步
nginx 对
location = /main.html(含发布页主入口)做了
proxy_cache,缓存目录
/var/cache/nginx/pages/ 与
/var/cache/nginx/ad/。改完 pink.html /
header.html / 其它前端模板后,
git pull + 容器重启 +
nginx reload 都不会清这层缓存,
浏览器看到的还是老内容。curl 'https://<域名>/main.html?v=$(date +%s)'
能拿到新代码而
curl 'https://<域名>/main.html' 拿不到,
即为缓存命中。rm -rf /var/cache/nginx/pages/* /var/cache/nginx/ad/*, 或在 sync-video.sh 部署末尾固化这一步(推荐)。
注意:清缓存对动态接口(/api/*、广告
/ad/api/config/*)无影响,只清页面/广告聚合的 HTML
缓存。
03a1d817
OKAY 防御系统全套:nginx 实时拦截 + 事件驱动 + 0 cron
77c3e0ef 添加落地时自动 CF
解析(根+www)+ ZeroSSL 证书申请
3e6c8b69
发布页落地入口改为直接输入域名,自动创建落地站 + Nginx 配置
5e332b8c
发布页支持关联指定落地站,被风险提示可快速替换
12a33213
站点管理:负责人分类筛选 + 简化添加流程
8021f5e0 统一落地站点 Nginx
模板,与 okaysssss.com 一致
a15081cb
站点保存时总是重新配置 Nginx,确保统计注入生效
554dc610 落地站点百度统计管理
— 全局 + 独立同时生效
7b943cc5 Nginx 模板去掉
try_files fallback,非注册路径返回 404
d8285b24
添加遗漏的落地自动化模块
664259b0
分享链接使用当前域名 + 永久域名管理
fc04569b VPN 安全防护 + Nginx
模板补全广告代理
position)+ 分类型(image / text /
banner)调度
zone 推断规则:position.rsplit("-", 1)[0](如 inline-3 → zone inline)
/ad/api/config/{site_id}
返回该站点所有广告位 + 投放
POST /ad/api/config/cache/clear →
流媒体立即拉新配置
start_tg_ad_bot
长轮询(getUpdates,不是 webhook),靠
tg_processed_updates 去重
site_id
/ position(见下)/ zone /
name / url / image /
width / height /
extra_data(jsonb:文字广告 links/labelUrl)/
advertiser(广告主名,TG 自动维护,最大 100 char)/
status(active/paused)/
auto_title / title_fetched_at
url_host → advertiser
映射兜底(用户在「广告主管理」UI 改的)
(stat_date, site_id, ad_slot, ip_hash))
update_id,ON CONFLICT DO NOTHING)
position 命名(以模板实际渲染为准)
| position | UI 中文名 | 类型 |
|---|---|---|
| fixed-top / fixed-bottom | 顶部 / 底部横幅 | image |
| nav-banner-N | 导航横幅 第 N 条 | image/text |
| icon-grid-N | 图标 #N | image |
| inline-N | 内嵌广告 第 N 条 | image/text |
| text-row-1..4 | 文字广告(header.html,不是 text-top-N) | text |
| float-right-1 / 2 / float-left-1 | 右 / 左漂浮 | image |
| player-below / player-middle | 播放器下方 / 中间 | image |
| gallery-top / gallery-middle / gallery-bottom | 套图页 顶 / 中 / 底 | image |
| list-interstitial-* / novel-interstitial-* / gallery-interstitial-* | 列表 / 小说 / 套图 插屏(动态) | image |
⚠️ 后台 引擎/ads/广告管理.py 中尚有
nav-top / nav-bottom 等老预设,不是现网真实 slot, 真实命名以前端模板 data-ad-slot 为准。
ad_campaigns.name,任一含子串
「直播」则归
直播-{host 首段[:20]};否则归
BC。无其他关键词参与判断(不识别 tv / 色播
等)
原/旧 + 换/新(含可选 :)位置 XX 行作广告主名兜底原/换(type: text)
image_by_size:多行
宽x高 + URL,按
(advertiser, width, height) 匹配;广告主名必填
TELEGRAM_BOT_TOKEN — TG 长轮询认证TG_AD_GROUP_ID — 逗号分隔多群,解析为
set[int]
DATABASE_URL — PG 连接CLOUDFLARE_*(与站点 SSL 完全分离)
/ad)
/api/config/{site_id} —
返回站点广告位(流媒体 SDK 调用)
/api/config/cache/clear —
清缓存(增删改后必调)
/api/ads — CRUD
/api/ads/reorder —
调整位置顺序
/api/ads/bulk /
/api/ads/bulk-link — 批量操作
/api/ads/<id>/stats —
单广告统计
/api/stats/url-aliases — TG
改了 advertiser 后重算聚合(节流 30s)
cache/clear,否则流媒体 5 分钟才看到(缓存 TTL)
(stat_date, ad_slot, ip_hash) 三元 PK,同 IP 同位
同自然北京日 只算 1 次;stat_date
不是 timestamp 是 TEXT
YYYY-MM-DD
links[].url / links[].text /
labelUrl 都在这里;TG 替换链接需要遍历
extra_data 修改对应字段
[:100]
(advertiser, width, height)
匹配;广告主名必填,否则跳过
getUpdates → 用
tg_processed_updates 表
ON CONFLICT DO NOTHING 原子去重
extra_data 字段
87a75f95
ad-management 表加「广告主」列(可内联编辑)
3c3c6c9d URL 加密 —
隐藏广告主域名
c878580f 广告文案加密 —
规避百度风险检测
5c4437e4 修复文字广告不显示 —
XOR 加密字节级别不匹配
1062ac0d
修复内嵌广告加载逻辑 + 添加 zone 字段
48b2d20b
广告搜索支持文字广告内容
99f8b933
广告搜索支持匹配图片 URL
0ef38094
解决多子项目引擎包命名冲突导致缓存通知失败
eef6c221
修复缓存通知导入失败 + 取消发布不清缓存
6a50c1f2
精确化缓存清理 + SPA 返回修复 + 图片发布状态修复