From 806e6e6ea450e83b077826b266de5616053ae90f Mon Sep 17 00:00:00 2001 From: Onlyacat233 Date: Sat, 12 Aug 2023 00:37:05 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E4=BA=86=E6=A0=B9?= =?UTF-8?q?=E6=8D=AE=E6=AD=8C=E5=8D=95=E4=B8=8B=E8=BD=BD=E7=9A=84=E5=8A=9F?= =?UTF-8?q?=E8=83=BD,=E4=BF=AE=E5=A4=8D=E4=BA=86=E5=A4=9A=E4=B8=AA?= =?UTF-8?q?=E9=9F=B3=E4=B9=90=E4=B8=80=E5=9D=97=E4=B8=8B=E8=BD=BD=E6=97=B6?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E5=90=8D=E6=A0=BC=E5=BC=8F=E6=97=A0=E6=95=88?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98,=E4=BC=98=E5=8C=96=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 增加了根据歌单下载的功能,修复了多个音乐一块下载时文件名格式无效的问题,优化代码 --- .gitignore | 4 ++ main.py | 37 +++++++------ .../mainly/download_multiple_songs.py | 15 +++++ modules/functions/mainly/get_playlist.py | 28 ++++++++++ modules/functions/mainly/get_song.py | 2 + modules/functions/mainly/multi_download.py | 13 +---- modules/functions/mainly/playlist_download.py | 45 +++++++++++++++ modules/submenus/settings.py | 55 ++++++++++--------- modules/utils/initapp.py | 12 +++- 9 files changed, 156 insertions(+), 55 deletions(-) create mode 100644 modules/functions/mainly/download_multiple_songs.py create mode 100644 modules/functions/mainly/get_playlist.py create mode 100644 modules/functions/mainly/playlist_download.py diff --git a/.gitignore b/.gitignore index 0716e7f..3874a1c 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,7 @@ modules/functions/mainly/__pycache__ modules/functions/settings/__pycache__ modules/submenus/__pycache__ modules/utils/__pycache__ + +node_modules +package.json +yarn.lock diff --git a/main.py b/main.py index ea6ffd9..eaa1e4a 100644 --- a/main.py +++ b/main.py @@ -15,6 +15,7 @@ from modules.submenus.settings import settings_menu from modules.functions.settings.save_load_settings import load_settings from modules.utils.clear_screen import cls_stay from modules.functions.mainly.load_file_song import get_lyric_from_folder +from modules.functions.mainly.playlist_download import download_by_playlist class MainProcess(object): @@ -29,27 +30,31 @@ class MainProcess(object): print_menu({ "0": "退出程序", "1": "单个歌曲的歌词下载", - "2": "多个歌曲的歌词下载", - "3": "从网易云下载的歌曲中获取歌词", + "2": "通过歌单下载", + "3": "多个歌曲的歌词下载", + "4": "从网易云下载的歌曲中获取歌词", "s": "进入设置", "i": "程序信息", }) r = rinput("请选择:") - if r == "1": - download_one_lyric(self) - elif r == "2": - mdl(self) - elif r == "3": - get_lyric_from_folder(self) - elif r == "0": - exit(0) - elif r == "i": - print_info(self) - elif r == "s": - settings_menu(self) - else: - input("请输入正确的选项\n按回车键继续...") + match r: + case "1": + download_one_lyric(self) + case "2": + download_by_playlist(self) + case "3": + mdl(self) + case "4": + get_lyric_from_folder(self) + case "0": + exit(0) + case "i": + print_info(self) + case "s": + settings_menu(self) + case _: + input("请输入正确的选项\n按回车键继续...") if __name__ == "__main__": diff --git a/modules/functions/mainly/download_multiple_songs.py b/modules/functions/mainly/download_multiple_songs.py new file mode 100644 index 0000000..73a7ce0 --- /dev/null +++ b/modules/functions/mainly/download_multiple_songs.py @@ -0,0 +1,15 @@ +from colorama import Fore + +from modules.utils.bar import CompactArrowBar +from modules.functions.mainly.get_song import get_song_lyric + +def donload_multiple_songs(self, lyric_path: str, ids): + with CompactArrowBar(f"进度: %(index){len(str(len(ids)))}d/%(max)d", + suffix="", max=len(ids), color="yellow", width=9999) as bar: + for i in range(0, len(ids)): + print(ids[i]) + r = get_song_lyric(ids[i], lyric_path, self.settings.lyric_format, bar=bar, save_lyrics_time = self.settings.save_lyrics_time) + if r == "dl_err_connection": + bar.print_onto_bar(Fore.RED + "下载发生错误!可能是连接被拒绝!请检查网络后再试\n按回车键继续任务(该任务会被跳过)...") + input() + bar.next() diff --git a/modules/functions/mainly/get_playlist.py b/modules/functions/mainly/get_playlist.py new file mode 100644 index 0000000..c3c8825 --- /dev/null +++ b/modules/functions/mainly/get_playlist.py @@ -0,0 +1,28 @@ +"""获取歌单中歌曲id""" +from typing import Dict, List +from requests import get +from json import loads + +headers = { + 'Referer':'http://music.163.com/', + 'Host':'music.163.com', + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.75 Safari/537.36', + 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8', +} + +def getplaylist(playlist_id: int | str, get_count: int | str = "all") -> Dict[str, str | List[str]]: + url1 = f"http://play.onlyacat233.top:10002/playlist/track/all?id={playlist_id}" + url2 = f"http://play.onlyacat233.top:10002/playlist/detail?id={playlist_id}" + context2 = loads(get(url2).text) + + context1 = loads(get(url1).text) + + playlist = [] + + for song in context1['songs']: + playlist.append(song['id']) + + return {"name": context2['playlist']['name'], "playlist": playlist} + +if __name__ == "__main__": + print(getplaylist("8134802489")) diff --git a/modules/functions/mainly/get_song.py b/modules/functions/mainly/get_song.py index 52c0af1..b5054bc 100644 --- a/modules/functions/mainly/get_song.py +++ b/modules/functions/mainly/get_song.py @@ -103,6 +103,8 @@ def get_song_lyric(identify: str | int | dict, bprint(Fore.YELLOW + "\t-> 歌曲:" + Style.RESET_ALL + f"{name} - {artists}", bar) filename = f"{lyric_format % {'name': name, 'artists': artists}}.lrc" + if len(filename) >= 128: + filename = filename[:123] + ".lrc" try: info = post(f"https://music.163.com/api/song/media?id={identify}").json() diff --git a/modules/functions/mainly/multi_download.py b/modules/functions/mainly/multi_download.py index 92ca3a4..db74289 100644 --- a/modules/functions/mainly/multi_download.py +++ b/modules/functions/mainly/multi_download.py @@ -3,8 +3,7 @@ from colorama import Fore from modules.utils.clear_screen import cls_stay from modules.utils.inputs import rinput -from modules.functions.mainly.get_song import get_song_lyric -from modules.utils.bar import CompactArrowBar +from modules.functions.mainly.download_multiple_songs import donload_multiple_songs def mdl(self): @@ -31,12 +30,6 @@ def mdl(self): ids.append(int(r)) print("\t#%d id:%s - 已添加!" % (len(ids), r)) cls_stay(self, "[手动-多个下载]") - with CompactArrowBar(f"进度: %(index){len(str(len(ids)))}d/%(max)d", - suffix="", max=len(ids), color="yellow", width=9999) as bar: - for i in range(0, len(ids)): - r = get_song_lyric(ids[i], self.settings.lyric_path, self.settings.lyric_path, bar=bar) - if r == "dl_err_connection": - bar.print_onto_bar(Fore.RED + "下载发生错误!可能是连接被拒绝!请检查网络后再试\n按回车键继续任务(该任务会被跳过)...") - input() - bar.next() + donload_multiple_songs(self, self.settings.lyric_path, ids) + input("按回车键返回...") diff --git a/modules/functions/mainly/playlist_download.py b/modules/functions/mainly/playlist_download.py new file mode 100644 index 0000000..648e611 --- /dev/null +++ b/modules/functions/mainly/playlist_download.py @@ -0,0 +1,45 @@ +import re +from modules.utils.inputs import rinput +from modules.functions.mainly.get_playlist import getplaylist +from modules.utils.clear_screen import clear +from modules.functions.mainly.download_multiple_songs import donload_multiple_songs +from os.path import sep +from modules.utils.initapp import mkdir + +def download_by_playlist(self) -> None: + """ + 按照歌单id获取歌词 + + :params: path: str 存储歌词的路径 + + :return: None + + """ + clear() + playlist_id = rinput( + f"[NeteaseMusicLyricDownloader] {self.version}\n" + "[手动-歌单下载]\n" + "请输入歌曲id:") + try: + int(playlist_id) + except ValueError: + r = re.search("playlist\?id=[0-9]*", playlist_id) + if r: + playlist_id = r.group()[12:] + else: + input("不合法的形式.\n按回车键返回...") + return + + playlist = getplaylist(playlist_id) + + if not playlist["playlist"]: + print("改歌单为空集,下载停止!") + input() + return + + if mkdir(self.settings.lyric_path+sep+playlist["name"]): + print("歌单文件夹已存在") + + donload_multiple_songs(self, self.settings.lyric_path+sep+playlist["name"], playlist["playlist"]) + input("按回车键返回...") + diff --git a/modules/submenus/settings.py b/modules/submenus/settings.py index 56883a9..4b34e6d 100644 --- a/modules/submenus/settings.py +++ b/modules/submenus/settings.py @@ -56,19 +56,21 @@ def __remove_output_files(self): "2": "清除歌曲文件", "a": "清除所有文件", }) # 选择清除的文件格式 - if r == "0": - return - elif r == "1": - dellist = [".lrc"] - break - elif r == "2": - dellist = [".mp3", ".flac"] - break - elif r == "a": - dellist = ["ALL"] - break - else: - input("输入无效!\n按回车键继续...") + + match r: + case "0": + return + case "1": + dellist = [".lrc"] + break + case "2": + dellist = [".mp3", ".flac"] + break + case "a": + dellist = ["ALL"] + break + case _: + input("输入无效!\n按回车键继续...") files = [] for i in os.listdir(self.settings.lyric_path): # 列出所有文件 if dellist[0] == "ALL": @@ -133,18 +135,19 @@ def __set_lyric_filename_format(self): "2": "%(artists)s - %(name)s" % {"name": "曲名", "artists": "歌手名"}, "3": "%(name)s" % {"name": "曲名", "artists": "歌手名"}, }) - if r == "0": - return - elif r == "1": - self.settings.lyric_format = "%(name)s - %(artists)s" - break - elif r == "2": - self.settings.lyric_format = "%(artists)s - %(name)s" - break - elif r == "3": - self.settings.lyric_format = "%(name)s" - break - else: - input("输入无效!\n按回车继续...") + match r: + case "0": + return + case "1": + self.settings.lyric_format = "%(name)s - %(artists)s" + break + case "2": + self.settings.lyric_format = "%(artists)s - %(name)s" + break + case "3": + self.settings.lyric_format = "%(name)s" + break + case _: + input("输入无效!\n按回车继续...") input("修改成功! \n按回车返回...") return diff --git a/modules/utils/initapp.py b/modules/utils/initapp.py index f05f380..8295e09 100644 --- a/modules/utils/initapp.py +++ b/modules/utils/initapp.py @@ -1,11 +1,17 @@ -from os import mkdir +from os import mkdir as raw_mkdir from os.path import exists INIT_DIRECTORIES = [ 'out' ] +def mkdir(dirpath: str) -> bool: + if not exists(dirpath): + raw_mkdir(dirpath) + + return [True if exists(dirpath) else False][0] + + def init_directories(): for dir_name in INIT_DIRECTORIES: - if not exists(dir_name): - mkdir(dir_name) + mkdir(dir_name)