spotifywebapiPython 1.0.46__py3-none-any.whl → 1.0.47__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of spotifywebapiPython might be problematic. Click here for more details.

Files changed (34) hide show
  1. {spotifywebapiPython-1.0.46.dist-info → spotifywebapiPython-1.0.47.dist-info}/METADATA +1 -1
  2. {spotifywebapiPython-1.0.46.dist-info → spotifywebapiPython-1.0.47.dist-info}/RECORD +34 -28
  3. spotifywebapipython/const.py +1 -1
  4. spotifywebapipython/docs/__init__.html +15 -3
  5. spotifywebapipython/docs/index.html +20 -2
  6. spotifywebapipython/docs/search.js +1 -1
  7. spotifywebapipython/docs/spotifywebapiPython/const.html +3 -3
  8. spotifywebapipython/docs/spotifywebapiPython/saappmessages.html +22 -2
  9. spotifywebapipython/docs/spotifywebapiPython/sautils.html +2 -2
  10. spotifywebapipython/docs/spotifywebapiPython/spotifyapierror.html +2 -2
  11. spotifywebapipython/docs/spotifywebapiPython/spotifyapimessage.html +2 -2
  12. spotifywebapipython/docs/spotifywebapiPython/spotifyauthtoken.html +2 -2
  13. spotifywebapipython/docs/spotifywebapiPython/spotifyclient.html +2 -200
  14. spotifywebapipython/docs/spotifywebapiPython/spotifydiscovery.html +2 -28
  15. spotifywebapipython/docs/spotifywebapiPython/spotifywebapiauthenticationerror.html +2 -2
  16. spotifywebapipython/docs/spotifywebapiPython/spotifywebapierror.html +2 -2
  17. spotifywebapipython/models/__init__.py +0 -10
  18. spotifywebapipython/saappmessages.py +7 -1
  19. spotifywebapipython/spotifyclient.py +0 -249
  20. spotifywebapipython/spotifydiscovery.py +0 -46
  21. spotifywebapipython/zeroconfapi/__init__.py +21 -0
  22. spotifywebapipython/{models/zeroconfblobbuilder.py → zeroconfapi/blobbuilder.py} +10 -58
  23. spotifywebapipython/zeroconfapi/credentials.py +18 -0
  24. spotifywebapipython/zeroconfapi/cryptodiffiehellman.py +24 -0
  25. spotifywebapipython/zeroconfapi/helpers.py +30 -0
  26. spotifywebapipython/zeroconfapi/spotifyzeroconfapierror.py +108 -0
  27. spotifywebapipython/zeroconfapi/zeroconfconnect.py +562 -0
  28. spotifywebapipython/{models → zeroconfapi}/zeroconfgetinfo.py +21 -7
  29. spotifywebapipython/{models → zeroconfapi}/zeroconfgetinfoalias.py +1 -1
  30. spotifywebapipython/{models → zeroconfapi}/zeroconfgetinfodrmmediaformat.py +1 -1
  31. spotifywebapipython/{models → zeroconfapi}/zeroconfresponse.py +3 -3
  32. {spotifywebapiPython-1.0.46.dist-info → spotifywebapiPython-1.0.47.dist-info}/LICENSE +0 -0
  33. {spotifywebapiPython-1.0.46.dist-info → spotifywebapiPython-1.0.47.dist-info}/WHEEL +0 -0
  34. {spotifywebapiPython-1.0.46.dist-info → spotifywebapiPython-1.0.47.dist-info}/top_level.txt +0 -0
@@ -9,7 +9,7 @@
9
9
  </title>
