feat: auto-regenerate matrix status daily in update.sh
This commit is contained in:
+1
-1
@@ -1 +1 @@
|
|||||||
{"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IlA0SkRvOUx1emlkeUVoZlF6SG1qbHRKR0R5bC81UXNKVzBZMDhkTmkrTHM9In0.eyJhdWQiOlsib3BlbmFwaSJdLCJ1c2VyX25hbWUiOiJhZG1pbiIsInNjb3BlIjpbInJlYWQiXSwiZXhwIjoxNzg4OTY1MTI4LCJhdXRob3JpdGllcyI6WyJST0xFX0FETUlOIl0sImp0aSI6IjgyMzIyYTFkLTFmZTQtNDA2Ny05MTM1LTg2M2ZlZjAzMWUxNCIsImNsaWVudF9pZCI6IjI2MDMyNTY0NDIyMTIwNDA2MTAwNDgifQ.I0EQigC2GTHdVKxiCdfXEiq7lEppIly53soQkvcc66AXfYHAaRwr41gFdpjR0pudI7lUbl9_sMzRq3IHIQs4LUmy9p3Zqx9YW9WV6GTAiw3HL4UEt92-j2wxtqEGus21NejP42IHU155lP_RQC726PX5Jjy_mf4cAlzj0o0MxIabTgP2jntT6Y3tpY9Xq851-t2bFflRxGddhjJKikqJbfT2P85eXcnmv3rWVlcxVQAkz0_wctKVGy27RHliQL7gkimjBpOQdx07sVWPqiBLL0aNHHrMvbF2E9V4XtH8uhNlyQy55yo1VtvCSd8TTvtbKhySnoAuQbfQH9UzP9AZDQ", "token_type": "bearer", "refresh_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IlA0SkRvOUx1emlkeUVoZlF6SG1qbHRKR0R5bC81UXNKVzBZMDhkTmkrTHM9In0.eyJhdWQiOlsib3BlbmFwaSJdLCJ1c2VyX25hbWUiOiJhZG1pbiIsInNjb3BlIjpbInJlYWQiXSwiYXRpIjoiODIzMjJhMWQtMWZlNC00MDY3LTkxMzUtODYzZmVmMDMxZTE0IiwiZXhwIjoxNzkxNDcwNzI4LCJhdXRob3JpdGllcyI6WyJST0xFX0FETUlOIl0sImp0aSI6ImI5MmY1NDg0LTY1NWMtNGQ1Yi1hMjRiLTZiZDFlNTk0NzM0NCIsImNsaWVudF9pZCI6IjI2MDMyNTY0NDIyMTIwNDA2MTAwNDgifQ.Kf-bBcgOYd5ZyL8VMu1un0lqJGB4zjA8YvTj-riZ7BKdZH49cEwnk6JCeqkgSXm1tSUWwnmW89Og1EkteiUMcJNtXHDejehGPdtKCsqgZPtL06O_flbbdLW8SlBEarvLUNxMj1_ELXTJ9kdZPUVVGig7oXSzLah2B8MISejnyD9LF_iGZL6Rq8NE0YlJgqZRjXN2Js7qUN6TWSGBpcNBI0Lh5iDFqVVojejuzatTLkOUWxKhBX40LteQgYjB_JD1zhAxtjtUGqZWy17H8qHhDTW9dPP-9tsGFCKGuRxRvEaPFExOi7OacT9hBdpZ65E_C0mZ1k0BLqqH26kUabVrQg", "expires_in": 86399, "scope": "read", "jti": "82322a1d-1fe4-4067-9135-863fef031e14"}
|
{"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IlA0SkRvOUx1emlkeUVoZlF6SG1qbHRKR0R5bC81UXNKVzBZMDhkTmkrTHM9In0.eyJhdWQiOlsib3BlbmFwaSJdLCJ1c2VyX25hbWUiOiJhZG1pbiIsInNjb3BlIjpbInJlYWQiXSwiZXhwIjoxNzg4OTY5MzA2LCJhdXRob3JpdGllcyI6WyJST0xFX0FETUlOIl0sImp0aSI6IjIzNDVjOWJjLTNkNDYtNGY3Ny04OTlmLTRkODVlZTU2ZDg0ZCIsImNsaWVudF9pZCI6IjI2MDMyNTY0NDIyMTIwNDA2MTAwNDgifQ.B-An6CSSoFY29Lmiol02QbXjQPpNROratIjTjfal0CNx1s17agletk3bcMoQntkujLYTDJYqt4mtZzaA3_IwIf-nuYmiMDe1KAHOIa5wInNtQWRqvHy5vRb8vQ_q9-fFD-BuZX7Qc2IHpDqeR_LIi1cgK2Ps6HVWtY7jdMyvTMiM_jv7cdDSI2fAlvR0FZkDaTzNqC7YebUsmVX500ZMn1iTZpI29s9N3s1zAWjxQyuOV4DKvUFEtTOaloOBF2LxeySdO6IJMnGM4wMbC0Bv1wdWG9NBoHBzFV1c0FL8wGqJ4O1EDwcKr98X_wWD4P99xsTylr3rUliuNtVkISAYGA", "token_type": "bearer", "refresh_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IlA0SkRvOUx1emlkeUVoZlF6SG1qbHRKR0R5bC81UXNKVzBZMDhkTmkrTHM9In0.eyJhdWQiOlsib3BlbmFwaSJdLCJ1c2VyX25hbWUiOiJhZG1pbiIsInNjb3BlIjpbInJlYWQiXSwiYXRpIjoiMjM0NWM5YmMtM2Q0Ni00Zjc3LTg5OWYtNGQ4NWVlNTZkODRkIiwiZXhwIjoxNzkxNDc0OTA2LCJhdXRob3JpdGllcyI6WyJST0xFX0FETUlOIl0sImp0aSI6IjYzMGJhNmUyLTgwZmMtNGQ5Yi1hMTQ5LWM4MzYwMDlhZjgwNCIsImNsaWVudF9pZCI6IjI2MDMyNTY0NDIyMTIwNDA2MTAwNDgifQ.E4c75ef9fBQnJ3Ia1_Llz39_d5IELgyeEHqVZ3JAe1zGgUoew_Vzor2DpkpcmUX4rEIjvbPcYpDSrB1ElEQMeNR3i92--QlL5gNdJ9S0PyHGk2Ufze75Amlnk4FnAWFuXX8daA9Kyo4Kv1Gg8wzHY7_rvtu-6GGZDdyZE-68hOSAFbAq0SfG4A4vEmh-UDXiAUEAY6XIwfk_3-hNhcW9ljpATj9uF-irJFLDbOHWYLzeLua-S2embkv-4EXENzcDQd5DLPJB8o5joOfqKR4yv-RbX99vYRuwl2Rv9XDEk4Mt_ArE8SW7eO-ylNwEvKo26sGOu6Eg2JHYSgopwBz5ig", "expires_in": 86399, "scope": "read", "jti": "2345c9bc-3d46-4f77-899f-4d85ee56d84d"}
|
||||||
@@ -279,4 +279,51 @@ json.dump(out, open("mtg_data.json","w"), ensure_ascii=False, indent=2)
|
|||||||
print(f"[update] MediaGo 合并后共 {len(out)} 条,已写入 mtg_data.json")
|
print(f"[update] MediaGo 合并后共 {len(out)} 条,已写入 mtg_data.json")
|
||||||
PYEOF
|
PYEOF
|
||||||
|
|
||||||
|
# ============ 重新生成渠道投放矩阵状态(matrix_overrides.json)============
|
||||||
|
python3 - <<'PYEOF'
|
||||||
|
import json, os
|
||||||
|
from collections import defaultdict
|
||||||
|
|
||||||
|
if not os.path.exists("mtg_data.json"):
|
||||||
|
raise SystemExit(0)
|
||||||
|
d = json.load(open("mtg_data.json"))
|
||||||
|
orders = json.load(open("orders.json")) if os.path.exists("orders.json") else []
|
||||||
|
|
||||||
|
# 产品状态:按 pkg -> status("a / b" 合并形式拆开)
|
||||||
|
pkg_status = {}
|
||||||
|
for o in orders:
|
||||||
|
for p in str(o.get("pkg","")).replace(" ","").split("/"):
|
||||||
|
if p: pkg_status[p] = o.get("status","Pause")
|
||||||
|
|
||||||
|
# 聚合每个 (channel, pkg) 的每日展示
|
||||||
|
g = defaultdict(lambda: defaultdict(int))
|
||||||
|
for r in d:
|
||||||
|
g[(r["channel"], r["pkg"])][r["date"]] += r.get("impression", 0)
|
||||||
|
alldates = sorted(set(r["date"] for r in d))
|
||||||
|
if not alldates:
|
||||||
|
raise SystemExit(0)
|
||||||
|
lastday = alldates[-1]
|
||||||
|
last3 = alldates[-3:]
|
||||||
|
|
||||||
|
overrides = {}
|
||||||
|
for (ch, pkg), days in g.items():
|
||||||
|
prod_status = pkg_status.get(pkg, "Pause")
|
||||||
|
# 第一优先级:产品订单状态为 Pause -> 直接 Pause
|
||||||
|
if prod_status != "Active":
|
||||||
|
overrides[f"{ch}|{pkg}"] = "Pause"
|
||||||
|
continue
|
||||||
|
# 产品在投 -> 看数据判定该渠道
|
||||||
|
total = sum(days.values())
|
||||||
|
lastval = days.get(lastday, 0)
|
||||||
|
recent3 = sum(days.get(dt, 0) for dt in last3)
|
||||||
|
if total == 0:
|
||||||
|
overrides[f"{ch}|{pkg}"] = "none" # 零曝光=从未投放(前端留空)
|
||||||
|
elif lastval >= 10 and recent3 >= 30:
|
||||||
|
overrides[f"{ch}|{pkg}"] = "Active" # 末日两位数以上且近期持续
|
||||||
|
else:
|
||||||
|
overrides[f"{ch}|{pkg}"] = "Pause" # 掉到个位数/断更=已停
|
||||||
|
json.dump(overrides, open("matrix_overrides.json","w"), ensure_ascii=False, indent=2)
|
||||||
|
print(f"[update] 矩阵状态已刷新,共 {len(overrides)} 个渠道×产品组合")
|
||||||
|
PYEOF
|
||||||
|
|
||||||
echo "[update] $(date '+%Y-%m-%d %H:%M:%S') 完成"
|
echo "[update] $(date '+%Y-%m-%d %H:%M:%S') 完成"
|
||||||
|
|||||||
Reference in New Issue
Block a user