From f903439cbc504b9a7b676eb8a1c4e1d4c95a61fc Mon Sep 17 00:00:00 2001 From: Benjamin Chausse Date: Fri, 6 Sep 2024 19:59:21 -0400 Subject: Batman --- internal/service/service.go | 66 +++++++++++++++++++++++++++++++++++++++++++++ internal/urls/url.go | 36 +++++++++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 internal/service/service.go create mode 100644 internal/urls/url.go (limited to 'internal') diff --git a/internal/service/service.go b/internal/service/service.go new file mode 100644 index 0000000..49647fe --- /dev/null +++ b/internal/service/service.go @@ -0,0 +1,66 @@ +package services + +// service defines any Music service recognized by song.link +// Since most services have multiple url version (long, short, etc...), +// it is allowd to have multiple ones. +// This allows for seamless song link detection +type service struct { + name string + patterns []string +} + +func GetServices() []service { + return []service{ + *New( + "Apple Music", + []string{"https://music.apple.com/"}, + ), + *New( + "Spotify", + []string{"https://open.spotify.com/track/", "https://open.spotify.com/album/", "https://open.spotify.com/playlist/"}, + ), + *New( + "Youtube Music", + []string{"https://music.youtube.com/"}, + ), + // *New( + // "Amazon Music", + // []string{"https://music.amazon.com/",}, + // ), + *New( + "Tidal", + []string{"https://tidal.com/"}, + ), + *New( + "Deezer", + []string{"https://www.deezer.com/"}, + ), + *New( + "Pandora", + []string{"https://www.pandora.com/"}, + ), + } +} + +func New(name string, patterns []string) *service { + return &service{name, patterns} +} + +func (s *service) Name() string { + return s.name +} + +func (s *service) Owns(url string) bool { + // If the url begins the same as any of the patterns, it is owned by the service + for _, pattern := range s.patterns { + if len(url) >= len(pattern) && url[:len(pattern)] == pattern { + return true + } + } + return false +} + +// Resolve returns the song.link url for the given service url +func (s *service) Resolve(url string) string { + return "https://song.link/" + url +} diff --git a/internal/urls/url.go b/internal/urls/url.go new file mode 100644 index 0000000..bb76594 --- /dev/null +++ b/internal/urls/url.go @@ -0,0 +1,36 @@ +package urls + +import ( + "net/http" + "regexp" +) + +// Find takes in a string (i.e. a discord message) +// and returns a list of all the urls it has found in this +// string. +func Find(s string) []string { + // Regular expression to match URLs starting with https + re := regexp.MustCompile(`https://[^\s]+`) + + // Find all matching URLs + return re.FindAllString(s, -1) +} + +func Resolve(url string) (string, error) { + client := &http.Client{ + // Automatically follow redirects + CheckRedirect: func(req *http.Request, via []*http.Request) error { + return nil + }, + } + + resp, err := client.Head(url) + if err != nil { + return "", err + } + defer resp.Body.Close() + + // The final resolved URL after following redirects + finalURL := resp.Request.URL.String() + return finalURL, nil +} -- cgit v1.2.3