10
10
  <link rel="icon" type="image/svg+xml" href="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20role%3D%22img%22%20aria-label%3D%22pdoc%20logo%22%20width%3D%22300%22%20height%3D%22150%22%20viewBox%3D%22-1%200%2060%2030%22%3E%3Ctitle%3Epdoc%3C/title%3E%3Cpath%20d%3D%22M29.621%2021.293c-.011-.273-.214-.475-.511-.481a.5.5%200%200%200-.489.503l-.044%201.393c-.097.551-.695%201.215-1.566%201.704-.577.428-1.306.486-2.193.182-1.426-.617-2.467-1.654-3.304-2.487l-.173-.172a3.43%203.43%200%200%200-.365-.306.49.49%200%200%200-.286-.196c-1.718-1.06-4.931-1.47-7.353.191l-.219.15c-1.707%201.187-3.413%202.131-4.328%201.03-.02-.027-.49-.685-.141-1.763.233-.721.546-2.408.772-4.076.042-.09.067-.187.046-.288.166-1.347.277-2.625.241-3.351%201.378-1.008%202.271-2.586%202.271-4.362%200-.976-.272-1.935-.788-2.774-.057-.094-.122-.18-.184-.268.033-.167.052-.339.052-.516%200-1.477-1.202-2.679-2.679-2.679-.791%200-1.496.352-1.987.9a6.3%206.3%200%200%200-1.001.029c-.492-.564-1.207-.929-2.012-.929-1.477%200-2.679%201.202-2.679%202.679A2.65%202.65%200%200%200%20.97%206.554c-.383.747-.595%201.572-.595%202.41%200%202.311%201.507%204.29%203.635%205.107-.037.699-.147%202.27-.423%203.294l-.137.461c-.622%202.042-2.515%208.257%201.727%2010.643%201.614.908%203.06%201.248%204.317%201.248%202.665%200%204.492-1.524%205.322-2.401%201.476-1.559%202.886-1.854%206.491.82%201.877%201.393%203.514%201.753%204.861%201.068%202.223-1.713%202.811-3.867%203.399-6.374.077-.846.056-1.469.054-1.537zm-4.835%204.313c-.054.305-.156.586-.242.629-.034-.007-.131-.022-.307-.157-.145-.111-.314-.478-.456-.908.221.121.432.25.675.355.115.039.219.051.33.081zm-2.251-1.238c-.05.33-.158.648-.252.694-.022.001-.125-.018-.307-.157-.217-.166-.488-.906-.639-1.573.358.344.754.693%201.198%201.036zm-3.887-2.337c-.006-.116-.018-.231-.041-.342.635.145%201.189.368%201.599.625.097.231.166.481.174.642-.03.049-.055.101-.067.158-.046.013-.128.026-.298.004-.278-.037-.901-.57-1.367-1.087zm-1.127-.497c.116.306.176.625.12.71-.019.014-.117.045-.345.016-.206-.027-.604-.332-.986-.695.41-.051.816-.056%201.211-.031zm-4.535%201.535c.209.22.379.47.358.598-.006.041-.088.138-.351.234-.144.055-.539-.063-.979-.259a11.66%2011.66%200%200%200%20.972-.573zm.983-.664c.359-.237.738-.418%201.126-.554.25.237.479.548.457.694-.006.042-.087.138-.351.235-.174.064-.694-.105-1.232-.375zm-3.381%201.794c-.022.145-.061.29-.149.401-.133.166-.358.248-.69.251h-.002c-.133%200-.306-.26-.45-.621.417.091.854.07%201.291-.031zm-2.066-8.077a4.78%204.78%200%200%201-.775-.584c.172-.115.505-.254.88-.378l-.105.962zm-.331%202.302a10.32%2010.32%200%200%201-.828-.502c.202-.143.576-.328.984-.49l-.156.992zm-.45%202.157l-.701-.403c.214-.115.536-.249.891-.376a11.57%2011.57%200%200%201-.19.779zm-.181%201.716c.064.398.194.702.298.893-.194-.051-.435-.162-.736-.398.061-.119.224-.3.438-.495zM8.87%204.141c0%20.152-.123.276-.276.276s-.275-.124-.275-.276.123-.276.276-.276.275.124.275.276zm-.735-.389a1.15%201.15%200%200%200-.314.783%201.16%201.16%200%200%200%201.162%201.162c.457%200%20.842-.27%201.032-.653.026.117.042.238.042.362a1.68%201.68%200%200%201-1.679%201.679%201.68%201.68%200%200%201-1.679-1.679c0-.843.626-1.535%201.436-1.654zM5.059%205.406A1.68%201.68%200%200%201%203.38%207.085a1.68%201.68%200%200%201-1.679-1.679c0-.037.009-.072.011-.109.21.3.541.508.935.508a1.16%201.16%200%200%200%201.162-1.162%201.14%201.14%200%200%200-.474-.912c.015%200%20.03-.005.045-.005.926.001%201.679.754%201.679%201.68zM3.198%204.141c0%20.152-.123.276-.276.276s-.275-.124-.275-.276.123-.276.276-.276.275.124.275.276zM1.375%208.964c0-.52.103-1.035.288-1.52.466.394%201.06.64%201.717.64%201.144%200%202.116-.725%202.499-1.738.383%201.012%201.355%201.738%202.499%201.738.867%200%201.631-.421%202.121-1.062.307.605.478%201.267.478%201.942%200%202.486-2.153%204.51-4.801%204.51s-4.801-2.023-4.801-4.51zm24.342%2019.349c-.985.498-2.267.168-3.813-.979-3.073-2.281-5.453-3.199-7.813-.705-1.315%201.391-4.163%203.365-8.423.97-3.174-1.786-2.239-6.266-1.261-9.479l.146-.492c.276-1.02.395-2.457.444-3.268a6.11%206.11%200%200%200%201.18.115%206.01%206.01%200%200%200%202.536-.562l-.006.175c-.802.215-1.848.612-2.021%201.25-.079.295.021.601.274.837.219.203.415.364.598.501-.667.304-1.243.698-1.311%201.179-.02.144-.022.507.393.787.213.144.395.26.564.365-1.285.521-1.361.96-1.381%201.126-.018.142-.011.496.427.746l.854.489c-.473.389-.971.914-.999%201.429-.018.278.095.532.316.713.675.556%201.231.721%201.653.721.059%200%20.104-.014.158-.02.207.707.641%201.64%201.513%201.64h.013c.8-.008%201.236-.345%201.462-.626.173-.216.268-.457.325-.692.424.195.93.374%201.372.374.151%200%20.294-.021.423-.068.732-.27.944-.704.993-1.021.009-.061.003-.119.002-.179.266.086.538.147.789.147.15%200%20.294-.021.423-.069.542-.2.797-.489.914-.754.237.147.478.258.704.288.106.014.205.021.296.021.356%200%20.595-.101.767-.229.438.435%201.094.992%201.656%201.067.106.014.205.021.296.021a1.56%201.56%200%200%200%20.323-.035c.17.575.453%201.289.866%201.605.358.273.665.362.914.362a.99.99%200%200%200%20.421-.093%201.03%201.03%200%200%200%20.245-.164c.168.428.39.846.68%201.068.358.273.665.362.913.362a.99.99%200%200%200%20.421-.093c.317-.148.512-.448.639-.762.251.157.495.257.726.257.127%200%20.25-.024.37-.071.427-.17.706-.617.841-1.314.022-.015.047-.022.068-.038.067-.051.133-.104.196-.159-.443%201.486-1.107%202.761-2.086%203.257zM8.66%209.925a.5.5%200%201%200-1%200c0%20.653-.818%201.205-1.787%201.205s-1.787-.552-1.787-1.205a.5.5%200%201%200-1%200c0%201.216%201.25%202.205%202.787%202.205s2.787-.989%202.787-2.205zm4.4%2015.965l-.208.097c-2.661%201.258-4.708%201.436-6.086.527-1.542-1.017-1.88-3.19-1.844-4.198a.4.4%200%200%200-.385-.414c-.242-.029-.406.164-.414.385-.046%201.249.367%203.686%202.202%204.896.708.467%201.547.7%202.51.7%201.248%200%202.706-.392%204.362-1.174l.185-.086a.4.4%200%200%200%20.205-.527c-.089-.204-.326-.291-.527-.206zM9.547%202.292c.093.077.205.114.317.114a.5.5%200%200%200%20.318-.886L8.817.397a.5.5%200%200%200-.703.068.5.5%200%200%200%20.069.703l1.364%201.124zm-7.661-.065c.086%200%20.173-.022.253-.068l1.523-.893a.5.5%200%200%200-.506-.863l-1.523.892a.5.5%200%200%200-.179.685c.094.158.261.247.432.247z%22%20transform%3D%22matrix%28-1%200%200%201%2058%200%29%22%20fill%3D%22%233bb300%22/%3E%3Cpath%20d%3D%22M.3%2021.86V10.18q0-.46.02-.68.04-.22.18-.5.28-.54%201.34-.54%201.06%200%201.42.28.38.26.44.78.76-1.04%202.38-1.04%201.64%200%203.1%201.54%201.46%201.54%201.46%203.58%200%202.04-1.46%203.58-1.44%201.54-3.08%201.54-1.64%200-2.38-.92v4.04q0%20.46-.04.68-.02.22-.18.5-.14.3-.5.42-.36.12-.98.12-.62%200-1-.12-.36-.12-.52-.4-.14-.28-.18-.5-.02-.22-.02-.68zm3.96-9.42q-.46.54-.46%201.18%200%20.64.46%201.18.48.52%201.2.52.74%200%201.24-.52.52-.52.52-1.18%200-.66-.48-1.18-.48-.54-1.26-.54-.76%200-1.22.54zm14.741-8.36q.16-.3.54-.42.38-.12%201-.12.64%200%201.02.12.38.12.52.42.16.3.18.54.04.22.04.68v11.94q0%20.46-.04.7-.02.22-.18.5-.3.54-1.7.54-1.38%200-1.54-.98-.84.96-2.34.96-1.8%200-3.28-1.56-1.48-1.58-1.48-3.66%200-2.1%201.48-3.68%201.5-1.58%203.28-1.58%201.48%200%202.3%201v-4.2q0-.46.02-.68.04-.24.18-.52zm-3.24%2010.86q.52.54%201.26.54.74%200%201.22-.54.5-.54.5-1.18%200-.66-.48-1.22-.46-.56-1.26-.56-.8%200-1.28.56-.48.54-.48%201.2%200%20.66.52%201.2zm7.833-1.2q0-2.4%201.68-3.96%201.68-1.56%203.84-1.56%202.16%200%203.82%201.56%201.66%201.54%201.66%203.94%200%201.66-.86%202.96-.86%201.28-2.1%201.9-1.22.6-2.54.6-1.32%200-2.56-.64-1.24-.66-2.1-1.92-.84-1.28-.84-2.88zm4.18%201.44q.64.48%201.3.48.66%200%201.32-.5.66-.5.66-1.48%200-.98-.62-1.46-.62-.48-1.34-.48-.72%200-1.34.5-.62.5-.62%201.48%200%20.96.64%201.46zm11.412-1.44q0%20.84.56%201.32.56.46%201.18.46.64%200%201.18-.36.56-.38.9-.38.6%200%201.46%201.06.46.58.46%201.04%200%20.76-1.1%201.42-1.14.8-2.8.8-1.86%200-3.58-1.34-.82-.64-1.34-1.7-.52-1.08-.52-2.36%200-1.3.52-2.34.52-1.06%201.34-1.7%201.66-1.32%203.54-1.32.76%200%201.48.22.72.2%201.06.4l.32.2q.36.24.56.38.52.4.52.92%200%20.5-.42%201.14-.72%201.1-1.38%201.1-.38%200-1.08-.44-.36-.34-1.04-.34-.66%200-1.24.48-.58.48-.58%201.34z%22%20fill%3D%22green%22/%3E%3C/svg%3E"/>
