package admin import ( "context" "time" "oneblog/internal/linkmeta" "oneblog/internal/model" ) // linkFetchBudget 是给外链抓取的时间预算:发布不该被一个慢站点拖住, // 超时就当作「这篇没有卡片」。 const linkFetchBudget = 2500 * time.Millisecond // linkFetch 是要不要抓远端的注入点:默认走带 SSRF 防护的真实抓取, // 测试里换成假实现(真实抓取在测试环境会被自己的防护拦掉)。 var linkFetch = linkmeta.Fetch // attachLinkCard 按正文重算短文链接卡片,结果写进 in.LinkCard。 // // 只处理短文(长文在时间线已有封面媒体位,再加卡片会抢位置); // 链接没变就沿用旧卡片,不重复抓远端;正文里删掉链接、或抓取失败, // 一律传空卡片把旧的清掉——宁可没有卡片,也不要挂着别的地址抓来的旧数据。 func attachLinkCard(ctx context.Context, in *model.PostInput, cur *model.LinkCard) { if in.Kind != model.KindShort || in.ContentMd == "" { return } u := linkmeta.FirstURL(in.ContentMd) if u == "" { in.LinkCard = &model.LinkCard{} return } if cur != nil && cur.URL == u { in.LinkCard = cur return } cctx, cancel := context.WithTimeout(ctx, linkFetchBudget) defer cancel() card, err := linkFetch(cctx, u) if err != nil { in.LinkCard = &model.LinkCard{} return } in.LinkCard = card }