147 lines
3.3 KiB
Go
147 lines
3.3 KiB
Go
package plugin
|
|
|
|
import (
|
|
"errors"
|
|
"regexp"
|
|
|
|
"gitea.elara.ws/Hazel/music-kraken/internal/data"
|
|
)
|
|
|
|
type Plugin interface {
|
|
Name() string
|
|
Regex() *regexp.Regexp
|
|
RegexArtist() *regexp.Regexp
|
|
RegexAlbum() *regexp.Regexp
|
|
RegexSong() *regexp.Regexp
|
|
|
|
Search(query string) ([]data.MusicObject, error)
|
|
|
|
FetchArtist(source data.Source) (data.Artist, error)
|
|
FetchAlbum(source data.Source) (data.Album, error)
|
|
FetchSong(source data.Source) (data.Song, error)
|
|
}
|
|
|
|
var namePlugins = map[string]Plugin{}
|
|
var nameSourceType = map[string]data.SourceType{}
|
|
|
|
func RegisterPlugin(plugin Plugin) error {
|
|
name := plugin.Name()
|
|
|
|
if _, ok := namePlugins[name]; ok {
|
|
return errors.New("plugin " + name + " is already registered")
|
|
}
|
|
|
|
nameSourceType[name] = data.SourceType{
|
|
Name: name,
|
|
Regex: plugin.Regex(),
|
|
RegexArtist: plugin.RegexArtist(),
|
|
RegexAlbum: plugin.RegexAlbum(),
|
|
RegexSong: plugin.RegexSong(),
|
|
}
|
|
|
|
namePlugins[name] = plugin
|
|
return nil
|
|
}
|
|
|
|
func compileSourceType(source data.Source) (data.Source, error) {
|
|
if source.SourceType != nil {
|
|
if _, ok := namePlugins[source.SourceType.Name]; !ok {
|
|
return source, errors.New("source type " + source.SourceType.Name + " not found")
|
|
}
|
|
return source, nil
|
|
}
|
|
|
|
for _, st := range nameSourceType {
|
|
if m := st.Regex.FindString(source.Url); m != "" {
|
|
source.Url = m
|
|
source.SourceType = &st
|
|
return source, nil
|
|
}
|
|
}
|
|
|
|
return source, errors.New("couldn't find source type for " + source.Url)
|
|
}
|
|
|
|
func compileSource(source data.Source) (data.Source, error) {
|
|
source, err := compileSourceType(source)
|
|
if err != nil {
|
|
return source, err
|
|
}
|
|
|
|
// find what object this source corresponds to
|
|
if source.ObjectType != "" {
|
|
return source, nil
|
|
}
|
|
|
|
sourceType := source.SourceType
|
|
|
|
if sourceType.RegexSong.MatchString(source.Url) {
|
|
source.ObjectType = data.SongSource
|
|
return source, nil
|
|
}
|
|
|
|
if sourceType.RegexAlbum.MatchString(source.Url) {
|
|
source.ObjectType = data.AlbumSource
|
|
return source, nil
|
|
}
|
|
|
|
if sourceType.RegexArtist.MatchString(source.Url) {
|
|
source.ObjectType = data.ArtistSource
|
|
return source, nil
|
|
}
|
|
|
|
return source, errors.New("couldn't find corresponding object source on " + sourceType.Name + " for " + source.Url)
|
|
}
|
|
|
|
func Fetch(source data.Source) (data.MusicObject, error) {
|
|
// the fetch function without the post processing of the music objects
|
|
source, err := compileSource(source)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
plugin, ok := namePlugins[source.SourceType.Name]
|
|
if !ok {
|
|
return nil, errors.New("didn't find plugin of the name " + source.SourceType.Name)
|
|
}
|
|
|
|
if source.ObjectType == data.SongSource {
|
|
song, err := plugin.FetchSong(source)
|
|
|
|
if err != nil {
|
|
return song, err
|
|
}
|
|
song.Sources = append(song.Sources, source)
|
|
song = song.Compile().(data.Song)
|
|
return song, nil
|
|
}
|
|
|
|
if source.ObjectType == data.AlbumSource {
|
|
album, err := plugin.FetchAlbum(source)
|
|
|
|
if err != nil {
|
|
return album, err
|
|
}
|
|
album.Sources = append(album.Sources, source)
|
|
album = album.Compile().(data.Album)
|
|
return album, nil
|
|
}
|
|
|
|
if source.ObjectType == data.ArtistSource {
|
|
artist, err := plugin.FetchArtist(source)
|
|
|
|
if err != nil {
|
|
return artist, err
|
|
}
|
|
artist.Sources = append(artist.Sources, source)
|
|
artist = artist.Compile().(data.Artist)
|
|
return artist, nil
|
|
}
|
|
|
|
return nil, nil
|
|
}
|
|
|
|
func Search(q string) {
|
|
|
|
}
|