11
11
  <!-- build env - Package Name = "spotifywebapiPython" -->
12
- <!-- build env - Package Version = "1.0.46" -->
12
+ <!-- build env - Package Version = "1.0.47" -->
13
13
  <!-- pdoc module.modulename = "spotifywebapipython.spotifywebapiauthenticationerror" -->
14
14
  <!-- pdoc module.is_package = "False" -->
15
15
  <!-- pdoc root_module_name = "None" -->
@@ -74,7 +74,7 @@
74
74
 
75
75
  <footer class="footertext">
76
76
  spotifywebapiPython</br>
77
- Version 1.0.46</br>
77
+ Version 1.0.47</br>
78
78
  <a href="https://developer.spotify.com/documentation/web-api" target="_blank">
79
79
  <img src="../spotifywebapipython.ico" alt="brand icon" style="width:32px; height:32px; padding:4px;"/>
80
80
  A Spotify Web Api Client
@@ -9,7 +9,7 @@
9
9
  </title>
10
10
  <link rel="icon" type="image/svg+xml" href="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20role%3D%22img%22%20aria-label%3D%22pdoc%20logo%22%20width%3D%22300%22%20height%3D%22150%22%20viewBox%3D%22-1%200%2060%2030%22%3E%3Ctitle%3Epdoc%3C/title%3E%3Cpath%20d%3D%22M29.621%2021.293c-.011-.273-.214-.475-.511-.481a.5.5%200%200%200-.489.503l-.044%201.393c-.097.551-.695%201.215-1.566%201.704-.577.428-1.306.486-2.193.182-1.426-.617-2.467-1.654-3.304-2.487l-.173-.172a3.43%203.43%200%200%200-.365-.306.49.49%200%200%200-.286-.196c-1.718-1.06-4.931-1.47-7.353.191l-.219.15c-1.707%201.187-3.413%202.131-4.328%201.03-.02-.027-.49-.685-.141-1.763.233-.721.546-2.408.772-4.076.042-.09.067-.187.046-.288.166-1.347.277-2.625.241-3.351%201.378-1.008%202.271-2.586%202.271-4.362%200-.976-.272-1.935-.788-2.774-.057-.094-.122-.18-.184-.268.033-.167.052-.339.052-.516%200-1.477-1.202-2.679-2.679-2.679-.791%200-1.496.352-1.987.9a6.3%206.3%200%200%200-1.001.029c-.492-.564-1.207-.929-2.012-.929-1.477%200-2.679%201.202-2.679%202.679A2.65%202.65%200%200%200%20.97%206.554c-.383.747-.595%201.572-.595%202.41%200%202.311%201.507%204.29%203.635%205.107-.037.699-.147%202.27-.423%203.294l-.137.461c-.622%202.042-2.515%208.257%201.727%2010.643%201.614.908%203.06%201.248%204.317%201.248%202.665%200%204.492-1.524%205.322-2.401%201.476-1.559%202.886-1.854%206.491.82%201.877%201.393%203.514%201.753%204.861%201.068%202.223-1.713%202.811-3.867%203.399-6.374.077-.846.056-1.469.054-1.537zm-4.835%204.313c-.054.305-.156.586-.242.629-.034-.007-.131-.022-.307-.157-.145-.111-.314-.478-.456-.908.221.121.432.25.675.355.115.039.219.051.33.081zm-2.251-1.238c-.05.33-.158.648-.252.694-.022.001-.125-.018-.307-.157-.217-.166-.488-.906-.639-1.573.358.344.754.693%201.198%201.036zm-3.887-2.337c-.006-.116-.018-.231-.041-.342.635.145%201.189.368%201.599.625.097.231.166.481.174.642-.03.049-.055.101-.067.158-.046.013-.128.026-.298.004-.278-.037-.901-.57-1.367-1.087zm-1.127-.497c.116.306.176.625.12.71-.019.014-.117.045-.345.016-.206-.027-.604-.332-.986-.695.41-.051.816-.056%201.211-.031zm-4.535%201.535c.209.22.379.47.358.598-.006.041-.088.138-.351.234-.144.055-.539-.063-.979-.259a11.66%2011.66%200%200%200%20.972-.573zm.983-.664c.359-.237.738-.418%201.126-.554.25.237.479.548.457.694-.006.042-.087.138-.351.235-.174.064-.694-.105-1.232-.375zm-3.381%201.794c-.022.145-.061.29-.149.401-.133.166-.358.248-.69.251h-.002c-.133%200-.306-.26-.45-.621.417.091.854.07%201.291-.031zm-2.066-8.077a4.78%204.78%200%200%201-.775-.584c.172-.115.505-.254.88-.378l-.105.962zm-.331%202.302a10.32%2010.32%200%200%201-.828-.502c.202-.143.576-.328.984-.49l-.156.992zm-.45%202.157l-.701-.403c.214-.115.536-.249.891-.376a11.57%2011.57%200%200%201-.19.779zm-.181%201.716c.064.398.194.702.298.893-.194-.051-.435-.162-.736-.398.061-.119.224-.3.438-.495zM8.87%204.141c0%20.152-.123.276-.276.276s-.275-.124-.275-.276.123-.276.276-.276.275.124.275.276zm-.735-.389a1.15%201.15%200%200%200-.314.783%201.16%201.16%200%200%200%201.162%201.162c.457%200%20.842-.27%201.032-.653.026.117.042.238.042.362a1.68%201.68%200%200%201-1.679%201.679%201.68%201.68%200%200%201-1.679-1.679c0-.843.626-1.535%201.436-1.654zM5.059%205.406A1.68%201.68%200%200%201%203.38%207.085a1.68%201.68%200%200%201-1.679-1.679c0-.037.009-.072.011-.109.21.3.541.508.935.508a1.16%201.16%200%200%200%201.162-1.162%201.14%201.14%200%200%200-.474-.912c.015%200%20.03-.005.045-.005.926.001%201.679.754%201.679%201.68zM3.198%204.141c0%20.152-.123.276-.276.276s-.275-.124-.275-.276.123-.276.276-.276.275.124.275.276zM1.375%208.964c0-.52.103-1.035.288-1.52.466.394%201.06.64%201.717.64%201.144%200%202.116-.725%202.499-1.738.383%201.012%201.355%201.738%202.499%201.738.867%200%201.631-.421%202.121-1.062.307.605.478%201.267.478%201.942%200%202.486-2.153%204.51-4.801%204.51s-4.801-2.023-4.801-4.51zm24.342%2019.349c-.985.498-2.267.168-3.813-.979-3.073-2.281-5.453-3.199-7.813-.705-1.315%201.391-4.163%203.365-8.423.97-3.174-1.786-2.239-6.266-1.261-9.479l.146-.492c.276-1.02.395-2.457.444-3.268a6.11%206.11%200%200%200%201.18.115%206.01%206.01%200%200%200%202.536-.562l-.006.175c-.802.215-1.848.612-2.021%201.25-.079.295.021.601.274.837.219.203.415.364.598.501-.667.304-1.243.698-1.311%201.179-.02.144-.022.507.393.787.213.144.395.26.564.365-1.285.521-1.361.96-1.381%201.126-.018.142-.011.496.427.746l.854.489c-.473.389-.971.914-.999%201.429-.018.278.095.532.316.713.675.556%201.231.721%201.653.721.059%200%20.104-.014.158-.02.207.707.641%201.64%201.513%201.64h.013c.8-.008%201.236-.345%201.462-.626.173-.216.268-.457.325-.692.424.195.93.374%201.372.374.151%200%20.294-.021.423-.068.732-.27.944-.704.993-1.021.009-.061.003-.119.002-.179.266.086.538.147.789.147.15%200%20.294-.021.423-.069.542-.2.797-.489.914-.754.237.147.478.258.704.288.106.014.205.021.296.021.356%200%20.595-.101.767-.229.438.435%201.094.992%201.656%201.067.106.014.205.021.296.021a1.56%201.56%200%200%200%20.323-.035c.17.575.453%201.289.866%201.605.358.273.665.362.914.362a.99.99%200%200%200%20.421-.093%201.03%201.03%200%200%200%20.245-.164c.168.428.39.846.68%201.068.358.273.665.362.913.362a.99.99%200%200%200%20.421-.093c.317-.148.512-.448.639-.762.251.157.495.257.726.257.127%200%20.25-.024.37-.071.427-.17.706-.617.841-1.314.022-.015.047-.022.068-.038.067-.051.133-.104.196-.159-.443%201.486-1.107%202.761-2.086%203.257zM8.66%209.925a.5.5%200%201%200-1%200c0%20.653-.818%201.205-1.787%201.205s-1.787-.552-1.787-1.205a.5.5%200%201%200-1%200c0%201.216%201.25%202.205%202.787%202.205s2.787-.989%202.787-2.205zm4.4%2015.965l-.208.097c-2.661%201.258-4.708%201.436-6.086.527-1.542-1.017-1.88-3.19-1.844-4.198a.4.4%200%200%200-.385-.414c-.242-.029-.406.164-.414.385-.046%201.249.367%203.686%202.202%204.896.708.467%201.547.7%202.51.7%201.248%200%202.706-.392%204.362-1.174l.185-.086a.4.4%200%200%200%20.205-.527c-.089-.204-.326-.291-.527-.206zM9.547%202.292c.093.077.205.114.317.114a.5.5%200%200%200%20.318-.886L8.817.397a.5.5%200%200%200-.703.068.5.5%200%200%200%20.069.703l1.364%201.124zm-7.661-.065c.086%200%20.173-.022.253-.068l1.523-.893a.5.5%200%200%200-.506-.863l-1.523.892a.5.5%200%200%200-.179.685c.094.158.261.247.432.247z%22%20transform%3D%22matrix%28-1%200%200%201%2058%200%29%22%20fill%3D%22%233bb300%22/%3E%3Cpath%20d%3D%22M.3%2021.86V10.18q0-.46.02-.68.04-.22.18-.5.28-.54%201.34-.54%201.06%200%201.42.28.38.26.44.78.76-1.04%202.38-1.04%201.64%200%203.1%201.54%201.46%201.54%201.46%203.58%200%202.04-1.46%203.58-1.44%201.54-3.08%201.54-1.64%200-2.38-.92v4.04q0%20.46-.04.68-.02.22-.18.5-.14.3-.5.42-.36.12-.98.12-.62%200-1-.12-.36-.12-.52-.4-.14-.28-.18-.5-.02-.22-.02-.68zm3.96-9.42q-.46.54-.46%201.18%200%20.64.46%201.18.48.52%201.2.52.74%200%201.24-.52.52-.52.52-1.18%200-.66-.48-1.18-.48-.54-1.26-.54-.76%200-1.22.54zm14.741-8.36q.16-.3.54-.42.38-.12%201-.12.64%200%201.02.12.38.12.52.42.16.3.18.54.04.22.04.68v11.94q0%20.46-.04.7-.02.22-.18.5-.3.54-1.7.54-1.38%200-1.54-.98-.84.96-2.34.96-1.8%200-3.28-1.56-1.48-1.58-1.48-3.66%200-2.1%201.48-3.68%201.5-1.58%203.28-1.58%201.48%200%202.3%201v-4.2q0-.46.02-.68.04-.24.18-.52zm-3.24%2010.86q.52.54%201.26.54.74%200%201.22-.54.5-.54.5-1.18%200-.66-.48-1.22-.46-.56-1.26-.56-.8%200-1.28.56-.48.54-.48%201.2%200%20.66.52%201.2zm7.833-1.2q0-2.4%201.68-3.96%201.68-1.56%203.84-1.56%202.16%200%203.82%201.56%201.66%201.54%201.66%203.94%200%201.66-.86%202.96-.86%201.28-2.1%201.9-1.22.6-2.54.6-1.32%200-2.56-.64-1.24-.66-2.1-1.92-.84-1.28-.84-2.88zm4.18%201.44q.64.48%201.3.48.66%200%201.32-.5.66-.5.66-1.48%200-.98-.62-1.46-.62-.48-1.34-.48-.72%200-1.34.5-.62.5-.62%201.48%200%20.96.64%201.46zm11.412-1.44q0%20.84.56%201.32.56.46%201.18.46.64%200%201.18-.36.56-.38.9-.38.6%200%201.46%201.06.46.58.46%201.04%200%20.76-1.1%201.42-1.14.8-2.8.8-1.86%200-3.58-1.34-.82-.64-1.34-1.7-.52-1.08-.52-2.36%200-1.3.52-2.34.52-1.06%201.34-1.7%201.66-1.32%203.54-1.32.76%200%201.48.22.72.2%201.06.4l.32.2q.36.24.56.38.52.4.52.92%200%20.5-.42%201.14-.72%201.1-1.38%201.1-.38%200-1.08-.44-.36-.34-1.04-.34-.66%200-1.24.48-.58.48-.58%201.34z%22%20fill%3D%22green%22/%3E%3C/svg%3E"/>
