Files
AynaLivePlayer/adapters/provider/local.go
2023-02-19 04:23:03 -08:00

166 lines
3.6 KiB
Go

package provider
import (
"AynaLivePlayer/common/util"
"AynaLivePlayer/core/adapter"
"AynaLivePlayer/core/model"
"os"
"sort"
"strings"
)
type _LocalPlaylist struct {
Name string
Medias []*model.Media
}
type Local struct {
localDir string
Playlists []*_LocalPlaylist
}
func NewLocalCtor(config adapter.MediaProviderConfig) adapter.MediaProvider {
localDir, ok := config["local_dir"]
if !ok {
localDir = "./local"
}
l := &Local{Playlists: make([]*_LocalPlaylist, 0), localDir: localDir}
if err := os.MkdirAll(localDir, 0755); err != nil {
return l
}
for _, n := range getPlaylistNames(localDir) {
l.Playlists = append(l.Playlists, &_LocalPlaylist{Name: n})
}
for i, _ := range l.Playlists {
_ = readLocalPlaylist(localDir, l.Playlists[i])
}
LocalAPI = l
Providers[LocalAPI.GetName()] = LocalAPI
return l
}
var LocalAPI *Local
func NewLocal(localdir string) *Local {
l := &Local{Playlists: make([]*_LocalPlaylist, 0), localDir: localdir}
if err := os.MkdirAll(localdir, 0755); err != nil {
return l
}
for _, n := range getPlaylistNames(localdir) {
l.Playlists = append(l.Playlists, &_LocalPlaylist{Name: n})
}
for i, _ := range l.Playlists {
_ = readLocalPlaylist(localdir, l.Playlists[i])
}
LocalAPI = l
Providers[LocalAPI.GetName()] = LocalAPI
return l
}
func (l *Local) GetName() string {
return "local"
}
func (l *Local) MatchMedia(keyword string) *model.Media {
return nil
}
func (l *Local) UpdateMediaLyric(media *model.Media) error {
// already update in UpdateMedia, do nothing
return nil
}
func (l *Local) FormatPlaylistUrl(uri string) string {
return uri
}
func (l *Local) GetPlaylist(playlist *model.Meta) ([]*model.Media, error) {
var pl *_LocalPlaylist = nil
for _, p := range l.Playlists {
if p.Name == playlist.Id {
pl = p
}
}
if pl == nil {
l.Playlists = append(l.Playlists, &_LocalPlaylist{Name: playlist.Id})
pl = l.Playlists[len(l.Playlists)-1]
}
if readLocalPlaylist(l.localDir, pl) != nil {
return nil, ErrorExternalApi
}
return pl.Medias, nil
}
func (l *Local) Search(keyword string) ([]*model.Media, error) {
allMedias := make([]*model.Media, 0)
for _, p := range l.Playlists {
for _, m := range p.Medias {
allMedias = append(allMedias, m)
}
}
MediaSort(keyword, allMedias)
c := util.Min(len(allMedias), 32)
medias := make([]*model.Media, c)
for i := 0; i < c; i++ {
medias[i] = allMedias[i].Copy()
}
return medias, nil
}
func (l *Local) SearchV1(keyword string) ([]*model.Media, error) {
result := make([]struct {
M *model.Media
N int
}, 0)
keywords := strings.Split(keyword, " ")
for _, p := range l.Playlists {
for _, m := range p.Medias {
title := strings.ToLower(m.Title)
artist := strings.ToLower(m.Artist)
n := 0
for _, k := range keywords {
kw := strings.ToLower(k)
if strings.Contains(title, kw) || strings.Contains(artist, kw) {
n++
}
if kw == title {
n += 3
}
}
if n > 0 {
result = append(result, struct {
M *model.Media
N int
}{M: m, N: n})
}
}
}
sort.Slice(result, func(i, j int) bool {
return result[i].N > result[j].N
})
medias := make([]*model.Media, len(result))
for i, r := range result {
medias[i] = r.M.Copy()
}
return medias, nil
}
func (l *Local) UpdateMedia(media *model.Media) error {
mediaPath := media.Meta.(model.Meta).Id
_, err := os.Stat(mediaPath)
if err != nil {
return err
}
return readMediaFile(media)
}
func (l *Local) UpdateMediaUrl(media *model.Media) error {
mediaPath := media.Meta.(model.Meta).Id
_, err := os.Stat(mediaPath)
if err != nil {
return err
}
media.Url = mediaPath
return nil
}