diff --git a/assets/views/user.jet.html b/assets/views/user.jet.html index 8234121..9a74d07 100644 --- a/assets/views/user.jet.html +++ b/assets/views/user.jet.html @@ -92,10 +92,10 @@ -
+ +
@@ -138,6 +139,22 @@ {{ if len(.User.Illustrations) != 0 }}

Illustrations{{ .User.WorkCounts.Illustrations }}

+ +
+ {{- range .User.Categories.illustrations.FrequentTags }} +
+ + + #{{ .Name }} + + {{- if .TranslatedName }} + ({{ .TranslatedName }}) + {{- end }} + +
+ {{- end }} +
+
{{- include "fragments/small-tn" .User.Illustrations }}
@@ -155,8 +172,23 @@

Manga{{ .User.WorkCounts.Manga }}

+
+ {{- range .User.Categories.manga.FrequentTags }} +
+ + + #{{ .Name }} + + {{- if .TranslatedName }} + ({{ .TranslatedName }}) + {{- end }} + +
+ {{- end }} +
+ {{- if len(.User.MangaSeries) != 0 }} -
+
{{- range .User.MangaSeries }} {{- include "fragments/mangaseries-tn" . }} @@ -181,8 +213,23 @@

Novels{{ .User.WorkCounts.Novels }}

+
+ {{- range .User.Categories.novels.FrequentTags }} +
+ + + #{{ .Name }} + + {{- if .TranslatedName }} + ({{ .TranslatedName }}) + {{- end }} + +
+ {{- end }} +
+ {{- if len(.User.NovelSeries) != 0 }} -
+
{{- range .User.NovelSeries }} {{- include "fragments/novelseries-tn" . }} @@ -218,6 +265,22 @@ {{- combinedUrl := "/artworks-multi/" + joinArtworkIds(.User.Illustrations) }}
+ +
+ {{- range .User.Categories.illustrations.FrequentTags }} +
+ + + #{{ .Name }} + + {{- if .TranslatedName }} + ({{ .TranslatedName }}) + {{- end }} + +
+ {{- end }} +
+
{{- include "fragments/small-tn" .User.Illustrations }}
@@ -231,6 +294,21 @@
+
+ {{- range .User.Categories.manga.FrequentTags }} +
+ + + #{{ .Name }} + + {{- if .TranslatedName }} + ({{ .TranslatedName }}) + {{- end }} + +
+ {{- end }} +
+ {{- if len(.User.MangaSeries) != 0 }}
@@ -251,6 +329,22 @@

Novels{{ .User.WorkCounts.Novels }}