11
11
  <!-- build env - Package Name = "spotifywebapiPython" -->
12
- <!-- build env - Package Version = "1.0.46" -->
12
+ <!-- build env - Package Version = "1.0.47" -->
13
13
  <!-- pdoc module.modulename = "spotifywebapipython.spotifywebapierror" -->
14
14
  <!-- pdoc module.is_package = "False" -->
15
15
  <!-- pdoc root_module_name = "None" -->
@@ -71,7 +71,7 @@
71
71
 
72
72
  <footer class="footertext">
73
73
  spotifywebapiPython</br>
74
- Version 1.0.46</br>
74
+ Version 1.0.47</br>
75
75
  <a href="https://developer.spotify.com/documentation/web-api" target="_blank">
76
76
  <img src="../spotifywebapipython.ico" alt="brand icon" style="width:32px; height:32px; padding:4px;"/>
77
77
  A Spotify Web Api Client
@@ -50,13 +50,8 @@ from .trackpagesaved import TrackPageSaved, TrackSaved
50
50
  from .trackpagesimplified import TrackPageSimplified
51
51
  from .trackrecommendations import TrackRecommendations
52
52
  from .userprofile import UserProfile, UserProfileSimplified
53
- from .zeroconfblobbuilder import ZeroconfBlobBuilder, ZeroconfCredentials
54
53
  from .zeroconfdiscoveryresult import ZeroconfDiscoveryResult
