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

188 lines
4.9 KiB
Go

package plugin
import (
"context"
"errors"
"seanime/internal/extension"
"seanime/internal/goja/goja_bindings"
"seanime/internal/manga"
goja_util "seanime/internal/util/goja"
"github.com/dop251/goja"
"github.com/rs/zerolog"
)
type Manga struct {
ctx *AppContextImpl
vm *goja.Runtime
logger *zerolog.Logger
ext *extension.Extension
scheduler *goja_util.Scheduler
}
func (a *AppContextImpl) BindMangaToContextObj(vm *goja.Runtime, obj *goja.Object, logger *zerolog.Logger, ext *extension.Extension, scheduler *goja_util.Scheduler) {
m := &Manga{
ctx: a,
vm: vm,
logger: logger,
ext: ext,
scheduler: scheduler,
}
mangaObj := vm.NewObject()
// Get downloaded chapter containers
_ = mangaObj.Set("getDownloadedChapters", m.getDownloadedChapterContainers)
_ = mangaObj.Set("getCollection", m.getCollection)
_ = mangaObj.Set("refreshChapters", m.refreshChapterContainers)
_ = mangaObj.Set("emptyCache", m.emptyCache)
_ = mangaObj.Set("getChapterContainer", m.getChapterContainer)
_ = mangaObj.Set("getProviders", m.getProviders)
_ = obj.Set("manga", mangaObj)
}
func (m *Manga) getProviders() (map[string]string, error) {
mangaRepo, ok := m.ctx.mangaRepository.Get()
if !ok {
return nil, errors.New("manga repository not found")
}
providers := make(map[string]string)
extension.RangeExtensions(mangaRepo.GetProviderExtensionBank(), func(id string, ext extension.MangaProviderExtension) bool {
providers[id] = ext.GetName()
return true
})
return providers, nil
}
type GetChapterContainerOptions struct {
MediaId int
Provider string
Titles []*string
Year int
}
func (m *Manga) getChapterContainer(opts *GetChapterContainerOptions) goja.Value {
promise, resolve, reject := m.vm.NewPromise()
mangaRepo, ok := m.ctx.mangaRepository.Get()
if !ok {
// reject(goja_bindings.NewErrorString(m.vm, "manga repository not set"))
// return m.vm.ToValue(promise)
goja_bindings.PanicThrowErrorString(m.vm, "manga repository not set")
}
go func() {
ret, err := mangaRepo.GetMangaChapterContainer(&manga.GetMangaChapterContainerOptions{
MediaId: opts.MediaId,
Provider: opts.Provider,
Titles: opts.Titles,
Year: opts.Year,
})
m.scheduler.ScheduleAsync(func() error {
if err != nil {
reject(err.Error())
} else {
resolve(ret)
}
return nil
})
}()
return m.vm.ToValue(promise)
}
func (m *Manga) getDownloadedChapterContainers() ([]*manga.ChapterContainer, error) {
mangaRepo, ok := m.ctx.mangaRepository.Get()
if !ok {
return nil, errors.New("manga repository not found")
}
anilistPlatform, foundAnilistPlatform := m.ctx.anilistPlatform.Get()
if !foundAnilistPlatform {
return nil, errors.New("anilist platform not found")
}
mangaCollection, err := anilistPlatform.GetMangaCollection(context.Background(), false)
if err != nil {
return nil, err
}
return mangaRepo.GetDownloadedChapterContainers(mangaCollection)
}
func (m *Manga) getCollection() (*manga.Collection, error) {
anilistPlatform, foundAnilistPlatform := m.ctx.anilistPlatform.Get()
if !foundAnilistPlatform {
return nil, errors.New("anilist platform not found")
}
mangaCollection, err := anilistPlatform.GetMangaCollection(context.Background(), false)
if err != nil {
return nil, err
}
return manga.NewCollection(&manga.NewCollectionOptions{
MangaCollection: mangaCollection,
Platform: anilistPlatform,
})
}
func (m *Manga) refreshChapterContainers(selectedProviderMap map[int]string) goja.Value {
promise, resolve, reject := m.vm.NewPromise()
mangaRepo, ok := m.ctx.mangaRepository.Get()
if !ok {
jsErr := m.vm.NewGoError(errors.New("manga repository not found"))
_ = reject(jsErr)
return m.vm.ToValue(promise)
}
anilistPlatform, foundAnilistPlatform := m.ctx.anilistPlatform.Get()
if !foundAnilistPlatform {
jsErr := m.vm.NewGoError(errors.New("anilist platform not found"))
_ = reject(jsErr)
return m.vm.ToValue(promise)
}
mangaCollection, err := anilistPlatform.GetMangaCollection(context.Background(), false)
if err != nil {
reject(err.Error())
return m.vm.ToValue(promise)
}
go func() {
err := mangaRepo.RefreshChapterContainers(mangaCollection, selectedProviderMap)
m.scheduler.ScheduleAsync(func() error {
if err != nil {
reject(err.Error())
} else {
resolve(nil)
}
return nil
})
}()
return m.vm.ToValue(promise)
}
func (m *Manga) emptyCache(mediaId int) goja.Value {
promise, resolve, reject := m.vm.NewPromise()
mangaRepo, ok := m.ctx.mangaRepository.Get()
if !ok {
// reject(goja_bindings.NewErrorString(m.vm, "manga repository not found"))
// return m.vm.ToValue(promise)
goja_bindings.PanicThrowErrorString(m.vm, "manga repository not found")
}
go func() {
err := mangaRepo.EmptyMangaCache(mediaId)
m.scheduler.ScheduleAsync(func() error {
if err != nil {
reject(err.Error())
} else {
resolve(nil)
}
return nil
})
}()
return m.vm.ToValue(promise)
}