From 5a4a5873f0923fb15d24b419a4a2d07e7ebd30d3 Mon Sep 17 00:00:00 2001 From: Dniel97 <6324072+Dniel97@users.noreply.github.com> Date: Sun, 8 Jan 2023 16:07:25 +0100 Subject: [PATCH 1/3] Updated user-agent, fixes BOT Protection issue, close #28 --- tidal_api.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tidal_api.py b/tidal_api.py index 9c9c07e..5ca2f38 100644 --- a/tidal_api.py +++ b/tidal_api.py @@ -379,8 +379,8 @@ class TidalMobileSession(TidalSession): self.code_verifier = base64.urlsafe_b64encode(secrets.token_bytes(32)).rstrip(b'=') self.code_challenge = base64.urlsafe_b64encode(hashlib.sha256(self.code_verifier).digest()).rstrip(b'=') self.client_unique_key = secrets.token_hex(8) - self.user_agent = 'Mozilla/5.0 (Linux; Android 12; Pixel 6 Build/RKQ1.200826.002; wv) AppleWebKit/537.36 ' \ - '(KHTML, like Gecko) Version/4.0 Chrome/105.0.5195.136 Mobile Safari/537.36' + self.user_agent = 'Mozilla/5.0 (Linux; Android 13; Pixel 7 Build/TD1A.221105.001; wv) AppleWebKit/537.36' \ + '(KHTML, like Gecko) Version/4.0 Chrome/109.0.5414.80 Mobile Safari/537.36' def auth(self, username: str, password: str): s = requests.Session() From 39d64eaef2b611b2c363083af46b9a8158bcd8c1 Mon Sep 17 00:00:00 2001 From: Dniel97 <6324072+Dniel97@users.noreply.github.com> Date: Mon, 16 Jan 2023 14:25:58 +0100 Subject: [PATCH 2/3] Cleanup and small improvements --- interface.py | 13 ++++++---- tidal_api.py | 70 ++++++---------------------------------------------- 2 files changed, 15 insertions(+), 68 deletions(-) diff --git a/interface.py b/interface.py index 6da85b7..7ade841 100644 --- a/interface.py +++ b/interface.py @@ -107,7 +107,8 @@ class ModuleInterface: else: if not username or not password: self.print(f'{module_information.service_name}: Creating a Mobile session') - self.print(f'{module_information.service_name}: Enter your Tidal username and password:') + self.print(f'{module_information.service_name}: Enter your TIDAL username and password:') + self.print(f'{module_information.service_name}: (password will not be echoed)') username = input(' Username: ') password = getpass(' Password: ') sessions[session_type].auth(username, password) @@ -142,7 +143,8 @@ class ModuleInterface: sessions[session_type].auth() else: self.print(f'{module_information.service_name}: Recreating a Mobile session') - self.print(f'{module_information.service_name}: Enter your Tidal username and password:') + self.print(f'{module_information.service_name}: Enter your TIDAL username and password:') + self.print(f'{module_information.service_name}: (password will not be echoed)') username = input('Username: ') password = getpass('Password: ') sessions[session_type].auth(username, password) @@ -187,7 +189,7 @@ class ModuleInterface: items = [] for i in results[query_type.name + 's'].get('items'): - duration = None + duration, name = None, None if query_type is DownloadTypeEnum.artist: name = i.get('name') artists = None @@ -427,7 +429,8 @@ class ModuleInterface: # lmao what did I smoke when I wrote this, track_data and not album_data! if (self.settings['force_non_spatial'] or ( (quality_tier is QualityEnum.LOSSLESS or track_data.get('audioQuality') == 'LOSSLESS') - and track_data.get('audioModes') == ['STEREO'])) and SessionType.MOBILE_DEFAULT.name in self.available_sessions: + and track_data.get('audioModes') == ['STEREO'])) and ( + SessionType.MOBILE_DEFAULT.name in self.available_sessions): self.session.default = SessionType.MOBILE_DEFAULT elif (track_data.get('audioModes') == ['SONY_360RA'] or ('DOLBY_ATMOS' in track_data.get('audioModes') and self.settings['prefer_ac4'])) \ @@ -683,7 +686,7 @@ class ModuleInterface: silentremove(merged_temp_location) for temp_location in temp_locations: silentremove(temp_location) - except Exception: + except: self.print('FFmpeg is not installed or working! Using fallback, may have errors') # return the MP4 temp file, but tell orpheus to change the container to .m4a (AAC) diff --git a/tidal_api.py b/tidal_api.py index 5ca2f38..9a3ef04 100644 --- a/tidal_api.py +++ b/tidal_api.py @@ -212,25 +212,25 @@ class TidalApi(object): def get_artist_albums_ep_singles(self, artist_id): return self._get('artists/' + str(artist_id) + '/albums', params={'filter': 'EPSANDSINGLES'}) - def get_type_from_id(self, id): + def get_type_from_id(self, id_): result = None try: - result = self.get_album(id) + result = self.get_album(id_) return 'a' except TidalError: pass try: - result = self.get_artist(id) + result = self.get_artist(id_) return 'r' except TidalError: pass try: - result = self.get_track(id) + result = self.get_track(id_) return 't' except TidalError: pass try: - result = self.get_video(id) + result = self.get_video(id_) return 'v' except TidalError: pass @@ -238,62 +238,6 @@ class TidalApi(object): return result -class SessionFormats: - def __init__(self, session): - self.mqa_trackid = '91950969' - self.dolby_trackid = '131069353' - self.sony_trackid = '142292058' - - self.quality = ['HI_RES', 'LOSSLESS', 'HIGH', 'LOW'] - - self.formats = { - 'eac3': False, - 'mha1': False, - 'ac4': False, - 'mqa': False, - 'flac': False, - 'alac': False, - 'mp4a.40.2': False, - 'mp4a.40.5': False - } - - try: - self.check_formats(session) - except TidalRequestError: - print('\tERROR: No (HiFi) subscription found!') - - def check_formats(self, session): - api = TidalApi(session) - - for id in [self.dolby_trackid, self.sony_trackid]: - playback_info = api.get_stream_url(id, ['LOW']) - if playback_info['manifestMimeType'] == 'application/dash+xml': - continue - manifest_unparsed = base64.b64decode(playback_info['manifest']).decode('UTF-8') - if 'ContentProtection' not in manifest_unparsed: - self.formats[json.loads(manifest_unparsed)['codecs']] = True - - for i in range(len(self.quality)): - playback_info = api.get_stream_url(self.mqa_trackid, [self.quality[i]]) - if playback_info['manifestMimeType'] == 'application/dash+xml': - continue - - manifest_unparsed = base64.b64decode(playback_info['manifest']).decode('UTF-8') - if 'ContentProtection' not in manifest_unparsed: - self.formats[json.loads(manifest_unparsed)['codecs']] = True - - def print_fomats(self): - table = prettytable.PrettyTable() - table.field_names = ['Codec', 'Technical name', 'Supported'] - table.align = 'l' - for format in self.formats: - table.add_row([format, technical_names[format], self.formats[format]]) - - string_table = '\t' + table.__str__().replace('\n', '\n\t') - print(string_table) - print('') - - @dataclass class SessionStorage: access_token: str @@ -513,7 +457,7 @@ class TidalMobileSession(TidalSession): }) if r.status_code == 200: - print('\tRefreshing token successful') + # print('TIDAL: Refreshing token successful') self.access_token = r.json()['access_token'] self.expires = datetime.now() + timedelta(seconds=r.json()['expires_in']) @@ -628,7 +572,7 @@ class TidalTvSession(TidalSession): }) if r.status_code == 200: - print('Tidal: Refreshing token successful') + # print('TIDAL: Refreshing token successful') self.access_token = r.json()['access_token'] self.expires = datetime.now() + timedelta(seconds=r.json()['expires_in']) From 729a205dcaa6d7c5bf64668216377aac3a1d9e43 Mon Sep 17 00:00:00 2001 From: Dniel97 <6324072+Dniel97@users.noreply.github.com> Date: Mon, 16 Jan 2023 14:38:12 +0100 Subject: [PATCH 3/3] Added updating instructions --- README.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5a0631d..dc8ece8 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ A TIDAL module for the OrpheusDL modular archival music program - [Getting Started](#getting-started) - [Prerequisites](#prerequisites) - [Installation](#installation) + - [Updating](#updating) - [Usage](#usage) - [Configuration](#configuration) - [Global](#global) @@ -42,7 +43,7 @@ Follow these steps to get a local copy of Orpheus up and running: ### Installation -1. Go to your `orpheusdl/` directory and run the following command: +1. Go to your already cloned `orpheusdl/` directory and run the following command: ```sh git clone --recurse-submodules https://github.com/Dniel97/orpheusdl-tidal.git modules/tidal ``` @@ -52,6 +53,19 @@ Follow these steps to get a local copy of Orpheus up and running: ``` 3. Now the `config/settings.json` file should be updated with the [TIDAL settings](#tidal) +### Updating + +1. Go to your already cloned `orpheusdl/` directory and run the following command: + ```sh + git -C modules/tidal pull + ``` +2. Execute to update your already existing TIDAL settings (if needed): + ```sh + python orpheus.py + ``` +3. Now the `config/settings.json` file should be updated with the new updated [TIDAL settings](#tidal) + + ## Usage