Files
pod_trend_agent/graph/seeds/holidays.py
T
3218485270 f493bde8a9 POD 趋势感知 Agent:缓存热点模式 + 三图合成 + 热点去重/风格去重 + review 兜底
- 缓存热点批量流程(有采集缓存不触发 Google)
- 简报不足直接从采集缓存生成(轻量补齐)
- 三图合成(模特/印花/底图)+ 底图压缩 <2MB
- 热点去重→风格去重自动切换 + 不适合类目 review 兜底
- 透明背景(background=transparent)+ 提示词清洗(敏感词/背景描述)
- 任务前 basemap 校验 + 模板国家校验 + 模特任务级分配
2026-08-22 14:14:01 +08:00

187 lines
7.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""月份 / 季节 / 临近节日上下文(按国家),供动态种子词生成的 LLM 上下文使用。
提供 build_holiday_context(country, now=None) -> dict
{
"date": "2026-08-21",
"year": 2026,
"month": 8,
"season": "Summer",
"month_themes": ["back to school", "late summer", "outdoor adventure"],
"upcoming_holidays": ["Back to School", "Summer Solstice"]
}
- month_themes:固定月度灵感,作为种子词生成的稳定基础。
- upcoming_holidays:按国家节日表,用窗口计算临近(含刚过的)固定/浮动节日,
让 LLM 注入"当前该国的可能节日",生成对应节日主题种子。
"""
import datetime
from typing import Dict, List, Optional
# 北半球季节(南半球可反向扩展)
SEASON_BY_MONTH = {
12: "Winter", 1: "Winter", 2: "Winter",
3: "Spring", 4: "Spring", 5: "Spring",
6: "Summer", 7: "Summer", 8: "Summer",
9: "Autumn", 10: "Autumn", 11: "Autumn",
}
# 月度主题词(通用印花设计灵感)
MONTH_THEMES: Dict[int, List[str]] = {
1: ["new year", "winter cozy", "resolution"],
2: ["valentine", "love", "heart"],
3: ["spring bloom", "st patrick", "fresh start"],
4: ["easter", "spring garden", "pastel"],
5: ["mother day", "flower", "spring outdoor"],
6: ["pride", "summer start", "beach"],
7: ["summer vibe", "travel", "festival"],
8: ["back to school", "late summer", "outdoor adventure"],
9: ["autumn equinox", "harvest", "cozy"],
10: ["halloween", "autumn goth", "spooky"],
11: ["thanksgiving", "gratitude", "autumn warm"],
12: ["christmas", "winter holiday", "cozy festive"],
}
# (name, month, day, rule, window_days)
# rule: None=固定日; "mother"=第2周日; "father"=第3周日; "thanks"=第4周四; "easter"=Computus; "bf"=thanks+1
_HOLIDAYS_BY_COUNTRY: Dict[str, List[tuple]] = {
"US": [
("New Year", 1, 1, None, 14),
("Valentine's Day", 2, 14, None, 21),
("St Patrick's Day", 3, 17, None, 14),
("Easter", 0, 0, "easter", 21),
("Mother's Day", 5, 0, "mother", 14),
("Father's Day", 6, 0, "father", 14),
("Pride Month", 6, 1, None, 7),
("Independence Day", 7, 4, None, 21),
("Summer Solstice", 6, 21, None, 14),
("Back to School", 8, 15, None, 30),
("Labor Day", 9, 0, "labor", 14),
("Halloween", 10, 31, None, 30),
("Thanksgiving (US)", 11, 0, "thanks", 21),
("Black Friday", 11, 0, "bf", 14),
("Christmas", 12, 25, None, 30),
("Winter Solstice", 12, 21, None, 14),
],
"GB": [
("New Year", 1, 1, None, 14),
("Valentine's Day", 2, 14, None, 21),
("St Patrick's Day", 3, 17, None, 14),
("Easter", 0, 0, "easter", 21),
("Mother's Day (UK)", 3, 0, "mother_uk", 14),
("Father's Day", 6, 0, "father", 14),
("Summer Bank Holiday", 8, 25, None, 14),
("Halloween", 10, 31, None, 30),
("Bonfire Night", 11, 5, None, 21),
("Remembrance Day", 11, 11, None, 14),
("Christmas", 12, 25, None, 30),
("Boxing Day", 12, 26, None, 14),
],
"JP": [
("New Year", 1, 1, None, 14),
("Valentine's Day", 2, 14, None, 21),
("Hinamatsuri", 3, 3, None, 14), # 雏祭
("Hanami", 4, 1, None, 21), # 花见(樱花季)
("Golden Week", 4, 29, None, 21),
("Children's Day", 5, 5, None, 14), # 子供の日
("Tanabata", 7, 7, None, 14), # 七夕
("Fireworks Season", 8, 1, None, 30), # 花火大会
("Obon", 8, 13, None, 21), # お盆
("Halloween", 10, 31, None, 30),
("Christmas", 12, 25, None, 30),
("New Year Eve", 12, 31, None, 14), # 大晦日
],
"AU": [
("New Year", 1, 1, None, 14),
("Australia Day", 1, 26, None, 21),
("Valentine's Day", 2, 14, None, 21),
("Easter", 0, 0, "easter", 21),
("Anzac Day", 4, 25, None, 21),
("Mother's Day (AU)", 5, 0, "mother", 14),
("Father's Day (AU)", 9, 0, "father", 14),
("Summer Christmas", 12, 25, None, 30),
("Boxing Day", 12, 26, None, 21),
("Halloween", 10, 31, None, 21),
],
}
def _easter(year: int) -> datetime.date:
a = year % 19
b = year // 100
c = year % 100
d = b // 4
e = b % 4
f = (b + 8) // 25
g = (b - f + 1) // 3
h = (19 * a + b - d - g + 15) % 30
i = c // 4
k = c % 4
l = (32 + 2 * e + 2 * i - h - k) % 7
m = (a + 11 * h + 22 * l) // 451
month = (h + l - 7 * m + 114) // 31
day = ((h + l - 7 * m + 114) % 31) + 1
return datetime.date(year, month, day)
def _resolve(name: str, month: int, day: int, rule, year: int) -> Optional[datetime.date]:
if rule is None:
return datetime.date(year, month, day)
if rule == "easter":
return _easter(year)
if rule in ("mother", "mother_uk"):
# 第2个周日(UK 用"母亲节"但实际 3 月第4周日前的第4大斋期周日——简化为 3 月第2周日)
if rule == "mother_uk":
month, week = 3, 2
else:
month, week = month, 2
first = datetime.date(year, month, 1)
return first + datetime.timedelta(days=(6 - first.weekday()) % 7 + (week - 1) * 7)
if rule == "father":
first = datetime.date(year, month, 1)
return first + datetime.timedelta(days=(6 - first.weekday()) % 7 + 2 * 7)
if rule == "thanks":
first = datetime.date(year, month, 1)
return first + datetime.timedelta(days=(3 - first.weekday()) % 7 + 3 * 7)
if rule == "bf":
t = _resolve("", 11, 0, "thanks", year)
return t + datetime.timedelta(days=1) if t else None
if rule == "labor":
first = datetime.date(year, month, 1)
return first + datetime.timedelta(days=(0 - first.weekday()) % 7)
return None
def holidays_for(country: str = "US") -> List[tuple]:
key = (country or "US").upper()
return _HOLIDAYS_BY_COUNTRY.get(key, _HOLIDAYS_BY_COUNTRY["US"])
def upcoming_holidays(now: Optional[datetime.date] = None, country: str = "US",
lower: int = -10) -> List[str]:
"""返回该国临近(未来 window 内,或刚过 lower 天内)的节日名。"""
now = now or datetime.date.today()
out: List[str] = []
for name, month, day, rule, window in holidays_for(country):
try:
d = _resolve(name, month, day, rule, now.year)
except Exception:
continue
if d is None:
continue
delta = (d - now).days
if lower <= delta <= window:
out.append(name)
return out
def build_holiday_context(country: str = "US",
now: Optional[datetime.date] = None) -> Dict[str, object]:
now = now or datetime.date.today()
return {
"date": now.isoformat(),
"year": now.year,
"month": now.month,
"season": SEASON_BY_MONTH.get(now.month, ""),
"month_themes": MONTH_THEMES.get(now.month, []),
"upcoming_holidays": upcoming_holidays(now, country),
}