+ +
+ {{- range .User.Categories.novels.FrequentTags }} +
+ + + #{{ .Name }} + + {{- if .TranslatedName }} + ({{ .TranslatedName }}) + {{- end }} + +
+ {{- end }} +
+
{{- range .User.Novels }}
diff --git a/core/user.go b/core/user.go index e948615..3bc9af4 100644 --- a/core/user.go +++ b/core/user.go @@ -15,17 +15,18 @@ import ( "go.uber.org/zap" ) -// UserWorkCategory is a struct that represents a category of user work with a page limit. +// UserWorkCategory is a struct that represents a category of user work with a page limit and frequent tags. // // pixivfe internal data type. not used by pixiv. type UserWorkCategory struct { - Value string - PageLimit int + Value string + PageLimit int + FrequentTags []FrequentTag } // NewUserWorkCategory creates UserWorkCategory instances func NewUserWorkCategory(value string) UserWorkCategory { - return UserWorkCategory{Value: value, PageLimit: 0} + return UserWorkCategory{Value: value, PageLimit: 0, FrequentTags: []FrequentTag{}} } func (c *UserWorkCategory) SetPageLimit(limit int) { @@ -103,6 +104,8 @@ type User struct { // Used to display the number of works for a given category WorkCounts WorkCounts + + Categories map[string]*UserWorkCategory } // GetUserProfile retrieves the user profile, including counts, artworks/bookmarks, and social data. @@ -296,15 +299,45 @@ func getPopulatedWorks(auditor *audit.Auditor, r *http.Request, user *User, id s auditor.Logger.Debug("NovelBriefs populated", zap.Int("novelsCount", len(novels))) } - // Fetch a user's frequently used tags if requested + // Initialize the user categories + user.Categories = map[string]*UserWorkCategory{ + "illustrations": {Value: "illustrations"}, + "manga": {Value: "manga"}, + "novels": {Value: "novels"}, + } + + // Define the categories with their IDs + categories := []struct { + name string + ids string + workCategory *UserWorkCategory + }{ + { + name: "illustrations", + ids: illustrationIDs, + workCategory: user.Categories["illustrations"], + }, + { + name: "manga", + ids: mangaIDs, + workCategory: user.Categories["manga"], + }, + { + name: "novels", + ids: novelIDs, + workCategory: user.Categories["novels"], + }, + } + + // Fetch frequent tags if getTags { auditor.Logger.Debug("Fetching frequent tags") - user.FrequentTags, err = populateFrequentTags(auditor, r, id, currentCategory, illustrationIDs, mangaIDs, novelIDs) + err := populateFrequentTags(auditor, r, id, categories) if err != nil { auditor.SugaredLogger.Error("Failed to populate frequent tags", zap.Error(err)) return err } - auditor.Logger.Debug("Frequent tags populated", zap.Int("tagsCount", len(user.FrequentTags))) + auditor.Logger.Debug("Frequent tags populated") } // Handle series data @@ -330,109 +363,24 @@ func populateFrequentTags( auditor *audit.Auditor, r *http.Request, id string, - currentCategory *UserWorkCategory, - illustrationIDs string, - mangaIDs string, - novelIDs string, -) ([]FrequentTag, error) { - var ( - primaryTagsIDs []string // For illustrationIDs and mangaIDs - secondaryTagsIDs []string // For novelIDs - ) - - // Append illustrationIDs to primaryTagsIDs if applicable - if illustrationIDs != "" { - primaryTagsIDs = append(primaryTagsIDs, illustrationIDs) - auditor.Logger.Debug( - "illustrationIDs found, appended to primaryTagsIDs", - // zap.Strings("primaryTagsIDs", primaryTagsIDs), - // zap.String("illustrationIDs", illustrationIDs), - ) - } - - // Append mangaIDs to primaryTagsIDs if applicable - if mangaIDs != "" { - primaryTagsIDs = append(primaryTagsIDs, mangaIDs) - auditor.Logger.Debug( - "mangaIDs found, appended to primaryTagsIDs", - // zap.Strings("primaryTagsIDs", primaryTagsIDs), - // zap.String("mangaIDs", mangaIDs), - ) - } - - // Append novelIDs to secondaryTagsIDs if applicable - if novelIDs != "" { - secondaryTagsIDs = append(secondaryTagsIDs, novelIDs) - auditor.Logger.Debug( - "novelIDs found, appended to secondaryTagsIDs", - // zap.Strings("secondaryTagsIDs", secondaryTagsIDs), - // zap.String("novelIDs", novelIDs), - ) - } - - // Function to count the number of items based on delimiter - countIDs := func(ids []string) int { - count := 0 - for _, idStr := range ids { - // Each idStr contains multiple "&ids[]=" entries, so we split by "&ids[]=" and count non-empty parts - parts := strings.Split(idStr, "&ids[]=") - for _, part := range parts { - if part != "" { - count++ - } - } + categories []struct { + name string + ids string + workCategory *UserWorkCategory + }, +) error { + for _, cat := range categories { + if cat.ids == "" { + continue } - return count - } - - // Count the number of items in each group - primaryCount := countIDs(primaryTagsIDs) - secondaryCount := countIDs(secondaryTagsIDs) - - auditor.Logger.Debug( - "Counts of primary and secondary tags", - zap.Int("primaryCount", primaryCount), - zap.Int("secondaryCount", secondaryCount), - ) - - var finalTagsIDs []string - - // Decide which tagsIDs to use based on the count - if primaryCount > secondaryCount { - finalTagsIDs = primaryTagsIDs - auditor.Logger.Debug( - "Selected primaryTagsIDs as finalTagsIDs", - zap.Strings("finalTagsIDs", finalTagsIDs), - ) - } else { - finalTagsIDs = secondaryTagsIDs - auditor.Logger.Debug( - "Selected secondaryTagsIDs as finalTagsIDs", - zap.Strings("finalTagsIDs", finalTagsIDs), - ) - } - - // Check if any tags were found - if len(finalTagsIDs) != 0 { - // Concatenate IDs to form a single string - ids := strings.Join(finalTagsIDs, "") - frequentTags, err := fetchFrequentTags(auditor, r, ids, currentCategory) + tags, err := fetchFrequentTags(auditor, r, cat.ids, cat.workCategory) if err != nil { - return nil, fmt.Errorf("failed to get user frequent tags: %w", err) + auditor.SugaredLogger.Error("Failed to fetch frequent tags", zap.String("category", cat.name), zap.Error(err)) + return err } - return frequentTags, nil + cat.workCategory.FrequentTags = tags } - - auditor.Logger.Warn( - "No tags found to fetch, setting FrequentTags to empty slice", - zap.String("currentCategory", currentCategory.Value), - zap.Strings("primaryTagsIDs", primaryTagsIDs), - zap.Strings("secondaryTagsIDs", secondaryTagsIDs), - zap.String("illustrationIDs", illustrationIDs), - zap.String("mangaIDs", mangaIDs), - zap.String("novelIDs", novelIDs), - ) - return []FrequentTag{}, nil + return nil } // The HasID interface allows for generic handling of the ArtworkBrief @@ -783,15 +731,17 @@ func handleSeriesData(auditor *audit.Auditor, mangaSeriesData, novelSeriesData j } // fetchFrequentTags fetches a user's frequently used tags, based on category. -func fetchFrequentTags(auditor *audit.Auditor, r *http.Request, ids string, currentCategory *UserWorkCategory) ([]FrequentTag, error) { +func fetchFrequentTags(auditor *audit.Auditor, r *http.Request, ids string, workCategory *UserWorkCategory) ([]FrequentTag, error) { var tags []FrequentTag var URL string - // TODO: If overall, request both? - if currentCategory != &CategoryNovels { + switch workCategory.Value { + case "illustrations", "manga": URL = GetUserFrequentArtworkTagsURL(ids) - } else { + case "novels": URL = GetUserFrequentNovelTagsURL(ids) + default: + return tags, fmt.Errorf("unsupported category: %s", workCategory.Value) } // Return early if there are no IDs