Merge pull request #213 from exislow/update-tidal-api

Update tidalapi
This commit is contained in:
exislow
2024-11-08 17:29:29 +01:00
committed by GitHub
11 changed files with 26 additions and 69 deletions
+1 -1
View File
@@ -36,7 +36,7 @@ If you like this projects and want to support it, you can buy me a coffee :-)
## 💻 Installation / Upgrade ## 💻 Installation / Upgrade
**Requirements**: Python 3.11 (other versions might work but are not tested!) **Requirements**: Python 3.11 or 3.12 (other versions might work but are not tested!)
```bash ```bash
pip install --upgrade tidal-dl-ng pip install --upgrade tidal-dl-ng
Generated
+11 -14
View File
@@ -675,18 +675,15 @@ files = [
[[package]] [[package]]
name = "isodate" name = "isodate"
version = "0.6.1" version = "0.7.2"
description = "An ISO 8601 date/time/duration parser and formatter" description = "An ISO 8601 date/time/duration parser and formatter"
optional = false optional = false
python-versions = "*" python-versions = ">=3.7"
files = [ files = [
{file = "isodate-0.6.1-py2.py3-none-any.whl", hash = "sha256:0751eece944162659049d35f4f549ed815792b38793f07cf73381c1c87cbed96"}, {file = "isodate-0.7.2-py3-none-any.whl", hash = "sha256:28009937d8031054830160fce6d409ed342816b543597cece116d966c6d99e15"},
{file = "isodate-0.6.1.tar.gz", hash = "sha256:48c5881de7e8b0a0d648cb024c8062dc84e7b840ed81e864c7614fd3c127bde9"}, {file = "isodate-0.7.2.tar.gz", hash = "sha256:4cd1aa0f43ca76f4a6c6c0292a85f40b35ec2e43e315b59f06e6d32171a953e6"},
] ]
[package.dependencies]
six = "*"
[[package]] [[package]]
name = "isort" name = "isort"
version = "5.13.2" version = "5.13.2"
@@ -2023,22 +2020,22 @@ pbr = ">=2.0.0"
[[package]] [[package]]
name = "tidalapi" name = "tidalapi"
version = "0.7.6" version = "0.8.0"
description = "Unofficial API for TIDAL music streaming service." description = "Unofficial API for TIDAL music streaming service."
optional = false optional = false
python-versions = "<4.0,>=3.8" python-versions = "<4.0,>=3.8"
files = [ files = [
{file = "tidalapi-0.7.6-py3-none-any.whl", hash = "sha256:ac9afe91296d2db71381e70470a710c052ce45b5014c4735bd1908ca3938f233"}, {file = "tidalapi-0.8.0-py3-none-any.whl", hash = "sha256:114b8cf127bb9d6f02796b446f9202571989fbd5c3c62b69b58c43d9ada77e38"},
{file = "tidalapi-0.7.6.tar.gz", hash = "sha256:5fa537e13d6c3383fe245a4e7dc23b0a650b7066784825f03f67c51ca8b57161"}, {file = "tidalapi-0.8.0.tar.gz", hash = "sha256:da0fca3cb790db6475526d724d868d079554203eb9b0636af7ff60f7e023a690"},
] ]
[package.dependencies] [package.dependencies]
isodate = ">=0.6.1,<0.7.0" isodate = ">=0.7.2,<0.8.0"
mpegdash = ">=0.4.0,<0.5.0" mpegdash = ">=0.4.0,<0.5.0"
python-dateutil = ">=2.8.2,<3.0.0" python-dateutil = ">=2.8.2,<3.0.0"
ratelimit = ">=2.2.1,<3.0.0" ratelimit = ">=2.2.1,<3.0.0"
requests = ">=2.28.0,<3.0.0" requests = ">=2.32.3,<3.0.0"
typing-extensions = ">=4.10.0,<5.0.0" typing-extensions = ">=4.12.2,<5.0.0"
[[package]] [[package]]
name = "tokenize-rt" name = "tokenize-rt"
@@ -2239,4 +2236,4 @@ gui = ["pyqtdarktheme-fork", "pyside6"]
[metadata] [metadata]
lock-version = "2.0" lock-version = "2.0"
python-versions = ">=3.10,<3.13" python-versions = ">=3.10,<3.13"
content-hash = "15808a09d378226205d3abaa3aa116ba8579e092e875ef2855c87912c36e5918" content-hash = "92af866c0916091be26c50790b79c210f70a939fc8c89c9e44857d30b76bc7bd"
+1 -1
View File
@@ -29,7 +29,6 @@ python = ">=3.10,<3.13"
requests = "~2.32.3" requests = "~2.32.3"
mutagen = "^1.47.0" mutagen = "^1.47.0"
pycryptodome = "^3.21.0" pycryptodome = "^3.21.0"
tidalapi = "~0.7.6"
dataclasses-json = "^0.6.7" dataclasses-json = "^0.6.7"
pathvalidate = "^3.2.1" pathvalidate = "^3.2.1"
m3u8 = "^6.0.0" m3u8 = "^6.0.0"
@@ -41,6 +40,7 @@ rich = "^13.9.4"
toml = "^0.10.2" toml = "^0.10.2"
typer = "^0.12.5" typer = "^0.12.5"
ffmpeg-python = "^0.2.0" ffmpeg-python = "^0.2.0"
tidalapi = "^0.8.0"
[tool.poetry.extras] [tool.poetry.extras]
gui = ["pyside6", "pyqtdarktheme-fork"] gui = ["pyside6", "pyqtdarktheme-fork"]
-1
View File
@@ -171,7 +171,6 @@ class DialogPreferences(QtWidgets.QDialog):
"download_delay", "download_delay",
"video_convert_mp4", "video_convert_mp4",
"extract_flac", "extract_flac",
"downgrade_on_hi_res",
] ]
def gui_populate(self): def gui_populate(self):
+1 -5
View File
@@ -94,7 +94,7 @@ class Download:
# Get urls for media. # Get urls for media.
if isinstance(media, Track): if isinstance(media, Track):
urls = media.get_stream().get_stream_manifest().urls urls = media.get_stream().get_stream_manifest().get_urls()
stream_manifest: StreamManifest = media.get_stream().get_stream_manifest() stream_manifest: StreamManifest = media.get_stream().get_stream_manifest()
elif isinstance(media, Video): elif isinstance(media, Video):
m3u8_variant: m3u8.M3U8 = m3u8.load(media.get_url()) m3u8_variant: m3u8.M3U8 = m3u8.load(media.get_url())
@@ -211,10 +211,6 @@ class Download:
file_extension: str file_extension: str
if isinstance(media, Track): if isinstance(media, Track):
# If hi_res is forbidden in settings and highest track quality is hi_res, downgrade to high_lossless.
if self.settings.data.downgrade_on_hi_res and media.get_stream().audio_quality == Quality.hi_res:
quality_audio = Quality.high_lossless
# If a quality is explicitly set, change it. # If a quality is explicitly set, change it.
if quality_audio: if quality_audio:
quality_audio_old: Quality = self.adjust_quality_audio(quality_audio) quality_audio_old: Quality = self.adjust_quality_audio(quality_audio)
-1
View File
@@ -618,7 +618,6 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
if ( if (
self.settings.data.quality_audio == quality_highest self.settings.data.quality_audio == quality_highest
or self.settings.data.quality_audio == Quality.hi_res_lossless or self.settings.data.quality_audio == Quality.hi_res_lossless
or (self.settings.data.quality_audio == Quality.hi_res and quality_highest == Quality.hi_res)
): ):
quality = quality_highest quality = quality_highest
else: else:
+2 -1
View File
@@ -37,7 +37,8 @@ def decrypt_security_token(security_token: str) -> (str, str):
def decrypt_file(path_file_encrypted: str, path_file_destination: str, key: str, nonce: str) -> None: def decrypt_file(path_file_encrypted: str, path_file_destination: str, key: str, nonce: str) -> None:
""" """
Decrypts an encrypted MQA file given the file, key and nonce Decrypts an encrypted MQA file given the file, key and nonce.
TODO: Is it really only necessary for MQA of for all other formats, too?
""" """
# Initialize counter and file decryptor # Initialize counter and file decryptor
-2
View File
@@ -188,8 +188,6 @@ def quality_audio_highest(media: Track | Album) -> Quality:
if MediaMetadataTags.hires_lossless in media.media_metadata_tags: if MediaMetadataTags.hires_lossless in media.media_metadata_tags:
quality = Quality.hi_res_lossless quality = Quality.hi_res_lossless
elif MediaMetadataTags.mqa in media.media_metadata_tags:
quality = Quality.hi_res
elif MediaMetadataTags.lossless in media.media_metadata_tags: elif MediaMetadataTags.lossless in media.media_metadata_tags:
quality = Quality.high_lossless quality = Quality.high_lossless
else: else:
+1 -5
View File
@@ -36,7 +36,6 @@ class Settings:
path_binary_ffmpeg: str = "" path_binary_ffmpeg: str = ""
metadata_cover_dimension: CoverDimensions = CoverDimensions.Px320 metadata_cover_dimension: CoverDimensions = CoverDimensions.Px320
extract_flac: bool = True extract_flac: bool = True
downgrade_on_hi_res: bool = False
@dataclass_json @dataclass_json
@@ -59,7 +58,7 @@ class HelpSettings:
quality_audio: str = ( quality_audio: str = (
'Desired audio download quality: "LOW" (96kbps), "HIGH" (320kbps), ' 'Desired audio download quality: "LOW" (96kbps), "HIGH" (320kbps), '
'"LOSSLESS" (16 Bit, 44,1 kHz), ' '"LOSSLESS" (16 Bit, 44,1 kHz), '
'"HI_RES" (MQA 24 Bit, 96 kHz), "HI_RES_LOSSLESS" (up to 24 Bit, 192 kHz)' '"HI_RES_LOSSLESS" (up to 24 Bit, 192 kHz)'
) )
quality_video: str = 'Desired video download quality: "360", "480", "720", "1080"' quality_video: str = 'Desired video download quality: "360", "480", "720", "1080"'
# TODO: Describe possible variables. # TODO: Describe possible variables.
@@ -80,9 +79,6 @@ class HelpSettings:
"The dimensions of the cover image embedded into the track. Possible values: 320x320, 640x640x 1280x1280." "The dimensions of the cover image embedded into the track. Possible values: 320x320, 640x640x 1280x1280."
) )
extract_flac: str = "Extract FLAC audio tracks from MP4 containers and save them as `*.flac` (uses FFmpeg)." extract_flac: str = "Extract FLAC audio tracks from MP4 containers and save them as `*.flac` (uses FFmpeg)."
downgrade_on_hi_res: bool = (
"Never download HI_RES (MQA) quality. Downgrade to the next best available quality instead."
)
@dataclass_json @dataclass_json
+5 -19
View File
@@ -1,7 +1,7 @@
################################################################################ ################################################################################
## Form generated from reading UI file 'dialog_settings.ui' ## Form generated from reading UI file 'dialog_settings.ui'
## ##
## Created by: Qt User Interface Compiler version 6.7.0 ## Created by: Qt User Interface Compiler version 6.8.0
## ##
## WARNING! All changes made in this file will be lost when recompiling UI file! ## WARNING! All changes made in this file will be lost when recompiling UI file!
################################################################################ ################################################################################
@@ -26,7 +26,7 @@ class Ui_DialogSettings:
def setupUi(self, DialogSettings): def setupUi(self, DialogSettings):
if not DialogSettings.objectName(): if not DialogSettings.objectName():
DialogSettings.setObjectName("DialogSettings") DialogSettings.setObjectName("DialogSettings")
DialogSettings.resize(640, 682) DialogSettings.resize(640, 705)
sizePolicy = QSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding) sizePolicy = QSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
sizePolicy.setHorizontalStretch(100) sizePolicy.setHorizontalStretch(100)
sizePolicy.setVerticalStretch(100) sizePolicy.setVerticalStretch(100)
@@ -131,19 +131,6 @@ class Ui_DialogSettings:
self.lv_flags.addLayout(self.lh_flag_3) self.lv_flags.addLayout(self.lh_flag_3)
self.horizontalLayout = QHBoxLayout()
self.horizontalLayout.setObjectName("horizontalLayout")
self.lv_flag_downgrade_on_hi_res = QVBoxLayout()
self.lv_flag_downgrade_on_hi_res.setObjectName("lv_flag_downgrade_on_hi_res")
self.cb_downgrade_on_hi_res = QCheckBox(self.gb_flags)
self.cb_downgrade_on_hi_res.setObjectName("cb_downgrade_on_hi_res")
self.lv_flag_downgrade_on_hi_res.addWidget(self.cb_downgrade_on_hi_res)
self.horizontalLayout.addLayout(self.lv_flag_downgrade_on_hi_res)
self.lv_flags.addLayout(self.horizontalLayout)
self.lv_main.addWidget(self.gb_flags) self.lv_main.addWidget(self.gb_flags)
self.gb_choices = QGroupBox(DialogSettings) self.gb_choices = QGroupBox(DialogSettings)
@@ -235,7 +222,7 @@ class Ui_DialogSettings:
self.lh_choices_cover_dimension = QHBoxLayout() self.lh_choices_cover_dimension = QHBoxLayout()
self.lh_choices_cover_dimension.setObjectName("lh_choices_cover_dimension") self.lh_choices_cover_dimension.setObjectName("lh_choices_cover_dimension")
self.lh_choices_cover_dimension.setSizeConstraint(QLayout.SetDefaultConstraint) self.lh_choices_cover_dimension.setSizeConstraint(QLayout.SizeConstraint.SetDefaultConstraint)
self.l_icon_metadata_cover_dimension = QLabel(self.gb_choices) self.l_icon_metadata_cover_dimension = QLabel(self.gb_choices)
self.l_icon_metadata_cover_dimension.setObjectName("l_icon_metadata_cover_dimension") self.l_icon_metadata_cover_dimension.setObjectName("l_icon_metadata_cover_dimension")
sizePolicy4.setHeightForWidth(self.l_icon_metadata_cover_dimension.sizePolicy().hasHeightForWidth()) sizePolicy4.setHeightForWidth(self.l_icon_metadata_cover_dimension.sizePolicy().hasHeightForWidth())
@@ -494,8 +481,8 @@ class Ui_DialogSettings:
self.bb_dialog = QDialogButtonBox(DialogSettings) self.bb_dialog = QDialogButtonBox(DialogSettings)
self.bb_dialog.setObjectName("bb_dialog") self.bb_dialog.setObjectName("bb_dialog")
self.bb_dialog.setOrientation(Qt.Horizontal) self.bb_dialog.setOrientation(Qt.Orientation.Horizontal)
self.bb_dialog.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok) self.bb_dialog.setStandardButtons(QDialogButtonBox.StandardButton.Cancel | QDialogButtonBox.StandardButton.Ok)
self.lv_main.addWidget(self.bb_dialog) self.lv_main.addWidget(self.bb_dialog)
@@ -521,7 +508,6 @@ class Ui_DialogSettings:
self.cb_lyrics_file.setText(QCoreApplication.translate("DialogSettings", "CheckBox", None)) self.cb_lyrics_file.setText(QCoreApplication.translate("DialogSettings", "CheckBox", None))
self.cb_download_delay.setText(QCoreApplication.translate("DialogSettings", "CheckBox", None)) self.cb_download_delay.setText(QCoreApplication.translate("DialogSettings", "CheckBox", None))
self.cb_extract_flac.setText(QCoreApplication.translate("DialogSettings", "CheckBox", None)) self.cb_extract_flac.setText(QCoreApplication.translate("DialogSettings", "CheckBox", None))
self.cb_downgrade_on_hi_res.setText(QCoreApplication.translate("DialogSettings", "CheckBox", None))
self.gb_choices.setTitle(QCoreApplication.translate("DialogSettings", "Choices", None)) self.gb_choices.setTitle(QCoreApplication.translate("DialogSettings", "Choices", None))
self.l_icon_skip_existing.setText(QCoreApplication.translate("DialogSettings", "TextLabel", None)) self.l_icon_skip_existing.setText(QCoreApplication.translate("DialogSettings", "TextLabel", None))
self.l_skip_existing.setText(QCoreApplication.translate("DialogSettings", "TextLabel", None)) self.l_skip_existing.setText(QCoreApplication.translate("DialogSettings", "TextLabel", None))
+4 -19
View File
@@ -7,7 +7,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>640</width> <width>640</width>
<height>682</height> <height>705</height>
</rect> </rect>
</property> </property>
<property name="sizePolicy"> <property name="sizePolicy">
@@ -184,21 +184,6 @@
</item> </item>
</layout> </layout>
</item> </item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<layout class="QVBoxLayout" name="lv_flag_downgrade_on_hi_res">
<item>
<widget class="QCheckBox" name="cb_downgrade_on_hi_res">
<property name="text">
<string>CheckBox</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>
@@ -316,7 +301,7 @@
<item> <item>
<layout class="QHBoxLayout" name="lh_choices_cover_dimension" stretch="0,0,50"> <layout class="QHBoxLayout" name="lh_choices_cover_dimension" stretch="0,0,50">
<property name="sizeConstraint"> <property name="sizeConstraint">
<enum>QLayout::SetDefaultConstraint</enum> <enum>QLayout::SizeConstraint::SetDefaultConstraint</enum>
</property> </property>
<item> <item>
<widget class="QLabel" name="l_icon_metadata_cover_dimension"> <widget class="QLabel" name="l_icon_metadata_cover_dimension">
@@ -679,10 +664,10 @@
<item> <item>
<widget class="QDialogButtonBox" name="bb_dialog"> <widget class="QDialogButtonBox" name="bb_dialog">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Orientation::Horizontal</enum>
</property> </property>
<property name="standardButtons"> <property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> <set>QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok</set>
</property> </property>
</widget> </widget>
</item> </item>