From 35f1f4cfe2047db4ab66f247a104b084277a5070 Mon Sep 17 00:00:00 2001 From: --Explosion-- Date: Fri, 1 Mar 2024 08:54:54 -0600 Subject: [PATCH] Truncate search query by iterating over components Iterate over components, limit them each to 50 characters, then limit whole query to 100 characters, e.g.: ``` {'artist': 'willie nelson, jimmy buffett, emmylou harris, sheryl crow, eric church, george strait, dave matthews, chris stapleton, derek trucks, kris kristofferson, the avett brothers, bobby bare, jack johnson, jamey johnson, lee ann womack, lukas nelson, lyle lovett, margo price, micah nelson, nathaniel rateliff, norah jones, the little willies, ray benson, steve earle, susan tedeschi, vince gill', 'recording': 'roll me up and smoke me when i die - live'} --> [ "artist:willie nelson, jimmy buffett, emmylou harris, sheryl crow, eric church, george strait, dave matthews, chris stapleton, derek trucks, kris kristofferson, the avett brothers, bobby bare, jack johnson, jamey johnson, lee ann womack, lukas nelson, lyle lovett, margo price, micah nelson, nathaniel rateliff, norah jones, the little willies, ray benson, steve earle, susan tedeschi, vince gill", "recording:roll me up and smoke me when i die" ] --> Iterate over each component, split by commas, then this should become: [ "artist:willie nelson, jimmy buffett", (Trimmed emmylou harris) "recording:roll me up and smoke me when i die" ] --> Now this is joined by spaces, split again and trunctuated to 100 characters: "artist:willie nelson, jimmy buffett recording:roll me up and smoke me when i die" (length 80 chars) ``` --- beetsplug/spotify.py | 50 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 43 insertions(+), 7 deletions(-) diff --git a/beetsplug/spotify.py b/beetsplug/spotify.py index b07b7884e..7153beb15 100644 --- a/beetsplug/spotify.py +++ b/beetsplug/spotify.py @@ -381,7 +381,36 @@ class SpotifyPlugin(MetadataSourcePlugin, BeetsPlugin): track.index = i track.medium_total = medium_total return track - + + @staticmethod + def _list_limit(str_input, max_length=50, delim=","): + """Return a list of strings from the input string that can be joined into + a single string with a length less than or equal to max_length. + + :param str_input: String to split and join. + :type str_input: str + :param max_length: Maximum length of the resulting string. + :type max_length: int + :param delim: Delimiter to use when splitting and joining the strings. + :type delim: str + :return: List of strings that can be joined into a single string with a + length less than or equal to max_length. + :rtype: List[str] + """ + str_list = str_input.split(delim) + if len(str_list) == 1: + # If the input string doesn't contain the delimiter, trim it to max_length + return [str_list[0][:max_length]] + result = [] + current_length = 0 + for item in str_list: + item_length = len(item) + len(delim) + if current_length + item_length > max_length: + break + result.append(item) + current_length += item_length + return result + @staticmethod def _construct_search_query(filters=None, keywords=""): """Construct a query string with the specified filters and keywords to @@ -399,10 +428,19 @@ class SpotifyPlugin(MetadataSourcePlugin, BeetsPlugin): keywords, " ".join(":".join((k, v)) for k, v in filters.items()), ] - query = " ".join([q for q in query_components if q]) - if not isinstance(query, str): - query = query.decode("utf8") - return unidecode.unidecode(query) + query = [] + + # Limit each component to 50 characters max, so, for example the artist field doesn't take up all 100 characters + for component in query_components: + if component + if not isinstance(component, str): + component = component.decode("utf8") + limited_list = self._list_limit(component, max_length=50, delim=',') + # Each component is split by a comma but queries are joined by a space + query.append(",".join(limited_list)) + + # Make sure it's less than 100 characters + return unidecode.unidecode(self._list_limit(" ".join(query), max_length=100, delim=' ')) def _search_api(self, query_type, filters=None, keywords=""): """Query the Spotify Search API for the specified ``keywords``, @@ -553,8 +591,6 @@ class SpotifyPlugin(MetadataSourcePlugin, BeetsPlugin): keywords = item[self.config["track_field"].get()] # Query the Web API for each track, look for the items' JSON data - if len(artist) > 50: - artist = ",".join(artist.split(",")[:2]) query_filters = {"artist": artist, "album": album} response_data_tracks = self._search_api( query_type="track", keywords=keywords, filters=query_filters