feat(listing): populate Tags and CategorizedTags from figure data-tags
FA's beta listing pages emit each submission's tag list on the
figure's <img data-tags="..."> attribute, mixing prefixed system tags
(s_/c_/a_/u_/t_) with the unprefixed keyword list. Reading it during
gallery-page parse lets callers classify favorites/gallery/scraps/
browse/search/inbox items at scrape time, avoiding a /view/{id}
round-trip per submission.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -85,6 +85,15 @@ func parseGalleryFigure(sel *goquery.Selection, jsonData listingJSONMap) *Submis
|
||||
}
|
||||
}
|
||||
|
||||
// data-tags on the figure's <img> carries both the unprefixed keyword
|
||||
// list and the prefixed system tags (s_/c_/a_/u_/t_). Splitting it lets
|
||||
// callers classify listing items without an extra /view/ fetch.
|
||||
if img := sel.Find("img[data-tags]").First(); img.Length() > 0 {
|
||||
if raw, ok := img.Attr("data-tags"); ok {
|
||||
applyListingDataTags(s, raw)
|
||||
}
|
||||
}
|
||||
|
||||
// JSON enrichment preferred sources for the fields it carries.
|
||||
if jsonData != nil {
|
||||
if entry, ok := jsonData[id]; ok {
|
||||
@@ -105,3 +114,35 @@ func parseGalleryFigure(sel *goquery.Selection, jsonData listingJSONMap) *Submis
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
// applyListingDataTags splits the whitespace-separated data-tags attribute
|
||||
// FA emits on listing-page <img> elements and routes each token to either
|
||||
// CategorizedTags (when the token has a known single-letter prefix
|
||||
// s_/c_/a_/u_/t_) or Tags (everything else).
|
||||
//
|
||||
// The prefix mapping mirrors the /view/ parser in submission_parser.go so a
|
||||
// listing-path Submission carries the same categorisation a /view/-path one
|
||||
// would, modulo tokens FA can't represent in this flat attribute (multi-word
|
||||
// tags, the a_ vs u_ distinction).
|
||||
func applyListingDataTags(s *Submission, raw string) {
|
||||
for _, tok := range strings.Fields(raw) {
|
||||
if len(tok) >= 3 && tok[1] == '_' {
|
||||
name := tok[2:]
|
||||
switch tok[0] {
|
||||
case 's':
|
||||
s.CategorizedTags.Species = append(s.CategorizedTags.Species, name)
|
||||
continue
|
||||
case 'c':
|
||||
s.CategorizedTags.Characters = append(s.CategorizedTags.Characters, name)
|
||||
continue
|
||||
case 'a', 'u':
|
||||
s.CategorizedTags.Artists = append(s.CategorizedTags.Artists, name)
|
||||
continue
|
||||
case 't':
|
||||
s.CategorizedTags.Types = append(s.CategorizedTags.Types, name)
|
||||
continue
|
||||
}
|
||||
}
|
||||
s.Tags = append(s.Tags, tok)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user