From 028d237d96c893c092c63f1150fbfc3d12bec507 Mon Sep 17 00:00:00 2001 From: Weiliang Li Date: Mon, 18 Jan 2021 22:45:45 +0900 Subject: [PATCH] fix login (#901) --- .gitignore | 2 + NEMbox/api.py | 14 +-- NEMbox/cmd_parser.py | 26 +++--- NEMbox/menu.py | 209 ++++++++++++++++++++++--------------------- NEMbox/storage.py | 7 +- NEMbox/ui.py | 4 +- NEMbox/utils.py | 15 +++- README.md | 140 +++++++++++++++-------------- pyproject.toml | 2 +- setup.cfg | 2 +- 10 files changed, 219 insertions(+), 202 deletions(-) diff --git a/.gitignore b/.gitignore index b5b1247c..378ac1db 100644 --- a/.gitignore +++ b/.gitignore @@ -149,3 +149,5 @@ nemcache.sqlite .undodir Session.vim .vim + +test_login.py diff --git a/NEMbox/api.py b/NEMbox/api.py index dfd130da..8880c7cf 100644 --- a/NEMbox/api.py +++ b/NEMbox/api.py @@ -278,7 +278,7 @@ def __init__(self): "Content-Type": "application/x-www-form-urlencoded", "Host": "music.163.com", "Referer": "http://music.163.com", - "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36", + "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 11_1_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.87 Safari/537.36", } self.storage = Storage() @@ -383,17 +383,11 @@ def login(self, username, password): rememberLogin="true", ) else: - # magic token for login - # see https://github.com/Binaryify/NeteaseCloudMusicApi/blob/master/router/login.js#L15 - client_token = ( - "1_jVUMqWEPke0/1/Vu56xCmJpo5vP1grjn_SOVVDzOc78w8OKLVZ2JH7IfkjSXqgfmh" - ) path = "/weapi/login" params = dict( username=username, password=password, rememberLogin="true", - clientToken=client_token, ) data = self.request("POST", path, params, custom_cookies={"os": "pc"}) self.session.cookies.save() @@ -408,7 +402,7 @@ def daily_task(self, is_mobile=True): # 用户歌单 def user_playlist(self, uid, offset=0, limit=50): path = "/weapi/user/playlist" - params = dict(uid=uid, offset=offset, limit=limit, csrf_token="") + params = dict(uid=uid, offset=offset, limit=limit) return self.request("POST", path, params).get("playlist", []) # 每日推荐歌单 @@ -418,8 +412,8 @@ def recommend_resource(self): # 每日推荐歌曲 def recommend_playlist(self, total=True, offset=0, limit=20): - path = "/weapi/v1/discovery/recommend/songs" # NOQA - params = dict(total=total, offset=offset, limit=limit, csrf_token="") + path = "/weapi/v1/discovery/recommend/songs" + params = dict(total=total, offset=offset, limit=limit) return self.request("POST", path, params).get("recommend", []) # 私人FM diff --git a/NEMbox/cmd_parser.py b/NEMbox/cmd_parser.py index 1b0ff165..c73b1f63 100644 --- a/NEMbox/cmd_parser.py +++ b/NEMbox/cmd_parser.py @@ -14,7 +14,7 @@ __all__ = ["cmd_parser", "parse_keylist", "coroutine", "erase_coroutine"] -keyMap = Config().get("keymap") +KEY_MAP = Config().get("keymap") def coroutine(func): @@ -40,7 +40,7 @@ def _cmd_parser(): keylist.append(key) elif key > 0 and pre_key > 0: keylist.append(key) - elif curses.keyname(key).decode("utf-8") in keyMap.values() and pre_key > 0: + elif curses.keyname(key).decode("utf-8") in KEY_MAP.values() and pre_key > 0: keylist.append(key) return keylist pre_key = key @@ -83,16 +83,16 @@ def parse_keylist(keylist): keylist = deepcopy(keylist) if keylist == []: return None - if (set(keylist) | {ord(keyMap["prevSong"]), ord(keyMap["nextSong"])}) == { - ord(keyMap["prevSong"]), - ord(keyMap["nextSong"]), + if (set(keylist) | {ord(KEY_MAP["prevSong"]), ord(KEY_MAP["nextSong"])}) == { + ord(KEY_MAP["prevSong"]), + ord(KEY_MAP["nextSong"]), }: - delta_key = keylist.count(ord(keyMap["nextSong"])) - keylist.count( - ord(keyMap["prevSong"]) + delta_key = keylist.count(ord(KEY_MAP["nextSong"])) - keylist.count( + ord(KEY_MAP["prevSong"]) ) if delta_key < 0: - return (-delta_key, ord(keyMap["prevSong"])) - return (delta_key, ord(keyMap["nextSong"])) + return (-delta_key, ord(KEY_MAP["prevSong"])) + return (delta_key, ord(KEY_MAP["nextSong"])) tail_cmd = keylist.pop() if tail_cmd in range(48, 58) and (set(keylist) | set(range(48, 58))) == set( range(48, 58) @@ -104,10 +104,10 @@ def parse_keylist(keylist): if ( tail_cmd in ( - ord(keyMap["prevSong"]), - ord(keyMap["nextSong"]), - ord(keyMap["down"]), - ord(keyMap["up"]), + ord(KEY_MAP["prevSong"]), + ord(KEY_MAP["nextSong"]), + ord(KEY_MAP["down"]), + ord(KEY_MAP["up"]), ) and max(keylist) <= 57 and min(keylist) >= 48 diff --git a/NEMbox/menu.py b/NEMbox/menu.py index 6b5bf404..82261127 100644 --- a/NEMbox/menu.py +++ b/NEMbox/menu.py @@ -54,57 +54,57 @@ def carousel(left, right, x): return x -keyMap = Config().get("keymap") -commandList = list(map(ord, keyMap.values())) +KEY_MAP = Config().get("keymap") +COMMAND_LIST = list(map(ord, KEY_MAP.values())) if Config().get("mouse_movement"): - keyMap["mouseUp"] = 259 - keyMap["mouseDown"] = 258 + KEY_MAP["mouseUp"] = 259 + KEY_MAP["mouseDown"] = 258 else: - keyMap["mouseUp"] = -259 - keyMap["mouseDown"] = -258 + KEY_MAP["mouseUp"] = -259 + KEY_MAP["mouseDown"] = -258 shortcut = [ - [keyMap["down"], "Down", "下移"], - [keyMap["up"], "Up", "上移"], - ["+" + keyMap["up"], " Up", "上移num"], - ["+" + keyMap["down"], " Down", "下移num"], - [keyMap["back"], "Back", "后退"], - [keyMap["forward"], "Forward", "前进"], - [keyMap["prevPage"], "Prev page", "上一页"], - [keyMap["nextPage"], "Next page", "下一页"], - [keyMap["search"], "Search", "快速搜索"], - [keyMap["prevSong"], "Prev song", "上一曲"], - [keyMap["nextSong"], "Next song", "下一曲"], - ["+" + keyMap["nextSong"], " Next Song", "下num曲"], - ["+" + keyMap["prevSong"], " Prev song", "上num曲"], + [KEY_MAP["down"], "Down", "下移"], + [KEY_MAP["up"], "Up", "上移"], + ["+" + KEY_MAP["up"], " Up", "上移num"], + ["+" + KEY_MAP["down"], " Down", "下移num"], + [KEY_MAP["back"], "Back", "后退"], + [KEY_MAP["forward"], "Forward", "前进"], + [KEY_MAP["prevPage"], "Prev page", "上一页"], + [KEY_MAP["nextPage"], "Next page", "下一页"], + [KEY_MAP["search"], "Search", "快速搜索"], + [KEY_MAP["prevSong"], "Prev song", "上一曲"], + [KEY_MAP["nextSong"], "Next song", "下一曲"], + ["+" + KEY_MAP["nextSong"], " Next Song", "下num曲"], + ["+" + KEY_MAP["prevSong"], " Prev song", "上num曲"], ["", "Goto song ", "跳转指定歌曲id"], - [keyMap["playPause"], "Play/Pause", "播放/暂停"], - [keyMap["shuffle"], "Shuffle", "手气不错"], - [keyMap["volume+"], "Volume+", "音量增加"], - [keyMap["volume-"], "Volume-", "音量减少"], - [keyMap["menu"], "Menu", "主菜单"], - [keyMap["presentHistory"], "Present/History", "当前/历史播放列表"], - [keyMap["musicInfo"], "Music Info", "当前音乐信息"], - [keyMap["playingMode"], "Playing Mode", "播放模式切换"], - [keyMap["enterAlbum"], "Enter album", "进入专辑"], - [keyMap["add"], "Add", "添加曲目到打碟"], - [keyMap["djList"], "DJ list", "打碟列表(退出后清空)"], - [keyMap["star"], "Star", "添加到本地收藏"], - [keyMap["collection"], "Collection", "本地收藏列表"], - [keyMap["remove"], "Remove", "删除当前条目"], - [keyMap["moveDown"], "Move Down", "向下移动当前条目"], - [keyMap["moveUp"], "Move Up", "向上移动当前条目"], - [keyMap["like"], "Like", "喜爱"], - [keyMap["cache"], "Cache", "缓存歌曲到本地"], - [keyMap["nextFM"], "Next FM", "下一 FM"], - [keyMap["trashFM"], "Trash FM", "删除 FM"], - [keyMap["quit"], "Quit", "退出"], - [keyMap["quitClear"], "Quit&Clear", "退出并清除用户信息"], - [keyMap["help"], "Help", "帮助"], - [keyMap["top"], "Top", "回到顶部"], - [keyMap["bottom"], "Bottom", "跳转到底部"], - [keyMap["countDown"], "Count Down", "定时"], + [KEY_MAP["playPause"], "Play/Pause", "播放/暂停"], + [KEY_MAP["shuffle"], "Shuffle", "手气不错"], + [KEY_MAP["volume+"], "Volume+", "音量增加"], + [KEY_MAP["volume-"], "Volume-", "音量减少"], + [KEY_MAP["menu"], "Menu", "主菜单"], + [KEY_MAP["presentHistory"], "Present/History", "当前/历史播放列表"], + [KEY_MAP["musicInfo"], "Music Info", "当前音乐信息"], + [KEY_MAP["playingMode"], "Playing Mode", "播放模式切换"], + [KEY_MAP["enterAlbum"], "Enter album", "进入专辑"], + [KEY_MAP["add"], "Add", "添加曲目到打碟"], + [KEY_MAP["djList"], "DJ list", "打碟列表(退出后清空)"], + [KEY_MAP["star"], "Star", "添加到本地收藏"], + [KEY_MAP["collection"], "Collection", "本地收藏列表"], + [KEY_MAP["remove"], "Remove", "删除当前条目"], + [KEY_MAP["moveDown"], "Move Down", "向下移动当前条目"], + [KEY_MAP["moveUp"], "Move Up", "向上移动当前条目"], + [KEY_MAP["like"], "Like", "喜爱"], + [KEY_MAP["cache"], "Cache", "缓存歌曲到本地"], + [KEY_MAP["nextFM"], "Next FM", "下一 FM"], + [KEY_MAP["trashFM"], "Trash FM", "删除 FM"], + [KEY_MAP["quit"], "Quit", "退出"], + [KEY_MAP["quitClear"], "Quit&Clear", "退出并清除用户信息"], + [KEY_MAP["help"], "Help", "帮助"], + [KEY_MAP["top"], "Top", "回到顶部"], + [KEY_MAP["bottom"], "Bottom", "跳转到底部"], + [KEY_MAP["countDown"], "Count Down", "定时"], ] @@ -194,7 +194,7 @@ def login(self): else: self.storage.logout() x = self.ui.build_login_error() - if x >= 0 and C.keyname(x).decode("utf-8") != keyMap["forward"]: + if x >= 0 and C.keyname(x).decode("utf-8") != KEY_MAP["forward"]: return False return self.login() @@ -214,12 +214,12 @@ def in_place_search(self): search_result = process.extract( keyword, self.datalist, limit=max(10, 2 * self.step) ) + if not search_result: + return search_result, keyword + search_result.sort(key=lambda ele: ele[1], reverse=True) + return (list(map(lambda ele: ele[0], search_result)), keyword) except Exception as e: log.warn(e) - if not search_result: - return search_result, keyword - search_result.sort(key=lambda ele: ele[1], reverse=True) - return (list(map(lambda ele: ele[0], search_result)), keyword) def search(self, category): self.ui.screen.timeout(-1) @@ -471,15 +471,15 @@ def num_jump_key_event(self): if num == 0: # 0j -> 1j num = 1 for _ in range(num): - if cmd in (keyMap["mouseUp"], ord(keyMap["up"])): + if cmd in (KEY_MAP["mouseUp"], ord(KEY_MAP["up"])): self.up_key_event() - elif cmd in (keyMap["mouseDown"], ord(keyMap["down"])): + elif cmd in (KEY_MAP["mouseDown"], ord(KEY_MAP["down"])): self.down_key_event() - elif cmd == ord(keyMap["nextSong"]): + elif cmd == ord(KEY_MAP["nextSong"]): self.next_key_event() - elif cmd == ord(keyMap["prevSong"]): + elif cmd == ord(KEY_MAP["prevSong"]): self.prev_key_event() - if cmd in (ord(keyMap["nextSong"]), ord(keyMap["prevSong"])): + if cmd in (ord(KEY_MAP["nextSong"]), ord(KEY_MAP["prevSong"])): self.player.stop() self.player.replay() self.build_menu_processbar() @@ -604,28 +604,29 @@ def start(self): key = self.screen.getch() if ( - key in commandList - and key != ord(keyMap["nextSong"]) - and key != ord(keyMap["prevSong"]) + key in COMMAND_LIST + and key != ord(KEY_MAP["nextSong"]) + and key != ord(KEY_MAP["prevSong"]) ): if not ( ( set(self.pre_keylist) - | {ord(keyMap["prevSong"]), ord(keyMap["nextSong"])} + | {ord(KEY_MAP["prevSong"]), ord(KEY_MAP["nextSong"])} ) - == {ord(keyMap["prevSong"]), ord(keyMap["nextSong"])} + == {ord(KEY_MAP["prevSong"]), ord(KEY_MAP["nextSong"])} ): self.pre_keylist.append(key) self.key_list = deepcopy(self.pre_keylist) self.pre_keylist.clear() elif ( key in range(48, 58) - or key == ord(keyMap["nextSong"]) - or key == ord(keyMap["prevSong"]) + or key == ord(KEY_MAP["nextSong"]) + or key == ord(KEY_MAP["prevSong"]) ): self.pre_keylist.append(key) elif key == -1 and ( - pre_key == ord(keyMap["nextSong"]) or pre_key == ord(keyMap["prevSong"]) + pre_key == ord(KEY_MAP["nextSong"]) + or pre_key == ord(KEY_MAP["prevSong"]) ): self.key_list = deepcopy(self.pre_keylist) self.pre_keylist.clear() @@ -638,8 +639,8 @@ def start(self): # 如果 keylist 全都是数字 + G if keylist and ( - set(keylist) | set(range(48, 58)) | {ord(keyMap["jumpIndex"])} - ) == set(range(48, 58)) | {ord(keyMap["jumpIndex"])}: + set(keylist) | set(range(48, 58)) | {ord(KEY_MAP["jumpIndex"])} + ) == set(range(48, 58)) | {ord(KEY_MAP["jumpIndex"])}: # 歌曲数字映射 self.digit_key_song_event() self.key_list.clear() @@ -647,8 +648,8 @@ def start(self): # 如果 keylist 只有 [ ] if len(keylist) > 0 and ( - set(keylist) | {ord(keyMap["prevSong"]), ord(keyMap["nextSong"])} - ) == {ord(keyMap["prevSong"]), ord(keyMap["nextSong"])}: + set(keylist) | {ord(KEY_MAP["prevSong"]), ord(KEY_MAP["nextSong"])} + ) == {ord(KEY_MAP["prevSong"]), ord(KEY_MAP["nextSong"])}: self.player.stop() self.player.replay() self.key_list.clear() @@ -667,52 +668,52 @@ def start(self): self.player.update_size() # 退出 - elif C.keyname(key).decode("utf-8") == keyMap["quit"]: + elif C.keyname(key).decode("utf-8") == KEY_MAP["quit"]: if pyqt_activity: stop_lyrics_process() break # 退出并清除用户信息 - elif C.keyname(key).decode("utf-8") == keyMap["quitClear"]: + elif C.keyname(key).decode("utf-8") == KEY_MAP["quitClear"]: if pyqt_activity: stop_lyrics_process() self.api.logout() break # 上移 - elif C.keyname(key).decode("utf-8") == keyMap[ + elif C.keyname(key).decode("utf-8") == KEY_MAP[ "up" ] and pre_key not in range(ord("0"), ord("9")): self.up_key_event() - elif self.config.get("mouse_movement") and key == keyMap["mouseUp"]: + elif self.config.get("mouse_movement") and key == KEY_MAP["mouseUp"]: self.up_key_event() # 下移 - elif C.keyname(key).decode("utf-8") == keyMap[ + elif C.keyname(key).decode("utf-8") == KEY_MAP[ "down" ] and pre_key not in range(ord("0"), ord("9")): self.down_key_event() - elif self.config.get("mouse_movement") and key == keyMap["mouseDown"]: + elif self.config.get("mouse_movement") and key == KEY_MAP["mouseDown"]: self.down_key_event() # 向上翻页 - elif C.keyname(key).decode("utf-8") == keyMap["prevPage"]: + elif C.keyname(key).decode("utf-8") == KEY_MAP["prevPage"]: self.up_page_event() # 向下翻页 - elif C.keyname(key).decode("utf-8") == keyMap["nextPage"]: + elif C.keyname(key).decode("utf-8") == KEY_MAP["nextPage"]: self.down_page_event() # 前进 - elif C.keyname(key).decode("utf-8") == keyMap["forward"] or key == 10: + elif C.keyname(key).decode("utf-8") == KEY_MAP["forward"] or key == 10: self.enter_page_event() # 回退 - elif C.keyname(key).decode("utf-8") == keyMap["back"]: + elif C.keyname(key).decode("utf-8") == KEY_MAP["back"]: self.back_page_event() # 模糊搜索 - elif C.keyname(key).decode("utf-8") == keyMap["search"]: + elif C.keyname(key).decode("utf-8") == KEY_MAP["search"]: if self.at_search_result: self.back_page_event() self.stack.append( @@ -725,33 +726,33 @@ def start(self): self.at_search_result = True # 播放下一曲 - elif C.keyname(key).decode("utf-8") == keyMap[ + elif C.keyname(key).decode("utf-8") == KEY_MAP[ "nextSong" ] and pre_key not in range(ord("0"), ord("9")): self.next_key_event() # 播放上一曲 - elif C.keyname(key).decode("utf-8") == keyMap[ + elif C.keyname(key).decode("utf-8") == KEY_MAP[ "prevSong" ] and pre_key not in range(ord("0"), ord("9")): self.prev_key_event() # 增加音量 - elif C.keyname(key).decode("utf-8") == keyMap["volume+"]: + elif C.keyname(key).decode("utf-8") == KEY_MAP["volume+"]: self.player.volume_up() # 减少音量 - elif C.keyname(key).decode("utf-8") == keyMap["volume-"]: + elif C.keyname(key).decode("utf-8") == KEY_MAP["volume-"]: self.player.volume_down() # 随机播放 - elif C.keyname(key).decode("utf-8") == keyMap["shuffle"]: + elif C.keyname(key).decode("utf-8") == KEY_MAP["shuffle"]: if len(self.player.info["player_list"]) == 0: continue self.player.shuffle() # 喜爱 - elif C.keyname(key).decode("utf-8") == keyMap["like"]: + elif C.keyname(key).decode("utf-8") == KEY_MAP["like"]: return_data = self.request_api(self.api.fm_like, self.player.playing_id) if return_data: song_name = self.player.playing_name @@ -760,7 +761,7 @@ def start(self): notify("Adding song failed!", 0) # 删除FM - elif C.keyname(key).decode("utf-8") == keyMap["trashFM"]: + elif C.keyname(key).decode("utf-8") == KEY_MAP["trashFM"]: if self.datatype == "fmsongs": if len(self.player.info["player_list"]) == 0: continue @@ -772,7 +773,7 @@ def start(self): notify("Deleted successfully!", 0) # 更多FM - elif C.keyname(key).decode("utf-8") == keyMap["nextFM"]: + elif C.keyname(key).decode("utf-8") == KEY_MAP["nextFM"]: if self.datatype == "fmsongs": # if len(self.player.info['player_list']) == 0: # continue @@ -785,22 +786,22 @@ def start(self): self.offset = self.index - self.index % self.step # 播放、暂停 - elif C.keyname(key).decode("utf-8") == keyMap["playPause"]: + elif C.keyname(key).decode("utf-8") == KEY_MAP["playPause"]: if self.at_search_result: self.space_key_event_in_search_result() else: self.space_key_event() # 加载当前播放列表 - elif C.keyname(key).decode("utf-8") == keyMap["presentHistory"]: + elif C.keyname(key).decode("utf-8") == KEY_MAP["presentHistory"]: self.show_playing_song() # 播放模式切换 - elif C.keyname(key).decode("utf-8") == keyMap["playingMode"]: + elif C.keyname(key).decode("utf-8") == KEY_MAP["playingMode"]: self.player.change_mode() # 进入专辑 - elif C.keyname(key).decode("utf-8") == keyMap["enterAlbum"]: + elif C.keyname(key).decode("utf-8") == KEY_MAP["enterAlbum"]: if datatype == "album": continue if datatype in ["songs", "fmsongs"]: @@ -827,14 +828,14 @@ def start(self): break # 添加到打碟歌单 - elif C.keyname(key).decode("utf-8") == keyMap["add"]: + elif C.keyname(key).decode("utf-8") == KEY_MAP["add"]: if datatype == "songs" and len(datalist) != 0: self.djstack.append(datalist[idx]) elif datatype == "artists": pass # 加载打碟歌单 - elif C.keyname(key).decode("utf-8") == keyMap["djList"]: + elif C.keyname(key).decode("utf-8") == KEY_MAP["djList"]: self.stack.append( [self.datatype, self.title, self.datalist, self.offset, self.index] ) @@ -845,7 +846,7 @@ def start(self): self.index = 0 # 添加到本地收藏 - elif C.keyname(key).decode("utf-8") == keyMap["star"]: + elif C.keyname(key).decode("utf-8") == KEY_MAP["star"]: if (self.datatype == "songs" or self.datatype == "djchannels") and len( self.datalist ) != 0: @@ -853,7 +854,7 @@ def start(self): notify("Added successfully", 0) # 加载本地收藏 - elif C.keyname(key).decode("utf-8") == keyMap["collection"]: + elif C.keyname(key).decode("utf-8") == KEY_MAP["collection"]: self.stack.append( [self.datatype, self.title, self.datalist, self.offset, self.index] ) @@ -864,7 +865,7 @@ def start(self): self.index = 0 # 从当前列表移除 - elif C.keyname(key).decode("utf-8") == keyMap["remove"]: + elif C.keyname(key).decode("utf-8") == KEY_MAP["remove"]: if ( self.datatype in ("songs", "djchannels", "fmsongs") and len(self.datalist) != 0 @@ -881,11 +882,11 @@ def start(self): ) # 倒计时 - elif C.keyname(key).decode("utf-8") == keyMap["countDown"]: + elif C.keyname(key).decode("utf-8") == KEY_MAP["countDown"]: self.time_key_event() # 当前项目下移 - elif C.keyname(key).decode("utf-8") == keyMap["moveDown"]: + elif C.keyname(key).decode("utf-8") == KEY_MAP["moveDown"]: if ( self.datatype != "main" and len(self.datalist) != 0 @@ -900,7 +901,7 @@ def start(self): self.offset = self.offset + self.step # 当前项目上移 - elif C.keyname(key).decode("utf-8") == keyMap["moveUp"]: + elif C.keyname(key).decode("utf-8") == KEY_MAP["moveUp"]: if ( self.datatype != "main" and len(self.datalist) != 0 @@ -915,7 +916,7 @@ def start(self): self.offset = self.offset - self.step # 菜单 - elif C.keyname(key).decode("utf-8") == keyMap["menu"]: + elif C.keyname(key).decode("utf-8") == KEY_MAP["menu"]: if self.datatype != "main": self.stack.append( [ @@ -930,7 +931,7 @@ def start(self): self.offset = 0 self.index = 0 # 跳到开头 g键 - elif C.keyname(key).decode("utf-8") == keyMap["top"]: + elif C.keyname(key).decode("utf-8") == KEY_MAP["top"]: if self.datatype == "help": webbrowser.open_new_tab("https://github.com/darknessomi/musicbox") else: @@ -938,12 +939,12 @@ def start(self): self.offset = 0 # 跳到末尾ord('G') 键 - elif C.keyname(key).decode("utf-8") == keyMap["bottom"]: + elif C.keyname(key).decode("utf-8") == KEY_MAP["bottom"]: self.index = len(self.datalist) - 1 self.offset = self.index - self.index % self.step # 开始下载 - elif C.keyname(key).decode("utf-8") == keyMap["cache"]: + elif C.keyname(key).decode("utf-8") == KEY_MAP["cache"]: s = self.datalist[self.index] cache_thread = threading.Thread( target=self.player.cache_song, @@ -951,7 +952,7 @@ def start(self): ) cache_thread.start() # 在网页打开 ord(i) - elif C.keyname(key).decode("utf-8") == keyMap["musicInfo"]: + elif C.keyname(key).decode("utf-8") == KEY_MAP["musicInfo"]: if self.player.playing_id != -1: webbrowser.open_new_tab( "http://music.163.com/song?id={}".format(self.player.playing_id) @@ -1213,6 +1214,8 @@ def choice_channel(self, idx): self.title += " > 精选歌单" self.datatype = "recommend_lists" elif idx == 4: + if not self.account: + self.login() myplaylist = self.request_api(self.api.user_playlist, self.userid) self.datatype = "top_playlists" self.datalist = self.api.dig_info(myplaylist, self.datatype) diff --git a/NEMbox/storage.py b/NEMbox/storage.py index 4c4a3933..5756a833 100644 --- a/NEMbox/storage.py +++ b/NEMbox/storage.py @@ -73,7 +73,10 @@ def __init__(self): def login(self, username, password, userid, nickname): self.database["user"] = dict( - username=username, password=password, user_id=userid, nickname=nickname + username=username, + password=password, + user_id=userid, + nickname=nickname, ) def logout(self): @@ -92,7 +95,7 @@ def load(self): self.database[k].update(v) else: self.database[k] = v - except (OSError, KeyError, ValueError) as e: + except (OSError, KeyError, ValueError): pass self.save() diff --git a/NEMbox/ui.py b/NEMbox/ui.py index f596845c..f2b44b0f 100644 --- a/NEMbox/ui.py +++ b/NEMbox/ui.py @@ -10,7 +10,6 @@ """ import curses import datetime -import hashlib import os import re from shutil import get_terminal_size @@ -21,6 +20,7 @@ from .scrollstring import truelen from .scrollstring import truelen_cut from .storage import Storage +from .utils import md5 log = logger.getLogger(__name__) @@ -693,7 +693,7 @@ def build_login(self): curses.curs_set(0) self.build_login_bar() account = self.get_account() - password = hashlib.md5(self.get_password().encode("utf-8")).hexdigest() + password = md5(self.get_password()) return account, password def build_login_bar(self): diff --git a/NEMbox/utils.py b/NEMbox/utils.py index ae87dfdd..79da8df8 100644 --- a/NEMbox/utils.py +++ b/NEMbox/utils.py @@ -8,10 +8,23 @@ import os import platform import subprocess +import hashlib + from collections import OrderedDict -__all__ = ["utf8_data_to_file", "notify", "uniq", "create_dir", "create_file"] +__all__ = [ + "utf8_data_to_file", + "notify", + "uniq", + "create_dir", + "create_file", + "md5", +] + + +def md5(s): + return hashlib.md5(s.encode("utf-8")).hexdigest() def mkdir(path): diff --git a/README.md b/README.md index 2e97807e..955194a5 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ **感谢为 MusicBox 的开发付出过努力的[每一个人](https://github.com/darknessomi/musicbox/graphs/contributors)!** -高品质网易云音乐命令行版本,简洁优雅,丝般顺滑,基于Python编写。 +高品质网易云音乐命令行版本,简洁优雅,丝般顺滑,基于 Python 编写。 [![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg)](LICENSE) [![versions](https://img.shields.io/pypi/v/NetEase-MusicBox.svg)](https://pypi.org/project/NetEase-MusicBox/) @@ -14,21 +14,21 @@ ## 功能特性 -1. 320kbps的高品质音乐 +1. 320kbps 的高品质音乐 2. 歌曲,艺术家,专辑检索 -3. 网易22个歌曲排行榜 +3. 网易 22 个歌曲排行榜 4. 网易新碟推荐 5. 网易精选歌单 6. 网易主播电台 7. 私人歌单,每日推荐 8. 随心打碟 -9. 本地收藏,随时加❤ +9. 本地收藏,随时加 ❤ 10. 播放进度及播放模式显示 11. 现在播放及桌面歌词显示 12. 歌曲评论显示 13. 一键进入歌曲专辑 14. 定时退出 -15. Vimer式快捷键让操作丝般顺滑 +15. Vimer 式快捷键让操作丝般顺滑 16. 可使用数字快捷键 17. 可使用自定义全局快捷键 18. 对当前歌单列表进行本地模糊搜索 @@ -37,47 +37,47 @@ 有 num + 字样的快捷键可以用数字修饰,按键顺序为先输入数字再键入被修饰的键,即 num + 后的快捷键。 -| Key | Effect | | -| --------- | --------------- | ------------------ | -| j | Down | 下移 | -| k | Up | 上移 | -| num + j | Quick Jump | 快速向后跳转n首 | -| num + k | Quick Up | 快速向前跳转n首 | -| h | Back | 后退 | -| l | Forword | 前进 | -| u | Prev Page | 上一页 | -| d | Next Page | 下一页 | -| f | Search | 当前列表模糊搜索 | -| \[ | Prev Song | 上一曲 | -| ] | Next Song | 下一曲 | -| num + \[ | Quick Prev Song | 快速前n首 | -| num + ] | Quick Next Song | 快速后n首 | -| num + Shift + g | Index for Song | 跳到第n首 | -| = | Volume + | 音量增加 | -| - | Volume - | 音量减少 | -| Space | Play/Pause | 播放/暂停 | -| ? | Shuffle | 手气不错 | -| m | Menu | 主菜单 | -| p | Present/History | 当前/历史播放列表 | -| i | Music Info | 当前音乐信息 | -| Shift + p | Playing Mode | 播放模式切换 | -| a | Add | 添加曲目到打碟 | -| Shift + a | Enter Album | 进入专辑 | -| g | To the First | 跳至首项 | -| Shift + g | To the End | 跳至尾项 | -| z | DJ List | 打碟列表 | -| s | Star | 添加到收藏 | -| c | Collection | 收藏列表 | -| r | Remove | 删除当前条目 | -| Shift + j | Move Down | 向下移动当前项目 | -| Shift + k | Move Up | 向上移动当前项目 | -| Shift + c | Cache | 缓存歌曲到本地 | -| , | Like | 喜爱 | -| . | Trash FM | 删除 FM | -| / | Next FM | 下一FM | -| q | Quit | 退出 | -| t | Timing Exit | 定时退出 | -| w | Quit & Clear | 退出并清除用户信息 | +| Key | Effect | | +| ------------------------------------- | --------------- | ------------------ | +| j | Down | 下移 | +| k | Up | 上移 | +| num + j | Quick Jump | 快速向后跳转 n 首 | +| num + k | Quick Up | 快速向前跳转 n 首 | +| h | Back | 后退 | +| l | Forword | 前进 | +| u | Prev Page | 上一页 | +| d | Next Page | 下一页 | +| f | Search | 当前列表模糊搜索 | +| \[ | Prev Song | 上一曲 | +| ] | Next Song | 下一曲 | +| num + \[ | Quick Prev Song | 快速前 n 首 | +| num + ] | Quick Next Song | 快速后 n 首 | +| num + Shift + g | Index for Song | 跳到第 n 首 | +| = | Volume + | 音量增加 | +| - | Volume - | 音量减少 | +| Space | Play/Pause | 播放/暂停 | +| ? | Shuffle | 手气不错 | +| m | Menu | 主菜单 | +| p | Present/History | 当前/历史播放列表 | +| i | Music Info | 当前音乐信息 | +| Shift + p | Playing Mode | 播放模式切换 | +| a | Add | 添加曲目到打碟 | +| Shift + a | Enter Album | 进入专辑 | +| g | To the First | 跳至首项 | +| Shift + g | To the End | 跳至尾项 | +| z | DJ List | 打碟列表 | +| s | Star | 添加到收藏 | +| c | Collection | 收藏列表 | +| r | Remove | 删除当前条目 | +| Shift + j | Move Down | 向下移动当前项目 | +| Shift + k | Move Up | 向上移动当前项目 | +| Shift + c | Cache | 缓存歌曲到本地 | +| , | Like | 喜爱 | +| . | Trash FM | 删除 FM | +| / | Next FM | 下一 FM | +| q | Quit | 退出 | +| t | Timing Exit | 定时退出 | +| w | Quit & Clear | 退出并清除用户信息 | ## 安装 @@ -89,32 +89,32 @@ ### 可选依赖 1. `aria2` 用于缓存歌曲 -2. `libnotify-bin` 用于支持消息提示(Linux平台) +2. `libnotify-bin` 用于支持消息提示(Linux 平台) 3. `qtpy python-dbus dbus qt` 用于支持桌面歌词 - (根据系统qt的版本还需要安装 pyqt4 pyqt4 pyside pyside2 中的任意一个) + (根据系统 qt 的版本还需要安装 pyqt4 pyqt4 pyside pyside2 中的任意一个) 4. `python-levenshtein` 用于模糊搜索 -### PyPi安装(*nix系统) +### PyPi 安装(\*nix 系统) ```bash pip3 install NetEase-MusicBox ``` -### Git clone安装master分支(*nix系统) +### Git clone 安装 master 分支(\*nix 系统) ```bash git clone https://github.com/darknessomi/musicbox.git && cd musicbox poetry build && poetry install ``` -### macOS安装 +### macOS 安装 ```bash pip3 install NetEase-MusicBox brew install mpg123 ``` -### Linux安装 +### Linux 安装 **注意:通过以下方法安装可能仍然需要`pip3 install -U NetEase-MusicBox`更新到最新版**。 @@ -148,7 +148,7 @@ 配置文件地址: `~/.config/netease-musicbox/config.json` 可配置缓存,快捷键,消息,桌面歌词。 -由于歌曲 API 只接受中国大陆地区访问,非中国大陆地区用户请自行设置代理(可用polipo将socks5代理转换成http代理): +由于歌曲 API 只接受中国大陆地区访问,非中国大陆地区用户请自行设置代理(可用 polipo 将 socks5 代理转换成 http 代理): ```bash export http_proxy=http://IP:PORT @@ -156,30 +156,30 @@ export https_proxy=http://IP:PORT curl -L ip.cn ``` -显示IP属于中国大陆地区即可。 +显示 IP 属于中国大陆地区即可。 ### 已测试的系统兼容列表 -| OS | Version | -| -------- | --------------------- | -| Arch | Rolling | -| macOS | 10.15.7 | +| OS | Version | +| ----- | ------- | +| Arch | Rolling | +| macOS | 10.15.7 | ### 错误处理 当某些歌曲不能播放时,总时长为 00:01 时,请检查是否为版权问题导致。 -如遇到在特定终端下不能播放问题,首先检查**此终端**下mpg123能否正常使用,其次检查**其他终端**下musicbox能否正常使用,报告issue的时候请告知以上使用情况以及出问题终端的报错信息。 +如遇到在特定终端下不能播放问题,首先检查**此终端**下 mpg123 能否正常使用,其次检查**其他终端**下 musicbox 能否正常使用,报告 issue 的时候请告知以上使用情况以及出问题终端的报错信息。 同时,您可以通过`tail -f ~/.local/share/netease-musicbox/musicbox.log`自行查看日志。 -mpg123 最新的版本可能会报找不到声音硬件的错误,测试了1.25.6版本可以正常使用。 +mpg123 最新的版本可能会报找不到声音硬件的错误,测试了 1.25.6 版本可以正常使用。 ### 已知问题及解决方案 -- [#374](https://github.com/darknessomi/musicbox/issues/374) i3wm下播放杂音或快进问题,此问题常见于Arch Linux。尝试更改mpg123配置。 -- [#405](https://github.com/darknessomi/musicbox/issues/405) 32位Python下cookie时间戳超出了32位整数最大值。尝试使用64位版本的Python或者拷贝cookie文件到对应位置。 -- [#347](https://github.com/darknessomi/musicbox/issues/347) 暂停时间超过一定长度(数分钟)之后mpg123停止输出,导致切换到下一首歌。此问题是mpg123的bug,暂时无解决方案。 -- [#791](https://github.com/darknessomi/musicbox/issues/791) 版权问题,master分支已经修复 +- [#374](https://github.com/darknessomi/musicbox/issues/374) i3wm 下播放杂音或快进问题,此问题常见于 Arch Linux。尝试更改 mpg123 配置。 +- [#405](https://github.com/darknessomi/musicbox/issues/405) 32 位 Python 下 cookie 时间戳超出了 32 位整数最大值。尝试使用 64 位版本的 Python 或者拷贝 cookie 文件到对应位置。 +- [#347](https://github.com/darknessomi/musicbox/issues/347) 暂停时间超过一定长度(数分钟)之后 mpg123 停止输出,导致切换到下一首歌。此问题是 mpg123 的 bug,暂时无解决方案。 +- [#791](https://github.com/darknessomi/musicbox/issues/791) 版权问题,master 分支已经修复 ## 使用 @@ -191,15 +191,17 @@ Enjoy it ! ## 更新日志 -2020-10-23 版本 0.3.0 接口更新,错误修复 +2021-01-18 版本 0.3.1 错误修复 -2018-11-28 版本 0.2.5.4 修复多处错误 +2020-10-23 版本 0.3.0 接口更新,错误修复 -2018-06-21 版本 0.2.5.3 修复多处播放错误 +2018-11-28 版本 0.2.5.4 修复多处错误 -2018-06-07 版本 0.2.5.1 修复配置文件错误 +2018-06-21 版本 0.2.5.3 修复多处播放错误 -2018-06-05 版本 0.2.5.0 全部迁移到新版api,大量错误修复 +2018-06-07 版本 0.2.5.1 修复配置文件错误 + +2018-06-05 版本 0.2.5.0 全部迁移到新版 api,大量错误修复 [更多>>](https://github.com/darknessomi/musicbox/blob/master/CHANGELOG.md) diff --git a/pyproject.toml b/pyproject.toml index ee60f4fd..119ee5bd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ name = "NetEase-MusicBox" packages = [ {include = "NEMbox"}, ] -version = "0.3.0" +version = "0.3.1" # docs authors = [ "omi <4399.omi@gmail.com>", diff --git a/setup.cfg b/setup.cfg index c566bae9..90f34ce0 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,5 +1,5 @@ [flake8] -ignore = E501,E402,W503 +ignore = E501,E402,W503,E203 exclude = .git,__pycache__,docs/source/conf.py,old,build,dist,venv max-complexity = 15 max-line-length = 88