108 lines
2.4 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) {
name := plugin.Name()
nameSourceType[name] = data.SourceType{
Name: name,
Regex: plugin.Regex(),
RegexArtist: plugin.RegexArtist(),
RegexAlbum: plugin.RegexAlbum(),
RegexSong: plugin.RegexSong(),
}
namePlugins[name] = plugin
}
func compileSourceType(source data.Source) (data.Source, error) {
if source.SourceType != nil {
return source, nil
}
for _, st := range nameSourceType {
if m := st.Regex.FindString(source.Url); m != "" {
source.Url = m
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
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) {
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 {
return plugin.FetchSong(source)
}
if source.ObjectType == data.AlbumSource {
return plugin.FetchAlbum(source)
}
if source.ObjectType == data.ArtistSource {
return plugin.FetchArtist(source)
}
return nil, nil
}