Improved README and fixed naming
This commit is contained in:
59
README.md
59
README.md
@@ -1,9 +1,9 @@
|
||||
<!-- PROJECT INTRO -->
|
||||
|
||||
OrpheusDL - Tidal
|
||||
OrpheusDL - TIDAL
|
||||
=================
|
||||
|
||||
A Tidal module for the OrpheusDL modular archival music program
|
||||
A TIDAL module for the OrpheusDL modular archival music program
|
||||
|
||||
[Report Bug](https://github.com/Dniel97/orpheusdl-tidal/issues)
|
||||
·
|
||||
@@ -12,23 +12,23 @@ A Tidal module for the OrpheusDL modular archival music program
|
||||
|
||||
## Table of content
|
||||
|
||||
- [About OrpheusDL - Tidal](#about-orpheusdl-tidal)
|
||||
- [About OrpheusDL - TIDAL](#about-orpheusdl---tidal)
|
||||
- [Getting Started](#getting-started)
|
||||
- [Prerequisites](#prerequisites)
|
||||
- [Installation](#installation)
|
||||
- [Usage](#usage)
|
||||
- [Configuration](#configuration)
|
||||
- [Global](#global)
|
||||
- [Tidal](#tidal)
|
||||
- [TIDAL](#tidal)
|
||||
- [Contact](#contact)
|
||||
- [Acknowledgements](#acknowledgements)
|
||||
|
||||
|
||||
|
||||
<!-- ABOUT ORPHEUS -->
|
||||
## About OrpheusDL - Tidal
|
||||
## About OrpheusDL - TIDAL
|
||||
|
||||
OrpheusDL - Tidal is a module written in Python which allows archiving from **Tidal** for the modular music archival program.
|
||||
OrpheusDL - TIDAL is a module written in Python which allows archiving from **[tidal.com](https://listen.tidal.com)** for the modular music archival program.
|
||||
|
||||
|
||||
<!-- GETTING STARTED -->
|
||||
@@ -42,15 +42,15 @@ Follow these steps to get a local copy of Orpheus up and running:
|
||||
|
||||
### Installation
|
||||
|
||||
1. Clone the repo inside the folder `orpheusdl/modules/`
|
||||
1. Go to your `orpheusdl/` directory and run the following command:
|
||||
```sh
|
||||
git clone https://github.com/Dniel97/orpheusdl-tidal.git tidal
|
||||
git clone https://github.com/Dniel97/orpheusdl-tidal.git modules/tidal
|
||||
```
|
||||
2. Execute:
|
||||
```sh
|
||||
python orpheus.py
|
||||
```
|
||||
3. Now the `config/settings.json` file should be updated with the Tidal settings
|
||||
3. Now the `config/settings.json` file should be updated with the [TIDAL settings](#tidal)
|
||||
|
||||
<!-- USAGE EXAMPLES -->
|
||||
## Usage
|
||||
@@ -94,8 +94,10 @@ loaded module. You'll find the configuration file here: `config/settings.json`
|
||||
`download_quality`: Choose one of the following settings:
|
||||
* "hifi": FLAC with MQA up to 48/24
|
||||
* "lossless": FLAC with 44.1/16 (is MQA if the album is available in MQA)
|
||||
* "high": AAC 320 kbit/s
|
||||
* "low": AAC 96 kbit/s
|
||||
* "high": same as "medium"
|
||||
* "medium": AAC 320 kbit/s
|
||||
* "low": same as "minimum"
|
||||
* "minimum": AAC 96 kbit/s
|
||||
|
||||
`album_format`:
|
||||
* `{quality}` will add
|
||||
@@ -104,12 +106,12 @@ loaded module. You'll find the configuration file here: `config/settings.json`
|
||||
[360]
|
||||
[M]
|
||||
```
|
||||
depending on the album quality
|
||||
depending on the album quality (with a space in at the first character)
|
||||
* `{explicit}` will add
|
||||
```
|
||||
[E]
|
||||
```
|
||||
to the album path
|
||||
to the album path (with a space in at the first character)
|
||||
|
||||
`proprietary_codecs`: Enables/Disables MQA (Tidal Masters) downloading regardless the "hifi" setting from `download_quality`
|
||||
|
||||
@@ -120,7 +122,7 @@ loaded module. You'll find the configuration file here: `config/settings.json`
|
||||
the highest is 4000x4000px. That's because Tidal doesn't provide the "origin artwork" size, so the module will just get
|
||||
the largest.
|
||||
|
||||
### Tidal
|
||||
### TIDAL
|
||||
```json
|
||||
{
|
||||
"tv_token": "7m7Ap0JC9j1cOM3n",
|
||||
@@ -133,30 +135,23 @@ the largest.
|
||||
"fix_mqa": true
|
||||
}
|
||||
```
|
||||
`tv_token`: Enter a valid TV client token
|
||||
|
||||
`tv_secret`: Enter a valid TV client secret for the `tv_token`
|
||||
| Option | Info |
|
||||
|-------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| tv_token | Enter a valid TV client token |
|
||||
| tv_secret | Enter a valid TV client secret for the `tv_token` |
|
||||
| mobile_* | Enter a valid MOBILE client token for the desired session |
|
||||
| enable_mobile | Enables a second MOBILE session which needs a `username` and `password` (can be the same "TV" account) to archive Sony 360RA and Dolby AC-4 if available or allows `force_non_spatial` to work properly |
|
||||
| force_non_spatial | Forces a default Mobile session (`mobile_default_token` without support for Dolby Atmos at all, Sony 360RA will still be available) to get FLAC/AAC tracks |
|
||||
| prefer_ac4 | If enabled and a mobile session is available (`enable_mobile` is set to `true`) this will ensure to get Dolby AC-4 on Dolby Atmos tracks |
|
||||
| fix_mqa | If enabled it will download the MQA file before the actual track and analyze the FLAC file to extract the bitDepth and originalSampleRate. The tags `MQAENCODER`, `ENCODER` and `ORIGINALSAMPLERATE` are than added to the FLAC file in order to get properly detected my MQA enabled software. |
|
||||
|
||||
`mobile_atmos_token`/`mobile_atmos_token`: Enter a valid MOBILE client token
|
||||
|
||||
`enable_mobile`: Enables a second MOBILE session which needs a `username` and `password` (can be the same "TV" account)
|
||||
to archive Sony 360RA and Dolby AC-4 if available or allows `force_non_spatial` to work properly
|
||||
|
||||
`force_non_spatial`: Forces a default Mobile session (`mobile_default_token` without support for Dolby Atmos at all,
|
||||
Sony 360RA will still be available tho) to get FLAC/AAC tracks
|
||||
|
||||
`prefer_ac4`: If enabled and a mobile session is available (`enable_mobile` is set to `true`) this will ensure to get
|
||||
Dolby AC-4 on Dolby Atmos tracks
|
||||
|
||||
`fix_mqa`: If enabled it will download the MQA file before the actual track and analyze the FLAC file to extract the
|
||||
bitDepth and originalSampleRate. The tags `MQAENCODER`, `ENCODER` and `ORIGINALSAMPLERATE` are than added to the FLAC
|
||||
file in order to get properly detected.
|
||||
|
||||
**Credits: [MQA_identifier](https://github.com/purpl3F0x/MQA_identifier) by
|
||||
[@purpl3F0x](https://github.com/purpl3F0x) and [mqaid](https://github.com/redsudo/mqaid) by
|
||||
[@redsudo](https://github.com/redsudo).**
|
||||
|
||||
**NOTE: `fix_mqa` is enabled which is experimental! May be slower as normal download and could not be working at all**
|
||||
**NOTE: `fix_mqa` is experimental! May be slower as a download with `fix_mqa` disabled and could be incorrect**
|
||||
|
||||
<!-- Contact -->
|
||||
## Contact
|
||||
@@ -165,7 +160,7 @@ Yarrm80s (pronounced 'Yeargh mateys!') - [@yarrm80s](https://github.com/yarrm80s
|
||||
|
||||
Dniel97 - [@Dniel97](https://github.com/Dniel97)
|
||||
|
||||
Project Link: [OrpheusDL Tidal Public GitHub Repository](https://github.com/Dniel97/orpheusdl-tidal)
|
||||
Project Link: [OrpheusDL TIDAL Public GitHub Repository](https://github.com/Dniel97/orpheusdl-tidal)
|
||||
|
||||
|
||||
<!-- ACKNOWLEDGEMENTS -->
|
||||
|
||||
29
interface.py
29
interface.py
@@ -17,7 +17,7 @@ from .mqa_identifier_python.mqa_identifier import MqaIdentifier
|
||||
from .tidal_api import TidalTvSession, TidalApi, TidalMobileSession, SessionType, TidalError, TidalRequestError
|
||||
|
||||
module_information = ModuleInformation(
|
||||
service_name='Tidal',
|
||||
service_name='TIDAL',
|
||||
module_supported_modes=ModuleModes.download | ModuleModes.credits | ModuleModes.covers | ModuleModes.lyrics,
|
||||
login_behaviour=ManualEnum.manual,
|
||||
global_settings={
|
||||
@@ -55,6 +55,7 @@ class ModuleInterface:
|
||||
|
||||
# LOW = 96kbit/s AAC, HIGH = 320kbit/s AAC, LOSSLESS = 44.1/16 FLAC, HI_RES <= 48/24 FLAC with MQA
|
||||
self.quality_parse = {
|
||||
QualityEnum.MINIMUM: 'LOW',
|
||||
QualityEnum.LOW: 'LOW',
|
||||
QualityEnum.MEDIUM: 'HIGH',
|
||||
QualityEnum.HIGH: 'HIGH',
|
||||
@@ -92,19 +93,19 @@ class ModuleInterface:
|
||||
sessions[session_type] = TidalMobileSession(self.settings['mobile_default_token'])
|
||||
|
||||
if session_type in saved_sessions:
|
||||
logging.debug(f'Tidal: {session_type} session found, loading')
|
||||
logging.debug(f'{module_information.service_name}: {session_type} session found, loading')
|
||||
|
||||
# load the dictionary from the temporary_settings_controller inside the TidalSession class
|
||||
sessions[session_type].set_storage(saved_sessions[session_type])
|
||||
else:
|
||||
logging.debug(f'Tidal: No {session_type} session found, creating new one')
|
||||
logging.debug(f'{module_information.service_name}: No {session_type} session found, creating new one')
|
||||
if session_type == SessionType.TV.name:
|
||||
self.print('Tidal: Creating a TV session')
|
||||
self.print(f'{module_information.service_name}: Creating a TV session')
|
||||
sessions[session_type].auth()
|
||||
else:
|
||||
if not username or not password:
|
||||
self.print('Tidal: Creating a Mobile session')
|
||||
self.print('Tidal: Enter your Tidal username and 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:')
|
||||
username = input(' Username: ')
|
||||
password = getpass(' Password: ')
|
||||
sessions[session_type].auth(username, password)
|
||||
@@ -135,11 +136,11 @@ class ModuleInterface:
|
||||
|
||||
# create a new session finally
|
||||
if session_type == SessionType.TV.name:
|
||||
self.print('Tidal: Recreating a TV session')
|
||||
self.print(f'{module_information.service_name}: Recreating a TV session')
|
||||
sessions[session_type].auth()
|
||||
else:
|
||||
self.print('Tidal: Recreating a Mobile session')
|
||||
self.print('Tidal: Enter your Tidal username and password:')
|
||||
self.print(f'{module_information.service_name}: Recreating a Mobile session')
|
||||
self.print(f'{module_information.service_name}: Enter your Tidal username and password:')
|
||||
username = input('Username: ')
|
||||
password = getpass('Password: ')
|
||||
sessions[session_type].auth(username, password)
|
||||
@@ -159,7 +160,8 @@ class ModuleInterface:
|
||||
def check_subscription(self, subscription: str) -> bool:
|
||||
# returns true if "disable_subscription_checks" is enabled or subscription is HIFI Plus
|
||||
if not self.disable_subscription_check and subscription not in {'HIFI', 'PREMIUM_PLUS'}:
|
||||
self.print(f'Tidal: Account is not a HiFi Plus account, detected subscription: {subscription}')
|
||||
self.print(f'{module_information.service_name}: Account is not a HiFi Plus account, '
|
||||
f'detected subscription: {subscription}')
|
||||
return False
|
||||
return True
|
||||
|
||||
@@ -191,7 +193,7 @@ class ModuleInterface:
|
||||
if 'name' in i.get('creator'):
|
||||
artists = [i.get('creator').get('name')]
|
||||
elif i.get('type') == 'EDITORIAL':
|
||||
artists = ['TIDAL']
|
||||
artists = [module_information.service_name]
|
||||
else:
|
||||
artists = ['Unknown']
|
||||
|
||||
@@ -244,7 +246,7 @@ class ModuleInterface:
|
||||
if 'name' in playlist_data.get('creator'):
|
||||
creator_name = playlist_data.get('creator').get('name')
|
||||
elif playlist_data.get('type') == 'EDITORIAL':
|
||||
creator_name = 'TIDAL'
|
||||
creator_name = module_information.service_name
|
||||
else:
|
||||
creator_name = 'Unknown'
|
||||
|
||||
@@ -252,7 +254,6 @@ class ModuleInterface:
|
||||
name=playlist_data.get('title'),
|
||||
creator=creator_name,
|
||||
tracks=tracks,
|
||||
# TODO: Use playlist creation date or lastUpdated?
|
||||
release_year=playlist_data.get('created')[:4],
|
||||
creator_id=playlist_data['creator'].get('id'),
|
||||
cover_url=self.generate_artwork_url(playlist_data['squareImage'], size=self.cover_size,
|
||||
@@ -373,7 +374,7 @@ class ModuleInterface:
|
||||
album_data = data[album_id] if album_id in data else self.session.get_album(album_id)
|
||||
except TidalError as e:
|
||||
# if an error occurs, catch it and set the album_data to an empty dict to catch it
|
||||
self.print(f'Tidal: {e} Trying workaround ...', drop_level=1)
|
||||
self.print(f'{module_information.service_name}: {e} Trying workaround ...', drop_level=1)
|
||||
album_data = track_data.get('album')
|
||||
album_data.update({
|
||||
'artist': track_data.get('artist'),
|
||||
|
||||
Reference in New Issue
Block a user