55
- from .zeroconfgetinfoalias import ZeroconfGetInfoAlias
56
- from .zeroconfgetinfodrmmediaformat import ZeroconfGetInfoDrmMediaFormat
57
- from .zeroconfgetinfo import ZeroconfGetInfo
58
54
  from .zeroconfproperty import ZeroconfProperty
59
- from .zeroconfresponse import ZeroconfResponse
60
55
 
61
56
  # all classes to import when "import *" is specified.
62
57
  __all__ = [
@@ -111,11 +106,6 @@ __all__ = [
111
106
  'TrackPageSimplified',
112
107
  'TrackRecommendations',
113
108
  'UserProfile','UserProfileSimplified',
114
- 'ZeroconfBlobBuilder', 'ZeroconfCredentials',
115
109
  'ZeroconfDiscoveryResult',
116
- 'ZeroconfGetInfo',
117
- 'ZeroconfGetInfoAlias',
118
- 'ZeroconfGetInfoDrmMediaFormat',
119
110
  'ZeroconfProperty',
120
- 'ZeroconfResponse',
121
111
  ]
@@ -38,4 +38,10 @@ class SAAppMessages:
38
38
  MSG_SPOTIFY_WEB_API_AUTH_ERROR:str = "SAM1002E - Spotify Web API returned an authorization error status while processing the \"{methodname}\" method.\nHTTP Status: {httpstatus} - {httpreason}\nError: {error}\nError Description: \"{errordescription}\""
39
39
  """
40
40
  SAM1002E - Spotify Web API returned an authorization error status while processing the \"{methodname}\" method.\nHTTP Status: {httpstatus} - {httpreason}\nError: {error}\nError Description: \"{errordescription}\"
41
- """
41
+ """
42
+
43
+ MSG_SPOTIFY_ZEROCONF_API_ERROR:str = "SAM1003E - Spotify ZeroConf API returned an error status while processing the \"{methodname}\" method.\nStatus: {status} - {httpreason}\nMessage: \"{message}\""
44
+ """
45
+ SAM1001E - Spotify ZeroConf API returned an error status while processing the \"{methodname}\" method.\nStatus: {status} - {httpreason}\nMessage: \"{message}\"
46
+ """
47
+
@@ -14,7 +14,6 @@ from lxml.etree import fromstring, Element
14
14
  from .oauthcli import AuthClient
15
15
  from .models import *
16
16
  from .models import UserProfile as UserProfileCurrentUser
17
- from .models.zeroconfblobbuilder import int_to_b64str
18
17
  from .sautils import export, GetUnixTimestampMSFromUtcNow, _xmlGetInnerText
19
18
  from .saappmessages import SAAppMessages
20
19
  from .spotifyapierror import SpotifyApiError
@@ -13819,251 +13818,3 @@ class SpotifyClient:
13819
13818
 
13820
13819
  # trace.
13821
13820
  _logsi.LeaveMethod(SILevel.Debug, apiMethodName)
13822
-
13823
-
13824
-
13825
- def ZeroconfGetInformation(self,
13826
- actionUrl:str,
13827
- ) -> ZeroconfGetInfo:
13828
- """
13829
- Retrieve Spotify Connect device information from the Spotify Zeroconf API `getInfo` endpoint.
13830
-
13831
- Args:
13832
- actionUrl (str):
13833
- The Zeroconf action url to issue the request to.
13834
- Example: `http://192.168.1.80:8200/zc?action=getInfo`
13835
-
13836
- Returns:
13837
- An `ZeroconfGetInfo` object that contains the response.
13838
-
13839
- Raises:
13840
- SpotifyWebApiError:
13841
- If the Spotify Web API request was for a non-authorization service
13842
- and the response contains error information.
13843
- SpotifApiError:
13844
- If the method fails for any other reason.
13845
-
13846
- <details>
13847
- <summary>Sample Code</summary>
13848
- ```python
13849
- .. include:: ../docs/include/samplecode/SpotifyClient/ZeroconfGetInformation.py
13850
- ```
13851
- </details>
13852
- """
13853
- apiMethodName:str = 'ZeroconfGetInformation'
13854
- apiMethodParms:SIMethodParmListContext = None
13855
- result:ZeroconfGetInfo = None
13856
-
13857
- try:
13858
-
13859
- # trace.
13860
- apiMethodParms = _logsi.EnterMethodParmList(SILevel.Debug, apiMethodName)
13861
- apiMethodParms.AppendKeyValue("actionUrl", actionUrl)
13862
- _logsi.LogMethodParmList(SILevel.Verbose, "Get Spotify Zeroconf getInfo response", apiMethodParms)
13863
-
13864
- # execute spotify zeroconf api request.
13865
- msg:SpotifyApiMessage = SpotifyApiMessage(apiMethodName, actionUrl)
13866
- self.MakeRequest('GET', msg)
13867
-
13868
- # process results.
13869
- result = ZeroconfGetInfo(root=msg.ResponseData)
13870
-
13871
- # trace.
13872
- _logsi.LogObject(SILevel.Verbose, TRACE_METHOD_RESULT_TYPE % (apiMethodName, type(result).__name__), result, excludeNonPublic=True)
13873
- return result
13874
-
13875
- except SpotifyWebApiError: raise # pass handled exceptions on thru
13876
- except SpotifyWebApiAuthenticationError: raise # pass handled exceptions on thru
13877
- except Exception as ex:
13878
-
13879
- # format unhandled exception.
13880
- raise SpotifyApiError(SAAppMessages.UNHANDLED_EXCEPTION.format(apiMethodName, str(ex)), ex, logsi=_logsi)
13881
-
13882
- finally:
13883
-
13884
- # trace.
13885
- _logsi.LeaveMethod(SILevel.Debug, apiMethodName)
13886
-
13887
-
13888
- def ZeroconfResetUsers(self,
13889
- actionUrl:str,
13890
- ) -> ZeroconfResponse:
13891
- """
13892
- Reset users for a Spotify Connect device by calling the Spotify Zeroconf API `resetUsers` endpoint.
13893
-
13894
- Args:
13895
- actionUrl (str):
13896
- The Zeroconf action url to issue the request to.
13897
- Example: `http://192.168.1.80:8200/zc?action=resetUsers`
13898
-
13899
- Returns:
13900
- An `ZeroconfResponse` object that contains the response.
13901
-
13902
- Raises:
13903
- SpotifyWebApiError:
13904
- If the Spotify Web API request was for a non-authorization service
13905
- and the response contains error information.
13906
- SpotifApiError:
13907
- If the method fails for any other reason.
13908
-
13909
- <details>
13910
- <summary>Sample Code</summary>
13911
- ```python
13912
- .. include:: ../docs/include/samplecode/SpotifyClient/ZeroconfResetUsers.py
13913
- ```
13914
- </details>
13915
- """
13916
- apiMethodName:str = 'ZeroconfResetUsers'
13917
- apiMethodParms:SIMethodParmListContext = None
13918
- result:ZeroconfResponse = None
13919
-
13920
- try:
13921
-
13922
- # trace.
13923
- apiMethodParms = _logsi.EnterMethodParmList(SILevel.Debug, apiMethodName)
13924
- apiMethodParms.AppendKeyValue("actionUrl", actionUrl)
13925
- _logsi.LogMethodParmList(SILevel.Verbose, "Get Spotify Zeroconf ResetUsers response", apiMethodParms)
13926
-
13927
- # execute spotify zeroconf api request.
13928
- msg:SpotifyApiMessage = SpotifyApiMessage(apiMethodName, actionUrl)
13929
- self.MakeRequest('GET', msg)
13930
-
13931
- # process results.
13932
- result = ZeroconfResponse(root=msg.ResponseData)
13933
-
13934
- # trace.
13935
- _logsi.LogObject(SILevel.Verbose, TRACE_METHOD_RESULT_TYPE % (apiMethodName, type(result).__name__), result, excludeNonPublic=True)
13936
- return result
13937
-
13938
- except SpotifyWebApiError: raise # pass handled exceptions on thru
13939
- except SpotifyWebApiAuthenticationError: raise # pass handled exceptions on thru
13940
- except Exception as ex:
13941
-
13942
- # format unhandled exception.
13943
- raise SpotifyApiError(SAAppMessages.UNHANDLED_EXCEPTION.format(apiMethodName, str(ex)), ex, logsi=_logsi)
13944
-
13945
- finally:
13946
-
13947
- # trace.
13948
- _logsi.LeaveMethod(SILevel.Debug, apiMethodName)
13949
-
13950
-
13951
- def ZeroconfAddUser(self,
13952
- actionUrl:str,
13953
- getInfoResponse:ZeroconfGetInfo,
13954
- username:str,
13955
- password:str,
13956
- ) -> ZeroconfResponse:
13957
- """
13958
- Add a user to a Spotify Connect device by calling the Spotify Zeroconf API `addUser` endpoint.
13959
-
13960
- Args:
13961
- actionUrl (str):
13962
- The Zeroconf action url to issue the request to.
13963
- Example: `http://192.168.1.80:8200/zc?action=addUser&version=1.0`
13964
-
13965
- Returns:
13966
- An `ZeroconfResponse` object that contains the response.
13967
-
13968
- Raises:
13969
- SpotifyWebApiError:
13970
- If the Spotify Web API request was for a non-authorization service
13971
- and the response contains error information.
13972
- SpotifApiError:
13973
- If the method fails for any other reason.
13974
-
13975
- <details>
13976
- <summary>Sample Code</summary>
13977
- ```python
13978
- .. include:: ../docs/include/samplecode/SpotifyClient/ZeroconfGetInformation.py
13979
- ```
13980
- </details>
13981
- """
13982
- apiMethodName:str = 'ZeroconfAddUser'
13983
- apiMethodParms:SIMethodParmListContext = None
13984
- result:ZeroconfResponse = None
13985
-
13986
- try:
13987
-
13988
- # trace.
13989
- apiMethodParms = _logsi.EnterMethodParmList(SILevel.Debug, apiMethodName)
13990
- apiMethodParms.AppendKeyValue("actionUrl", actionUrl)
13991
- apiMethodParms.AppendKeyValue("getInfoResponse", getInfoResponse)
13992
- apiMethodParms.AppendKeyValue("username", username)
13993
- apiMethodParms.AppendKeyValue("password", password)
13994
- _logsi.LogMethodParmList(SILevel.Verbose, "Get Spotify Zeroconf addUser response", apiMethodParms)
13995
-
13996
- raise NotImplemented()
13997
-
13998
- # build credentials object.
13999
- self.credentials = ZeroconfCredentials(username, password)
14000
-
14001
- # build authentication blob.
14002
- builder = ZeroconfBlobBuilder(self.credentials, getInfoResponse.DeviceId, getInfoResponse.PublicKey)
14003
- blob = builder.build()
14004
-
14005
- # # call zeroconf to add the user to the device.
14006
- # r = self._add_user(
14007
- # self.credentials.username.decode('ascii'),
14008
- # int_to_b64str(builder.dh_keys.public_key),
14009
- # blob)
14010
-
14011
- # def _add_user(self, username: str, client_key: str, blob: str): # -> bool
14012
- # respone = requests.post(
14013
- # self.uri,
14014
- # headers={
14015
- # 'Content-Type': 'application/x-www-form-urlencoded'
14016
- # },
14017
- # params={
14018
- # 'action': 'addUser',
14019
- # 'userName': username,
14020
- # 'clientKey': client_key,
14021
- # 'blob': blob
14022
- # }
14023
- # )
14024
- # return respone
14025
-
14026
- # build spotify zeroconf addUser parameters.
14027
- urlParms:dict = \
14028
- {
14029
- 'userName': self.credentials.username.decode('ascii'),
14030
- 'clientKey': int_to_b64str(builder.dh_keys.public_key),
14031
- 'blob': blob,
14032
- 'deviceId': getInfoResponse.DeviceId,
14033
- 'deviceName': getInfoResponse.RemoteName,
14034
- 'loginId': 'xxxxxxxxxxx',
14035
- }
14036
-
14037
- # let params = [
14038
- # 3 ("action", "addUser"),
14039
- # 3 ("userName", username),
14040
- # 3 ("blob", blob),
14041
- # 3 ("clientKey", my_public_key),
14042
- # ("deviceId", &device_id),
14043
- # ("deviceName", "spotify-connect"),
14044
- # ("loginId", &login_id),
14045
-
14046
-
14047
- # execute spotify zeroconf api request.
14048
- msg:SpotifyApiMessage = SpotifyApiMessage(apiMethodName, actionUrl)
14049
- msg.UrlParameters = urlParms
14050
- self.MakeRequest('POST', msg)
14051
-
14052
- # process results.
14053
- result = ZeroconfResponse(root=msg.ResponseData)
14054
-
14055
- # trace.
14056
- _logsi.LogObject(SILevel.Verbose, TRACE_METHOD_RESULT_TYPE % (apiMethodName, type(result).__name__), result, excludeNonPublic=True)
14057
- return result
14058
-
14059
- except SpotifyWebApiError: raise # pass handled exceptions on thru
14060
- except SpotifyWebApiAuthenticationError: raise # pass handled exceptions on thru
14061
- except Exception as ex:
14062
-
14063
- # format unhandled exception.
14064
- raise SpotifyApiError(SAAppMessages.UNHANDLED_EXCEPTION.format(apiMethodName, str(ex)), ex, logsi=_logsi)
14065
-
14066
- finally:
14067
-
14068
- # trace.
14069
- _logsi.LeaveMethod(SILevel.Debug, apiMethodName)
@@ -300,52 +300,6 @@ class SpotifyDiscovery:
300
300
  return self._DiscoveredDeviceNames
301
301
 
302
302
 
303
- def BroadcastService(self, serviceInfo:ServiceInfo, port:int=5353) -> None:
304
- """
305
- Generate a Zeroconf / mDNS broadcast to announce a service, and sends the broadcast out.
306
-
307
- Args:
308
- serviceInfo (ServiceInfo):
309
- Service information to broadcast.
310
- port (int):
311
- mDNS port number to send the broadcast on.
312
- Default is 5353.
313
- """
314
- try:
315
-
316
- # create the zeroconf service.
317
- zeroconf:Zeroconf = Zeroconf(ip_version=IPVersion.V4Only)
318
-
319
- # # TEST TODO - hardcoded serviceinfo properties for testing.
320
- # serviceType:str = '_spotify-connect._tcp.local.'
321
- # serviceName:str = 'Bose-ST10-95._spotify-connect._tcp.local.'
322
- # parsedAddresses:list[str] = ['192.168.1.82']
323
- # port:int = 8200
324
- # hostTTL:int = 120
325
- # priority:int = 0
326
- # otherTTL:int = 4500
327
- # server:str = 'Bose-SM2-987bf3244-95.local.'
328
- # weight:int = 0
329
- # properties:dict = {b'CPath': b'/zc', b'VERSION': b'1.0'}
330
-
331
- # # create the zeroconf serviceinfo object.
332
- # zcfServiceInfo:ServiceInfo = ServiceInfo(serviceType, serviceName, port, weight, priority, properties, server, hostTTL, otherTTL, parsed_addresses=parsedAddresses)
333
-
334
- # generate a broadcast packet to announce the service.
335
- _logsi.LogVerbose("Generating Zeroconf Service Broadcast for service: '%s'" % serviceInfo.name)
336
- dnsOutgoing = zeroconf.generate_service_broadcast(serviceInfo, serviceInfo.host_ttl, True)
337
-
338
- # send the broadcast packet.
339
- _logsi.LogVerbose("Sending Zeroconf Service Broadcast for service: '%s'" % serviceInfo.name)
340
- zeroconf.send(dnsOutgoing, addr=None, port=port)
341
-
342
- except Exception as ex:
343
-
344
- # this is not really an exception, but more of an indicator that
345
- # the timeout has been reached.
346
- _logsi.LogException("Zeroconf Broadcast Service exception: %s" % str(ex), ex, logToSystemLogger=False)
347
-
348
-
349
303
  def ToString(self, includeItems:bool=False) -> str:
350
304
  """
351
305
  Returns a displayable string representation of the class.
@@ -0,0 +1,21 @@
1
+ # import all classes from the namespace.
2
+ from .blobbuilder import BlobBuilder
3
+ from .credentials import Credentials
4
+ from .spotifyzeroconfapierror import SpotifyZeroconfApiError
5
+ from .zeroconfconnect import ZeroconfConnect
6
+ from .zeroconfresponse import ZeroconfResponse
7
+ from .zeroconfgetinfo import ZeroconfGetInfo
8
+ from .zeroconfgetinfoalias import ZeroconfGetInfoAlias
9
+ from .zeroconfgetinfodrmmediaformat import ZeroconfGetInfoDrmMediaFormat
10
+
11
+ # all classes to import when "import *" is specified.
12
+ __all__ = [
13
+ 'BlobBuilder',
14
+ 'Credentials',
15
+ 'SpotifyZeroconfApiError',
16
+ 'ZeroconfConnect',
17
+ 'ZeroconfGetInfo',
18
+ 'ZeroconfGetInfoAlias',
19
+ 'ZeroconfGetInfoDrmMediaFormat',
20
+ 'ZeroconfResponse',
21
+ ]
@@ -5,35 +5,29 @@ from Crypto.Util import Counter
5
5
  from Crypto.Protocol.KDF import PBKDF2
6
6
  from Crypto.Hash import SHA1
7
7
  from base64 import b64decode, b64encode
8
- import secrets
9
8
 
10
- #from .crypto import DiffieHellman
11
- #from .helpers import write_bytes, write_int, byte_list_to_int, Credentials, b64_to_int, int_to_bytes
9
+ from .credentials import Credentials
10
+ from .cryptodiffiehellman import CryptoDiffieHellman
11
+ from .helpers import write_bytes, write_int, byte_list_to_int, b64_to_int, int_to_bytes
12
12
 
13
- # copied from https://github.com/maraid/zerospot
14
13
 
15
- class ZeroconfCredentials:
16
- def __init__(self, username: str, password: str):
17
- self.username: bytes = bytes(username, 'ascii')
18
- self.password: bytes = bytes(password, 'ascii')
19
- self.auth_type: int = 0x00
20
-
21
-
22
- class ZeroconfBlobBuilder:
14
+ class BlobBuilder:
23
15
 
24
- def __init__(self, credentials: ZeroconfCredentials, device_id: str, remote_pubkey: str):
25
- self.credentials: ZeroconfCredentials = credentials
16
+ def __init__(self, credentials: Credentials, device_id: str, remote_pubkey: str):
17
+ self.credentials: Credentials = credentials
26
18
  self.device_id: bytes = bytes(device_id, 'ascii')
27
19
  self.remote_pubkey: str = remote_pubkey
28
- self.dh_keys = DiffieHellman()
20
+ self.dh_keys = CryptoDiffieHellman()
29
21
  self._blob = b''
30
22
  self._encrypted_blob = b''
31
23
 
24
+
32
25
  def build(self):
33
26
  self._build()
34
27
  self._encrypt()
35
28
  return self._encrypted_blob.decode("ascii")
36
29
 
30
+
37
31
  def _build(self): # -> bytes
38
32
  blob = bytearray()
39
33
  # 'I'
@@ -75,6 +69,7 @@ class ZeroconfBlobBuilder:
75
69
 
76
70
  self._blob = b64encode(encrypted_blob)
77
71
 
72
+
78
73
  def _encrypt(self):
79
74
  remote_device_key = b64_to_int(self.remote_pubkey)
80
75
  shared_key = self.dh_keys.shared_secret(remote_device_key)
@@ -98,47 +93,4 @@ class ZeroconfBlobBuilder:
98
93
 
99
94
  self._encrypted_blob = b64encode(encrypted_signed_blob)
100
95
 
101
-
102
- def write_int(i: int, out: bytearray):
103
- if i < 0x80:
104
- out.append(i)
105
- else:
106
- out.append(0x80 | (i & 0x7f))
107
- out.append((i >> 7))
108
-
109
-
110
- def write_bytes(b: bytes, out: bytearray):
111
- write_int(len(b), out)
112
- out.extend(b)
113
-
114
- def byte_list_to_int(byte_list):
115
- return int.from_bytes(bytes(byte_list), 'big')
116
-
117
- def int_to_bytes(i: int):
118
- return i.to_bytes((i.bit_length() + 7) // 8, byteorder='big')
119
-
120
- def int_to_b64str(i: int):
121
- return b64encode(int_to_bytes(i)).decode('ascii')
122
-
123
- def b64_to_int(b64: str):
124
- return int.from_bytes(b64decode(b64), 'big')
125
-
126
-
127
- class DiffieHellman:
128
- DH_GENERATOR = 2
129
- DH_PRIME = byte_list_to_int([
130
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc9, 0x0f, 0xda, 0xa2, 0x21, 0x68, 0xc2,
131
- 0x34, 0xc4, 0xc6, 0x62, 0x8b, 0x80, 0xdc, 0x1c, 0xd1, 0x29, 0x02, 0x4e, 0x08, 0x8a, 0x67,
132
- 0xcc, 0x74, 0x02, 0x0b, 0xbe, 0xa6, 0x3b, 0x13, 0x9b, 0x22, 0x51, 0x4a, 0x08, 0x79, 0x8e,
133
- 0x34, 0x04, 0xdd, 0xef, 0x95, 0x19, 0xb3, 0xcd, 0x3a, 0x43, 0x1b, 0x30, 0x2b, 0x0a, 0x6d,
134
- 0xf2, 0x5f, 0x14, 0x37, 0x4f, 0xe1, 0x35, 0x6d, 0x6d, 0x51, 0xc2, 0x45, 0xe4, 0x85, 0xb5,
135
- 0x76, 0x62, 0x5e, 0x7e, 0xc6, 0xf4, 0x4c, 0x42, 0xe9, 0xa6, 0x3a, 0x36, 0x20, 0xff, 0xff,
136
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff])
137
-
138
- def __init__(self):
139
- self._private_key = secrets.randbits(95 * 8)
140
- self.public_key = pow(DiffieHellman.DH_GENERATOR, self._private_key, DiffieHellman.DH_PRIME)
141
-
142
- def shared_secret(self, remote_key):
143
- return pow(remote_key, self._private_key, DiffieHellman.DH_PRIME)
144
96
 
@@ -0,0 +1,18 @@
1
+ class Credentials:
2
+ """
3
+ Credentials used by the Spotify SpConnectionLoginBlob method.
4
+ """
5
+
6
+ def __init__(self, username: str, password: str):
7
+ """
8
+ Initializes a new instance of the class.
9
+
10
+ Args:
11
+ username (str):
12
+ Spotify Connect user name to login with.
13
+ password (str):
14
+ Spotify Connect user password to login with.
15
+ """
16
+ self.username: bytes = bytes(username, 'ascii')
17
+ self.password: bytes = bytes(password, 'ascii')
18
+ self.auth_type: int = 0x00
@@ -0,0 +1,24 @@
1
+ import secrets
2
+
3
+ from .helpers import byte_list_to_int
4
+
5
+ class CryptoDiffieHellman:
6
+
7
+ DH_GENERATOR = 2
8
+ DH_PRIME = byte_list_to_int([
9
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc9, 0x0f, 0xda, 0xa2, 0x21, 0x68, 0xc2,
10
+ 0x34, 0xc4, 0xc6, 0x62, 0x8b, 0x80, 0xdc, 0x1c, 0xd1, 0x29, 0x02, 0x4e, 0x08, 0x8a, 0x67,
11
+ 0xcc, 0x74, 0x02, 0x0b, 0xbe, 0xa6, 0x3b, 0x13, 0x9b, 0x22, 0x51, 0x4a, 0x08, 0x79, 0x8e,
12
+ 0x34, 0x04, 0xdd, 0xef, 0x95, 0x19, 0xb3, 0xcd, 0x3a, 0x43, 0x1b, 0x30, 0x2b, 0x0a, 0x6d,
13
+ 0xf2, 0x5f, 0x14, 0x37, 0x4f, 0xe1, 0x35, 0x6d, 0x6d, 0x51, 0xc2, 0x45, 0xe4, 0x85, 0xb5,
14
+ 0x76, 0x62, 0x5e, 0x7e, 0xc6, 0xf4, 0x4c, 0x42, 0xe9, 0xa6, 0x3a, 0x36, 0x20, 0xff, 0xff,
15
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff])
16
+
17
+
18
+ def __init__(self):
19
+ self._private_key = secrets.randbits(95 * 8)
20
+ self.public_key = pow(CryptoDiffieHellman.DH_GENERATOR, self._private_key, CryptoDiffieHellman.DH_PRIME)
21
+
22
+
23
+ def shared_secret(self, remote_key):
24
+ return pow(remote_key, self._private_key, CryptoDiffieHellman.DH_PRIME)
@@ -0,0 +1,30 @@
1
+ from base64 import b64decode, b64encode
2
+
3
+
4
+ def write_int(i: int, out: bytearray):
5
+ if i < 0x80:
6
+ out.append(i)
7
+ else:
8
+ out.append(0x80 | (i & 0x7f))
9
+ out.append((i >> 7))
10
+
11
+
12
+ def write_bytes(b: bytes, out: bytearray):
13
+ write_int(len(b), out)
14
+ out.extend(b)
15
+
16
+
17
+ def byte_list_to_int(byte_list):
18
+ return int.from_bytes(bytes(byte_list), 'big')
19
+
20
+
21
+ def int_to_bytes(i: int):
22
+ return i.to_bytes((i.bit_length() + 7) // 8, byteorder='big')
23
+
24
+
25
+ def int_to_b64str(i: int):
26
+ return b64encode(int_to_bytes(i)).decode('ascii')
27
+
28
+
29
+ def b64_to_int(b64: str):
30
+ return int.from_bytes(b64decode(b64), 'big')