spotify-monitor 2.3__py3-none-any.whl → 2.4__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 spotify-monitor might be problematic. Click here for more details.
- {spotify_monitor-2.3.dist-info → spotify_monitor-2.4.dist-info}/METADATA +85 -7
- spotify_monitor-2.4.dist-info/RECORD +7 -0
- spotify_monitor.py +127 -40
- spotify_monitor-2.3.dist-info/RECORD +0 -7
- {spotify_monitor-2.3.dist-info → spotify_monitor-2.4.dist-info}/WHEEL +0 -0
- {spotify_monitor-2.3.dist-info → spotify_monitor-2.4.dist-info}/entry_points.txt +0 -0
- {spotify_monitor-2.3.dist-info → spotify_monitor-2.4.dist-info}/licenses/LICENSE +0 -0
- {spotify_monitor-2.3.dist-info → spotify_monitor-2.4.dist-info}/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: spotify_monitor
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.4
|
|
4
4
|
Summary: Tool implementing real-time tracking of Spotify friends music activity
|
|
5
5
|
Author-email: Michal Szymanski <misiektoja-pypi@rm-rf.ninja>
|
|
6
6
|
License-Expression: GPL-3.0-or-later
|
|
@@ -21,13 +21,16 @@ Requires-Dist: python-dateutil>=2.8
|
|
|
21
21
|
Requires-Dist: urllib3>=2.0.7
|
|
22
22
|
Requires-Dist: pyotp>=2.9.0
|
|
23
23
|
Requires-Dist: python-dotenv>=0.19
|
|
24
|
+
Requires-Dist: wcwidth>=0.2.7
|
|
24
25
|
Dynamic: license-file
|
|
25
26
|
|
|
26
27
|
# spotify_monitor
|
|
27
28
|
|
|
28
|
-
Tool for real-time monitoring of Spotify friends' music activity feed
|
|
29
|
+
Tool for real-time monitoring of **Spotify friends' music activity feed**.
|
|
29
30
|
|
|
30
|
-
|
|
31
|
+
✨ If you're interested in tracking changes to Spotify users' profiles including their playlists, take a look at another tool I've developed: [spotify_profile_monitor](https://github.com/misiektoja/spotify_profile_monitor).
|
|
32
|
+
|
|
33
|
+
🛠️ If you're looking for debug tools to get Spotify Web Player access tokens and extract secret keys: [click here](#debugging-tools)
|
|
31
34
|
|
|
32
35
|
<a id="features"></a>
|
|
33
36
|
## Features
|
|
@@ -73,14 +76,17 @@ NOTE: If you're interested in tracking changes to Spotify users' profiles includ
|
|
|
73
76
|
* [Check Intervals](#check-intervals)
|
|
74
77
|
* [Signal Controls (macOS/Linux/Unix)](#signal-controls-macoslinuxunix)
|
|
75
78
|
* [Coloring Log Output with GRC](#coloring-log-output-with-grc)
|
|
76
|
-
6. [
|
|
77
|
-
|
|
79
|
+
6. [Debugging Tools](#debugging-tools)
|
|
80
|
+
* [Access Token Retrieval via sp_dc Cookie and TOTP](#access-token-retrieval-via-sp_dc-cookie-and-totp)
|
|
81
|
+
* [Secret Key Extraction from Spotify Web Player Bundles](#secret-key-extraction-from-spotify-web-player-bundles)
|
|
82
|
+
7. [Change Log](#change-log)
|
|
83
|
+
8. [License](#license)
|
|
78
84
|
|
|
79
85
|
<a id="requirements"></a>
|
|
80
86
|
## Requirements
|
|
81
87
|
|
|
82
88
|
* Python 3.6 or higher
|
|
83
|
-
* Libraries: `requests`, `python-dateutil`, `urllib3`, `pyotp`, `python-dotenv`
|
|
89
|
+
* Libraries: `requests`, `python-dateutil`, `urllib3`, `pyotp`, `python-dotenv`, `wcwidth`
|
|
84
90
|
|
|
85
91
|
Tested on:
|
|
86
92
|
|
|
@@ -108,7 +114,7 @@ Download the *[spotify_monitor.py](https://raw.githubusercontent.com/misiektoja/
|
|
|
108
114
|
Install dependencies via pip:
|
|
109
115
|
|
|
110
116
|
```sh
|
|
111
|
-
pip install requests python-dateutil urllib3 pyotp python-dotenv
|
|
117
|
+
pip install requests python-dateutil urllib3 pyotp python-dotenv wcwidth
|
|
112
118
|
```
|
|
113
119
|
|
|
114
120
|
Alternatively, from the downloaded *[requirements.txt](https://raw.githubusercontent.com/misiektoja/spotify_monitor/refs/heads/main/requirements.txt)*:
|
|
@@ -195,6 +201,8 @@ If your `sp_dc` cookie expires, the tool will notify you via the console and ema
|
|
|
195
201
|
|
|
196
202
|
If you store the `SP_DC_COOKIE` in a dotenv file you can update its value and send a `SIGHUP` signal to reload the file with the new `sp_dc` cookie without restarting the tool. More info in [Storing Secrets](#storing-secrets) and [Signal Controls (macOS/Linux/Unix)](#signal-controls-macoslinuxunix).
|
|
197
203
|
|
|
204
|
+
> **NOTE:** secrets used for TOTP generation (`SECRET_CIPHER_DICT`) expire every two days, that's why since v2.4 the tool fetches it from remote URL (see `SECRET_CIPHER_DICT_URL`); you can also run the [spotify_monitor_secret_grabber](https://github.com/misiektoja/spotify_monitor/blob/dev/debug/spotify_monitor_secret_grabber.py) and extract it by yourself (see [Secret Key Extraction from Spotify Web Player Bundles](#secret-key-extraction-from-spotify-web-player-bundles) for more info).
|
|
205
|
+
|
|
198
206
|
<a id="spotify-desktop-client"></a>
|
|
199
207
|
#### Spotify Desktop Client
|
|
200
208
|
|
|
@@ -563,6 +571,76 @@ Example:
|
|
|
563
571
|
grc tail -F -n 100 spotify_monitor_<user_uri_id/file_suffix>.log
|
|
564
572
|
```
|
|
565
573
|
|
|
574
|
+
<a id="debugging-tools"></a>
|
|
575
|
+
## Debugging Tools
|
|
576
|
+
|
|
577
|
+
To help with troubleshooting and development, two debug utilities are available in the [debug](https://github.com/misiektoja/spotify_monitor/tree/dev/debug) directory.
|
|
578
|
+
|
|
579
|
+
<a id="access-token-retrieval-via-sp_dc-cookie-and-totp"></a>
|
|
580
|
+
### Access Token Retrieval via sp_dc Cookie and TOTP
|
|
581
|
+
|
|
582
|
+
The [spotify_monitor_totp_test](https://github.com/misiektoja/spotify_monitor/blob/dev/debug/spotify_monitor_totp_test.py) tool retrieves a Spotify access token using a Web Player `sp_dc` cookie and TOTP parameters.
|
|
583
|
+
|
|
584
|
+
Download from [here](https://github.com/misiektoja/spotify_monitor/blob/dev/debug/spotify_monitor_totp_test.py) or:
|
|
585
|
+
|
|
586
|
+
```sh
|
|
587
|
+
wget https://raw.githubusercontent.com/misiektoja/spotify_monitor/refs/heads/dev/debug/spotify_monitor_totp_test.py
|
|
588
|
+
```
|
|
589
|
+
|
|
590
|
+
Install requirements:
|
|
591
|
+
|
|
592
|
+
```sh
|
|
593
|
+
pip install requests python-dateutil pyotp
|
|
594
|
+
```
|
|
595
|
+
|
|
596
|
+
Run:
|
|
597
|
+
|
|
598
|
+
```sh
|
|
599
|
+
python3 spotify_monitor_totp_test.py --sp-dc "your_sp_dc_cookie_value"
|
|
600
|
+
```
|
|
601
|
+
|
|
602
|
+
You should get a valid Spotify access token, example output:
|
|
603
|
+
|
|
604
|
+
<p align="center">
|
|
605
|
+
<img src="https://raw.githubusercontent.com/misiektoja/spotify_monitor/refs/heads/main/assets/spotify_monitor_totp_test.png" alt="spotify_monitor_totp_test" width="100%"/>
|
|
606
|
+
</p>
|
|
607
|
+
|
|
608
|
+
> **NOTE:** secrets used for TOTP generation (`SECRET_CIPHER_DICT`) expire every two days; you can either run the [spotify_monitor_secret_grabber](https://github.com/misiektoja/spotify_monitor/blob/dev/debug/spotify_monitor_secret_grabber.py) and extract it by yourself (see [here](#secret-key-extraction-from-spotify-web-player-bundles) for more info) or you can pass `--fetch-secrets` flag in [spotify_monitor_totp_test](https://github.com/misiektoja/spotify_monitor/blob/dev/debug/spotify_monitor_totp_test.py) (available since v1.6). There is also a [Thereallo1026/spotify-secrets](https://github.com/Thereallo1026/spotify-secrets) repo which offers JSON files that are automatically updated with current secrets.
|
|
609
|
+
|
|
610
|
+
<a id="secret-key-extraction-from-spotify-web-player-bundles"></a>
|
|
611
|
+
### Secret Key Extraction from Spotify Web Player Bundles
|
|
612
|
+
|
|
613
|
+
The [spotify_monitor_secret_grabber](https://github.com/misiektoja/spotify_monitor/blob/dev/debug/spotify_monitor_secret_grabber.py) tool automatically extracts secret keys used for TOTP generation in Spotify Web Player JavaScript bundles.
|
|
614
|
+
|
|
615
|
+
Download from [here](https://github.com/misiektoja/spotify_monitor/blob/dev/debug/spotify_monitor_secret_grabber.py) or:
|
|
616
|
+
|
|
617
|
+
```sh
|
|
618
|
+
wget https://raw.githubusercontent.com/misiektoja/spotify_monitor/refs/heads/dev/debug/spotify_monitor_secret_grabber.py
|
|
619
|
+
```
|
|
620
|
+
|
|
621
|
+
Install requirements:
|
|
622
|
+
|
|
623
|
+
```sh
|
|
624
|
+
pip install playwright
|
|
625
|
+
playwright install
|
|
626
|
+
```
|
|
627
|
+
|
|
628
|
+
Run:
|
|
629
|
+
|
|
630
|
+
```sh
|
|
631
|
+
python3 spotify_monitor_secret_grabber.py
|
|
632
|
+
```
|
|
633
|
+
|
|
634
|
+
You should get output similar to below:
|
|
635
|
+
|
|
636
|
+
<p align="center">
|
|
637
|
+
<img src="https://raw.githubusercontent.com/misiektoja/spotify_monitor/refs/heads/main/assets/spotify_monitor_secret_grabber.png" alt="spotify_monitor_secret_grabber" width="100%"/>
|
|
638
|
+
</p>
|
|
639
|
+
|
|
640
|
+
You can now update the secrets used for TOTP generation (for example `SECRET_CIPHER_DICT` in `spotify_monitor_totp_test`, `spotify_monitor` and `spotify_profile_monitor`).
|
|
641
|
+
|
|
642
|
+
> **NOTE:** you can also use [Thereallo1026/spotify-secrets](https://github.com/Thereallo1026/spotify-secrets) repo which offers JSON files that are automatically updated with current secrets (its secret extraction code is based on `spotify_monitor_secret_grabber`).
|
|
643
|
+
|
|
566
644
|
<a id="change-log"></a>
|
|
567
645
|
## Change Log
|
|
568
646
|
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
spotify_monitor.py,sha256=TtB0dWvl5Yn1ti4y8VFk61V8rqXEZfnLY2PJZ26hVsw,161638
|
|
2
|
+
spotify_monitor-2.4.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
3
|
+
spotify_monitor-2.4.dist-info/METADATA,sha256=rcnYf1XgMu4k55OO0m1yfP61TXRA_CkZLLDXUzDLHLM,27747
|
|
4
|
+
spotify_monitor-2.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
5
|
+
spotify_monitor-2.4.dist-info/entry_points.txt,sha256=8HzePfUcCSXrYaXOwLbNNYO8GJcnhgCSl4wcDNECht8,57
|
|
6
|
+
spotify_monitor-2.4.dist-info/top_level.txt,sha256=EP6IPD4vHT12rLM5b_jo2i3nrfOuwk3ehhr2gWdQx9Y,16
|
|
7
|
+
spotify_monitor-2.4.dist-info/RECORD,,
|
spotify_monitor.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
"""
|
|
3
3
|
Author: Michal Szymanski <misiektoja-github@rm-rf.ninja>
|
|
4
|
-
v2.
|
|
4
|
+
v2.4
|
|
5
5
|
|
|
6
6
|
Tool implementing real-time tracking of Spotify friends music activity:
|
|
7
7
|
https://github.com/misiektoja/spotify_monitor/
|
|
@@ -13,9 +13,10 @@ python-dateutil
|
|
|
13
13
|
urllib3
|
|
14
14
|
pyotp (optional, needed when the token source is set to cookie)
|
|
15
15
|
python-dotenv (optional)
|
|
16
|
+
wcwidth (optional, needed by TRUNCATE_CHARS feature)
|
|
16
17
|
"""
|
|
17
18
|
|
|
18
|
-
VERSION = "2.
|
|
19
|
+
VERSION = "2.4"
|
|
19
20
|
|
|
20
21
|
# ---------------------------
|
|
21
22
|
# CONFIGURATION SECTION START
|
|
@@ -238,14 +239,38 @@ TRUNCATE_CHARS = 0
|
|
|
238
239
|
# Value added/subtracted via signal handlers to adjust inactivity timeout (SPOTIFY_INACTIVITY_CHECK); in seconds
|
|
239
240
|
SPOTIFY_INACTIVITY_CHECK_SIGNAL_VALUE = 30 # 30 seconds
|
|
240
241
|
|
|
242
|
+
# ---------------------------------------------------------------------
|
|
243
|
+
|
|
244
|
+
# The section below is used when the token source is set to 'cookie'
|
|
245
|
+
|
|
241
246
|
# Maximum number of attempts to get a valid access token in a single run of the spotify_get_access_token_from_sp_dc() function
|
|
242
|
-
|
|
243
|
-
TOKEN_MAX_RETRIES = 10
|
|
247
|
+
TOKEN_MAX_RETRIES = 3
|
|
244
248
|
|
|
245
249
|
# Interval between access token retry attempts; in seconds
|
|
246
|
-
# Used only when the token source is set to 'cookie'
|
|
247
250
|
TOKEN_RETRY_TIMEOUT = 0.5 # 0.5 second
|
|
248
251
|
|
|
252
|
+
# Mapping of TOTP version identifiers to the secrets needed for TOTP generation
|
|
253
|
+
# Newest secrets are downloaded automatically from SECRET_CIPHER_DICT_URL (see below)
|
|
254
|
+
# Can also be fetched via spotify_monitor_secret_grabber.py utility - see debug dir
|
|
255
|
+
SECRET_CIPHER_DICT = {
|
|
256
|
+
"12": [107, 81, 49, 57, 67, 93, 87, 81, 69, 67, 40, 93, 48, 50, 46, 91, 94, 113, 41, 108, 77, 107, 34],
|
|
257
|
+
"11": [111, 45, 40, 73, 95, 74, 35, 85, 105, 107, 60, 110, 55, 72, 69, 70, 114, 83, 63, 88, 91],
|
|
258
|
+
"10": [61, 110, 58, 98, 35, 79, 117, 69, 102, 72, 92, 102, 69, 93, 41, 101, 42, 75],
|
|
259
|
+
"9": [109, 101, 90, 99, 66, 92, 116, 108, 85, 70, 86, 49, 68, 54, 87, 50, 72, 121, 52, 64, 57, 43, 36, 81, 97, 72, 53, 41, 78, 56],
|
|
260
|
+
"8": [37, 84, 32, 76, 87, 90, 87, 47, 13, 75, 48, 54, 44, 28, 19, 21, 22],
|
|
261
|
+
"7": [59, 91, 66, 74, 30, 66, 74, 38, 46, 50, 72, 61, 44, 71, 86, 39, 89],
|
|
262
|
+
"6": [21, 24, 85, 46, 48, 35, 33, 8, 11, 63, 76, 12, 55, 77, 14, 7, 54],
|
|
263
|
+
"5": [12, 56, 76, 33, 88, 44, 88, 33, 78, 78, 11, 66, 22, 22, 55, 69, 54],
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
# Remote URL used to fetch updated secrets needed for TOTP generation
|
|
267
|
+
# Set to empty string to disable
|
|
268
|
+
SECRET_CIPHER_DICT_URL = "https://github.com/Thereallo1026/spotify-secrets/blob/main/secrets/secretDict.json?raw=true"
|
|
269
|
+
|
|
270
|
+
# Identifier used to select the appropriate secret from SECRET_CIPHER_DICT when generating a TOTP token
|
|
271
|
+
# Set to 0 to auto-select the highest available version
|
|
272
|
+
TOTP_VER = 0
|
|
273
|
+
|
|
249
274
|
# ---------------------------------------------------------------------
|
|
250
275
|
|
|
251
276
|
# The section below is used when the token source is set to 'client'
|
|
@@ -446,6 +471,9 @@ CLEAR_SCREEN = False
|
|
|
446
471
|
SPOTIFY_INACTIVITY_CHECK_SIGNAL_VALUE = 0
|
|
447
472
|
TOKEN_MAX_RETRIES = 0
|
|
448
473
|
TOKEN_RETRY_TIMEOUT = 0.0
|
|
474
|
+
SECRET_CIPHER_DICT = {}
|
|
475
|
+
SECRET_CIPHER_DICT_URL = ""
|
|
476
|
+
TOTP_VER = 0
|
|
449
477
|
FLAG_FILE = ""
|
|
450
478
|
TRUNCATE_CHARS = 0
|
|
451
479
|
|
|
@@ -480,9 +508,6 @@ TOKEN_URL = "https://open.spotify.com/api/token"
|
|
|
480
508
|
# URL of the endpoint to get server time needed to create TOTP object
|
|
481
509
|
SERVER_TIME_URL = "https://open.spotify.com/"
|
|
482
510
|
|
|
483
|
-
# Identifier used to select the appropriate encrypted secret from secret_cipher_dict when generating a TOTP token
|
|
484
|
-
TOTP_VER = 10
|
|
485
|
-
|
|
486
511
|
# Variables for caching functionality of the Spotify client token to avoid unnecessary refreshing
|
|
487
512
|
SP_CACHED_CLIENT_TOKEN = None
|
|
488
513
|
SP_CLIENT_TOKEN_EXPIRES_AT = 0
|
|
@@ -561,14 +586,30 @@ SESSION.mount("http://", adapter)
|
|
|
561
586
|
|
|
562
587
|
|
|
563
588
|
# Truncates each line of a string to a specified number of characters including tab expansion and multi-line support
|
|
564
|
-
def truncate_string_per_line(message,
|
|
589
|
+
def truncate_string_per_line(message, truncate_width, tabsize=8):
|
|
590
|
+
try:
|
|
591
|
+
from wcwidth import wcwidth
|
|
592
|
+
except ImportError:
|
|
593
|
+
return message
|
|
594
|
+
|
|
565
595
|
lines = message.split('\n')
|
|
566
596
|
truncated_lines = []
|
|
567
597
|
|
|
568
598
|
for line in lines:
|
|
569
|
-
expanded_line = line.expandtabs(tabsize
|
|
570
|
-
|
|
571
|
-
|
|
599
|
+
expanded_line = line.expandtabs(tabsize)
|
|
600
|
+
current_width = 0
|
|
601
|
+
truncated = ''
|
|
602
|
+
|
|
603
|
+
for char in expanded_line:
|
|
604
|
+
char_width = wcwidth(char)
|
|
605
|
+
if char_width < 0:
|
|
606
|
+
char_width = 0 # Non-printable or unknown width
|
|
607
|
+
if current_width + char_width > truncate_width:
|
|
608
|
+
break
|
|
609
|
+
truncated += char
|
|
610
|
+
current_width += char_width
|
|
611
|
+
|
|
612
|
+
truncated_lines.append(truncated)
|
|
572
613
|
|
|
573
614
|
return '\n'.join(truncated_lines)
|
|
574
615
|
|
|
@@ -1241,15 +1282,10 @@ def fetch_server_time(session: req.Session, ua: str) -> int:
|
|
|
1241
1282
|
def generate_totp():
|
|
1242
1283
|
import pyotp
|
|
1243
1284
|
|
|
1244
|
-
|
|
1245
|
-
"
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
"7": [59, 91, 66, 74, 30, 66, 74, 38, 46, 50, 72, 61, 44, 71, 86, 39, 89],
|
|
1249
|
-
"6": [21, 24, 85, 46, 48, 35, 33, 8, 11, 63, 76, 12, 55, 77, 14, 7, 54],
|
|
1250
|
-
"5": [12, 56, 76, 33, 88, 44, 88, 33, 78, 78, 11, 66, 22, 22, 55, 69, 54],
|
|
1251
|
-
}
|
|
1252
|
-
secret_cipher_bytes = secret_cipher_dict[str(TOTP_VER)]
|
|
1285
|
+
if str((ver := TOTP_VER or max(map(int, SECRET_CIPHER_DICT)))) not in SECRET_CIPHER_DICT:
|
|
1286
|
+
raise Exception(f"generate_totp(): Defined TOTP_VER ({ver}) is missing in SECRET_CIPHER_DICT")
|
|
1287
|
+
|
|
1288
|
+
secret_cipher_bytes = SECRET_CIPHER_DICT[str(ver)]
|
|
1253
1289
|
|
|
1254
1290
|
transformed = [e ^ ((t % 33) + 9) for t, e in enumerate(secret_cipher_bytes)]
|
|
1255
1291
|
joined = "".join(str(num) for num in transformed)
|
|
@@ -1259,6 +1295,34 @@ def generate_totp():
|
|
|
1259
1295
|
return pyotp.TOTP(secret, digits=6, interval=30)
|
|
1260
1296
|
|
|
1261
1297
|
|
|
1298
|
+
def fetch_and_update_secrets():
|
|
1299
|
+
global SECRET_CIPHER_DICT
|
|
1300
|
+
|
|
1301
|
+
if not SECRET_CIPHER_DICT_URL:
|
|
1302
|
+
return False
|
|
1303
|
+
|
|
1304
|
+
try:
|
|
1305
|
+
response = req.get(SECRET_CIPHER_DICT_URL, timeout=FUNCTION_TIMEOUT, verify=VERIFY_SSL)
|
|
1306
|
+
response.raise_for_status()
|
|
1307
|
+
secrets = response.json()
|
|
1308
|
+
|
|
1309
|
+
if not isinstance(secrets, dict) or not secrets:
|
|
1310
|
+
raise ValueError("fetch_and_update_secrets(): Fetched payload not a non‑empty dict")
|
|
1311
|
+
|
|
1312
|
+
for key, value in secrets.items():
|
|
1313
|
+
if not isinstance(key, str) or not key.isdigit():
|
|
1314
|
+
raise ValueError(f"fetch_and_update_secrets(): Invalid key format: {key}")
|
|
1315
|
+
if not isinstance(value, list) or not all(isinstance(x, int) for x in value):
|
|
1316
|
+
raise ValueError(f"fetch_and_update_secrets(): Invalid value format for key {key}")
|
|
1317
|
+
|
|
1318
|
+
SECRET_CIPHER_DICT = secrets
|
|
1319
|
+
return True
|
|
1320
|
+
|
|
1321
|
+
except Exception as e:
|
|
1322
|
+
print(f"fetch_and_update_secrets(): Failed to get new secrets: {e}")
|
|
1323
|
+
return False
|
|
1324
|
+
|
|
1325
|
+
|
|
1262
1326
|
# Refreshes the Spotify access token using the sp_dc cookie, tries first with mode "transport" and if needed with "init"
|
|
1263
1327
|
def refresh_access_token_from_sp_dc(sp_dc: str) -> dict:
|
|
1264
1328
|
transport = True
|
|
@@ -1358,29 +1422,52 @@ def spotify_get_access_token_from_sp_dc(sp_dc: str):
|
|
|
1358
1422
|
max_retries = TOKEN_MAX_RETRIES
|
|
1359
1423
|
retry = 0
|
|
1360
1424
|
|
|
1361
|
-
|
|
1362
|
-
token_data = refresh_access_token_from_sp_dc(sp_dc)
|
|
1363
|
-
token = token_data["access_token"]
|
|
1364
|
-
client_id = token_data.get("client_id", "")
|
|
1365
|
-
length = token_data["length"]
|
|
1425
|
+
last_error = ""
|
|
1366
1426
|
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1427
|
+
while retry < max_retries:
|
|
1428
|
+
try:
|
|
1429
|
+
token_data = refresh_access_token_from_sp_dc(sp_dc)
|
|
1430
|
+
token = token_data["access_token"]
|
|
1431
|
+
client_id = token_data.get("client_id", "")
|
|
1432
|
+
length = token_data["length"]
|
|
1433
|
+
|
|
1434
|
+
SP_CACHED_ACCESS_TOKEN = token
|
|
1435
|
+
SP_ACCESS_TOKEN_EXPIRES_AT = token_data["expires_at"]
|
|
1436
|
+
SP_CACHED_CLIENT_ID = client_id
|
|
1437
|
+
|
|
1438
|
+
if SP_CACHED_ACCESS_TOKEN is None or not check_token_validity(SP_CACHED_ACCESS_TOKEN, SP_CACHED_CLIENT_ID, USER_AGENT):
|
|
1439
|
+
retry += 1
|
|
1440
|
+
time.sleep(TOKEN_RETRY_TIMEOUT)
|
|
1441
|
+
else:
|
|
1442
|
+
break
|
|
1443
|
+
except Exception as e:
|
|
1444
|
+
last_error = str(e)
|
|
1372
1445
|
retry += 1
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
break
|
|
1446
|
+
if retry < max_retries:
|
|
1447
|
+
time.sleep(TOKEN_RETRY_TIMEOUT)
|
|
1376
1448
|
|
|
1377
1449
|
if retry == max_retries:
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1450
|
+
|
|
1451
|
+
if fetch_and_update_secrets():
|
|
1452
|
+
try:
|
|
1453
|
+
token_data = refresh_access_token_from_sp_dc(sp_dc)
|
|
1454
|
+
token = token_data["access_token"]
|
|
1455
|
+
client_id = token_data.get("client_id", "")
|
|
1456
|
+
length = token_data["length"]
|
|
1457
|
+
|
|
1458
|
+
SP_CACHED_ACCESS_TOKEN = token
|
|
1459
|
+
SP_ACCESS_TOKEN_EXPIRES_AT = token_data["expires_at"]
|
|
1460
|
+
SP_CACHED_CLIENT_ID = client_id
|
|
1461
|
+
|
|
1462
|
+
if SP_CACHED_ACCESS_TOKEN and check_token_validity(SP_CACHED_ACCESS_TOKEN, SP_CACHED_CLIENT_ID, USER_AGENT):
|
|
1463
|
+
return SP_CACHED_ACCESS_TOKEN
|
|
1464
|
+
except Exception as e:
|
|
1465
|
+
last_error = str(e)
|
|
1466
|
+
|
|
1467
|
+
error_msg = f"Failed to obtain a valid Spotify access token after {max_retries} attempts"
|
|
1468
|
+
if last_error:
|
|
1469
|
+
error_msg += f": {last_error}"
|
|
1470
|
+
raise RuntimeError(error_msg)
|
|
1384
1471
|
|
|
1385
1472
|
return SP_CACHED_ACCESS_TOKEN
|
|
1386
1473
|
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
spotify_monitor.py,sha256=Nq4RTsG9bHUeVpGJLOOCX8lr5xySEniNsu4aohrpU-o,158392
|
|
2
|
-
spotify_monitor-2.3.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
3
|
-
spotify_monitor-2.3.dist-info/METADATA,sha256=MFBSxyNhzVr5ZCJHMWWenD4CH9EWGYvgA0UB2ZM-bgI,23411
|
|
4
|
-
spotify_monitor-2.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
5
|
-
spotify_monitor-2.3.dist-info/entry_points.txt,sha256=8HzePfUcCSXrYaXOwLbNNYO8GJcnhgCSl4wcDNECht8,57
|
|
6
|
-
spotify_monitor-2.3.dist-info/top_level.txt,sha256=EP6IPD4vHT12rLM5b_jo2i3nrfOuwk3ehhr2gWdQx9Y,16
|
|
7
|
-
spotify_monitor-2.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|