From 7aa298f90fb17bc915f15a90180feb8434d596a0 Mon Sep 17 00:00:00 2001 From: Bobby <30593201+luciferreeves@users.noreply.github.com> Date: Tue, 3 Feb 2026 15:17:34 +0530 Subject: Enhance episode ID generation and task management: include MAL ID and episode number for uniqueness, and update AnimeSync task to run weekly with last run tracking --- metachan/main.go | 4 +++- services/anime/helpers.go | 10 ++++++---- services/anime/service.go | 4 ++-- tasks/manager.go | 24 ++++++++++++++++++++++++ tasks/tasks.go | 8 +++++++- 5 files changed, 42 insertions(+), 8 deletions(-) diff --git a/metachan/main.go b/metachan/main.go index 9d57ce7..3892060 100644 --- a/metachan/main.go +++ b/metachan/main.go @@ -19,7 +19,9 @@ func main() { tasks.GlobalTaskManager.StartAllTasks() - app := fiber.New() + app := fiber.New(fiber.Config{ + DisableStartupMessage: true, + }) app.Use(cors.New(cors.Config{ AllowOrigins: "*", AllowMethods: "GET, HEAD, PUT, PATCH, POST, DELETE, OPTIONS", diff --git a/services/anime/helpers.go b/services/anime/helpers.go index 2c81116..2e735b0 100644 --- a/services/anime/helpers.go +++ b/services/anime/helpers.go @@ -16,7 +16,7 @@ import ( "time" ) -func generateEpisodeID(titles types.EpisodeTitles) string { +func generateEpisodeID(malID int, episodeNumber int, titles types.EpisodeTitles) string { var title string if titles.English != "" { title = titles.English @@ -26,11 +26,13 @@ func generateEpisodeID(titles types.EpisodeTitles) string { title = titles.Japanese } - hash := md5.Sum([]byte(title)) + // Include MAL ID and episode number to ensure uniqueness across all anime + uniqueString := fmt.Sprintf("%d-%d-%s", malID, episodeNumber, title) + hash := md5.Sum([]byte(uniqueString)) return fmt.Sprintf("%x", hash) } -func generateBasicEpisodes(episodes []jikan.JikanAnimeEpisode) []types.AnimeSingleEpisode { +func generateBasicEpisodes(malID int, episodes []jikan.JikanAnimeEpisode) []types.AnimeSingleEpisode { var animeEpisodes []types.AnimeSingleEpisode for _, episode := range episodes { @@ -41,7 +43,7 @@ func generateBasicEpisodes(episodes []jikan.JikanAnimeEpisode) []types.AnimeSing } animeEpisodes = append(animeEpisodes, types.AnimeSingleEpisode{ - ID: generateEpisodeID(titles), + ID: generateEpisodeID(malID, episode.MALID, titles), Titles: titles, Aired: episode.Aired, Score: episode.Score, diff --git a/services/anime/service.go b/services/anime/service.go index a22752b..ff7d0a6 100644 --- a/services/anime/service.go +++ b/services/anime/service.go @@ -227,7 +227,7 @@ func (s *Service) GetAnimeDetailsWithSource(mapping *entities.AnimeMapping, sour Prefix: "AnimeAPI", }) // Fallback to basic episode generation - basicEpisodes := generateBasicEpisodes(episodes.Data) + basicEpisodes := generateBasicEpisodes(anime.Data.MALID, episodes.Data) enrichedEpisodes = basicEpisodes } } else { @@ -265,7 +265,7 @@ func (s *Service) GetAnimeDetailsWithSource(mapping *entities.AnimeMapping, sour // Fallback to TMDB if TVDB failed or wasn't available if usedfallback { - basicEpisodes := generateBasicEpisodes(episodes.Data) + basicEpisodes := generateBasicEpisodes(anime.Data.MALID, episodes.Data) logger.Log(fmt.Sprintf("Generated basic episodes: %d", len(basicEpisodes)), logger.LogOptions{ Level: logger.Debug, Prefix: "AnimeAPI", diff --git a/tasks/manager.go b/tasks/manager.go index a420148..ef686dc 100644 --- a/tasks/manager.go +++ b/tasks/manager.go @@ -152,6 +152,15 @@ func (tm *TaskManager) StartTask(taskName string) { } } + // Skip ticker creation for manual-only tasks (interval = 0) + if task.Interval == 0 { + logger.Log(fmt.Sprintf("Task %s is manual-only (no scheduled interval)", taskName), logger.LogOptions{ + Level: logger.Debug, + Prefix: "TaskManager", + }) + return + } + // Create ticker for subsequent executions ticker := time.NewTicker(task.Interval) tm.Mutex.Lock() @@ -204,6 +213,21 @@ func (tm *TaskManager) StopTask(taskName string) { } } +// UpdateTaskLastRun manually updates a task's LastRun time +func (tm *TaskManager) UpdateTaskLastRun(taskName string, lastRun time.Time) { + tm.Mutex.Lock() + defer tm.Mutex.Unlock() + + if task, exists := tm.Tasks[taskName]; exists { + task.LastRun = lastRun + tm.Tasks[taskName] = task + logger.Log(fmt.Sprintf("Updated task %s LastRun: %v", taskName, lastRun), logger.LogOptions{ + Level: logger.Debug, + Prefix: "TaskManager", + }) + } +} + func (tm *TaskManager) StartAllTasks() { tm.Mutex.Lock() var taskNames []string diff --git a/tasks/tasks.go b/tasks/tasks.go index ecf8d80..484a826 100644 --- a/tasks/tasks.go +++ b/tasks/tasks.go @@ -36,6 +36,12 @@ func init() { Level: logger.Error, Prefix: "TaskManager", }) + GlobalTaskManager.logTaskExecution("AnimeSync", "error", err.Error()) + } else { + // Update AnimeSync's LastRun after successful completion + animeSyncEndTime := time.Now() + GlobalTaskManager.UpdateTaskLastRun("AnimeSync", animeSyncEndTime) + GlobalTaskManager.logTaskExecution("AnimeSync", "success", "Task executed successfully") } }() return nil @@ -52,7 +58,7 @@ func init() { // Register AnimeSync task (triggered automatically after AnimeFetch completes) err = GlobalTaskManager.RegisterTask(types.Task{ Name: "AnimeSync", - Interval: 0, // No scheduled interval - runs after AnimeFetch + Interval: 7 * 24 * time.Hour, // Same interval as AnimeFetch Execute: AniSync, }) -- cgit v1.2.3