Files
seanime-docker/seanime-2.9.10/internal/database/models/models.go
2025-09-20 14:08:38 +01:00

512 lines
24 KiB
Go

package models
import (
"database/sql/driver"
"errors"
"strconv"
"strings"
"time"
)
type BaseModel struct {
ID uint `gorm:"primarykey" json:"id"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
type Token struct {
BaseModel
Value string `json:"value"`
}
type Account struct {
BaseModel
Username string `gorm:"column:username" json:"username"`
Token string `gorm:"column:token" json:"token"`
Viewer []byte `gorm:"column:viewer" json:"viewer"`
}
// +---------------------+
// | LocalFiles |
// +---------------------+
type LocalFiles struct {
BaseModel
Value []byte `gorm:"column:value" json:"value"`
}
// +---------------------+
// | Settings |
// +---------------------+
type Settings struct {
BaseModel
Library *LibrarySettings `gorm:"embedded" json:"library"`
MediaPlayer *MediaPlayerSettings `gorm:"embedded" json:"mediaPlayer"`
Torrent *TorrentSettings `gorm:"embedded" json:"torrent"`
Manga *MangaSettings `gorm:"embedded" json:"manga"`
Anilist *AnilistSettings `gorm:"embedded" json:"anilist"`
ListSync *ListSyncSettings `gorm:"embedded" json:"listSync"`
AutoDownloader *AutoDownloaderSettings `gorm:"embedded" json:"autoDownloader"`
Discord *DiscordSettings `gorm:"embedded" json:"discord"`
Notifications *NotificationSettings `gorm:"embedded" json:"notifications"`
Nakama *NakamaSettings `gorm:"embedded;embeddedPrefix:nakama_" json:"nakama"`
}
type AnilistSettings struct {
//AnilistClientId string `gorm:"column:anilist_client_id" json:"anilistClientId"`
HideAudienceScore bool `gorm:"column:hide_audience_score" json:"hideAudienceScore"`
EnableAdultContent bool `gorm:"column:enable_adult_content" json:"enableAdultContent"`
BlurAdultContent bool `gorm:"column:blur_adult_content" json:"blurAdultContent"`
}
type LibrarySettings struct {
LibraryPath string `gorm:"column:library_path" json:"libraryPath"`
AutoUpdateProgress bool `gorm:"column:auto_update_progress" json:"autoUpdateProgress"`
DisableUpdateCheck bool `gorm:"column:disable_update_check" json:"disableUpdateCheck"`
TorrentProvider string `gorm:"column:torrent_provider" json:"torrentProvider"`
AutoScan bool `gorm:"column:auto_scan" json:"autoScan"`
EnableOnlinestream bool `gorm:"column:enable_onlinestream" json:"enableOnlinestream"`
IncludeOnlineStreamingInLibrary bool `gorm:"column:include_online_streaming_in_library" json:"includeOnlineStreamingInLibrary"`
DisableAnimeCardTrailers bool `gorm:"column:disable_anime_card_trailers" json:"disableAnimeCardTrailers"`
EnableManga bool `gorm:"column:enable_manga" json:"enableManga"`
DOHProvider string `gorm:"column:doh_provider" json:"dohProvider"`
OpenTorrentClientOnStart bool `gorm:"column:open_torrent_client_on_start" json:"openTorrentClientOnStart"`
OpenWebURLOnStart bool `gorm:"column:open_web_url_on_start" json:"openWebURLOnStart"`
RefreshLibraryOnStart bool `gorm:"column:refresh_library_on_start" json:"refreshLibraryOnStart"`
// v2.1+
AutoPlayNextEpisode bool `gorm:"column:auto_play_next_episode" json:"autoPlayNextEpisode"`
// v2.2+
EnableWatchContinuity bool `gorm:"column:enable_watch_continuity" json:"enableWatchContinuity"`
LibraryPaths LibraryPaths `gorm:"column:library_paths;type:text" json:"libraryPaths"`
AutoSyncOfflineLocalData bool `gorm:"column:auto_sync_offline_local_data" json:"autoSyncOfflineLocalData"`
// v2.6+
ScannerMatchingThreshold float64 `gorm:"column:scanner_matching_threshold" json:"scannerMatchingThreshold"`
ScannerMatchingAlgorithm string `gorm:"column:scanner_matching_algorithm" json:"scannerMatchingAlgorithm"`
// v2.9+
AutoSyncToLocalAccount bool `gorm:"column:auto_sync_to_local_account" json:"autoSyncToLocalAccount"`
AutoSaveCurrentMediaOffline bool `gorm:"column:auto_save_current_media_offline" json:"autoSaveCurrentMediaOffline"`
}
func (o *LibrarySettings) GetLibraryPaths() (ret []string) {
ret = make([]string, len(o.LibraryPaths)+1)
ret[0] = o.LibraryPath
if len(o.LibraryPaths) > 0 {
copy(ret[1:], o.LibraryPaths)
}
return
}
type LibraryPaths []string
func (o *LibraryPaths) Scan(src interface{}) error {
str, ok := src.(string)
if !ok {
return errors.New("src value cannot cast to string")
}
*o = strings.Split(str, ",")
return nil
}
func (o LibraryPaths) Value() (driver.Value, error) {
if len(o) == 0 {
return nil, nil
}
return strings.Join(o, ","), nil
}
type NakamaSettings struct {
Enabled bool `gorm:"column:enabled" json:"enabled"`
// Username is the name used to identify a peer or host.
Username string `gorm:"column:username" json:"username"`
// IsHost allows the server to act as a host for other clients. This requires a password to be set.
IsHost bool `gorm:"column:is_host" json:"isHost"`
HostPassword string `gorm:"column:host_password" json:"hostPassword"`
RemoteServerURL string `gorm:"column:remote_server_url" json:"remoteServerURL"`
RemoteServerPassword string `gorm:"column:remote_server_password" json:"remoteServerPassword"`
// IncludeNakamaAnimeLibrary adds the local anime library of the host to the connected clients.
IncludeNakamaAnimeLibrary bool `gorm:"column:include_nakama_anime_library" json:"includeNakamaAnimeLibrary"`
// HostShareLocalAnimeLibrary shares the local anime library to connected clients
HostShareLocalAnimeLibrary bool `gorm:"column:host_share_local_anime_library" json:"hostShareLocalAnimeLibrary"`
// HostUnsharedAnimeIds is a list of anime IDs that should not be shared with connected clients.
HostUnsharedAnimeIds IntSlice `gorm:"column:host_unshared_anime_ids;type:text" json:"hostUnsharedAnimeIds"`
// HostEnablePortForwarding enables port forwarding.
HostEnablePortForwarding bool `gorm:"column:host_enable_port_forwarding" json:"hostEnablePortForwarding"`
}
type IntSlice []int
func (o *IntSlice) Scan(src interface{}) error {
str, ok := src.(string)
if !ok {
return errors.New("src value cannot cast to string")
}
ids := strings.Split(str, ",")
*o = make(IntSlice, len(ids))
for i, id := range ids {
(*o)[i], _ = strconv.Atoi(id)
}
return nil
}
func (o IntSlice) Value() (driver.Value, error) {
if len(o) == 0 {
return nil, nil
}
strs := make([]string, len(o))
for i, id := range o {
strs[i] = strconv.Itoa(id)
}
return strings.Join(strs, ","), nil
}
type MangaSettings struct {
DefaultProvider string `gorm:"column:default_manga_provider" json:"defaultMangaProvider"`
AutoUpdateProgress bool `gorm:"column:manga_auto_update_progress" json:"mangaAutoUpdateProgress"`
LocalSourceDirectory string `gorm:"column:manga_local_source_directory" json:"mangaLocalSourceDirectory"`
}
type MediaPlayerSettings struct {
Default string `gorm:"column:default_player" json:"defaultPlayer"` // "vlc" or "mpc-hc"
Host string `gorm:"column:player_host" json:"host"`
VlcUsername string `gorm:"column:vlc_username" json:"vlcUsername"`
VlcPassword string `gorm:"column:vlc_password" json:"vlcPassword"`
VlcPort int `gorm:"column:vlc_port" json:"vlcPort"`
VlcPath string `gorm:"column:vlc_path" json:"vlcPath"`
MpcPort int `gorm:"column:mpc_port" json:"mpcPort"`
MpcPath string `gorm:"column:mpc_path" json:"mpcPath"`
MpvSocket string `gorm:"column:mpv_socket" json:"mpvSocket"`
MpvPath string `gorm:"column:mpv_path" json:"mpvPath"`
MpvArgs string `gorm:"column:mpv_args" json:"mpvArgs"`
IinaSocket string `gorm:"column:iina_socket" json:"iinaSocket"`
IinaPath string `gorm:"column:iina_path" json:"iinaPath"`
IinaArgs string `gorm:"column:iina_args" json:"iinaArgs"`
}
type TorrentSettings struct {
Default string `gorm:"column:default_torrent_client" json:"defaultTorrentClient"`
QBittorrentPath string `gorm:"column:qbittorrent_path" json:"qbittorrentPath"`
QBittorrentHost string `gorm:"column:qbittorrent_host" json:"qbittorrentHost"`
QBittorrentPort int `gorm:"column:qbittorrent_port" json:"qbittorrentPort"`
QBittorrentUsername string `gorm:"column:qbittorrent_username" json:"qbittorrentUsername"`
QBittorrentPassword string `gorm:"column:qbittorrent_password" json:"qbittorrentPassword"`
QBittorrentTags string `gorm:"column:qbittorrent_tags" json:"qbittorrentTags"`
TransmissionPath string `gorm:"column:transmission_path" json:"transmissionPath"`
TransmissionHost string `gorm:"column:transmission_host" json:"transmissionHost"`
TransmissionPort int `gorm:"column:transmission_port" json:"transmissionPort"`
TransmissionUsername string `gorm:"column:transmission_username" json:"transmissionUsername"`
TransmissionPassword string `gorm:"column:transmission_password" json:"transmissionPassword"`
// v2.1+
ShowActiveTorrentCount bool `gorm:"column:show_active_torrent_count" json:"showActiveTorrentCount"`
// v2.2+
HideTorrentList bool `gorm:"column:hide_torrent_list" json:"hideTorrentList"`
}
type ListSyncSettings struct {
Automatic bool `gorm:"column:automatic_sync" json:"automatic"`
Origin string `gorm:"column:sync_origin" json:"origin"`
}
type DiscordSettings struct {
EnableRichPresence bool `gorm:"column:enable_rich_presence" json:"enableRichPresence"`
EnableAnimeRichPresence bool `gorm:"column:enable_anime_rich_presence" json:"enableAnimeRichPresence"`
EnableMangaRichPresence bool `gorm:"column:enable_manga_rich_presence" json:"enableMangaRichPresence"`
RichPresenceHideSeanimeRepositoryButton bool `gorm:"column:rich_presence_hide_seanime_repository_button" json:"richPresenceHideSeanimeRepositoryButton"`
RichPresenceShowAniListMediaButton bool `gorm:"column:rich_presence_show_anilist_media_button" json:"richPresenceShowAniListMediaButton"`
RichPresenceShowAniListProfileButton bool `gorm:"column:rich_presence_show_anilist_profile_button" json:"richPresenceShowAniListProfileButton"`
RichPresenceUseMediaTitleStatus bool `gorm:"column:rich_presence_use_media_title_status;default:true" json:"richPresenceUseMediaTitleStatus"`
}
type NotificationSettings struct {
DisableNotifications bool `gorm:"column:disable_notifications" json:"disableNotifications"`
DisableAutoDownloaderNotifications bool `gorm:"column:disable_auto_downloader_notifications" json:"disableAutoDownloaderNotifications"`
DisableAutoScannerNotifications bool `gorm:"column:disable_auto_scanner_notifications" json:"disableAutoScannerNotifications"`
}
// +---------------------+
// | MAL |
// +---------------------+
type Mal struct {
BaseModel
Username string `gorm:"column:username" json:"username"`
AccessToken string `gorm:"column:access_token" json:"accessToken"`
RefreshToken string `gorm:"column:refresh_token" json:"refreshToken"`
TokenExpiresAt time.Time `gorm:"column:token_expires_at" json:"tokenExpiresAt"`
}
// +---------------------+
// | Scan Summary |
// +---------------------+
type ScanSummary struct {
BaseModel
Value []byte `gorm:"column:value" json:"value"`
}
// +---------------------+
// | Auto downloader |
// +---------------------+
type AutoDownloaderRule struct {
BaseModel
Value []byte `gorm:"column:value" json:"value"`
}
type AutoDownloaderItem struct {
BaseModel
RuleID uint `gorm:"column:rule_id" json:"ruleId"`
MediaID int `gorm:"column:media_id" json:"mediaId"`
Episode int `gorm:"column:episode" json:"episode"`
Link string `gorm:"column:link" json:"link"`
Hash string `gorm:"column:hash" json:"hash"`
Magnet string `gorm:"column:magnet" json:"magnet"`
TorrentName string `gorm:"column:torrent_name" json:"torrentName"`
Downloaded bool `gorm:"column:downloaded" json:"downloaded"`
}
type AutoDownloaderSettings struct {
Provider string `gorm:"column:auto_downloader_provider" json:"provider"`
Interval int `gorm:"column:auto_downloader_interval" json:"interval"`
Enabled bool `gorm:"column:auto_downloader_enabled" json:"enabled"`
DownloadAutomatically bool `gorm:"column:auto_downloader_download_automatically" json:"downloadAutomatically"`
EnableEnhancedQueries bool `gorm:"column:auto_downloader_enable_enhanced_queries" json:"enableEnhancedQueries"`
EnableSeasonCheck bool `gorm:"column:auto_downloader_enable_season_check" json:"enableSeasonCheck"`
UseDebrid bool `gorm:"column:auto_downloader_use_debrid" json:"useDebrid"`
}
// +---------------------+
// | Media Entry |
// +---------------------+
type SilencedMediaEntry struct {
BaseModel
}
// +---------------------+
// | Theme |
// +---------------------+
type Theme struct {
BaseModel
// Main
EnableColorSettings bool `gorm:"column:enable_color_settings" json:"enableColorSettings"`
BackgroundColor string `gorm:"column:background_color" json:"backgroundColor"`
AccentColor string `gorm:"column:accent_color" json:"accentColor"`
SidebarBackgroundColor string `gorm:"column:sidebar_background_color" json:"sidebarBackgroundColor"` // DEPRECATED
AnimeEntryScreenLayout string `gorm:"column:anime_entry_screen_layout" json:"animeEntryScreenLayout"` // DEPRECATED
ExpandSidebarOnHover bool `gorm:"column:expand_sidebar_on_hover" json:"expandSidebarOnHover"`
HideTopNavbar bool `gorm:"column:hide_top_navbar" json:"hideTopNavbar"`
EnableMediaCardBlurredBackground bool `gorm:"column:enable_media_card_blurred_background" json:"enableMediaCardBlurredBackground"`
// Note: These are named "libraryScreen" but are used on all pages
LibraryScreenCustomBackgroundImage string `gorm:"column:library_screen_custom_background_image" json:"libraryScreenCustomBackgroundImage"`
LibraryScreenCustomBackgroundOpacity int `gorm:"column:library_screen_custom_background_opacity" json:"libraryScreenCustomBackgroundOpacity"`
// Anime
SmallerEpisodeCarouselSize bool `gorm:"column:smaller_episode_carousel_size" json:"smallerEpisodeCarouselSize"`
// Library Screen (Anime & Manga)
// LibraryScreenBannerType: "dynamic", "custom"
LibraryScreenBannerType string `gorm:"column:library_screen_banner_type" json:"libraryScreenBannerType"`
LibraryScreenCustomBannerImage string `gorm:"column:library_screen_custom_banner_image" json:"libraryScreenCustomBannerImage"`
LibraryScreenCustomBannerPosition string `gorm:"column:library_screen_custom_banner_position" json:"libraryScreenCustomBannerPosition"`
LibraryScreenCustomBannerOpacity int `gorm:"column:library_screen_custom_banner_opacity" json:"libraryScreenCustomBannerOpacity"`
DisableLibraryScreenGenreSelector bool `gorm:"column:disable_library_screen_genre_selector" json:"disableLibraryScreenGenreSelector"`
LibraryScreenCustomBackgroundBlur string `gorm:"column:library_screen_custom_background_blur" json:"libraryScreenCustomBackgroundBlur"`
EnableMediaPageBlurredBackground bool `gorm:"column:enable_media_page_blurred_background" json:"enableMediaPageBlurredBackground"`
DisableSidebarTransparency bool `gorm:"column:disable_sidebar_transparency" json:"disableSidebarTransparency"`
UseLegacyEpisodeCard bool `gorm:"column:use_legacy_episode_card" json:"useLegacyEpisodeCard"` // DEPRECATED
DisableCarouselAutoScroll bool `gorm:"column:disable_carousel_auto_scroll" json:"disableCarouselAutoScroll"`
// v2.6+
MediaPageBannerType string `gorm:"column:media_page_banner_type" json:"mediaPageBannerType"`
MediaPageBannerSize string `gorm:"column:media_page_banner_size" json:"mediaPageBannerSize"`
MediaPageBannerInfoBoxSize string `gorm:"column:media_page_banner_info_box_size" json:"mediaPageBannerInfoBoxSize"`
// v2.7+
ShowEpisodeCardAnimeInfo bool `gorm:"column:show_episode_card_anime_info" json:"showEpisodeCardAnimeInfo"`
ContinueWatchingDefaultSorting string `gorm:"column:continue_watching_default_sorting" json:"continueWatchingDefaultSorting"`
AnimeLibraryCollectionDefaultSorting string `gorm:"column:anime_library_collection_default_sorting" json:"animeLibraryCollectionDefaultSorting"`
MangaLibraryCollectionDefaultSorting string `gorm:"column:manga_library_collection_default_sorting" json:"mangaLibraryCollectionDefaultSorting"`
ShowAnimeUnwatchedCount bool `gorm:"column:show_anime_unwatched_count" json:"showAnimeUnwatchedCount"`
ShowMangaUnreadCount bool `gorm:"column:show_manga_unread_count" json:"showMangaUnreadCount"`
// v2.8+
HideEpisodeCardDescription bool `gorm:"column:hide_episode_card_description" json:"hideEpisodeCardDescription"`
HideDownloadedEpisodeCardFilename bool `gorm:"column:hide_downloaded_episode_card_filename" json:"hideDownloadedEpisodeCardFilename"`
CustomCSS string `gorm:"column:custom_css" json:"customCSS"`
MobileCustomCSS string `gorm:"column:mobile_custom_css" json:"mobileCustomCSS"`
// v2.9+
UnpinnedMenuItems StringSlice `gorm:"column:unpinned_menu_items;type:text" json:"unpinnedMenuItems"`
}
// +---------------------+
// | Playlist |
// +---------------------+
type PlaylistEntry struct {
BaseModel
Name string `gorm:"column:name" json:"name"`
Value []byte `gorm:"column:value" json:"value"`
}
// +------------------------+
// | Chapter Download Queue |
// +------------------------+
type ChapterDownloadQueueItem struct {
BaseModel
Provider string `gorm:"column:provider" json:"provider"`
MediaID int `gorm:"column:media_id" json:"mediaId"`
ChapterID string `gorm:"column:chapter_id" json:"chapterId"`
ChapterNumber string `gorm:"column:chapter_number" json:"chapterNumber"`
PageData []byte `gorm:"column:page_data" json:"pageData"` // Contains map of page index to page details
Status string `gorm:"column:status" json:"status"`
}
// +---------------------+
// | MediaStream |
// +---------------------+
type MediastreamSettings struct {
BaseModel
// DEVNOTE: Should really be "Enabled"
TranscodeEnabled bool `gorm:"column:transcode_enabled" json:"transcodeEnabled"`
TranscodeHwAccel string `gorm:"column:transcode_hw_accel" json:"transcodeHwAccel"`
TranscodeThreads int `gorm:"column:transcode_threads" json:"transcodeThreads"`
TranscodePreset string `gorm:"column:transcode_preset" json:"transcodePreset"`
DisableAutoSwitchToDirectPlay bool `gorm:"column:disable_auto_switch_to_direct_play" json:"disableAutoSwitchToDirectPlay"`
DirectPlayOnly bool `gorm:"column:direct_play_only" json:"directPlayOnly"`
PreTranscodeEnabled bool `gorm:"column:pre_transcode_enabled" json:"preTranscodeEnabled"`
PreTranscodeLibraryDir string `gorm:"column:pre_transcode_library_dir" json:"preTranscodeLibraryDir"`
FfmpegPath string `gorm:"column:ffmpeg_path" json:"ffmpegPath"`
FfprobePath string `gorm:"column:ffprobe_path" json:"ffprobePath"`
// v2.2+
TranscodeHwAccelCustomSettings string `gorm:"column:transcode_hw_accel_custom_settings" json:"transcodeHwAccelCustomSettings"`
//TranscodeTempDir string `gorm:"column:transcode_temp_dir" json:"transcodeTempDir"` // DEPRECATED
}
// +---------------------+
// | TorrentStream |
// +---------------------+
type TorrentstreamSettings struct {
BaseModel
Enabled bool `gorm:"column:enabled" json:"enabled"`
AutoSelect bool `gorm:"column:auto_select" json:"autoSelect"`
PreferredResolution string `gorm:"column:preferred_resolution" json:"preferredResolution"`
DisableIPV6 bool `gorm:"column:disable_ipv6" json:"disableIPV6"`
DownloadDir string `gorm:"column:download_dir" json:"downloadDir"`
AddToLibrary bool `gorm:"column:add_to_library" json:"addToLibrary"`
TorrentClientHost string `gorm:"column:torrent_client_host" json:"torrentClientHost"`
TorrentClientPort int `gorm:"column:torrent_client_port" json:"torrentClientPort"`
StreamingServerHost string `gorm:"column:streaming_server_host" json:"streamingServerHost"`
StreamingServerPort int `gorm:"column:streaming_server_port" json:"streamingServerPort"`
//FallbackToTorrentStreamingView bool `gorm:"column:fallback_to_torrent_streaming_view" json:"fallbackToTorrentStreamingView"` // DEPRECATED
IncludeInLibrary bool `gorm:"column:include_in_library" json:"includeInLibrary"`
// v2.6+
StreamUrlAddress string `gorm:"column:stream_url_address" json:"streamUrlAddress"`
// v2.7+
SlowSeeding bool `gorm:"column:slow_seeding" json:"slowSeeding"`
}
type TorrentstreamHistory struct {
BaseModel
MediaId int `gorm:"column:media_id" json:"mediaId"`
Torrent []byte `gorm:"column:torrent" json:"torrent"`
}
// +---------------------+
// | Filler |
// +---------------------+
type MediaFiller struct {
BaseModel
Provider string `gorm:"column:provider" json:"provider"`
Slug string `gorm:"column:slug" json:"slug"`
MediaID int `gorm:"column:media_id" json:"mediaId"`
LastFetchedAt time.Time `gorm:"column:last_fetched_at" json:"lastFetchedAt"`
Data []byte `gorm:"column:data" json:"data"`
}
// +---------------------+
// | Manga |
// +---------------------+
type MangaMapping struct {
BaseModel
Provider string `gorm:"column:provider" json:"provider"`
MediaID int `gorm:"column:media_id" json:"mediaId"`
MangaID string `gorm:"column:manga_id" json:"mangaId"` // ID from search result, used to fetch chapters
}
type MangaChapterContainer struct {
BaseModel
Provider string `gorm:"column:provider" json:"provider"`
MediaID int `gorm:"column:media_id" json:"mediaId"`
ChapterID string `gorm:"column:chapter_id" json:"chapterId"`
Data []byte `gorm:"column:data" json:"data"`
}
// +---------------------+
// | Online streaming |
// +---------------------+
type OnlinestreamMapping struct {
BaseModel
Provider string `gorm:"column:provider" json:"provider"`
MediaID int `gorm:"column:media_id" json:"mediaId"`
AnimeID string `gorm:"column:anime_id" json:"anime_id"` // ID from search result, used to fetch episodes
}
// +---------------------+
// | Debrid |
// +---------------------+
type DebridSettings struct {
BaseModel
Enabled bool `gorm:"column:enabled" json:"enabled"`
Provider string `gorm:"column:provider" json:"provider"`
ApiKey string `gorm:"column:api_key" json:"apiKey"`
//FallbackToDebridStreamingView bool `gorm:"column:fallback_to_debrid_streaming_view" json:"fallbackToDebridStreamingView"` // DEPRECATED
IncludeDebridStreamInLibrary bool `gorm:"column:include_debrid_stream_in_library" json:"includeDebridStreamInLibrary"`
StreamAutoSelect bool `gorm:"column:stream_auto_select" json:"streamAutoSelect"`
StreamPreferredResolution string `gorm:"column:stream_preferred_resolution" json:"streamPreferredResolution"`
}
type DebridTorrentItem struct {
BaseModel
TorrentItemID string `gorm:"column:torrent_item_id" json:"torrentItemId"`
Destination string `gorm:"column:destination" json:"destination"`
Provider string `gorm:"column:provider" json:"provider"`
MediaId int `gorm:"column:media_id" json:"mediaId"`
}
// +---------------------+
// | Plugin |
// +---------------------+
type PluginData struct {
BaseModel
PluginID string `gorm:"column:plugin_id;index" json:"pluginId"`
Data []byte `gorm:"column:data" json:"data"`
}
///////////////////////////////////////////////////////////////////////////
type StringSlice []string
func (o *StringSlice) Scan(src interface{}) error {
str, ok := src.(string)
if !ok {
return errors.New("src value cannot cast to string")
}
*o = strings.Split(str, ",")
return nil
}
func (o StringSlice) Value() (driver.Value, error) {
if len(o) == 0 {
return nil, nil
}
return strings.Join(o, ","), nil
}