aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBobby <[email protected]>2026-02-04 16:41:53 +0530
committerBobby <[email protected]>2026-02-04 16:41:53 +0530
commit34d69f0e2557f4d65ba976485d80b2df035c7ce1 (patch)
tree7985f260d7c020a6b7ae5bf8c2b6169df103240b
parent6e5715300894fec56ad97305fda5cdab6f84f700 (diff)
downloadmetachan-34d69f0e2557f4d65ba976485d80b2df035c7ce1.tar.xz
metachan-34d69f0e2557f4d65ba976485d80b2df035c7ce1.zip
Add entity definitions for anime, episodes, genres, mappings, and related structures
-rw-r--r--entities/anime.go302
-rw-r--r--entities/episode.go56
-rw-r--r--entities/genre.go12
-rw-r--r--entities/mapping.go26
-rw-r--r--entities/meta.go79
-rw-r--r--entities/persona.go24
-rw-r--r--entities/producer.go17
-rw-r--r--entities/seasons.go23
-rw-r--r--entities/tasks.go15
9 files changed, 282 insertions, 272 deletions
diff --git a/entities/anime.go b/entities/anime.go
index 34f3b04..0ae8df7 100644
--- a/entities/anime.go
+++ b/entities/anime.go
@@ -6,274 +6,40 @@ import (
"gorm.io/gorm"
)
-type MappingType string
-
-const (
- m_SPECIAL MappingType = "SPECIAL"
- m_TV MappingType = "TV"
- m_OVA MappingType = "OVA"
- m_MOVIE MappingType = "MOVIE"
- m_ONA MappingType = "ONA"
- m_UNKNOWN MappingType = "UNKNOWN"
-)
-
-type AnimeMapping struct {
- gorm.Model
- AniDB int
- Anilist int
- AnimeCountdown int
- AnimePlanet string
- AniSearch int
- IMDB string
- Kitsu int
- LiveChart int
- MAL int
- NotifyMoe string
- Simkl int
- TMDB int
- TVDB int
- Type MappingType
- MALAnilistComposite *string `gorm:"uniqueIndex"`
-}
-
type Anime struct {
gorm.Model
- MALID int `gorm:"uniqueIndex"`
- TitleRomaji string
- TitleEnglish string
- TitleJapanese string
- TitleSynonyms string
- Synopsis string `gorm:"type:text"`
- Type string
- Source string
- Airing bool
- Status string
- Duration string
- Color string
- Season string
- Year int
- SubbedCount int
- DubbedCount int
- TotalEpisodes int
- AiredEpisodes int
- LastUpdated time.Time
-
- Images *AnimeImages `gorm:"foreignKey:AnimeID"`
- Logos *AnimeLogos `gorm:"foreignKey:AnimeID"`
- Covers *AnimeCovers `gorm:"foreignKey:AnimeID"`
- Scores *AnimeScores `gorm:"foreignKey:AnimeID"`
- AiringStatus *AiringStatus `gorm:"foreignKey:AnimeID"`
- Broadcast *AnimeBroadcast `gorm:"foreignKey:AnimeID"`
- NextAiringEpisode *NextEpisode `gorm:"foreignKey:AnimeID"`
-
- Genres []AnimeGenre `gorm:"foreignKey:AnimeID"`
- Producers []AnimeProducer `gorm:"foreignKey:AnimeID"`
- Studios []AnimeStudio `gorm:"foreignKey:AnimeID"`
- Licensors []AnimeLicensor `gorm:"foreignKey:AnimeID"`
- Episodes []AnimeSingleEpisode `gorm:"foreignKey:AnimeID"`
- Characters []AnimeCharacter `gorm:"foreignKey:AnimeID"`
- AiringSchedule []ScheduleEpisode `gorm:"foreignKey:AnimeID;constraint:OnDelete:CASCADE"`
- Seasons []AnimeSeason `gorm:"foreignKey:ParentAnimeID"`
-}
-
-type AnimeImages struct {
- gorm.Model
- AnimeID uint
- Small string
- Large string
- Original string
-}
-
-type AnimeCovers struct {
- gorm.Model
- AnimeID uint
- Small string
- Large string
- Original string
-}
-
-type AnimeLogos struct {
- gorm.Model
- AnimeID uint
- Small string
- Medium string
- Large string
- XLarge string
- Original string
-}
-
-type AnimeScores struct {
- gorm.Model
- AnimeID uint
- Score float64
- ScoredBy int
- Rank int
- Popularity int
- Members int
- Favorites int
-}
-
-type AiringStatusDates struct {
- gorm.Model
- Day int
- Month int
- Year int
- String string
-}
-
-type AiringStatus struct {
- gorm.Model
- AnimeID uint
- FromID *uint
- ToID *uint
- String string
-
- From *AiringStatusDates `gorm:"foreignKey:FromID"`
- To *AiringStatusDates `gorm:"foreignKey:ToID"`
-}
-
-type AnimeBroadcast struct {
- gorm.Model
- AnimeID uint
- Day string
- Time string
- Timezone string
- String string
-}
-
-type AnimeGenre struct {
- gorm.Model
- AnimeID uint
- Name string
- GenreID int
- URL string
- Count int `gorm:"default:0"` // Total count from MAL (only set when AnimeID=0 for master genres)
-}
-
-type AnimeProducer struct {
- gorm.Model
- AnimeID uint
- Name string
- ProducerID int
- URL string
-}
-
-type AnimeStudio struct {
- gorm.Model
- AnimeID uint
- Name string
- StudioID int
- URL string
-}
-
-type AnimeLicensor struct {
- gorm.Model
- AnimeID uint
- Name string
- ProducerID int
- URL string
-}
-
-type ScheduleEpisode struct {
- gorm.Model
- AnimeID uint
- AiringAt int
- Episode int
- IsNext bool `gorm:"index"`
-}
-
-type EpisodeTitles struct {
- gorm.Model
- EpisodeID uint
- English string
- Japanese string
- Romaji string
-}
-
-type AnimeSingleEpisode struct {
- gorm.Model
- EpisodeID string `gorm:"uniqueIndex;size:32"`
- AnimeID uint
- TitlesID uint
- Description string `gorm:"type:text"`
- Aired string
- Score float64
- Filler bool
- Recap bool
- ForumURL string
- URL string
- ThumbnailURL string
-
- Titles *EpisodeTitles `gorm:"foreignKey:TitlesID"`
-}
-
-type AnimeSeason struct {
- gorm.Model
- ParentAnimeID uint
- MALID int
- TitleRomaji string
- TitleEnglish string
- TitleJapanese string
- TitleSynonyms string
- Synopsis string `gorm:"type:text"`
- Type string
- Source string
- Airing bool
- Status string
- Duration string
- Season string
- Year int
- Current bool
-
- Images *AnimeImages `gorm:"foreignKey:AnimeID"`
- Scores *AnimeScores `gorm:"foreignKey:AnimeID"`
- AiringStatus *AiringStatus `gorm:"foreignKey:AnimeID"`
-}
-
-type AnimeVoiceActor struct {
- gorm.Model
- CharacterID uint
- MALID int
- URL string
- Image string
- Name string
- Language string
-}
-
-type AnimeCharacter struct {
- gorm.Model
- AnimeID uint
- MALID int
- URL string
- ImageURL string
- Name string
- Role string
-
- VoiceActors []AnimeVoiceActor `gorm:"foreignKey:CharacterID"`
-}
-
-type NextEpisode struct {
- gorm.Model
- AnimeID uint
- AiringAt int
- Episode int
-}
-
-// EpisodeStreamingSource stores individual streaming sources for episodes
-type EpisodeStreamingSource struct {
- gorm.Model
- EpisodeStreamingID uint
- URL string
- Server string
- Type string // M3U8, MP4, or embed
-}
-
-// EpisodeStreaming stores streaming data for a specific episode
-type EpisodeStreaming struct {
- gorm.Model
- EpisodeID string `gorm:"uniqueIndex:idx_episode_streaming;size:32"`
- AnimeID uint `gorm:"uniqueIndex:idx_episode_streaming"`
- SubSources []EpisodeStreamingSource `gorm:"foreignKey:EpisodeStreamingID;constraint:OnDelete:CASCADE"`
- DubSources []EpisodeStreamingSource `gorm:"foreignKey:EpisodeStreamingID;constraint:OnDelete:CASCADE"`
- LastFetch time.Time
+ MALID int `gorm:"uniqueIndex" json:"id"`
+ TitleID uint `json:"title_id,omitempty"`
+ MappingID uint `json:"mapping_id,omitempty"`
+ Synopsis string `gorm:"type:text" json:"synopsis,omitempty"`
+ Type string `json:"type,omitempty"`
+ Source string `json:"source,omitempty"`
+ Airing bool `json:"airing,omitempty"`
+ Status string `json:"status,omitempty"`
+ Duration string `json:"duration,omitempty"`
+ Color string `json:"color,omitempty"`
+ Season string `json:"season,omitempty"`
+ Year int `json:"year,omitempty"`
+ SubbedCount int `json:"subbed_count,omitempty"`
+ DubbedCount int `json:"dubbed_count,omitempty"`
+ TotalEpisodes int `json:"total_episodes,omitempty"`
+ AiredEpisodes int `json:"aired_episodes,omitempty"`
+ LastUpdated time.Time `json:"last_updated,omitempty"`
+ Title *Title `gorm:"foreignKey:TitleID" json:"titles,omitempty"`
+ Mapping *Mapping `gorm:"foreignKey:MappingID" json:"mappings,omitempty"`
+ Images *Images `gorm:"foreignKey:AnimeID" json:"images,omitempty"`
+ Covers *Images `gorm:"foreignKey:AnimeID" json:"covers,omitempty"`
+ Logos *Logos `gorm:"foreignKey:AnimeID" json:"logos,omitempty"`
+ Scores *Scores `gorm:"foreignKey:AnimeID" json:"scores,omitempty"`
+ AiringStatus *AiringStatus `gorm:"foreignKey:AnimeID" json:"airing_status,omitempty"`
+ Broadcast *Broadcast `gorm:"foreignKey:AnimeID" json:"broadcast,omitempty"`
+ NextAiring *NextEpisode `gorm:"foreignKey:AnimeID" json:"next_airing_episode,omitempty"`
+ Genres []Genre `gorm:"many2many:anime_genres;" json:"genres,omitempty"`
+ Producers []Producer `gorm:"many2many:anime_producers;" json:"producers,omitempty"`
+ Studios []Producer `gorm:"many2many:anime_studios;" json:"studios,omitempty"`
+ Licensors []Producer `gorm:"many2many:anime_licensors;" json:"licensors,omitempty"`
+ Episodes []Episode `gorm:"foreignKey:AnimeID" json:"episodes,omitempty"`
+ Characters []Character `gorm:"foreignKey:AnimeID" json:"characters,omitempty"`
+ Schedule []EpisodeSchedule `gorm:"foreignKey:AnimeID;constraint:OnDelete:CASCADE" json:"airing_schedule,omitempty"`
+ Seasons []Season `gorm:"foreignKey:ParentAnimeID" json:"seasons,omitempty"`
}
diff --git a/entities/episode.go b/entities/episode.go
new file mode 100644
index 0000000..afe644a
--- /dev/null
+++ b/entities/episode.go
@@ -0,0 +1,56 @@
+package entities
+
+import (
+ "time"
+
+ "gorm.io/gorm"
+)
+
+type Episode struct {
+ gorm.Model
+ EpisodeID string `gorm:"uniqueIndex;size:32" json:"id"`
+ AnimeID uint `json:"anime_id,omitempty"`
+ TitleID uint `json:"title_id,omitempty"`
+ Description string `gorm:"type:text" json:"description,omitempty"`
+ Aired string `json:"aired,omitempty"`
+ Score float64 `json:"score,omitempty"`
+ Filler bool `json:"filler,omitempty"`
+ Recap bool `json:"recap,omitempty"`
+ ForumURL string `json:"forum_url,omitempty"`
+ URL string `json:"url,omitempty"`
+ ThumbnailURL string `json:"thumbnail_url,omitempty"`
+ Title *Title `gorm:"foreignKey:TitleID" json:"titles,omitempty"`
+ StreamInfo *StreamInfo `gorm:"foreignKey:EpisodeID;references:EpisodeID" json:"streaming,omitempty"`
+}
+
+type EpisodeSchedule struct {
+ gorm.Model
+ AnimeID uint `json:"anime_id,omitempty"`
+ AiringAt int `json:"airing_at,omitempty"`
+ Episode int `json:"episode,omitempty"`
+ IsNext bool `gorm:"index" json:"is_next,omitempty"`
+}
+
+type NextEpisode struct {
+ gorm.Model
+ AnimeID uint `json:"anime_id,omitempty"`
+ AiringAt int `json:"airing_at,omitempty"`
+ Episode int `json:"episode,omitempty"`
+}
+
+type StreamInfo struct {
+ gorm.Model
+ EpisodeID string `gorm:"uniqueIndex:idx_episode_streaming;size:32" json:"episode_id"`
+ AnimeID uint `gorm:"uniqueIndex:idx_episode_streaming" json:"anime_id,omitempty"`
+ SubSources []StreamingSource `gorm:"foreignKey:StreamInfoID;constraint:OnDelete:CASCADE" json:"sub_sources,omitempty"`
+ DubSources []StreamingSource `gorm:"foreignKey:StreamInfoID;constraint:OnDelete:CASCADE" json:"dub_sources,omitempty"`
+ LastFetch time.Time `json:"last_fetch,omitempty"`
+}
+
+type StreamingSource struct {
+ gorm.Model
+ StreamInfoID uint `json:"stream_info_id,omitempty"`
+ URL string `json:"url,omitempty"`
+ Server string `json:"server,omitempty"`
+ Type string `json:"type,omitempty"`
+}
diff --git a/entities/genre.go b/entities/genre.go
new file mode 100644
index 0000000..f8763b3
--- /dev/null
+++ b/entities/genre.go
@@ -0,0 +1,12 @@
+package entities
+
+import "gorm.io/gorm"
+
+type Genre struct {
+ gorm.Model
+ Name string `json:"name,omitempty"`
+ GenreID int `json:"genre_id,omitempty"`
+ URL string `json:"url,omitempty"`
+ Count int `gorm:"default:0" json:"count,omitempty"`
+ Anime []Anime `gorm:"many2many:anime_genres;" json:"anime,omitempty"`
+}
diff --git a/entities/mapping.go b/entities/mapping.go
new file mode 100644
index 0000000..51e588a
--- /dev/null
+++ b/entities/mapping.go
@@ -0,0 +1,26 @@
+package entities
+
+import (
+ "metachan/enums"
+
+ "gorm.io/gorm"
+)
+
+type Mapping struct {
+ gorm.Model
+ AniDB int `json:"anidb,omitempty"`
+ Anilist int `json:"anilist,omitempty"`
+ AnimeCountdown int `json:"anime_countdown,omitempty"`
+ AnimePlanet string `json:"anime_planet,omitempty"`
+ AniSearch int `json:"ani_search,omitempty"`
+ IMDB string `json:"imdb,omitempty"`
+ Kitsu int `json:"kitsu,omitempty"`
+ LiveChart int `json:"live_chart,omitempty"`
+ MAL int `json:"mal,omitempty"`
+ NotifyMoe string `json:"notify_moe,omitempty"`
+ Simkl int `json:"simkl,omitempty"`
+ TMDB int `json:"tmdb,omitempty"`
+ TVDB int `json:"tvdb,omitempty"`
+ Type enums.MappingAnimeType `json:"type,omitempty"`
+ MALAnilistComposite *string `gorm:"uniqueIndex"`
+}
diff --git a/entities/meta.go b/entities/meta.go
new file mode 100644
index 0000000..deb1e08
--- /dev/null
+++ b/entities/meta.go
@@ -0,0 +1,79 @@
+package entities
+
+import "gorm.io/gorm"
+
+type Title struct {
+ gorm.Model
+ English string `json:"english,omitempty"`
+ Japanese string `json:"japanese,omitempty"`
+ Romaji string `json:"romaji,omitempty"`
+ Synonyms []string `gorm:"serializer:json" json:"synonyms,omitempty"`
+}
+
+type Scores struct {
+ gorm.Model
+ Score float64 `json:"score,omitempty"`
+ ScoredBy int `json:"scored_by,omitempty"`
+ Rank int `json:"rank,omitempty"`
+ Popularity int `json:"popularity,omitempty"`
+ Members int `json:"members,omitempty"`
+ Favorites int `json:"favorites,omitempty"`
+}
+
+type Date struct {
+ gorm.Model
+ Day int `json:"day,omitempty"`
+ Month int `json:"month,omitempty"`
+ Year int `json:"year,omitempty"`
+ String string `json:"string,omitempty"`
+}
+
+type AiringStatus struct {
+ gorm.Model
+ FromID *uint `json:"from_id,omitempty"`
+ ToID *uint `json:"to_id,omitempty"`
+ String string `json:"string,omitempty"`
+ From *Date `gorm:"foreignKey:FromID" json:"from,omitempty"`
+ To *Date `gorm:"foreignKey:ToID" json:"to,omitempty"`
+}
+
+type Broadcast struct {
+ gorm.Model
+ Day string `json:"day,omitempty"`
+ Time string `json:"time,omitempty"`
+ Timezone string `json:"timezone,omitempty"`
+ String string `json:"string,omitempty"`
+}
+
+type Images struct {
+ gorm.Model
+ Small string `json:"small,omitempty"`
+ Large string `json:"large,omitempty"`
+ Original string `json:"original,omitempty"`
+}
+
+type Logos struct {
+ gorm.Model
+ Small string `json:"small,omitempty"`
+ Medium string `json:"medium,omitempty"`
+ Large string `json:"large,omitempty"`
+ XLarge string `json:"xlarge,omitempty"`
+ Original string `json:"original,omitempty"`
+}
+
+type ExternalURL struct {
+ gorm.Model
+ Name string `json:"name,omitempty"`
+ URL string `json:"url,omitempty"`
+}
+
+type SimpleTitle struct {
+ gorm.Model
+ Type string `json:"type,omitempty"`
+ Title string `json:"title,omitempty"`
+}
+
+type SimpleImage struct {
+ gorm.Model
+ ImageURL string `json:"image_url,omitempty"`
+}
diff --git a/entities/persona.go b/entities/persona.go
new file mode 100644
index 0000000..9928589
--- /dev/null
+++ b/entities/persona.go
@@ -0,0 +1,24 @@
+package entities
+
+import "gorm.io/gorm"
+
+type Character struct {
+ gorm.Model
+ AnimeID uint `json:"anime_id,omitempty"`
+ MALID int `json:"mal_id,omitempty"`
+ URL string `json:"url,omitempty"`
+ ImageURL string `json:"image_url,omitempty"`
+ Name string `json:"name,omitempty"`
+ Role string `json:"role,omitempty"`
+ VoiceActors []VoiceActor `gorm:"foreignKey:CharacterID" json:"voice_actors,omitempty"`
+}
+
+type VoiceActor struct {
+ gorm.Model
+ CharacterID uint `json:"character_id,omitempty"`
+ MALID int `json:"mal_id,omitempty"`
+ URL string `json:"url,omitempty"`
+ Image string `json:"image_url,omitempty"`
+ Name string `json:"name,omitempty"`
+ Language string `json:"language,omitempty"`
+}
diff --git a/entities/producer.go b/entities/producer.go
new file mode 100644
index 0000000..356eb06
--- /dev/null
+++ b/entities/producer.go
@@ -0,0 +1,17 @@
+package entities
+
+import "gorm.io/gorm"
+
+type Producer struct {
+ gorm.Model
+ MALID int `gorm:"uniqueIndex" json:"mal_id,omitempty"`
+ URL string `json:"url,omitempty"`
+ Favorites int `json:"favorites,omitempty"`
+ Count int `json:"count,omitempty"`
+ Established string `json:"established,omitempty"`
+ About string `gorm:"type:text" json:"about,omitempty"`
+ ImageID *uint `json:"image_id,omitempty"`
+ Image *SimpleImage `gorm:"foreignKey:ImageID" json:"image,omitempty"`
+ Titles []SimpleTitle `gorm:"many2many:producer_titles" json:"titles,omitempty"`
+ ExternalURLs []ExternalURL `gorm:"many2many:producer_external_urls" json:"external_urls,omitempty"`
+}
diff --git a/entities/seasons.go b/entities/seasons.go
new file mode 100644
index 0000000..be22d82
--- /dev/null
+++ b/entities/seasons.go
@@ -0,0 +1,23 @@
+package entities
+
+import "gorm.io/gorm"
+
+type Season struct {
+ gorm.Model
+ ParentAnimeID uint `json:"parent_anime_id,omitempty"`
+ MALID int `json:"mal_id,omitempty"`
+ TitleID uint `json:"title_id,omitempty"`
+ Synopsis string `gorm:"type:text" json:"synopsis,omitempty"`
+ Type string `json:"type,omitempty"`
+ Source string `json:"source,omitempty"`
+ Airing bool `json:"airing,omitempty"`
+ Status string `json:"status,omitempty"`
+ Duration string `json:"duration,omitempty"`
+ Season string `json:"season,omitempty"`
+ Year int `json:"year,omitempty"`
+ Current bool `json:"current,omitempty"`
+ Title *Title `gorm:"foreignKey:TitleID" json:"titles,omitempty"`
+ Images *Images `gorm:"foreignKey:AnimeID" json:"images,omitempty"`
+ Scores *Scores `gorm:"foreignKey:AnimeID" json:"scores,omitempty"`
+ AiringStatus *AiringStatus `gorm:"foreignKey:AnimeID" json:"airing_status,omitempty"`
+}
diff --git a/entities/tasks.go b/entities/tasks.go
index 06c1b65..25eddea 100644
--- a/entities/tasks.go
+++ b/entities/tasks.go
@@ -8,8 +8,15 @@ import (
type TaskLog struct {
gorm.Model
- TaskName string `gorm:"index"`
- Status string // 'success', 'error', 'running'
- Message string // error message if any
- ExecutedAt time.Time
+ TaskName string `gorm:"index" json:"task_name,omitempty"`
+ Status string `json:"status,omitempty"`
+ Message string `json:"message,omitempty"`
+ ExecutedAt time.Time `json:"executed_at,omitempty"`
+}
+
+type TaskStatus struct {
+ gorm.Model
+ TaskName string `gorm:"uniqueIndex;not null" json:"task_name"`
+ IsCompleted bool `gorm:"default:false" json:"is_completed,omitempty"`
+ LastRunAt time.Time `json:"last_run_at,omitempty"`
}