From 393b5593a2958ed34ff728dbd96c178dfe79e48e Mon Sep 17 00:00:00 2001 From: Santiago-Balcero Date: Sun, 14 Apr 2024 13:54:56 -0500 Subject: [PATCH 1/2] fix: market as request option to search for shows because spotify api issue --- countries.go | 7 +++--- examples/search/search.go | 19 ++++++++++++++- search.go | 13 +++++++---- search_test.go | 29 +++++++++++++++++++++++ test_data/search_show.txt | 49 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 109 insertions(+), 8 deletions(-) create mode 100644 test_data/search_show.txt diff --git a/countries.go b/countries.go index a8f3f4c..7968838 100644 --- a/countries.go +++ b/countries.go @@ -13,18 +13,19 @@ const ( CountryCanada = "CA" CountryChile = "CL" CountryChina = "CN" + CountryColombia = "CO" + CountryFinland = "FI" + CountryFrance = "FR" CountryGermany = "DE" CountryHongKong = "HK" CountryIreland = "IE" CountryIndia = "IN" CountryItaly = "IT" CountryJapan = "JP" - CountrySpain = "ES" - CountryFinland = "FI" - CountryFrance = "FR" CountryMexico = "MX" CountryNewZealand = "NZ" CountryRussia = "RU" + CountrySpain = "ES" CountrySwitzerland = "CH" CountryUnitedArabEmirates = "AE" CountryUnitedKingdom = "GB" diff --git a/examples/search/search.go b/examples/search/search.go index c00cfe7..21bc45b 100644 --- a/examples/search/search.go +++ b/examples/search/search.go @@ -3,10 +3,11 @@ package main import ( "context" "fmt" - spotifyauth "github.com/zmb3/spotify/v2/auth" "log" "os" + spotifyauth "github.com/zmb3/spotify/v2/auth" + "golang.org/x/oauth2/clientcredentials" "github.com/zmb3/spotify/v2" @@ -46,4 +47,20 @@ func main() { fmt.Println(" ", item.Name) } } + + // search for shows using market query parameter + options := []spotify.RequestOption{ + spotify.Market("CO"), + } + + results, err = client.Search(ctx, "cyclast", spotify.SearchTypeShow, options...) + if err != nil { + log.Fatal(err) + } + // handle show results + if results.Shows != nil { + for _, item := range results.Shows.Shows { + fmt.Println(" ", item.Name) + } + } } diff --git a/search.go b/search.go index aabd8a3..b25b274 100644 --- a/search.go +++ b/search.go @@ -2,6 +2,7 @@ package spotify import ( "context" + "fmt" "strings" ) @@ -68,14 +69,14 @@ type SearchResult struct { // search types. For example, `Search(query, SearchTypeArtist|SearchTypeAlbum)` // will search for artists or albums matching the specified keywords. // -// Matching +// # Matching // // Matching of search keywords is NOT case sensitive. Keywords are matched in // any order unless surrounded by double quotes. Searching for playlists will // return results where the query keyword(s) match any part of the playlist's // name or description. Only popular public playlists are returned. // -// Operators +// # Operators // // The operator NOT can be used to exclude results. For example, // query = "roadhouse NOT blues" returns items that match "roadhouse" but excludes @@ -85,14 +86,14 @@ type SearchResult struct { // // Operators should be specified in uppercase. // -// Wildcards +// # Wildcards // // The asterisk (*) character can, with some limitations, be used as a wildcard // (maximum of 2 per query). It will match a variable number of non-white-space // characters. It cannot be used in a quoted phrase, in a field filter, or as // the first character of a keyword string. // -// Field filters +// # Field filters // // By default, results are returned when a match is found in any field of the // target object type. Searches can be made more specific by specifying an album, @@ -124,6 +125,10 @@ func (c *Client) Search(ctx context.Context, query string, t SearchType, opts .. v.Set("q", query) v.Set("type", t.encode()) + if t == SearchTypeShow && v.Get("market") == "" { + return nil, fmt.Errorf("searching for shows requires market parameter") + } + spotifyURL := c.baseURL + "search?" + v.Encode() var result SearchResult diff --git a/search_test.go b/search_test.go index 2716fe7..e13c4ea 100644 --- a/search_test.go +++ b/search_test.go @@ -78,6 +78,35 @@ func TestSearchPlaylistTrack(t *testing.T) { } } +func TestSearchShow(t *testing.T) { + client, server := testClientFile(http.StatusOK, "test_data/search_show.txt") + defer server.Close() + + options := []RequestOption{ + Market("CO"), + } + + result, err := client.Search(context.Background(), "go time", SearchTypeShow, options...) + if err != nil { + t.Error(err) + } + if result.Albums != nil { + t.Error("Searched for shows but received album results") + } + if result.Playlists != nil { + t.Error("Searched for shows but received playlist results") + } + if result.Tracks != nil { + t.Error("Searched for shows but received track results") + } + if result.Shows == nil || len(result.Shows.Shows) == 0 { + t.Error("Didn't receive show results") + } + if result.Shows.Shows[0].Name != "Go Time: Golang, Software Engineering" { + t.Error("Got wrong show name") + } +} + func TestPrevNextSearchPageErrors(t *testing.T) { client, server := testClientString(0, "") defer server.Close() diff --git a/test_data/search_show.txt b/test_data/search_show.txt new file mode 100644 index 0000000..0a14454 --- /dev/null +++ b/test_data/search_show.txt @@ -0,0 +1,49 @@ +{ + "shows": { + "href": "https://api.spotify.com/v1/search?query=go+time&type=show&locale=es-CO%2Ces%3Bq%3D0.9%2Cen-US%3Bq%3D0.8%2Cen%3Bq%3D0.7%2Ces-419%3Bq%3D0.6&offset=0&limit=1", + "limit": 20, + "next": "https://api.spotify.com/v1/search?query=go+time&type=show&locale=es-CO%2Ces%3Bq%3D0.9%2Cen-US%3Bq%3D0.8%2Cen%3Bq%3D0.7%2Ces-419%3Bq%3D0.6&offset=1&limit=1", + "offset": 0, + "previous": null, + "total": 1, + "items": [ + { + "available_markets": ["AD", "AE", "AG", "AL", "AM", "AR", "AT", "AU", "BA", "BB", "BE", "BF", "BG", "BH", "BJ", "BO", "BR", "BS", "BT", "BW", "BZ", "CA", "CH", "CL", "CO", "CR", "CV", "CW", "CY", "CZ", "DE", "DK", "DM", "DO", "DZ", "EC", "EE", "EG", "ES", "FI", "FJ", "FM", "FR", "GB", "GD", "GE", "GH", "GM", "GR", "GT", "GW", "GY", "HK", "HN", "HR", "HT", "HU", "ID", "IE", "IL", "IN", "IS", "IT", "JM", "JO", "JP", "KE", "KI", "KN", "KR", "KW", "LB", "LC", "LI", "LR", "LS", "LT", "LU", "LV", "MA", "MC", "ME", "MG", "MH", "MK", "ML", "MT", "MU", "MV", "MW", "MX", "MY", "MZ", "NA", "NE", "NG", "NI", "NL", "NO", "NR", "NZ", "OM", "PA", "PE", "PG", "PH", "PL", "PR", "PS", "PT", "PW", "PY", "QA", "RO", "RS", "SA", "SB", "SC", "SE", "SG", "SI", "SK", "SL", "SM", "SN", "SR", "ST", "SV", "TH", "TL", "TN", "TO", "TR", "TT", "TV", "TW", "UA", "US", "UY", "VC", "VN", "VU", "WS", "XK", "ZA"], + "copyrights": [], + "description": "Your source for diverse discussions from around the Go community. This show records LIVE every Tuesday at 3pm US Eastern. Join the Golang community and chat with us during the show in the #gotimefm channel of Gophers slack. Panelists include Mat Ryer, Jon Calhoun, Natalie Pistunovich, Johnny Boursiquot, Angelica Hill, Kris Brandow, and Ian Lopshire. We discuss cloud infrastructure, distributed systems, microservices, Kubernetes, Docker… oh and also Go! Some people search for GoTime or GoTimeFM and can’t find the show, so now the strings GoTime and GoTimeFM are in our description too.", + "html_description": "Your source for diverse discussions from around the Go community. This show records LIVE every Tuesday at 3pm US Eastern. Join the Golang community and chat with us during the show in the #gotimefm channel of Gophers slack. Panelists include Mat Ryer, Jon Calhoun, Natalie Pistunovich, Johnny Boursiquot, Angelica Hill, Kris Brandow, and Ian Lopshire. We discuss cloud infrastructure, distributed systems, microservices, Kubernetes, Docker… oh and also Go! Some people search for GoTime or GoTimeFM and can’t find the show, so now the strings GoTime and GoTimeFM are in our description too.", + "explicit": false, + "external_urls": { + "spotify": "https://open.spotify.com/show/2cKdcxETn7jDp7uJCwqmSE" + }, + "href": "https://api.spotify.com/v1/shows/2cKdcxETn7jDp7uJCwqmSE", + "id": "2cKdcxETn7jDp7uJCwqmSE", + "images": [ + { + "url": "https://i.scdn.co/image/18d9cacf366a7173b10204eb983fe5d374b728dd", + "height": 640, + "width": 640 + }, + { + "url": "https://i.scdn.co/image/3f9b1dd55b3353a0d70dfcca6a44c01775cfbfcc", + "height": 300, + "width": 300 + }, + { + "url": "https://i.scdn.co/image/aa9e23de8a5a64bedaf526bb963123413984e53f", + "height": 64, + "width": 64 + } + ], + "is_externally_hosted": false, + "languages": ["en-US"], + "media_type": "audio", + "name": "Go Time: Golang, Software Engineering", + "publisher": "Changelog Media", + "type": "show", + "uri": "spotify:show:2cKdcxETn7jDp7uJCwqmSE", + "total_episodes": 316 + } + ] + } +} \ No newline at end of file From fd78fc336481e6f097e98b4c005aca1dac276400 Mon Sep 17 00:00:00 2001 From: Santiago-Balcero Date: Thu, 18 Apr 2024 18:21:26 -0500 Subject: [PATCH 2/2] feat: new error var --- search.go | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/search.go b/search.go index b25b274..a34fc76 100644 --- a/search.go +++ b/search.go @@ -2,10 +2,14 @@ package spotify import ( "context" - "fmt" + "errors" "strings" ) +// ErrSearchMarketRequired is the error returned when you attempt to search for shows +// but "market" is not part of options parameters. It is required due to Spotify API unsolved issue. +var ErrSearchMarketRequired = errors.New("spotify:search: searching for shows requires market parameter") + const ( // MarketFromToken can be used in place of the Options.Country parameter // if the Client has a valid access token. In this case, the @@ -69,14 +73,14 @@ type SearchResult struct { // search types. For example, `Search(query, SearchTypeArtist|SearchTypeAlbum)` // will search for artists or albums matching the specified keywords. // -// # Matching +// Matching // // Matching of search keywords is NOT case sensitive. Keywords are matched in // any order unless surrounded by double quotes. Searching for playlists will // return results where the query keyword(s) match any part of the playlist's // name or description. Only popular public playlists are returned. // -// # Operators +// Operators // // The operator NOT can be used to exclude results. For example, // query = "roadhouse NOT blues" returns items that match "roadhouse" but excludes @@ -86,14 +90,14 @@ type SearchResult struct { // // Operators should be specified in uppercase. // -// # Wildcards +// Wildcards // // The asterisk (*) character can, with some limitations, be used as a wildcard // (maximum of 2 per query). It will match a variable number of non-white-space // characters. It cannot be used in a quoted phrase, in a field filter, or as // the first character of a keyword string. // -// # Field filters +// Field filters // // By default, results are returned when a match is found in any field of the // target object type. Searches can be made more specific by specifying an album, @@ -126,7 +130,7 @@ func (c *Client) Search(ctx context.Context, query string, t SearchType, opts .. v.Set("type", t.encode()) if t == SearchTypeShow && v.Get("market") == "" { - return nil, fmt.Errorf("searching for shows requires market parameter") + return nil, ErrSearchMarketRequired } spotifyURL := c.baseURL + "search?" + v.Encode()