Skip to content

Commit

Permalink
[ 1.0.31 ] * Updated underlying spotifywebapiPython package require…
Browse files Browse the repository at this point in the history
…ment to version 1.0.64.

  * The underlying `spotifywebapiPython` update changes the way Spotify Connect Zeroconf API return codes are processed.  It now processes the Spotify Zeroconf API status code from the JSON response instead of processing the HTTP request status code.  It has been found that some Spotify Connect manufacturers return different HTTP status codes than other manufacturers; but the Spotify Connect `status`, `statusString` and `spotifyError` JSON properties seem to be consistent across the board.
  * The underlying `spotifywebapiPython` update also filters out duplicate Spotify Connect Device entries for devices that have been grouped together.  For example, the "Bose-ST10-1" and "Bose-ST10-2" are grouped as a stereo pair; there will be two Zeroconf discovery result entries with different instance names, but their Zeroconf getInfo endpoint url will be the same.  This was causing two entries to appear in the device list, when there should have been only one.
  • Loading branch information
thlucas1 committed Jun 24, 2024
1 parent f2f363c commit 8b5070a
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 5 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ Change are listed in reverse chronological order (newest to oldest).

<span class="changelog">

###### [ 1.0.31 ] - 2024/06/24

* Updated underlying `spotifywebapiPython` package requirement to version 1.0.64.
* The underlying `spotifywebapiPython` update changes the way Spotify Connect Zeroconf API return codes are processed. It now processes the Spotify Zeroconf API status code from the JSON response instead of processing the HTTP request status code. It has been found that some Spotify Connect manufacturers return different HTTP status codes than other manufacturers; but the Spotify Connect `status`, `statusString` and `spotifyError` JSON properties seem to be consistent across the board.
* The underlying `spotifywebapiPython` update also filters out duplicate Spotify Connect Device entries for devices that have been grouped together. For example, the "Bose-ST10-1" and "Bose-ST10-2" are grouped as a stereo pair; there will be two Zeroconf discovery result entries with different instance names, but their Zeroconf getInfo endpoint url will be the same. This was causing two entries to appear in the device list, when there should have been only one.

###### [ 1.0.30 ] - 2024/06/22

* Updated `config_flow` to utilize the HA shared Zeroconf instance.
Expand Down
3 changes: 2 additions & 1 deletion custom_components/spotifyplus/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,8 @@ def _GetPlayerDevicesList(self) -> list:
# get configuration instance data so we can reference the client instance.
_logsi.LogVerbose("'%s': OptionsFlow is retrieving instance data" % self._name)
data:InstanceDataSpotifyPlus = self.hass.data[DOMAIN].get(self._entry.entry_id, None)
_logsi.LogObject(SILevel.Verbose, "'%s': OptionsFlow instance data object" % self._name, data)
_logsi.LogObject(SILevel.Verbose, "'%s': OptionsFlow instance data.spotifyClient" % self._name, data.spotifyClient)
_logsi.LogObject(SILevel.Verbose, "'%s': OptionsFlow instance data.options" % self._name, data.options)

# get spotify connect player device list.
_logsi.LogVerbose("'%s': OptionsFlow is retrieving Spotify Connect player devices" % self._name)
Expand Down
4 changes: 2 additions & 2 deletions custom_components/spotifyplus/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@
"requests>=2.31.0",
"requests_oauthlib>=1.3.1",
"smartinspectPython>=3.0.33",
"spotifywebapiPython>=1.0.62",
"spotifywebapiPython>=1.0.64",
"urllib3>=1.21.1,<1.27",
"zeroconf>=0.132.2"
],
"version": "1.0.30",
"version": "1.0.31",
"zeroconf": [ "_spotify-connect._tcp.local." ]
}
3 changes: 2 additions & 1 deletion custom_components/spotifyplus/media_player.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
DOMAIN_SCRIPT,
LOGGER,
)
from .utils import passwordMaskString

# get smartinspect logger reference; create a new session for this module name.
from smartinspectpython.siauto import SIAuto, SILevel, SISession, SIMethodParmListContext, SIColors
Expand Down Expand Up @@ -4720,7 +4721,7 @@ def service_spotify_zeroconf_device_connect(
apiMethodParms.AppendKeyValue("version", version)
apiMethodParms.AppendKeyValue("useSSL", useSSL)
apiMethodParms.AppendKeyValue("username", username)
apiMethodParms.AppendKeyValue("password", password)
apiMethodParms.AppendKeyValue("password (with mask)", passwordMaskString(password))
apiMethodParms.AppendKeyValue("preDisconnect", preDisconnect)
apiMethodParms.AppendKeyValue("verifyDeviceListEntry", verifyDeviceListEntry)
_logsi.LogMethodParmList(SILevel.Verbose, "Spotify Connect ZeroConf Device Connect Service", apiMethodParms)
Expand Down
65 changes: 65 additions & 0 deletions custom_components/spotifyplus/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
from copy import deepcopy

# # get smartinspect logger reference; create a new session for this module name.
# from smartinspectpython.siauto import SIAuto, SILevel, SISession, SIColors
# import logging
# _logsi:SISession = SIAuto.Si.GetSession(__name__)
# if (_logsi == None):
# _logsi = SIAuto.Si.AddSession(__name__, True)
# _logsi.SystemLogger = logging.getLogger(__name__)

def passwordMaskDictionary(inputObj:dict) -> dict:
"""
Checks keys in a dictionary any keys that contain `password` and masks the
value so that the password is not displayed in a trace file.
Args:
inputObj (dict):
Dictionary object to check.
Returns:
A copy of the `inputObj` source dictionary with passwor(s) masked.
Note that this method performs a simple copy of the dictionary.
"""
# if input is null then don't bother.
if (inputObj is None):
return inputObj

# create a new dictionary.
result:dict = {}

# process keys in the dictionary.
key:str
for key in inputObj.keys():
keyLower:str = key.lower()
if (keyLower.find('password') == -1):
result[key] = inputObj[key]
else:
value:str = inputObj[key]
if (value is not None) and (isinstance(value, str)):
result[key] = ''.ljust(len(value), '*')

return result


def passwordMaskString(inputObj:str) -> str:
"""
Checks a string for a password value and masks the value so that the password is not displayed
in a trace file.
Args:
inputObj (str):
String object to check.
Returns:
A copy of the `inputObj` value with password masked.
"""
# if input is null then don't bother.
if (inputObj is None):
return inputObj

# create a new value.
result:str = ''.ljust(len(inputObj), '*')

return result
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ colorlog==6.7.0
homeassistant==2024.5.0
ruff==0.1.3
smartinspectPython>=3.0.33
spotifywebapiPython>=1.0.62
spotifywebapiPython>=1.0.64
1 change: 1 addition & 0 deletions spotifyplus.pyproj
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
<Compile Include="custom_components\spotifyplus\instancedata_spotifyplus.py" />
<Compile Include="custom_components\spotifyplus\media_player.py" />
<Compile Include="custom_components\spotifyplus\system_health.py" />
<Compile Include="custom_components\spotifyplus\utils.py" />
<Compile Include="custom_components\spotifyplus\__init__.py" />
</ItemGroup>
<ItemGroup>
Expand Down

0 comments on commit 8b5070a

Please sign in to comment.