diff --git a/TIDALDL-PY/exe/tidal-dl.exe b/TIDALDL-PY/exe/tidal-dl.exe index 2451f53..f17cb9d 100644 Binary files a/TIDALDL-PY/exe/tidal-dl.exe and b/TIDALDL-PY/exe/tidal-dl.exe differ diff --git a/TIDALDL-PY/setup-gui.py b/TIDALDL-PY/setup-gui.py index d5b55c4..eb57e8b 100644 --- a/TIDALDL-PY/setup-gui.py +++ b/TIDALDL-PY/setup-gui.py @@ -11,6 +11,6 @@ setup( packages=find_packages(exclude=['tidal_dl*']), include_package_data = True, platforms = "any", - install_requires=["tidal-dl", "PyQt5"], + install_requires=["tidal-dl"], entry_points={'console_scripts': [ 'tidal-gui = tidal_gui:main', ]} ) diff --git a/TIDALDL-PY/setup.py b/TIDALDL-PY/setup.py index 0f7fab5..2823119 100644 --- a/TIDALDL-PY/setup.py +++ b/TIDALDL-PY/setup.py @@ -17,8 +17,6 @@ setup( "requests>=2.22.0", "pycryptodome", "pydub", - "prettytable", - "PyQt5", - "qt-material"], + "prettytable"], entry_points={'console_scripts': ['tidal-dl = tidal_dl:main', ]} ) diff --git a/TIDALDL-PY/tidal_dl/__init__.py b/TIDALDL-PY/tidal_dl/__init__.py index 776e551..a2bd74c 100644 --- a/TIDALDL-PY/tidal_dl/__init__.py +++ b/TIDALDL-PY/tidal_dl/__init__.py @@ -13,7 +13,7 @@ import getopt from tidal_dl.events import * from tidal_dl.settings import * -from tidal_dl.gui import * +from tidal_dl.gui import startGui def mainCommand(): diff --git a/TIDALDL-PY/tidal_dl/download.py b/TIDALDL-PY/tidal_dl/download.py index 54bcc41..bbec8af 100644 --- a/TIDALDL-PY/tidal_dl/download.py +++ b/TIDALDL-PY/tidal_dl/download.py @@ -120,12 +120,12 @@ def downloadVideo(video: Video, album: Album = None, playlist: Playlist = None): m3u8content = requests.get(stream.m3u8Url).content if m3u8content is None: Printf.err(f"DL Video[{video.title}] getM3u8 failed.{str(e)}") - return False + return False, f"GetM3u8 failed.{str(e)}" urls = aigpy.m3u8.parseTsUrls(m3u8content) if len(urls) <= 0: Printf.err(f"DL Video[{video.title}] getTsUrls failed.{str(e)}") - return False + return False, "GetTsUrls failed.{str(e)}" check, msg = aigpy.m3u8.downloadByTsUrls(urls, path) if check: @@ -133,10 +133,10 @@ def downloadVideo(video: Video, album: Album = None, playlist: Playlist = None): return True else: Printf.err(f"DL Video[{video.title}] failed.{msg}") - return False + return False, msg except Exception as e: Printf.err(f"DL Video[{video.title}] failed.{str(e)}") - return False + return False, str(e) def downloadTrack(track: Track, album=None, playlist=None, userProgress=None, partSize=1048576): @@ -153,7 +153,7 @@ def downloadTrack(track: Track, album=None, playlist=None, userProgress=None, pa # check exist if __isSkip__(path, stream.url): Printf.success(aigpy.path.getFileName(path) + " (skip:already exists!)") - return True + return True, '' # download logging.info("[DL Track] name=" + aigpy.path.getFileName(path) + "\nurl=" + stream.url) @@ -164,7 +164,7 @@ def downloadTrack(track: Track, album=None, playlist=None, userProgress=None, pa check, err = tool.start(SETTINGS.showProgress) if not check: Printf.err(f"DL Track[{track.title}] failed.{str(err)}") - return False + return False, str(err) # encrypted -> decrypt and remove encrypted file __encrypted__(stream, path + '.part', path) @@ -186,7 +186,7 @@ def downloadTrack(track: Track, album=None, playlist=None, userProgress=None, pa __setMetaData__(track, album, path, contributors, lyrics) Printf.success(track.title) - return True + return True, '' except Exception as e: Printf.err(f"DL Track[{track.title}] failed.{str(e)}") - return False + return False, str(e) diff --git a/TIDALDL-PY/tidal_dl/gui.py b/TIDALDL-PY/tidal_dl/gui.py index 5b110e7..0d21f9c 100644 --- a/TIDALDL-PY/tidal_dl/gui.py +++ b/TIDALDL-PY/tidal_dl/gui.py @@ -8,169 +8,179 @@ @Contact : yaronhuang@foxmail.com @Desc : """ -import os import sys import _thread +import importlib from tidal_dl.events import * from tidal_dl.settings import * +from tidal_dl.printf import * -from PyQt5.QtCore import Qt -from PyQt5.QtCore import pyqtSignal -from PyQt5 import QtWidgets -from qt_material import apply_stylesheet +enableGui = False +try: + params = importlib.import_module('PyQt5') + enableGui = True +except Exception as e: + pass +if enableGui: + from PyQt5.QtCore import Qt + from PyQt5.QtCore import pyqtSignal + from PyQt5 import QtWidgets + from qt_material import apply_stylesheet -class MainView(QtWidgets.QWidget): - s_downloadEnd = pyqtSignal(str, bool, str) + class MainView(QtWidgets.QWidget): + s_downloadEnd = pyqtSignal(str, bool, str) - def __init__(self, ) -> None: - super().__init__() - self.initView() - self.setMinimumSize(600, 500) - self.setWindowTitle("Tidal-dl") - - def __info__(self, msg): - QtWidgets.QMessageBox.information(self, - 'Info', - msg, - QtWidgets.QMessageBox.Yes) - - def initView(self): - self.c_lineSearch = QtWidgets.QLineEdit() - self.c_btnSearch = QtWidgets.QPushButton("Search") - self.c_btnDownload = QtWidgets.QPushButton("Download") - - self.m_supportType = [Type.Album, Type.Playlist, Type.Track, Type.Video] - self.c_combType = QtWidgets.QComboBox() - for item in self.m_supportType: - self.c_combType.addItem(item.name, item) - - columnNames = ['#', 'Title', 'Artists', 'Quality'] - self.c_tableInfo = QtWidgets.QTableWidget() - self.c_tableInfo.setColumnCount(len(columnNames)) - self.c_tableInfo.setRowCount(0) - self.c_tableInfo.setShowGrid(False) - self.c_tableInfo.verticalHeader().setVisible(False) - self.c_tableInfo.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) - self.c_tableInfo.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection) - self.c_tableInfo.horizontalHeader().setStretchLastSection(True) - self.c_tableInfo.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.ResizeMode.ResizeToContents) - self.c_tableInfo.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) - self.c_tableInfo.setFocusPolicy(Qt.NoFocus) - for index, name in enumerate(columnNames): - item = QtWidgets.QTableWidgetItem(name) - self.c_tableInfo.setHorizontalHeaderItem(index, item) - - self.lineGrid = QtWidgets.QHBoxLayout() - self.lineGrid.addWidget(self.c_combType) - self.lineGrid.addWidget(self.c_lineSearch) - self.lineGrid.addWidget(self.c_btnSearch) - - self.mainGrid = QtWidgets.QVBoxLayout(self) - self.mainGrid.addLayout(self.lineGrid) - self.mainGrid.addWidget(self.c_tableInfo) - self.mainGrid.addWidget(self.c_btnDownload) - - self.c_btnSearch.clicked.connect(self.search) - self.c_btnDownload.clicked.connect(self.download) - self.s_downloadEnd.connect(self.downloadEnd) - - def addItem(self, rowIdx: int, colIdx: int, text): - if isinstance(text, str): - item = QtWidgets.QTableWidgetItem(text) - self.c_tableInfo.setItem(rowIdx, colIdx, item) - - def search(self): - self.c_tableInfo.setRowCount(0) + def __init__(self, ) -> None: + super().__init__() + self.initView() + self.setMinimumSize(600, 500) + self.setWindowTitle("Tidal-dl") - self.s_type = self.c_combType.currentData() - self.s_text = self.c_lineSearch.text() - if self.s_text.startswith('http'): - tmpType, tmpId = TIDAL_API.parseUrl(self.s_text) - if tmpType == Type.Null: - self.__info__('Url not support!') - return - elif tmpType not in self.m_supportType: - self.__info__(f'Type[{tmpType.name}] not support!') - return + def __info__(self, msg): + QtWidgets.QMessageBox.information(self, + 'Info', + msg, + QtWidgets.QMessageBox.Yes) + + def initView(self): + self.c_lineSearch = QtWidgets.QLineEdit() + self.c_btnSearch = QtWidgets.QPushButton("Search") + self.c_btnDownload = QtWidgets.QPushButton("Download") + + self.m_supportType = [Type.Album, Type.Playlist, Type.Track, Type.Video] + self.c_combType = QtWidgets.QComboBox() + for item in self.m_supportType: + self.c_combType.addItem(item.name, item) + + columnNames = ['#', 'Title', 'Artists', 'Quality'] + self.c_tableInfo = QtWidgets.QTableWidget() + self.c_tableInfo.setColumnCount(len(columnNames)) + self.c_tableInfo.setRowCount(0) + self.c_tableInfo.setShowGrid(False) + self.c_tableInfo.verticalHeader().setVisible(False) + self.c_tableInfo.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) + self.c_tableInfo.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection) + self.c_tableInfo.horizontalHeader().setStretchLastSection(True) + self.c_tableInfo.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.ResizeMode.ResizeToContents) + self.c_tableInfo.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) + self.c_tableInfo.setFocusPolicy(Qt.NoFocus) + for index, name in enumerate(columnNames): + item = QtWidgets.QTableWidgetItem(name) + self.c_tableInfo.setHorizontalHeaderItem(index, item) + + self.lineGrid = QtWidgets.QHBoxLayout() + self.lineGrid.addWidget(self.c_combType) + self.lineGrid.addWidget(self.c_lineSearch) + self.lineGrid.addWidget(self.c_btnSearch) + + self.mainGrid = QtWidgets.QVBoxLayout(self) + self.mainGrid.addLayout(self.lineGrid) + self.mainGrid.addWidget(self.c_tableInfo) + self.mainGrid.addWidget(self.c_btnDownload) + + self.c_btnSearch.clicked.connect(self.search) + self.c_btnDownload.clicked.connect(self.download) + self.s_downloadEnd.connect(self.downloadEnd) + + def addItem(self, rowIdx: int, colIdx: int, text): + if isinstance(text, str): + item = QtWidgets.QTableWidgetItem(text) + self.c_tableInfo.setItem(rowIdx, colIdx, item) + + def search(self): + self.c_tableInfo.setRowCount(0) - tmpData = TIDAL_API.getTypeData(tmpId, tmpType) - if tmpData is None: - self.__info__('Url is wrong!') + self.s_type = self.c_combType.currentData() + self.s_text = self.c_lineSearch.text() + if self.s_text.startswith('http'): + tmpType, tmpId = TIDAL_API.parseUrl(self.s_text) + if tmpType == Type.Null: + self.__info__('Url not support!') + return + elif tmpType not in self.m_supportType: + self.__info__(f'Type[{tmpType.name}] not support!') + return + + tmpData = TIDAL_API.getTypeData(tmpId, tmpType) + if tmpData is None: + self.__info__('Url is wrong!') + return + self.s_type = tmpType + self.s_array = [tmpData] + self.s_result = None + self.c_combType.setCurrentText(tmpType.name) + else: + self.s_result = TIDAL_API.search(self.s_text, self.s_type) + self.s_array = TIDAL_API.getSearchResultItems(self.s_result, self.s_type) + + if len(self.s_array) <= 0: + self.__info__('No result!') return - self.s_type = tmpType - self.s_array = [tmpData] - self.s_result = None - self.c_combType.setCurrentText(tmpType.name) - else: - self.s_result = TIDAL_API.search(self.s_text, self.s_type) - self.s_array = TIDAL_API.getSearchResultItems(self.s_result, self.s_type) - - if len(self.s_array) <= 0: - self.__info__('No result!') - return - self.c_tableInfo.setRowCount(len(self.s_array)) - for index, item in enumerate(self.s_array): - self.addItem(index, 0, str(index + 1)) - if self.s_type in [Type.Album, Type.Track]: - self.addItem(index, 1, item.title) - self.addItem(index, 2, TIDAL_API.getArtistsName(item.artists)) - self.addItem(index, 3, item.audioQuality) - elif self.s_type in [Type.Video]: - self.addItem(index, 1, item.title) - self.addItem(index, 2, TIDAL_API.getArtistsName(item.artists)) - self.addItem(index, 3, item.quality) - elif self.s_type in [Type.Playlist]: - self.addItem(index, 1, item.title) - self.addItem(index, 2, '') - self.addItem(index, 3, '') + self.c_tableInfo.setRowCount(len(self.s_array)) + for index, item in enumerate(self.s_array): + self.addItem(index, 0, str(index + 1)) + if self.s_type in [Type.Album, Type.Track]: + self.addItem(index, 1, item.title) + self.addItem(index, 2, TIDAL_API.getArtistsName(item.artists)) + self.addItem(index, 3, item.audioQuality) + elif self.s_type in [Type.Video]: + self.addItem(index, 1, item.title) + self.addItem(index, 2, TIDAL_API.getArtistsName(item.artists)) + self.addItem(index, 3, item.quality) + elif self.s_type in [Type.Playlist]: + self.addItem(index, 1, item.title) + self.addItem(index, 2, '') + self.addItem(index, 3, '') - def download(self): - index = self.c_tableInfo.currentIndex().row() - if index < 0: - self.__info__('Please select a row first.') - return + def download(self): + index = self.c_tableInfo.currentIndex().row() + if index < 0: + self.__info__('Please select a row first.') + return - self.c_btnDownload.setEnabled(False) - self.c_btnDownload.setText(f"Downloading [{self.s_array[index].title}]...") + self.c_btnDownload.setEnabled(False) + self.c_btnDownload.setText(f"Downloading [{self.s_array[index].title}]...") - def __thread_download__(model: MainView): - try: - type = model.s_type - item = model.s_array[index] - start_type(type, item) - model.s_downloadEnd.emit(item.title, True, '') - except Exception as e: - model.s_downloadEnd.emit(item.title, False, str(e)) + def __thread_download__(model: MainView): + try: + type = model.s_type + item = model.s_array[index] + start_type(type, item) + model.s_downloadEnd.emit(item.title, True, '') + except Exception as e: + model.s_downloadEnd.emit(item.title, False, str(e)) - _thread.start_new_thread(__thread_download__, (self, )) + _thread.start_new_thread(__thread_download__, (self, )) - def downloadEnd(self, title, result, msg): - self.c_btnDownload.setEnabled(True) - self.c_btnDownload.setText(f"Download") + def downloadEnd(self, title, result, msg): + self.c_btnDownload.setEnabled(True) + self.c_btnDownload.setText(f"Download") - if result: - self.__info__(f'Download [{title}] finish') - else: - self.__info__(f'Download [{title}] failed:{msg}') + if result: + self.__info__(f'Download [{title}] finish') + else: + self.__info__(f'Download [{title}] failed:{msg}') - def checkLogin(self): - if not loginByConfig(): - self.__info__('Login failed. Please log in using the command line first.') + def checkLogin(self): + if not loginByConfig(): + self.__info__('Login failed. Please log in using the command line first.') -def startGui(): - app = QtWidgets.QApplication(sys.argv) - apply_stylesheet(app, theme='dark_blue.xml') + def startGui(): + app = QtWidgets.QApplication(sys.argv) + apply_stylesheet(app, theme='dark_blue.xml') - window = MainView() - window.show() - window.checkLogin() - - app.exec_() + window = MainView() + window.show() + window.checkLogin() + app.exec_() +else: + def startGui(): + Printf.err("Not support gui. Please type: `pip3 install PyQt5 qt_material`") if __name__ == '__main__': SETTINGS.read(getProfilePath()) diff --git a/TIDALDL-PY/tidal_dl/printf.py b/TIDALDL-PY/tidal_dl/printf.py index f059eee..cab56b4 100644 --- a/TIDALDL-PY/tidal_dl/printf.py +++ b/TIDALDL-PY/tidal_dl/printf.py @@ -20,7 +20,7 @@ from tidal_dl.settings import * from tidal_dl.lang.language import * -VERSION = '2022.06.23.3' +VERSION = '2022.06.24.1' __LOGO__ = f''' /$$$$$$$$ /$$ /$$ /$$ /$$ /$$ |__ $$__/|__/ | $$ | $$ | $$| $$ diff --git a/TIDALDL-PY/upload.sh b/TIDALDL-PY/upload.sh deleted file mode 100644 index bff7988..0000000 --- a/TIDALDL-PY/upload.sh +++ /dev/null @@ -1,58 +0,0 @@ -cd TIDALDL-PY -rm -rf dist -rm -rf build -rm -rf exe/tidal-dl.exe -rm MANIFEST.in -rm -rf tidal_dl.egg-info -rm -rf tidal_gui.egg-info -rm -rf tidal_dl_test.egg-info -mkdir exe - -# pack -python setup.py sdist bdist_wheel -# creat exe file -pyinstaller -F tidal_dl/__init__.py -# rename exe name -mv dist/__init__.exe exe/tidal-dl.exe - -pip uninstall -y tidal-dl - -# creat requirements.txt -# pipreqs ./ --force --encoding=utf8 - -# python setup.py install - -# upload -twine upload dist/* - - - - - - - - - -cd TIDALDL-PY -rm -rf dist -rm -rf build -rm -rf exe/tidal-gui.exe -cp -rf guiStatic.in MANIFEST.in -rm -rf tidal_dl.egg-info -rm -rf tidal_gui.egg-info -rm -rf tidal_dl_test.egg-info - -# pack -python setup-gui.py sdist bdist_wheel -# creat exe file -pyinstaller -F tidal_gui/__init__.py -w -pyinstaller -F -w -p C:/Windows/System32/downlevel tidal_gui/__init__.py - - -# rename exe name -mv dist/__init__.exe exe/tidal-gui.exe - -pip uninstall -y tidal-gui - -# upload -twine upload dist/* diff --git a/build.sh b/build.sh new file mode 100644 index 0000000..9a94355 --- /dev/null +++ b/build.sh @@ -0,0 +1,20 @@ +rm -rf dist +rm -rf build +rm -rf __init__.spec + +cd TIDALDL-PY +rm -rf __init__.spec +rm -rf dist +rm -rf build +rm -rf exe +rm -rf MANIFEST.in +rm -rf *.egg-info + +python setup.py sdist bdist_wheel +pyinstaller -F tidal_dl/__init__.py +mkdir exe +mv dist/__init__.exe exe/tidal-dl.exe + +pip uninstall -y tidal-dl + +cd .. \ No newline at end of file diff --git a/logo.ico b/logo.ico deleted file mode 100644 index 7bb0245..0000000 Binary files a/logo.ico and /dev/null differ diff --git a/tidallog.png b/tidallog.png deleted file mode 100644 index 7f155a3..0000000 Binary files a/tidallog.png and /dev/null differ diff --git a/upload.sh b/upload.sh new file mode 100644 index 0000000..64e88f6 --- /dev/null +++ b/upload.sh @@ -0,0 +1,4 @@ +cd TIDALDL-PY +twine upload dist/* + +cd .. \ No newline at end of file