node build fixed
This commit is contained in:
255
seanime-2.9.10/internal/debrid/client/repository.go
Normal file
255
seanime-2.9.10/internal/debrid/client/repository.go
Normal file
@@ -0,0 +1,255 @@
|
||||
package debrid_client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"seanime/internal/api/anilist"
|
||||
"seanime/internal/api/metadata"
|
||||
"seanime/internal/database/db"
|
||||
"seanime/internal/database/models"
|
||||
"seanime/internal/debrid/debrid"
|
||||
"seanime/internal/debrid/realdebrid"
|
||||
"seanime/internal/debrid/torbox"
|
||||
"seanime/internal/directstream"
|
||||
"seanime/internal/events"
|
||||
"seanime/internal/library/playbackmanager"
|
||||
"seanime/internal/platforms/platform"
|
||||
"seanime/internal/torrents/torrent"
|
||||
"seanime/internal/util/result"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/samber/mo"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrProviderNotSet = fmt.Errorf("debrid: Provider not set")
|
||||
)
|
||||
|
||||
type (
|
||||
Repository struct {
|
||||
provider mo.Option[debrid.Provider]
|
||||
logger *zerolog.Logger
|
||||
db *db.Database
|
||||
settings *models.DebridSettings
|
||||
wsEventManager events.WSEventManagerInterface
|
||||
ctxMap *result.Map[string, context.CancelFunc]
|
||||
downloadLoopCancelFunc context.CancelFunc
|
||||
torrentRepository *torrent.Repository
|
||||
directStreamManager *directstream.Manager
|
||||
|
||||
playbackManager *playbackmanager.PlaybackManager
|
||||
streamManager *StreamManager
|
||||
completeAnimeCache *anilist.CompleteAnimeCache
|
||||
metadataProvider metadata.Provider
|
||||
platform platform.Platform
|
||||
|
||||
previousStreamOptions mo.Option[*StartStreamOptions]
|
||||
}
|
||||
|
||||
NewRepositoryOptions struct {
|
||||
Logger *zerolog.Logger
|
||||
WSEventManager events.WSEventManagerInterface
|
||||
Database *db.Database
|
||||
|
||||
TorrentRepository *torrent.Repository
|
||||
PlaybackManager *playbackmanager.PlaybackManager
|
||||
DirectStreamManager *directstream.Manager
|
||||
MetadataProvider metadata.Provider
|
||||
Platform platform.Platform
|
||||
}
|
||||
)
|
||||
|
||||
func NewRepository(opts *NewRepositoryOptions) (ret *Repository) {
|
||||
ret = &Repository{
|
||||
provider: mo.None[debrid.Provider](),
|
||||
logger: opts.Logger,
|
||||
wsEventManager: opts.WSEventManager,
|
||||
db: opts.Database,
|
||||
settings: &models.DebridSettings{
|
||||
Enabled: false,
|
||||
},
|
||||
torrentRepository: opts.TorrentRepository,
|
||||
platform: opts.Platform,
|
||||
playbackManager: opts.PlaybackManager,
|
||||
metadataProvider: opts.MetadataProvider,
|
||||
completeAnimeCache: anilist.NewCompleteAnimeCache(),
|
||||
ctxMap: result.NewResultMap[string, context.CancelFunc](),
|
||||
previousStreamOptions: mo.None[*StartStreamOptions](),
|
||||
directStreamManager: opts.DirectStreamManager,
|
||||
}
|
||||
|
||||
ret.streamManager = NewStreamManager(ret)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
func (r *Repository) startOrStopDownloadLoop() {
|
||||
// Cancel the previous download loop if it's running
|
||||
if r.downloadLoopCancelFunc != nil {
|
||||
r.downloadLoopCancelFunc()
|
||||
}
|
||||
|
||||
// Start the download loop if the provider is set and enabled
|
||||
if r.settings.Enabled && r.provider.IsPresent() {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
r.downloadLoopCancelFunc = cancel
|
||||
r.launchDownloadLoop(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
// InitializeProvider is called each time the settings change
|
||||
func (r *Repository) InitializeProvider(settings *models.DebridSettings) error {
|
||||
r.settings = settings
|
||||
|
||||
if !settings.Enabled {
|
||||
r.provider = mo.None[debrid.Provider]()
|
||||
// Stop the download loop if it's running
|
||||
r.startOrStopDownloadLoop()
|
||||
return nil
|
||||
}
|
||||
|
||||
switch settings.Provider {
|
||||
case "torbox":
|
||||
r.provider = mo.Some(torbox.NewTorBox(r.logger))
|
||||
case "realdebrid":
|
||||
r.provider = mo.Some(realdebrid.NewRealDebrid(r.logger))
|
||||
default:
|
||||
r.provider = mo.None[debrid.Provider]()
|
||||
}
|
||||
|
||||
if r.provider.IsAbsent() {
|
||||
r.logger.Warn().Str("provider", settings.Provider).Msg("debrid: No provider set")
|
||||
// Stop the download loop if it's running
|
||||
r.startOrStopDownloadLoop()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Authenticate the provider
|
||||
err := r.provider.MustGet().Authenticate(r.settings.ApiKey)
|
||||
if err != nil {
|
||||
r.logger.Err(err).Msg("debrid: Failed to authenticate")
|
||||
r.provider = mo.None[debrid.Provider]()
|
||||
// Cancel the download loop if it's running
|
||||
if r.downloadLoopCancelFunc != nil {
|
||||
r.downloadLoopCancelFunc()
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Start the download loop
|
||||
r.startOrStopDownloadLoop()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Repository) GetProvider() (debrid.Provider, error) {
|
||||
p, found := r.provider.Get()
|
||||
if !found {
|
||||
return nil, ErrProviderNotSet
|
||||
}
|
||||
|
||||
return p, nil
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// AddAndQueueTorrent adds a torrent to the debrid service and queues it for automatic download
|
||||
func (r *Repository) AddAndQueueTorrent(opts debrid.AddTorrentOptions, destination string, mId int) (string, error) {
|
||||
provider, err := r.GetProvider()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if !filepath.IsAbs(destination) {
|
||||
return "", fmt.Errorf("debrid: Failed to add torrent, destination must be an absolute path")
|
||||
}
|
||||
|
||||
// Add the torrent to the debrid service
|
||||
torrentItemId, err := provider.AddTorrent(opts)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Add the torrent item to the database (so it can be downloaded automatically once it's ready)
|
||||
// We ignore the error since it's non-critical
|
||||
_ = r.db.InsertDebridTorrentItem(&models.DebridTorrentItem{
|
||||
TorrentItemID: torrentItemId,
|
||||
Destination: destination,
|
||||
Provider: provider.GetSettings().ID,
|
||||
MediaId: mId,
|
||||
})
|
||||
|
||||
return torrentItemId, nil
|
||||
}
|
||||
|
||||
// GetTorrentInfo retrieves information about a torrent.
|
||||
// This is used for file section for debrid streaming.
|
||||
// On Real Debrid, this adds the torrent to the user's account.
|
||||
func (r *Repository) GetTorrentInfo(opts debrid.GetTorrentInfoOptions) (*debrid.TorrentInfo, error) {
|
||||
provider, err := r.GetProvider()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
torrentInfo, err := provider.GetTorrentInfo(opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Remove non-video files
|
||||
torrentInfo.Files = debrid.FilterVideoFiles(torrentInfo.Files)
|
||||
|
||||
return torrentInfo, nil
|
||||
}
|
||||
|
||||
func (r *Repository) HasProvider() bool {
|
||||
return r.provider.IsPresent()
|
||||
}
|
||||
|
||||
func (r *Repository) GetSettings() *models.DebridSettings {
|
||||
return r.settings
|
||||
}
|
||||
|
||||
// CancelDownload cancels the download for the given item ID
|
||||
func (r *Repository) CancelDownload(itemID string) error {
|
||||
cancelFunc, found := r.ctxMap.Get(itemID)
|
||||
if !found {
|
||||
return fmt.Errorf("no download found for item ID: %s", itemID)
|
||||
}
|
||||
|
||||
// Call the cancel function to cancel the download
|
||||
if cancelFunc != nil {
|
||||
cancelFunc()
|
||||
}
|
||||
|
||||
r.ctxMap.Delete(itemID)
|
||||
|
||||
// Notify that the download has been cancelled
|
||||
r.wsEventManager.SendEvent(events.DebridDownloadProgress, map[string]interface{}{
|
||||
"status": "cancelled",
|
||||
"itemID": itemID,
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Repository) StartStream(ctx context.Context, opts *StartStreamOptions) error {
|
||||
return r.streamManager.startStream(ctx, opts)
|
||||
}
|
||||
|
||||
func (r *Repository) GetStreamURL() (string, bool) {
|
||||
return r.streamManager.currentStreamUrl, r.streamManager.currentStreamUrl != ""
|
||||
}
|
||||
|
||||
func (r *Repository) CancelStream(opts *CancelStreamOptions) {
|
||||
r.streamManager.cancelStream(opts)
|
||||
}
|
||||
|
||||
func (r *Repository) GetPreviousStreamOptions() (*StartStreamOptions, bool) {
|
||||
return r.previousStreamOptions.Get()
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
Reference in New Issue
Block a user