From 1207f193e8c37ed3dcaacd440b01fbb0ec3cb389 Mon Sep 17 00:00:00 2001 From: Laptop Date: Wed, 9 Oct 2024 19:15:38 +0300 Subject: [PATCH] caching improvements; add more ways to get track for widget player --- README.md | 4 +-- assets/global.css | 2 +- lib/cfg/init.go | 15 +++++++-- lib/sc/init.go | 6 ++-- lib/sc/track.go | 86 ++++++++++++++++++++++++++++++++++++++++++++++- main.go | 14 +------- 6 files changed, 104 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 797a6e0..f5f93da 100644 --- a/README.md +++ b/README.md @@ -11,9 +11,9 @@ wip alternative frontend for soundcloud - Resolving shortened links (`https://on.soundcloud.com/boiKDP46fayYDoVK9` -> `https://sc.maid.zone/on/boiKDP46fayYDoVK9`) ## In the works -- Track player embeds (`https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/id` -> `https://sc.maid.zone/w/player/?url=https%3A//api.soundcloud.com/tracks/id`) +- Track player embeds (`https://w.soundcloud.com/player/` -> `https://sc.maid.zone/w/player/`) -The UI isn't really done yet. All parameters other than url are unsupported. You can also specify track by permalink instead of id (`https://sc.maid.zone/w/player/?url=username/track`) +The UI isn't really done yet. All parameters other than url are unsupported. You can also specify track without the `soundcloud.com` part: `https://sc.maid.zone/w/player/?url=` or `https://sc.maid.zone/w/player/?url=/` # Contributing Contributions are appreciated! This includes feedback, feature requests, issues, pull requests and etc. diff --git a/assets/global.css b/assets/global.css index 1c86c71..ea2a47f 100644 --- a/assets/global.css +++ b/assets/global.css @@ -33,7 +33,7 @@ h4, h5, h6 { font-family: "fixed", monospace, system-ui; - font-weight: normal; + font-weight: normal !important; } /* header { diff --git a/lib/cfg/init.go b/lib/cfg/init.go index 418ed7a..c766a38 100644 --- a/lib/cfg/init.go +++ b/lib/cfg/init.go @@ -16,13 +16,22 @@ const FullyPreloadTrack = false const ClientIDTTL = 30 * time.Minute // time-to-live for user profile cache -const UserTTL = 5 * time.Minute +const UserTTL = 10 * time.Minute + +// delay between cleanup of user cache +const UserCacheCleanDelay = UserTTL / 4 // time-to-live for track cache -const TrackTTL = 5 * time.Minute +const TrackTTL = 10 * time.Minute + +// delay between cleanup of track cache +const TrackCacheCleanDelay = TrackTTL / 4 // time-to-live for playlist cache -const PlaylistTTL = 5 * time.Minute +const PlaylistTTL = 10 * time.Minute + +// delay between cleanup of playlist cache +const PlaylistCacheCleanDelay = PlaylistTTL / 4 // default fasthttp one was causing connections to be stuck? todo make it cycle browser useragents or just choose random at startup const UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.3" diff --git a/lib/sc/init.go b/lib/sc/init.go index d0be3fc..2bbb376 100644 --- a/lib/sc/init.go +++ b/lib/sc/init.go @@ -245,7 +245,7 @@ func TagListParser(taglist string) (res []string) { // could probably make a generic function, whatever func init() { go func() { - ticker := time.NewTicker(cfg.UserTTL) + ticker := time.NewTicker(cfg.UserCacheCleanDelay) for range ticker.C { usersCacheLock.Lock() @@ -260,7 +260,7 @@ func init() { }() go func() { - ticker := time.NewTicker(cfg.TrackTTL) + ticker := time.NewTicker(cfg.TrackCacheCleanDelay) for range ticker.C { tracksCacheLock.Lock() @@ -275,7 +275,7 @@ func init() { }() go func() { - ticker := time.NewTicker(cfg.PlaylistTTL) + ticker := time.NewTicker(cfg.PlaylistCacheCleanDelay) for range ticker.C { playlistsCacheLock.Lock() diff --git a/lib/sc/track.go b/lib/sc/track.go index 6f23c12..3319357 100644 --- a/lib/sc/track.go +++ b/lib/sc/track.go @@ -3,6 +3,7 @@ package sc import ( "errors" "fmt" + "net/url" "strconv" "strings" "sync" @@ -107,6 +108,89 @@ func GetTrack(permalink string) (Track, error) { return t, nil } +// Currently supports: +// http/https links: +// - api.soundcloud.com/tracks/ (api-v2 subdomain also supported) +// - soundcloud.com// +// +// plain permalink/id: +// - / +// - +func GetArbitraryTrack(data string) (Track, error) { + if len(data) > 8 && (data[:8] == "https://" || data[:7] == "http://") { + u, err := url.Parse(data) + if err == nil { + if (u.Host == "api.soundcloud.com" || u.Host == "api-v2.soundcloud.com") && len(u.Path) > 8 && u.Path[:8] == "/tracks/" { + return GetTrackByID(u.Path[8:]) + } + + if u.Host == "soundcloud.com" { + if len(u.Path) < 4 { + return Track{}, ErrNoURL + } + + u.Path = u.Path[1:] + if u.Path[len(u.Path)-1] == '/' { + u.Path = u.Path[:len(u.Path)-1] + } + + var n uint = 0 + for _, c := range u.Path { + if c == '/' { + n++ + } + } + + if n != 1 { + return Track{}, ErrKindNotCorrect + } + + return GetTrack(u.Path) + } + } + } + + valid := true + for _, n := range data { + if n < '0' || n > '9' { + valid = false + break + } + } + + if valid { + return GetTrackByID(data) + } + + // this should be at the end since it manipulates data + if len(data) < 4 { + return Track{}, ErrNoURL + } + + if data[0] == '/' { + data = data[1:] + } + + if data[len(data)-1] == '/' { + data = data[:len(data)-1] + } + var n uint = 0 + for _, c := range data { + if c == '/' { + n++ + } + } + + fmt.Println(data) + + if n == 1 { + return GetTrack(data) + } + + // failed to find a data point + return Track{}, ErrKindNotCorrect +} + func SearchTracks(args string) (*Paginated[*Track], error) { cid, err := GetClientID() if err != nil { @@ -291,7 +375,7 @@ func GetTrackByID(id string) (Track, error) { t.Fix(true) tracksCacheLock.Lock() - tracksCache[t.Permalink] = cached[Track]{Value: t, Expires: time.Now().Add(cfg.TrackTTL)} + tracksCache[t.Author.Permalink+"/"+t.Permalink] = cached[Track]{Value: t, Expires: time.Now().Add(cfg.TrackTTL)} tracksCacheLock.Unlock() return t, nil diff --git a/main.go b/main.go index 11caee2..9922815 100644 --- a/main.go +++ b/main.go @@ -116,19 +116,7 @@ func main() { return fiber.ErrNotFound } - var ( - track sc.Track - err error - ) - if strings.HasPrefix(u, "https://") { - if !strings.HasPrefix(u, "https://api.soundcloud.com/tracks/") { - return fiber.ErrUnsupportedMediaType - } - - track, err = sc.GetTrackByID(u[34:]) // len("https://api.soundcloud.com/tracks/") == 34 - } else { - track, err = sc.GetTrack(u) - } + track, err := sc.GetArbitraryTrack(u) if err != nil { fmt.Printf("error getting %s: %s\n", u, err)