diff options
| author | Bobby <[email protected]> | 2026-02-25 10:42:51 +0530 |
|---|---|---|
| committer | Bobby <[email protected]> | 2026-02-25 10:42:51 +0530 |
| commit | c18acfafee26d7d2508848135aa94a524f8dde06 (patch) | |
| tree | e0b4d5e07f872d9252af6d73fb8b108e15a49f91 /repositories | |
| parent | 2df69fab61b580b6b329db214ee0025a9d84958d (diff) | |
| download | metachan-c18acfafee26d7d2508848135aa94a524f8dde06.tar.xz metachan-c18acfafee26d7d2508848135aa94a524f8dde06.zip | |
Refactor anime update logic and task management
- Simplified title retrieval in AnimeUpdate and updateAnime functions.
- Updated next airing checks to use new fields directly.
- Removed unnecessary nil checks for titles in various functions.
- Enhanced task management by eliminating redundant LastRun updates.
- Improved dependency handling in triggerDependentTasks for better clarity and performance.
- Streamlined Jikan API response structure by merging related fields.
- Added StopRateLimiters function to rate limiter utilities for better control.
- Refined episode title handling in TMDB and TVDB enrichment functions.
- Introduced Stop method in MultiLimiter for graceful shutdown of rate limiters.
Diffstat (limited to 'repositories')
| -rw-r--r-- | repositories/anime.go | 30 | ||||
| -rw-r--r-- | repositories/persona.go | 264 |
2 files changed, 158 insertions, 136 deletions
diff --git a/repositories/anime.go b/repositories/anime.go index 4778f72..ae823c2 100644 --- a/repositories/anime.go +++ b/repositories/anime.go @@ -23,17 +23,9 @@ func GetAnime[T idType](maptype enums.MappingType, id T) (entities.Anime, error) result := DB. Preload("Mapping"). - Preload("Title"). - Preload("Images"). - Preload("Covers"). - Preload("Logos"). - Preload("Scores"). - Preload("AiringStatus"). - Preload("AiringStatus.From"). - Preload("AiringStatus.To"). - Preload("Broadcast"). - Preload("NextAiring"). Preload("Genres"). + Preload("Themes"). + Preload("Demographics"). Preload("Producers"). Preload("Producers.Image"). Preload("Producers.Titles"). @@ -47,19 +39,12 @@ func GetAnime[T idType](maptype enums.MappingType, id T) (entities.Anime, error) Preload("Licensors.Titles"). Preload("Licensors.ExternalURLs"). Preload("Episodes"). - Preload("Episodes.Title"). Preload("Episodes.SkipTimes"). Preload("Episodes.StreamInfo"). Preload("Episodes.StreamInfo.SubSources"). Preload("Episodes.StreamInfo.DubSources"). Preload("Schedule"). Preload("Seasons"). - Preload("Seasons.Title"). - Preload("Seasons.Images"). - Preload("Seasons.Scores"). - Preload("Seasons.AiringStatus"). - Preload("Seasons.AiringStatus.From"). - Preload("Seasons.AiringStatus.To"). Where("mapping_id = ?", mapping.ID). First(&anime) @@ -110,12 +95,7 @@ func SaveAnimeEpisodes(animeID uint, episodes []entities.Episode) error { var existing entities.Episode if DB.Where("episode_id = ?", ep.EpisodeID).First(&existing).Error == nil { ep.ID = existing.ID - ep.TitleID = existing.TitleID - DB.Model(ep).Omit("SkipTimes", "StreamInfo", "Title").Updates(ep) - if ep.Title != nil && existing.TitleID != 0 { - ep.Title.ID = existing.TitleID - DB.Save(ep.Title) - } + DB.Model(ep).Omit("SkipTimes", "StreamInfo").Updates(ep) } else { DB.Session(&gorm.Session{FullSaveAssociations: true}). Omit("SkipTimes", "StreamInfo"). @@ -158,7 +138,6 @@ func GetAnimeEpisode[T idType](maptype enums.MappingType, id T, episodeID string var episode entities.Episode result := DB. - Preload("Title"). Preload("SkipTimes"). Preload("StreamInfo"). Preload("StreamInfo.SubSources"). @@ -192,7 +171,6 @@ func GetAnimeEpisodes[T idType](maptype enums.MappingType, id T) ([]entities.Epi var episodes []entities.Episode result := DB. - Preload("Title"). Preload("SkipTimes"). Preload("StreamInfo"). Preload("StreamInfo.SubSources"). @@ -240,9 +218,7 @@ func GetAiringAnime() ([]entities.Anime, error) { result := DB. Where("airing = ?", true). - Preload("NextAiring"). Preload("Schedule"). - Preload("Title"). Find(&anime) if result.Error != nil { diff --git a/repositories/persona.go b/repositories/persona.go index 1cb808c..1da6d29 100644 --- a/repositories/persona.go +++ b/repositories/persona.go @@ -36,43 +36,45 @@ func UpdateCharacterDetails(malID int, name, nameKanji, url, imageURL, about str return err } - DB.Where("character_id = ?", char.ID).Delete(&entities.CharacterVoiceActor{}) - for _, cva := range voiceActors { - va := cva.Person - if va == nil { - continue - } + return DB.Transaction(func(tx *gorm.DB) error { + tx.Where("character_id = ?", char.ID).Delete(&entities.CharacterVoiceActor{}) + for _, cva := range voiceActors { + va := cva.Person + if va == nil { + continue + } - DB.Clauses(clause.OnConflict{ - Columns: []clause.Column{{Name: "mal_id"}}, - DoUpdates: clause.AssignmentColumns([]string{"url", "image", "name"}), - }).Create(va) - if va.ID == 0 { - DB.Where("mal_id = ?", va.MALID).First(va) - } + tx.Clauses(clause.OnConflict{ + Columns: []clause.Column{{Name: "mal_id"}}, + DoUpdates: clause.AssignmentColumns([]string{"url", "image", "name"}), + }).Create(va) + if va.ID == 0 { + tx.Where("mal_id = ?", va.MALID).First(va) + } - DB.Clauses(clause.OnConflict{ - Columns: []clause.Column{{Name: "character_id"}, {Name: "person_id"}}, - DoUpdates: clause.AssignmentColumns([]string{"language"}), - }).Create(&entities.CharacterVoiceActor{ - CharacterID: char.ID, - PersonID: va.ID, - Language: cva.Language, - }) - } + tx.Clauses(clause.OnConflict{ + Columns: []clause.Column{{Name: "character_id"}, {Name: "person_id"}}, + DoUpdates: clause.AssignmentColumns([]string{"language"}), + }).Create(&entities.CharacterVoiceActor{ + CharacterID: char.ID, + PersonID: va.ID, + Language: cva.Language, + }) + } - DB.Where("character_id = ?", char.ID).Delete(&entities.CharacterAnimeAppearance{}) - for i := range animeAppearances { - animeAppearances[i].CharacterID = char.ID - } - if len(animeAppearances) > 0 { - DB.Clauses(clause.OnConflict{ - Columns: []clause.Column{{Name: "character_id"}, {Name: "anime_mal_id"}}, - DoUpdates: clause.AssignmentColumns([]string{"title", "url", "image_url", "role"}), - }).Create(&animeAppearances) - } + tx.Where("character_id = ?", char.ID).Delete(&entities.CharacterAnimeAppearance{}) + for i := range animeAppearances { + animeAppearances[i].CharacterID = char.ID + } + if len(animeAppearances) > 0 { + tx.Clauses(clause.OnConflict{ + Columns: []clause.Column{{Name: "character_id"}, {Name: "anime_mal_id"}}, + DoUpdates: clause.AssignmentColumns([]string{"title", "url", "image_url", "role"}), + }).Create(&animeAppearances) + } - return nil + return nil + }) } func GetAnimeCharacters[T idType](maptype enums.MappingType, id T) ([]entities.Character, error) { @@ -98,15 +100,31 @@ func GetAnimeCharacters[T idType](maptype enums.MappingType, id T) ([]entities.C Where("anime_id = ?", anime.ID). Scan(&rows) + if len(rows) == 0 { + return []entities.Character{}, nil + } + + charIDs := make([]uint, len(rows)) + roleMap := make(map[uint]string, len(rows)) + for i, row := range rows { + charIDs[i] = row.CharacterID + roleMap[row.CharacterID] = row.Role + } + var characters []entities.Character - for _, row := range rows { - var char entities.Character - if err := DB.First(&char, row.CharacterID).Error; err != nil { - continue - } - DB.Preload("Person").Where("character_id = ?", char.ID).Find(&char.VoiceActors) - char.Role = row.Role - characters = append(characters, char) + DB.Where("id IN ?", charIDs).Find(&characters) + + var voiceActors []entities.CharacterVoiceActor + DB.Preload("Person").Where("character_id IN ?", charIDs).Find(&voiceActors) + + voiceActorsByCharacterID := make(map[uint][]entities.CharacterVoiceActor) + for _, voiceActor := range voiceActors { + voiceActorsByCharacterID[voiceActor.CharacterID] = append(voiceActorsByCharacterID[voiceActor.CharacterID], voiceActor) + } + + for i := range characters { + characters[i].Role = roleMap[characters[i].ID] + characters[i].VoiceActors = voiceActorsByCharacterID[characters[i].ID] } return characters, nil @@ -159,17 +177,34 @@ func loadAnimeCharacters(anime *entities.Anime) { Where("anime_id = ?", anime.ID). Scan(&rows) - for _, row := range rows { - var char entities.Character - if err := DB.First(&char, row.CharacterID).Error; err != nil { - continue - } - DB.Preload("Person"). - Where("character_id = ?", char.ID). - Find(&char.VoiceActors) - char.Role = row.Role - anime.Characters = append(anime.Characters, char) + if len(rows) == 0 { + return } + + charIDs := make([]uint, len(rows)) + roleMap := make(map[uint]string, len(rows)) + for i, row := range rows { + charIDs[i] = row.CharacterID + roleMap[row.CharacterID] = row.Role + } + + var characters []entities.Character + DB.Where("id IN ?", charIDs).Find(&characters) + + var voiceActors []entities.CharacterVoiceActor + DB.Preload("Person").Where("character_id IN ?", charIDs).Find(&voiceActors) + + voiceActorsByCharacterID := make(map[uint][]entities.CharacterVoiceActor) + for _, voiceActor := range voiceActors { + voiceActorsByCharacterID[voiceActor.CharacterID] = append(voiceActorsByCharacterID[voiceActor.CharacterID], voiceActor) + } + + for i := range characters { + characters[i].Role = roleMap[characters[i].ID] + characters[i].VoiceActors = voiceActorsByCharacterID[characters[i].ID] + } + + anime.Characters = characters } func SaveAnimeCharacters(animeID uint, characters []entities.Character) error { @@ -279,40 +314,48 @@ func UpdatePersonDetails( return err } - DB.Where("person_id = ?", p.ID).Delete(&entities.PersonVoiceRole{}) - for i := range voiceRoles { - voiceRoles[i].PersonID = p.ID - } - if len(voiceRoles) > 0 { - DB.Clauses(clause.OnConflict{ - Columns: []clause.Column{{Name: "person_id"}, {Name: "anime_mal_id"}, {Name: "character_mal_id"}}, - DoUpdates: clause.AssignmentColumns([]string{"role", "anime_title", "anime_url", "anime_image_url", "character_name", "character_url", "character_image_url"}), - }).Create(&voiceRoles) - } + return DB.Transaction(func(tx *gorm.DB) error { + tx.Where("person_id = ?", p.ID).Delete(&entities.PersonVoiceRole{}) + for i := range voiceRoles { + voiceRoles[i].PersonID = p.ID + } + if len(voiceRoles) > 0 { + if err := tx.Clauses(clause.OnConflict{ + Columns: []clause.Column{{Name: "person_id"}, {Name: "anime_mal_id"}, {Name: "character_mal_id"}}, + DoUpdates: clause.AssignmentColumns([]string{"role", "anime_title", "anime_url", "anime_image_url", "character_name", "character_url", "character_image_url"}), + }).Create(&voiceRoles).Error; err != nil { + return err + } + } - DB.Where("person_id = ?", p.ID).Delete(&entities.PersonAnimeCredit{}) - for i := range animeCredits { - animeCredits[i].PersonID = p.ID - } - if len(animeCredits) > 0 { - DB.Clauses(clause.OnConflict{ - Columns: []clause.Column{{Name: "person_id"}, {Name: "anime_mal_id"}}, - DoUpdates: clause.AssignmentColumns([]string{"position", "anime_title", "anime_url", "anime_image_url"}), - }).Create(&animeCredits) - } + tx.Where("person_id = ?", p.ID).Delete(&entities.PersonAnimeCredit{}) + for i := range animeCredits { + animeCredits[i].PersonID = p.ID + } + if len(animeCredits) > 0 { + if err := tx.Clauses(clause.OnConflict{ + Columns: []clause.Column{{Name: "person_id"}, {Name: "anime_mal_id"}}, + DoUpdates: clause.AssignmentColumns([]string{"position", "anime_title", "anime_url", "anime_image_url"}), + }).Create(&animeCredits).Error; err != nil { + return err + } + } - DB.Where("person_id = ?", p.ID).Delete(&entities.PersonMangaCredit{}) - for i := range mangaCredits { - mangaCredits[i].PersonID = p.ID - } - if len(mangaCredits) > 0 { - DB.Clauses(clause.OnConflict{ - Columns: []clause.Column{{Name: "person_id"}, {Name: "manga_mal_id"}}, - DoUpdates: clause.AssignmentColumns([]string{"position", "manga_title", "manga_url", "manga_image_url"}), - }).Create(&mangaCredits) - } + tx.Where("person_id = ?", p.ID).Delete(&entities.PersonMangaCredit{}) + for i := range mangaCredits { + mangaCredits[i].PersonID = p.ID + } + if len(mangaCredits) > 0 { + if err := tx.Clauses(clause.OnConflict{ + Columns: []clause.Column{{Name: "person_id"}, {Name: "manga_mal_id"}}, + DoUpdates: clause.AssignmentColumns([]string{"position", "manga_title", "manga_url", "manga_image_url"}), + }).Create(&mangaCredits).Error; err != nil { + return err + } + } - return nil + return nil + }) } func SetPersonEnriched(malID int) error { @@ -334,46 +377,49 @@ func GetAnimePeople[T idType](maptype enums.MappingType, id T) ([]entities.Perso return nil, errors.New("anime not found") } - var charRows []struct { - CharacterID uint - } + var charIDs []uint DB.Table("anime_characters"). Select("character_id"). Where("anime_id = ?", anime.ID). - Scan(&charRows) + Pluck("character_id", &charIDs) + + if len(charIDs) == 0 { + return []entities.Person{}, nil + } + + var characters []entities.Character + DB.Where("id IN ?", charIDs).Find(&characters) + + characterByID := make(map[uint]*entities.Character, len(characters)) + for i := range characters { + characterByID[characters[i].ID] = &characters[i] + } + + var characterVoiceActors []entities.CharacterVoiceActor + DB.Preload("Person").Where("character_id IN ?", charIDs).Find(&characterVoiceActors) personMap := make(map[uint]*entities.Person) - personChars := make(map[uint][]entities.PersonCharacterEntry) + personCharacters := make(map[uint][]entities.PersonCharacterEntry) - for _, row := range charRows { - var char entities.Character - if err := DB.First(&char, row.CharacterID).Error; err != nil { + for _, voiceActorEntry := range characterVoiceActors { + if voiceActorEntry.Person == nil { continue } - - var cvas []entities.CharacterVoiceActor - DB.Preload("Person").Where("character_id = ?", char.ID).Find(&cvas) - - for _, cva := range cvas { - if cva.Person == nil { - continue - } - pID := cva.PersonID - if _, exists := personMap[pID]; !exists { - personMap[pID] = cva.Person - } - charCopy := char - personChars[pID] = append(personChars[pID], entities.PersonCharacterEntry{ - Character: &charCopy, - Language: cva.Language, + if _, exists := personMap[voiceActorEntry.PersonID]; !exists { + personMap[voiceActorEntry.PersonID] = voiceActorEntry.Person + } + if character, ok := characterByID[voiceActorEntry.CharacterID]; ok { + personCharacters[voiceActorEntry.PersonID] = append(personCharacters[voiceActorEntry.PersonID], entities.PersonCharacterEntry{ + Character: character, + Language: voiceActorEntry.Language, }) } } result := make([]entities.Person, 0, len(personMap)) - for pID, p := range personMap { - p.Characters = personChars[pID] - result = append(result, *p) + for personID, person := range personMap { + person.Characters = personCharacters[personID] + result = append(result, *person) } return result, nil } |
