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 }