node build fixed
This commit is contained in:
7
seanime-2.9.10/internal/database/db/README.md
Normal file
7
seanime-2.9.10/internal/database/db/README.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# db
|
||||
|
||||
Should only import `models` internal package.
|
||||
|
||||
### 🚫 Do not
|
||||
|
||||
- Do not define **models** here.
|
||||
59
seanime-2.9.10/internal/database/db/account.go
Normal file
59
seanime-2.9.10/internal/database/db/account.go
Normal file
@@ -0,0 +1,59 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"seanime/internal/database/models"
|
||||
|
||||
"gorm.io/gorm/clause"
|
||||
)
|
||||
|
||||
var accountCache *models.Account
|
||||
|
||||
func (db *Database) UpsertAccount(acc *models.Account) (*models.Account, error) {
|
||||
err := db.gormdb.Clauses(clause.OnConflict{
|
||||
Columns: []clause.Column{{Name: "id"}},
|
||||
UpdateAll: true,
|
||||
}).Create(acc).Error
|
||||
|
||||
if err != nil {
|
||||
db.Logger.Error().Err(err).Msg("Failed to save account in the database")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if acc.Username != "" {
|
||||
accountCache = acc
|
||||
} else {
|
||||
accountCache = nil
|
||||
}
|
||||
|
||||
return acc, nil
|
||||
}
|
||||
|
||||
func (db *Database) GetAccount() (*models.Account, error) {
|
||||
|
||||
if accountCache != nil {
|
||||
return accountCache, nil
|
||||
}
|
||||
|
||||
var acc models.Account
|
||||
err := db.gormdb.Last(&acc).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if acc.Username == "" || acc.Token == "" || acc.Viewer == nil {
|
||||
return nil, errors.New("account not found")
|
||||
}
|
||||
|
||||
accountCache = &acc
|
||||
|
||||
return &acc, err
|
||||
}
|
||||
|
||||
// GetAnilistToken retrieves the AniList token from the account or returns an empty string
|
||||
func (db *Database) GetAnilistToken() string {
|
||||
acc, err := db.GetAccount()
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return acc.Token
|
||||
}
|
||||
57
seanime-2.9.10/internal/database/db/autodownloader_item.go
Normal file
57
seanime-2.9.10/internal/database/db/autodownloader_item.go
Normal file
@@ -0,0 +1,57 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"seanime/internal/database/models"
|
||||
)
|
||||
|
||||
func (db *Database) GetAutoDownloaderItems() ([]*models.AutoDownloaderItem, error) {
|
||||
var res []*models.AutoDownloaderItem
|
||||
err := db.gormdb.Find(&res).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (db *Database) GetAutoDownloaderItem(id uint) (*models.AutoDownloaderItem, error) {
|
||||
var res models.AutoDownloaderItem
|
||||
err := db.gormdb.First(&res, id).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
func (db *Database) GetAutoDownloaderItemByMediaId(mId int) ([]*models.AutoDownloaderItem, error) {
|
||||
var res []*models.AutoDownloaderItem
|
||||
err := db.gormdb.Where("media_id = ?", mId).Find(&res).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (db *Database) InsertAutoDownloaderItem(item *models.AutoDownloaderItem) error {
|
||||
err := db.gormdb.Create(item).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Database) DeleteAutoDownloaderItem(id uint) error {
|
||||
return db.gormdb.Delete(&models.AutoDownloaderItem{}, id).Error
|
||||
}
|
||||
|
||||
// DeleteDownloadedAutoDownloaderItems will delete all the downloaded queued items from the database.
|
||||
func (db *Database) DeleteDownloadedAutoDownloaderItems() error {
|
||||
return db.gormdb.Where("downloaded = ?", true).Delete(&models.AutoDownloaderItem{}).Error
|
||||
}
|
||||
|
||||
func (db *Database) UpdateAutoDownloaderItem(id uint, item *models.AutoDownloaderItem) error {
|
||||
// Save the data
|
||||
return db.gormdb.Model(&models.AutoDownloaderItem{}).Where("id = ?", id).Updates(item).Error
|
||||
}
|
||||
135
seanime-2.9.10/internal/database/db/chapter_downloader_queue.go
Normal file
135
seanime-2.9.10/internal/database/db/chapter_downloader_queue.go
Normal file
@@ -0,0 +1,135 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"gorm.io/gorm"
|
||||
"seanime/internal/database/models"
|
||||
)
|
||||
|
||||
func (db *Database) GetChapterDownloadQueue() ([]*models.ChapterDownloadQueueItem, error) {
|
||||
var res []*models.ChapterDownloadQueueItem
|
||||
err := db.gormdb.Find(&res).Error
|
||||
if err != nil {
|
||||
db.Logger.Error().Err(err).Msg("db: Failed to get chapter download queue")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (db *Database) GetNextChapterDownloadQueueItem() (*models.ChapterDownloadQueueItem, error) {
|
||||
var res models.ChapterDownloadQueueItem
|
||||
err := db.gormdb.Where("status = ?", "not_started").First(&res).Error
|
||||
if err != nil {
|
||||
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
db.Logger.Error().Err(err).Msg("db: Failed to get next chapter download queue item")
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
func (db *Database) DequeueChapterDownloadQueueItem() (*models.ChapterDownloadQueueItem, error) {
|
||||
// Pop the first item from the queue
|
||||
var res models.ChapterDownloadQueueItem
|
||||
err := db.gormdb.Where("status = ?", "downloading").First(&res).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = db.gormdb.Delete(&res).Error
|
||||
if err != nil {
|
||||
db.Logger.Error().Err(err).Msg("db: Failed to delete chapter download queue item")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
func (db *Database) InsertChapterDownloadQueueItem(item *models.ChapterDownloadQueueItem) error {
|
||||
|
||||
// Check if the item already exists
|
||||
var existingItem models.ChapterDownloadQueueItem
|
||||
err := db.gormdb.Where("provider = ? AND media_id = ? AND chapter_id = ?", item.Provider, item.MediaID, item.ChapterID).First(&existingItem).Error
|
||||
if err == nil {
|
||||
db.Logger.Debug().Msg("db: Chapter download queue item already exists")
|
||||
return errors.New("chapter is already in the download queue")
|
||||
}
|
||||
|
||||
if item.ChapterID == "" {
|
||||
return errors.New("chapter ID is empty")
|
||||
}
|
||||
if item.Provider == "" {
|
||||
return errors.New("provider is empty")
|
||||
}
|
||||
if item.MediaID == 0 {
|
||||
return errors.New("media ID is empty")
|
||||
}
|
||||
if item.ChapterNumber == "" {
|
||||
return errors.New("chapter number is empty")
|
||||
}
|
||||
|
||||
err = db.gormdb.Create(item).Error
|
||||
if err != nil {
|
||||
db.Logger.Error().Err(err).Msg("db: Failed to insert chapter download queue item")
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Database) UpdateChapterDownloadQueueItemStatus(provider string, mId int, chapterId string, status string) error {
|
||||
err := db.gormdb.Model(&models.ChapterDownloadQueueItem{}).
|
||||
Where("provider = ? AND media_id = ? AND chapter_id = ?", provider, mId, chapterId).
|
||||
Update("status", status).Error
|
||||
if err != nil {
|
||||
db.Logger.Error().Err(err).Msg("db: Failed to update chapter download queue item status")
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Database) GetMediaQueuedChapters(mediaId int) ([]*models.ChapterDownloadQueueItem, error) {
|
||||
var res []*models.ChapterDownloadQueueItem
|
||||
err := db.gormdb.Where("media_id = ?", mediaId).Find(&res).Error
|
||||
if err != nil {
|
||||
db.Logger.Error().Err(err).Msg("db: Failed to get media queued chapters")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (db *Database) ClearAllChapterDownloadQueueItems() error {
|
||||
err := db.gormdb.
|
||||
Where("status = ? OR status = ? OR status = ?", "not_started", "downloading", "errored").
|
||||
Delete(&models.ChapterDownloadQueueItem{}).
|
||||
Error
|
||||
if err != nil {
|
||||
db.Logger.Error().Err(err).Msg("db: Failed to clear all chapter download queue items")
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Database) ResetErroredChapterDownloadQueueItems() error {
|
||||
err := db.gormdb.Model(&models.ChapterDownloadQueueItem{}).
|
||||
Where("status = ?", "errored").
|
||||
Update("status", "not_started").Error
|
||||
if err != nil {
|
||||
db.Logger.Error().Err(err).Msg("db: Failed to reset errored chapter download queue items")
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Database) ResetDownloadingChapterDownloadQueueItems() error {
|
||||
err := db.gormdb.Model(&models.ChapterDownloadQueueItem{}).
|
||||
Where("status = ?", "downloading").
|
||||
Update("status", "not_started").Error
|
||||
if err != nil {
|
||||
db.Logger.Error().Err(err).Msg("db: Failed to reset downloading chapter download queue items")
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
102
seanime-2.9.10/internal/database/db/db.go
Normal file
102
seanime-2.9.10/internal/database/db/db.go
Normal file
@@ -0,0 +1,102 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"seanime/internal/database/models"
|
||||
"time"
|
||||
|
||||
"github.com/glebarez/sqlite"
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/samber/mo"
|
||||
"gorm.io/gorm"
|
||||
gormlogger "gorm.io/gorm/logger"
|
||||
)
|
||||
|
||||
type Database struct {
|
||||
gormdb *gorm.DB
|
||||
Logger *zerolog.Logger
|
||||
CurrMediaFillers mo.Option[map[int]*MediaFillerItem]
|
||||
}
|
||||
|
||||
func (db *Database) Gorm() *gorm.DB {
|
||||
return db.gormdb
|
||||
}
|
||||
|
||||
func NewDatabase(appDataDir, dbName string, logger *zerolog.Logger) (*Database, error) {
|
||||
|
||||
// Set the SQLite database path
|
||||
var sqlitePath string
|
||||
if os.Getenv("TEST_ENV") == "true" {
|
||||
sqlitePath = ":memory:"
|
||||
} else {
|
||||
sqlitePath = filepath.Join(appDataDir, dbName+".db")
|
||||
}
|
||||
|
||||
// Connect to the SQLite database
|
||||
db, err := gorm.Open(sqlite.Open(sqlitePath), &gorm.Config{
|
||||
Logger: gormlogger.New(
|
||||
log.New(os.Stdout, "\r\n", log.LstdFlags),
|
||||
gormlogger.Config{
|
||||
SlowThreshold: time.Second,
|
||||
LogLevel: gormlogger.Error,
|
||||
IgnoreRecordNotFoundError: true,
|
||||
ParameterizedQueries: false,
|
||||
Colorful: true,
|
||||
},
|
||||
),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Migrate tables
|
||||
err = migrateTables(db)
|
||||
if err != nil {
|
||||
logger.Fatal().Err(err).Msg("db: Failed to perform auto migration")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
logger.Info().Str("name", fmt.Sprintf("%s.db", dbName)).Msg("db: Database instantiated")
|
||||
|
||||
return &Database{
|
||||
gormdb: db,
|
||||
Logger: logger,
|
||||
CurrMediaFillers: mo.None[map[int]*MediaFillerItem](),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// MigrateTables performs auto migration on the database
|
||||
func migrateTables(db *gorm.DB) error {
|
||||
err := db.AutoMigrate(
|
||||
&models.LocalFiles{},
|
||||
&models.Settings{},
|
||||
&models.Account{},
|
||||
&models.Mal{},
|
||||
&models.ScanSummary{},
|
||||
&models.AutoDownloaderRule{},
|
||||
&models.AutoDownloaderItem{},
|
||||
&models.SilencedMediaEntry{},
|
||||
&models.Theme{},
|
||||
&models.PlaylistEntry{},
|
||||
&models.ChapterDownloadQueueItem{},
|
||||
&models.TorrentstreamSettings{},
|
||||
&models.TorrentstreamHistory{},
|
||||
&models.MediastreamSettings{},
|
||||
&models.MediaFiller{},
|
||||
&models.MangaMapping{},
|
||||
&models.OnlinestreamMapping{},
|
||||
&models.DebridSettings{},
|
||||
&models.DebridTorrentItem{},
|
||||
&models.PluginData{},
|
||||
//&models.MangaChapterContainer{},
|
||||
)
|
||||
if err != nil {
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
56
seanime-2.9.10/internal/database/db/debrid_torrent_item.go
Normal file
56
seanime-2.9.10/internal/database/db/debrid_torrent_item.go
Normal file
@@ -0,0 +1,56 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"seanime/internal/database/models"
|
||||
)
|
||||
|
||||
func (db *Database) GetDebridTorrentItems() ([]*models.DebridTorrentItem, error) {
|
||||
var res []*models.DebridTorrentItem
|
||||
err := db.gormdb.Find(&res).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (db *Database) GetDebridTorrentItemByDbId(dbId uint) (*models.DebridTorrentItem, error) {
|
||||
var res models.DebridTorrentItem
|
||||
err := db.gormdb.First(&res, dbId).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
func (db *Database) GetDebridTorrentItemByTorrentItemId(tId string) (*models.DebridTorrentItem, error) {
|
||||
var res *models.DebridTorrentItem
|
||||
err := db.gormdb.Where("torrent_item_id = ?", tId).First(&res).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (db *Database) InsertDebridTorrentItem(item *models.DebridTorrentItem) error {
|
||||
err := db.gormdb.Create(item).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Database) DeleteDebridTorrentItemByDbId(dbId uint) error {
|
||||
return db.gormdb.Delete(&models.DebridTorrentItem{}, dbId).Error
|
||||
}
|
||||
|
||||
func (db *Database) DeleteDebridTorrentItemByTorrentItemId(tId string) error {
|
||||
return db.gormdb.Where("torrent_item_id = ?", tId).Delete(&models.DebridTorrentItem{}).Error
|
||||
}
|
||||
|
||||
func (db *Database) UpdateDebridTorrentItemByDbId(dbId uint, item *models.DebridTorrentItem) error {
|
||||
// Save the data
|
||||
return db.gormdb.Model(&models.DebridTorrentItem{}).Where("id = ?", dbId).Updates(item).Error
|
||||
}
|
||||
51
seanime-2.9.10/internal/database/db/localfiles.go
Normal file
51
seanime-2.9.10/internal/database/db/localfiles.go
Normal file
@@ -0,0 +1,51 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"seanime/internal/database/models"
|
||||
|
||||
"gorm.io/gorm/clause"
|
||||
)
|
||||
|
||||
// TrimLocalFileEntries will trim the local file entries if there are more than 10 entries.
|
||||
// This is run in a goroutine.
|
||||
func (db *Database) TrimLocalFileEntries() {
|
||||
go func() {
|
||||
var count int64
|
||||
err := db.gormdb.Model(&models.LocalFiles{}).Count(&count).Error
|
||||
if err != nil {
|
||||
db.Logger.Error().Err(err).Msg("database: Failed to count local file entries")
|
||||
return
|
||||
}
|
||||
if count > 10 {
|
||||
// Leave 5 entries
|
||||
err = db.gormdb.Delete(&models.LocalFiles{}, "id IN (SELECT id FROM local_files ORDER BY id ASC LIMIT ?)", count-5).Error
|
||||
if err != nil {
|
||||
db.Logger.Error().Err(err).Msg("database: Failed to delete old local file entries")
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
func (db *Database) UpsertLocalFiles(lfs *models.LocalFiles) (*models.LocalFiles, error) {
|
||||
err := db.gormdb.Clauses(clause.OnConflict{
|
||||
Columns: []clause.Column{{Name: "id"}},
|
||||
UpdateAll: true,
|
||||
}).Create(lfs).Error
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return lfs, nil
|
||||
}
|
||||
|
||||
func (db *Database) InsertLocalFiles(lfs *models.LocalFiles) (*models.LocalFiles, error) {
|
||||
err := db.gormdb.Create(lfs).Error
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return lfs, nil
|
||||
}
|
||||
50
seanime-2.9.10/internal/database/db/mal.go
Normal file
50
seanime-2.9.10/internal/database/db/mal.go
Normal file
@@ -0,0 +1,50 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/clause"
|
||||
"seanime/internal/database/models"
|
||||
)
|
||||
|
||||
func (db *Database) GetMalInfo() (*models.Mal, error) {
|
||||
// Get the first entry
|
||||
var res models.Mal
|
||||
err := db.gormdb.First(&res, 1).Error
|
||||
if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, errors.New("MAL not connected")
|
||||
} else if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
func (db *Database) UpsertMalInfo(info *models.Mal) (*models.Mal, error) {
|
||||
err := db.gormdb.Clauses(clause.OnConflict{
|
||||
Columns: []clause.Column{{Name: "id"}},
|
||||
UpdateAll: true,
|
||||
}).Create(info).Error
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return info, nil
|
||||
}
|
||||
|
||||
func (db *Database) InsertMalInfo(info *models.Mal) (*models.Mal, error) {
|
||||
err := db.gormdb.Create(info).Error
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return info, nil
|
||||
}
|
||||
|
||||
func (db *Database) DeleteMalInfo() error {
|
||||
err := db.gormdb.Delete(&models.Mal{}, 1).Error
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
102
seanime-2.9.10/internal/database/db/manga.go
Normal file
102
seanime-2.9.10/internal/database/db/manga.go
Normal file
@@ -0,0 +1,102 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"seanime/internal/database/models"
|
||||
"seanime/internal/util/result"
|
||||
)
|
||||
|
||||
var mangaMappingCache = result.NewResultMap[string, *models.MangaMapping]()
|
||||
|
||||
func formatMangaMappingCacheKey(provider string, mediaId int) string {
|
||||
return fmt.Sprintf("%s$%d", provider, mediaId)
|
||||
}
|
||||
|
||||
func (db *Database) GetMangaMapping(provider string, mediaId int) (*models.MangaMapping, bool) {
|
||||
|
||||
if res, ok := mangaMappingCache.Get(formatMangaMappingCacheKey(provider, mediaId)); ok {
|
||||
return res, true
|
||||
}
|
||||
|
||||
var res models.MangaMapping
|
||||
err := db.gormdb.Where("provider = ? AND media_id = ?", provider, mediaId).First(&res).Error
|
||||
if err != nil {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
mangaMappingCache.Set(formatMangaMappingCacheKey(provider, mediaId), &res)
|
||||
|
||||
return &res, true
|
||||
}
|
||||
|
||||
func (db *Database) InsertMangaMapping(provider string, mediaId int, mangaId string) error {
|
||||
mapping := models.MangaMapping{
|
||||
Provider: provider,
|
||||
MediaID: mediaId,
|
||||
MangaID: mangaId,
|
||||
}
|
||||
|
||||
mangaMappingCache.Set(formatMangaMappingCacheKey(provider, mediaId), &mapping)
|
||||
|
||||
return db.gormdb.Save(&mapping).Error
|
||||
}
|
||||
|
||||
func (db *Database) DeleteMangaMapping(provider string, mediaId int) error {
|
||||
err := db.gormdb.Where("provider = ? AND media_id = ?", provider, mediaId).Delete(&models.MangaMapping{}).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mangaMappingCache.Delete(formatMangaMappingCacheKey(provider, mediaId))
|
||||
return nil
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var mangaChapterContainerCache = result.NewResultMap[string, *models.MangaChapterContainer]()
|
||||
|
||||
func formatMangaChapterContainerCacheKey(provider string, mediaId int, chapterId string) string {
|
||||
return fmt.Sprintf("%s$%d$%s", provider, mediaId, chapterId)
|
||||
}
|
||||
|
||||
func (db *Database) GetMangaChapterContainer(provider string, mediaId int, chapterId string) (*models.MangaChapterContainer, bool) {
|
||||
|
||||
if res, ok := mangaChapterContainerCache.Get(formatMangaChapterContainerCacheKey(provider, mediaId, chapterId)); ok {
|
||||
return res, true
|
||||
}
|
||||
|
||||
var res models.MangaChapterContainer
|
||||
err := db.gormdb.Where("provider = ? AND media_id = ? AND chapter_id = ?", provider, mediaId, chapterId).First(&res).Error
|
||||
if err != nil {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
mangaChapterContainerCache.Set(formatMangaChapterContainerCacheKey(provider, mediaId, chapterId), &res)
|
||||
|
||||
return &res, true
|
||||
}
|
||||
|
||||
func (db *Database) InsertMangaChapterContainer(provider string, mediaId int, chapterId string, chapterContainer []byte) error {
|
||||
container := models.MangaChapterContainer{
|
||||
Provider: provider,
|
||||
MediaID: mediaId,
|
||||
ChapterID: chapterId,
|
||||
Data: chapterContainer,
|
||||
}
|
||||
|
||||
mangaChapterContainerCache.Set(formatMangaChapterContainerCacheKey(provider, mediaId, chapterId), &container)
|
||||
|
||||
return db.gormdb.Save(&container).Error
|
||||
}
|
||||
|
||||
func (db *Database) DeleteMangaChapterContainer(provider string, mediaId int, chapterId string) error {
|
||||
err := db.gormdb.Where("provider = ? AND media_id = ? AND chapter_id = ?", provider, mediaId, chapterId).Delete(&models.MangaChapterContainer{}).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mangaChapterContainerCache.Delete(formatMangaChapterContainerCacheKey(provider, mediaId, chapterId))
|
||||
return nil
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
182
seanime-2.9.10/internal/database/db/media_filler.go
Normal file
182
seanime-2.9.10/internal/database/db/media_filler.go
Normal file
@@ -0,0 +1,182 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"github.com/goccy/go-json"
|
||||
"github.com/samber/mo"
|
||||
"seanime/internal/api/filler"
|
||||
"seanime/internal/database/models"
|
||||
"time"
|
||||
)
|
||||
|
||||
type MediaFillerItem struct {
|
||||
DbId uint `json:"dbId"`
|
||||
Provider string `json:"provider"`
|
||||
Slug string `json:"slug"`
|
||||
MediaId int `json:"mediaId"`
|
||||
LastFetchedAt time.Time `json:"lastFetchedAt"`
|
||||
FillerEpisodes []string `json:"fillerEpisodes"`
|
||||
}
|
||||
|
||||
// GetCachedMediaFillers will return all the media fillers (cache-first).
|
||||
// If the cache is empty, it will fetch the media fillers from the database.
|
||||
func (db *Database) GetCachedMediaFillers() (map[int]*MediaFillerItem, error) {
|
||||
|
||||
if db.CurrMediaFillers.IsPresent() {
|
||||
return db.CurrMediaFillers.MustGet(), nil
|
||||
}
|
||||
|
||||
var res []*models.MediaFiller
|
||||
err := db.gormdb.Find(&res).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Unmarshal the media fillers
|
||||
mediaFillers := make(map[int]*MediaFillerItem)
|
||||
for _, mf := range res {
|
||||
|
||||
var fillerData filler.Data
|
||||
if err := json.Unmarshal(mf.Data, &fillerData); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Get the filler episodes
|
||||
var fillerEpisodes []string
|
||||
if fillerData.FillerEpisodes != nil || len(fillerData.FillerEpisodes) > 0 {
|
||||
fillerEpisodes = fillerData.FillerEpisodes
|
||||
}
|
||||
|
||||
mediaFillers[mf.MediaID] = &MediaFillerItem{
|
||||
DbId: mf.ID,
|
||||
Provider: mf.Provider,
|
||||
MediaId: mf.MediaID,
|
||||
Slug: mf.Slug,
|
||||
LastFetchedAt: mf.LastFetchedAt,
|
||||
FillerEpisodes: fillerEpisodes,
|
||||
}
|
||||
}
|
||||
|
||||
// Cache the media fillers
|
||||
db.CurrMediaFillers = mo.Some(mediaFillers)
|
||||
|
||||
return db.CurrMediaFillers.MustGet(), nil
|
||||
}
|
||||
|
||||
func (db *Database) GetMediaFillerItem(mediaId int) (*MediaFillerItem, bool) {
|
||||
|
||||
mediaFillers, err := db.GetCachedMediaFillers()
|
||||
if err != nil {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
item, ok := mediaFillers[mediaId]
|
||||
|
||||
return item, ok
|
||||
}
|
||||
|
||||
func (db *Database) InsertMediaFiller(
|
||||
provider string,
|
||||
mediaId int,
|
||||
slug string,
|
||||
lastFetchedAt time.Time,
|
||||
fillerEpisodes []string,
|
||||
) error {
|
||||
|
||||
// Marshal the filler data
|
||||
fillerData := filler.Data{
|
||||
FillerEpisodes: fillerEpisodes,
|
||||
}
|
||||
|
||||
fillerDataBytes, err := json.Marshal(fillerData)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Delete the existing media filler
|
||||
_ = db.DeleteMediaFiller(mediaId)
|
||||
|
||||
// Save the media filler
|
||||
err = db.gormdb.Create(&models.MediaFiller{
|
||||
Provider: provider,
|
||||
MediaID: mediaId,
|
||||
Slug: slug,
|
||||
LastFetchedAt: lastFetchedAt,
|
||||
Data: fillerDataBytes,
|
||||
}).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Update the cache
|
||||
db.CurrMediaFillers = mo.None[map[int]*MediaFillerItem]()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// SaveCachedMediaFillerItems will save the cached media filler items in the database.
|
||||
// Call this function after editing the cached media filler items.
|
||||
func (db *Database) SaveCachedMediaFillerItems() error {
|
||||
|
||||
if db.CurrMediaFillers.IsAbsent() {
|
||||
return nil
|
||||
}
|
||||
|
||||
mediaFillers, err := db.GetCachedMediaFillers()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, mf := range mediaFillers {
|
||||
if len(mf.FillerEpisodes) == 0 {
|
||||
continue
|
||||
}
|
||||
// Marshal the filler data
|
||||
fillerData := filler.Data{
|
||||
FillerEpisodes: mf.FillerEpisodes,
|
||||
}
|
||||
|
||||
fillerDataBytes, err := json.Marshal(fillerData)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Save the media filler
|
||||
err = db.gormdb.Model(&models.MediaFiller{}).
|
||||
Where("id = ?", mf.DbId).
|
||||
Updates(map[string]interface{}{
|
||||
"last_fetched_at": mf.LastFetchedAt,
|
||||
"data": fillerDataBytes,
|
||||
}).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Update the cache
|
||||
db.CurrMediaFillers = mo.None[map[int]*MediaFillerItem]()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Database) DeleteMediaFiller(mediaId int) error {
|
||||
|
||||
mediaFillers, err := db.GetCachedMediaFillers()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
item, ok := mediaFillers[mediaId]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
err = db.gormdb.Delete(&models.MediaFiller{}, item.DbId).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Update the cache
|
||||
db.CurrMediaFillers = mo.None[map[int]*MediaFillerItem]()
|
||||
|
||||
return nil
|
||||
}
|
||||
24
seanime-2.9.10/internal/database/db/nakama.go
Normal file
24
seanime-2.9.10/internal/database/db/nakama.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"seanime/internal/database/models"
|
||||
)
|
||||
|
||||
func (db *Database) UpsertNakamaSettings(nakamaSettings *models.NakamaSettings) (*models.NakamaSettings, error) {
|
||||
|
||||
// Get current settings
|
||||
currentSettings, err := db.GetSettings()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Update the settings
|
||||
*(currentSettings.Nakama) = *nakamaSettings
|
||||
|
||||
_, err = db.UpsertSettings(currentSettings)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return nakamaSettings, nil
|
||||
}
|
||||
52
seanime-2.9.10/internal/database/db/onlinestream.go
Normal file
52
seanime-2.9.10/internal/database/db/onlinestream.go
Normal file
@@ -0,0 +1,52 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"seanime/internal/database/models"
|
||||
"seanime/internal/util/result"
|
||||
)
|
||||
|
||||
var onlinestreamMappingCache = result.NewResultMap[string, *models.OnlinestreamMapping]()
|
||||
|
||||
func formatOnlinestreamMappingCacheKey(provider string, mediaId int) string {
|
||||
return fmt.Sprintf("%s$%d", provider, mediaId)
|
||||
}
|
||||
|
||||
func (db *Database) GetOnlinestreamMapping(provider string, mediaId int) (*models.OnlinestreamMapping, bool) {
|
||||
|
||||
if res, ok := onlinestreamMappingCache.Get(formatOnlinestreamMappingCacheKey(provider, mediaId)); ok {
|
||||
return res, true
|
||||
}
|
||||
|
||||
var res models.OnlinestreamMapping
|
||||
err := db.gormdb.Where("provider = ? AND media_id = ?", provider, mediaId).First(&res).Error
|
||||
if err != nil {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
onlinestreamMappingCache.Set(formatOnlinestreamMappingCacheKey(provider, mediaId), &res)
|
||||
|
||||
return &res, true
|
||||
}
|
||||
|
||||
func (db *Database) InsertOnlinestreamMapping(provider string, mediaId int, animeId string) error {
|
||||
mapping := models.OnlinestreamMapping{
|
||||
Provider: provider,
|
||||
MediaID: mediaId,
|
||||
AnimeID: animeId,
|
||||
}
|
||||
|
||||
onlinestreamMappingCache.Set(formatOnlinestreamMappingCacheKey(provider, mediaId), &mapping)
|
||||
|
||||
return db.gormdb.Save(&mapping).Error
|
||||
}
|
||||
|
||||
func (db *Database) DeleteOnlinestreamMapping(provider string, mediaId int) error {
|
||||
err := db.gormdb.Where("provider = ? AND media_id = ?", provider, mediaId).Delete(&models.OnlinestreamMapping{}).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
onlinestreamMappingCache.Delete(formatOnlinestreamMappingCacheKey(provider, mediaId))
|
||||
return nil
|
||||
}
|
||||
24
seanime-2.9.10/internal/database/db/scan_summary.go
Normal file
24
seanime-2.9.10/internal/database/db/scan_summary.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"seanime/internal/database/models"
|
||||
)
|
||||
|
||||
func (db *Database) TrimScanSummaryEntries() {
|
||||
go func() {
|
||||
var count int64
|
||||
err := db.gormdb.Model(&models.ScanSummary{}).Count(&count).Error
|
||||
if err != nil {
|
||||
db.Logger.Error().Err(err).Msg("Failed to count scan summary entries")
|
||||
return
|
||||
}
|
||||
if count > 10 {
|
||||
// Leave 5 entries
|
||||
err = db.gormdb.Delete(&models.ScanSummary{}, "id IN (SELECT id FROM scan_summaries ORDER BY id ASC LIMIT ?)", count-5).Error
|
||||
if err != nil {
|
||||
db.Logger.Error().Err(err).Msg("Failed to delete old scan summary entries")
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
200
seanime-2.9.10/internal/database/db/settings.go
Normal file
200
seanime-2.9.10/internal/database/db/settings.go
Normal file
@@ -0,0 +1,200 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"seanime/internal/database/models"
|
||||
|
||||
"gorm.io/gorm/clause"
|
||||
)
|
||||
|
||||
var CurrSettings *models.Settings
|
||||
|
||||
func (db *Database) UpsertSettings(settings *models.Settings) (*models.Settings, error) {
|
||||
|
||||
err := db.gormdb.Clauses(clause.OnConflict{
|
||||
Columns: []clause.Column{{Name: "id"}},
|
||||
UpdateAll: true,
|
||||
}).Create(settings).Error
|
||||
|
||||
if err != nil {
|
||||
db.Logger.Error().Err(err).Msg("db: Failed to save settings in the database")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
CurrSettings = settings
|
||||
|
||||
db.Logger.Debug().Msg("db: Settings saved")
|
||||
return settings, nil
|
||||
|
||||
}
|
||||
|
||||
func (db *Database) GetSettings() (*models.Settings, error) {
|
||||
|
||||
if CurrSettings != nil {
|
||||
return CurrSettings, nil
|
||||
}
|
||||
|
||||
var settings models.Settings
|
||||
err := db.gormdb.Where("id = ?", 1).Find(&settings).Error
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &settings, nil
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
func (db *Database) GetLibraryPathFromSettings() (string, error) {
|
||||
settings, err := db.GetSettings()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return settings.Library.LibraryPath, nil
|
||||
}
|
||||
|
||||
func (db *Database) GetAdditionalLibraryPathsFromSettings() ([]string, error) {
|
||||
settings, err := db.GetSettings()
|
||||
if err != nil {
|
||||
return []string{}, err
|
||||
}
|
||||
return settings.Library.LibraryPaths, nil
|
||||
}
|
||||
|
||||
func (db *Database) GetAllLibraryPathsFromSettings() ([]string, error) {
|
||||
settings, err := db.GetSettings()
|
||||
if err != nil {
|
||||
return []string{}, err
|
||||
}
|
||||
if settings.Library == nil {
|
||||
return []string{}, nil
|
||||
}
|
||||
return append([]string{settings.Library.LibraryPath}, settings.Library.LibraryPaths...), nil
|
||||
}
|
||||
|
||||
func (db *Database) AllLibraryPathsFromSettings(settings *models.Settings) *[]string {
|
||||
if settings.Library == nil {
|
||||
return &[]string{}
|
||||
}
|
||||
r := append([]string{settings.Library.LibraryPath}, settings.Library.LibraryPaths...)
|
||||
return &r
|
||||
}
|
||||
|
||||
func (db *Database) AutoUpdateProgressIsEnabled() (bool, error) {
|
||||
settings, err := db.GetSettings()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return settings.Library.AutoUpdateProgress, nil
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var CurrMediastreamSettings *models.MediastreamSettings
|
||||
|
||||
func (db *Database) UpsertMediastreamSettings(settings *models.MediastreamSettings) (*models.MediastreamSettings, error) {
|
||||
|
||||
err := db.gormdb.Clauses(clause.OnConflict{
|
||||
Columns: []clause.Column{{Name: "id"}},
|
||||
UpdateAll: true,
|
||||
}).Create(settings).Error
|
||||
|
||||
if err != nil {
|
||||
db.Logger.Error().Err(err).Msg("db: Failed to save media streaming settings in the database")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
CurrMediastreamSettings = settings
|
||||
|
||||
db.Logger.Debug().Msg("db: Media streaming settings saved")
|
||||
return settings, nil
|
||||
|
||||
}
|
||||
|
||||
func (db *Database) GetMediastreamSettings() (*models.MediastreamSettings, bool) {
|
||||
|
||||
if CurrMediastreamSettings != nil {
|
||||
return CurrMediastreamSettings, true
|
||||
}
|
||||
|
||||
var settings models.MediastreamSettings
|
||||
err := db.gormdb.Where("id = ?", 1).First(&settings).Error
|
||||
|
||||
if err != nil {
|
||||
return nil, false
|
||||
}
|
||||
return &settings, true
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var CurrTorrentstreamSettings *models.TorrentstreamSettings
|
||||
|
||||
func (db *Database) UpsertTorrentstreamSettings(settings *models.TorrentstreamSettings) (*models.TorrentstreamSettings, error) {
|
||||
|
||||
err := db.gormdb.Clauses(clause.OnConflict{
|
||||
Columns: []clause.Column{{Name: "id"}},
|
||||
UpdateAll: true,
|
||||
}).Create(settings).Error
|
||||
|
||||
if err != nil {
|
||||
db.Logger.Error().Err(err).Msg("db: Failed to save torrent streaming settings in the database")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
CurrTorrentstreamSettings = settings
|
||||
|
||||
db.Logger.Debug().Msg("db: Torrent streaming settings saved")
|
||||
return settings, nil
|
||||
}
|
||||
|
||||
func (db *Database) GetTorrentstreamSettings() (*models.TorrentstreamSettings, bool) {
|
||||
|
||||
if CurrTorrentstreamSettings != nil {
|
||||
return CurrTorrentstreamSettings, true
|
||||
}
|
||||
|
||||
var settings models.TorrentstreamSettings
|
||||
err := db.gormdb.Where("id = ?", 1).First(&settings).Error
|
||||
|
||||
if err != nil {
|
||||
return nil, false
|
||||
}
|
||||
return &settings, true
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var CurrentDebridSettings *models.DebridSettings
|
||||
|
||||
func (db *Database) UpsertDebridSettings(settings *models.DebridSettings) (*models.DebridSettings, error) {
|
||||
err := db.gormdb.Clauses(clause.OnConflict{
|
||||
Columns: []clause.Column{{Name: "id"}},
|
||||
UpdateAll: true,
|
||||
}).Create(settings).Error
|
||||
|
||||
if err != nil {
|
||||
db.Logger.Error().Err(err).Msg("db: Failed to save debrid settings in the database")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
CurrentDebridSettings = settings
|
||||
|
||||
db.Logger.Debug().Msg("db: Debrid settings saved")
|
||||
return settings, nil
|
||||
}
|
||||
|
||||
func (db *Database) GetDebridSettings() (*models.DebridSettings, bool) {
|
||||
|
||||
if CurrentDebridSettings != nil {
|
||||
return CurrentDebridSettings, true
|
||||
}
|
||||
|
||||
var settings models.DebridSettings
|
||||
err := db.gormdb.Where("id = ?", 1).First(&settings).Error
|
||||
if err != nil {
|
||||
return nil, false
|
||||
}
|
||||
return &settings, true
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
70
seanime-2.9.10/internal/database/db/silenced_media_entry.go
Normal file
70
seanime-2.9.10/internal/database/db/silenced_media_entry.go
Normal file
@@ -0,0 +1,70 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"gorm.io/gorm/clause"
|
||||
"seanime/internal/database/models"
|
||||
)
|
||||
|
||||
func (db *Database) GetSilencedMediaEntries() ([]*models.SilencedMediaEntry, error) {
|
||||
var res []*models.SilencedMediaEntry
|
||||
err := db.gormdb.Find(&res).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// GetSilencedMediaEntryIds returns the ids of all silenced media entries.
|
||||
// It returns an empty slice if there is an error.
|
||||
func (db *Database) GetSilencedMediaEntryIds() ([]int, error) {
|
||||
var res []*models.SilencedMediaEntry
|
||||
err := db.gormdb.Find(&res).Error
|
||||
if err != nil {
|
||||
return make([]int, 0), err
|
||||
}
|
||||
|
||||
if len(res) == 0 {
|
||||
return make([]int, 0), nil
|
||||
}
|
||||
|
||||
mIds := make([]int, len(res))
|
||||
for i, v := range res {
|
||||
mIds[i] = int(v.ID)
|
||||
}
|
||||
|
||||
return mIds, nil
|
||||
}
|
||||
|
||||
func (db *Database) GetSilencedMediaEntry(mId uint) (*models.SilencedMediaEntry, error) {
|
||||
var res models.SilencedMediaEntry
|
||||
err := db.gormdb.First(&res, mId).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
func (db *Database) InsertSilencedMediaEntry(mId uint) error {
|
||||
err := db.gormdb.Clauses(clause.OnConflict{
|
||||
Columns: []clause.Column{{Name: "id"}},
|
||||
UpdateAll: true,
|
||||
}).Create(&models.SilencedMediaEntry{
|
||||
BaseModel: models.BaseModel{
|
||||
ID: mId,
|
||||
},
|
||||
}).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Database) DeleteSilencedMediaEntry(id uint) error {
|
||||
err := db.gormdb.Delete(&models.SilencedMediaEntry{}, id).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
47
seanime-2.9.10/internal/database/db/theme.go
Normal file
47
seanime-2.9.10/internal/database/db/theme.go
Normal file
@@ -0,0 +1,47 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"gorm.io/gorm/clause"
|
||||
"seanime/internal/database/models"
|
||||
)
|
||||
|
||||
var themeCache *models.Theme
|
||||
|
||||
func (db *Database) GetTheme() (*models.Theme, error) {
|
||||
|
||||
if themeCache != nil {
|
||||
return themeCache, nil
|
||||
}
|
||||
|
||||
var theme models.Theme
|
||||
err := db.gormdb.Where("id = ?", 1).Find(&theme).Error
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
themeCache = &theme
|
||||
|
||||
return &theme, nil
|
||||
}
|
||||
|
||||
// UpsertTheme updates the theme settings.
|
||||
func (db *Database) UpsertTheme(settings *models.Theme) (*models.Theme, error) {
|
||||
|
||||
err := db.gormdb.Clauses(clause.OnConflict{
|
||||
Columns: []clause.Column{{Name: "id"}},
|
||||
UpdateAll: true,
|
||||
}).Create(settings).Error
|
||||
|
||||
if err != nil {
|
||||
db.Logger.Error().Err(err).Msg("db: Failed to save theme in the database")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
db.Logger.Debug().Msg("db: Theme saved")
|
||||
|
||||
themeCache = settings
|
||||
|
||||
return settings, nil
|
||||
|
||||
}
|
||||
21
seanime-2.9.10/internal/database/db/token.go
Normal file
21
seanime-2.9.10/internal/database/db/token.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"gorm.io/gorm/clause"
|
||||
"seanime/internal/database/models"
|
||||
)
|
||||
|
||||
func (db *Database) UpsertToken(token *models.Token) (*models.Token, error) {
|
||||
|
||||
err := db.gormdb.Clauses(clause.OnConflict{
|
||||
Columns: []clause.Column{{Name: "id"}},
|
||||
DoUpdates: clause.AssignmentColumns([]string{"value", "updated_at"}),
|
||||
}).Create(token).Error
|
||||
|
||||
if err != nil {
|
||||
db.Logger.Error().Err(err).Msg("Failed to save token in the database")
|
||||
return nil, err
|
||||
}
|
||||
return token, nil
|
||||
|
||||
}
|
||||
24
seanime-2.9.10/internal/database/db/torrentstream_history.go
Normal file
24
seanime-2.9.10/internal/database/db/torrentstream_history.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"seanime/internal/database/models"
|
||||
)
|
||||
|
||||
func (db *Database) TrimTorrentstreamHistory() {
|
||||
go func() {
|
||||
var count int64
|
||||
err := db.gormdb.Model(&models.TorrentstreamHistory{}).Count(&count).Error
|
||||
if err != nil {
|
||||
db.Logger.Error().Err(err).Msg("database: Failed to count torrent stream history entries")
|
||||
return
|
||||
}
|
||||
if count > 50 {
|
||||
// Leave 40 entries
|
||||
err = db.gormdb.Delete(&models.TorrentstreamHistory{}, "id IN (SELECT id FROM torrentstream_histories ORDER BY updated_at ASC LIMIT ?)", 10).Error
|
||||
if err != nil {
|
||||
db.Logger.Error().Err(err).Msg("database: Failed to delete old torrent stream history entries")
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
Reference in New Issue
Block a user