diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..e20329e --- /dev/null +++ b/Dockerfile @@ -0,0 +1,16 @@ +FROM ubuntu:14.04 + +# Install Python. +RUN \ + apt-get update && \ + apt-get install -y python python-dev python-pip python-virtualenv && \ + rm -rf /var/lib/apt/lists/* + +ADD ./apis /apis + +WORKDIR /apis + +RUN pip install -r requirements.txt +EXPOSE 80 + +ENTRYPOINT ["python","index.py"] \ No newline at end of file diff --git a/LICENSE.txt b/LICENSE.txt deleted file mode 100644 index 85126f1..0000000 --- a/LICENSE.txt +++ /dev/null @@ -1,21 +0,0 @@ -### The MIT License (MIT) - -CopyRight (c) 2014 vellow <i@vellow.net> - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/README.md b/README.md deleted file mode 100644 index bf26f12..0000000 --- a/README.md +++ /dev/null @@ -1,79 +0,0 @@ -NetEase-MusicBox -================= - -高品质网易云音乐命令行版本,简洁优雅,丝般顺滑,基于Python编写。 - -![NetEase-MusicBox](http://i.imgur.com/J5353vK.gif) - -### 功能特性 - -1. 320kps的高品质音乐 -2. 歌曲,艺术家,专辑检索 -3. 网易热门歌曲排行榜 -4. 网易新碟推荐 -5. 网易精选歌单 -6. 网易DJ节目 -7. 私人歌单 -8. 随心打碟 -9. 本地收藏(不提供下载) -10. 精心设计的快捷键让操作丝般顺滑 - -### 键盘快捷键 - - - - - - - - - - - - - - - - - - - - -
J Down 下移
K Up 上移
H Back 后退
L Forword 前进
U Prev page 上一页
D Next page 下一页
F Search 快速搜索
[ Prev song 上一曲
] Next song 下一曲
Space Play/Pause 播放/暂停
M Menu 主菜单
P Present 当前播放列表
A Add 添加曲目到打碟
Z DJ list 打碟列表
S Star 添加到收藏
C Collection 收藏列表
R Remove 删除当前条目
Q Quit 退出
- - -### 安装 - - $ pip install netease-musicbox - - $ brew install mpg123 - -### 使用 - - $ musicbox - - -Enjoy it ! - -### The MIT License (MIT) - -CopyRight (c) 2014 vellow <i@vellow.net> - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - diff --git a/src/api.py b/apis/api.py similarity index 99% rename from src/api.py rename to apis/api.py index 1bc00c0..fa28542 100644 --- a/src/api.py +++ b/apis/api.py @@ -83,7 +83,7 @@ def search(self, s, stype=1, offset=0, total='true', limit=60): 'type': stype, 'offset': offset, 'total': total, - 'limit': 60 + 'limit': limit } return self.httpRequest('POST', action, data) diff --git a/apis/index.py b/apis/index.py new file mode 100644 index 0000000..07bc825 --- /dev/null +++ b/apis/index.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python +#encoding: UTF-8 +from api import NetEase +from flask import Flask, jsonify, request +import requests +import json + +app = Flask(__name__) + +@app.route('/music/search//') +def search_music(q, limit): + netease = NetEase() + r = netease.search(q, limit=limit) + if r['code'] != 200: + return jsonify({ + "error" : True + }) + else: + ids = [] + for song in r['result']['songs']: + ids.append(song['id']) + musics = netease.songs_detail(ids) + outputs = [] + for music in musics: + outputs.append({ + "error" : False, + "name" : music['name'], + "cover" : music['album']['blurPicUrl'], + "album_name": music['album']['name'], + "author": music['artists'][0]['name'], + "url" : music['mp3Url'] + }) + outputs = { + "error" : False, + "type" : "music", + "musics" : outputs + } + return jsonify(outputs) + +@app.route('/music/search', methods=['POST']) +def search(): + q = request.form['content'] + return search_music(q, 1) + +@app.route("/weather/") +def weather(location): + url = "http://api.map.baidu.com/telematics/v3/weather?location=%s&output=json&ak=65VSjZ1CEe8lnb5q3XGzlCUc"%location + print url + r = requests.get(url) + r = r.json() + if r['error'] != 0: + return jsonify({ + "error" : True + }) + else: + return json.dumps({ + "error" : False, + "weathers" : r["results"][0]['weather_data'] + }) + +@app.route('/weather', methods=['POST']) +def check_weather(): + location = request.form['content'] + return weather(location) + +if __name__ == '__main__': + app.run(host='0.0.0.0', port=80,debug=True) \ No newline at end of file diff --git a/apis/requirements.txt b/apis/requirements.txt new file mode 100644 index 0000000..76249c0 --- /dev/null +++ b/apis/requirements.txt @@ -0,0 +1,2 @@ +requests==2.7.0 +flask==0.10.1 \ No newline at end of file diff --git a/setup.py b/setup.py deleted file mode 100644 index b46522d..0000000 --- a/setup.py +++ /dev/null @@ -1,60 +0,0 @@ -#!/usr/bin/env python -#encoding: UTF-8 - -''' -__ ___________________________________________ -| \ ||______ | |______|_____||______|______ -| \_||______ | |______| |______||______ - -________ __________________________ _____ _ _ -| | || ||______ | | |_____]| | \___/ -| | ||_____|______|__|__|_____ |_____]|_____|_/ \_ - - -+ ------------------------------------------ + -| NetEase-MusicBox 320kbps | -+ ------------------------------------------ + -| | -| ++++++++++++++++++++++++++++++++++++++ | -| ++++++++++++++++++++++++++++++++++++++ | -| ++++++++++++++++++++++++++++++++++++++ | -| ++++++++++++++++++++++++++++++++++++++ | -| ++++++++++++++++++++++++++++++++++++++ | -| | -| A sexy cli musicbox based on Python | -| Music resource from music.163.com | -| | -| Built with love to music by @vellow | -| | -+ ------------------------------------------ + - -''' - - -from setuptools import setup, find_packages - - -setup( - name = 'NetEase-MusicBox', - version = '0.1.0.1.10', - packages = find_packages(), - - include_package_data = True, - - install_requires = [ - 'requests', - ], - - entry_points = { - 'console_scripts' : [ - 'musicbox = src:start' - ], - }, - - author = 'vellow', - author_email = 'i@vellow.net', - url = 'https://github.com/vellow/NetEase-MusicBox', - description = 'A sexy command line interface musicbox', - keywords = ['music', 'netease', 'cli', 'player'], - zip_safe = False, -) \ No newline at end of file diff --git a/src/__init__.py b/src/__init__.py deleted file mode 100644 index fdefbef..0000000 --- a/src/__init__.py +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env python -#encoding: UTF-8 - -''' -网易云音乐 Entry -''' - -from menu import Menu - -def start(): - Menu().start() \ No newline at end of file diff --git a/src/menu.py b/src/menu.py deleted file mode 100644 index b9c3596..0000000 --- a/src/menu.py +++ /dev/null @@ -1,394 +0,0 @@ -#!/usr/bin/env python -#encoding: UTF-8 - -''' -网易云音乐 Menu -''' - -import curses -import locale -import sys -import os -import json -import time -import webbrowser -from api import NetEase -from player import Player -from ui import Ui - -home = os.path.expanduser("~") -if os.path.isdir(home + '/netease-musicbox') is False: - os.mkdir(home+'/netease-musicbox') - -locale.setlocale(locale.LC_ALL, "") -code = locale.getpreferredencoding() - -# carousel x in [left, right] -carousel = lambda left, right, x: left if (x>right) else (right if x 10 - self.index = (index-step)//step*step - - # 向下翻页 - elif key == ord('d'): - if offset + step >= len( datalist ): - continue - self.offset += step - - # e.g. 23 + 10 = 33 --> 30 - self.index = (index+step)//step*step - - # 前进 - elif key == ord('l') or key == 10: - if self.datatype == 'songs' or self.datatype == 'djchannels' or self.datatype == 'help': - continue - self.ui.build_loading() - self.dispatch_enter(idx) - self.index = 0 - self.offset = 0 - - # 回退 - elif key == ord('h'): - # if not main menu - if len(self.stack) == 1: - continue - up = stack.pop() - self.datatype = up[0] - self.title = up[1] - self.datalist = up[2] - self.offset = up[3] - self.index = up[4] - - # 搜索 - elif key == ord('f'): - self.search() - - # 播放下一曲 - elif key == ord(']'): - self.player.next() - time.sleep(0.1) - - # 播放上一曲 - elif key == ord('['): - self.player.prev() - time.sleep(0.1) - - # 播放、暂停 - elif key == ord(' '): - if datatype == 'songs': - self.presentsongs = ['songs', title, datalist, offset, index] - elif datatype == 'djchannels': - self.presentsongs = ['djchannels', title, datalist, offset, index] - self.player.play(datatype, datalist, idx) - time.sleep(0.1) - - # 加载当前播放列表 - elif key == ord('p'): - if len(self.presentsongs) == 0: - continue - self.stack.append( [datatype, title, datalist, offset, index] ) - self.datatype = self.presentsongs[0] - self.title = self.presentsongs[1] - self.datalist = self.presentsongs[2] - self.offset = self.presentsongs[3] - self.index = self.presentsongs[4] - - # 添加到打碟歌单 - elif key == ord('a'): - if datatype == 'songs' and len(datalist) != 0: - self.djstack.append( datalist[idx] ) - elif datatype == 'artists': - pass - - # 加载打碟歌单 - elif key == ord('z'): - self.stack.append( [datatype, title, datalist, offset, index] ) - self.datatype = 'songs' - self.title = '网易云音乐 > 打碟' - self.datalist = self.djstack - self.offset = 0 - self.index = 0 - - # 添加到收藏歌曲 - elif key == ord('s'): - if (datatype == 'songs' or datatype == 'djchannels') and len(datalist) != 0: - self.collection.append( datalist[idx] ) - - # 加载收藏歌曲 - elif key == ord('c'): - self.stack.append( [datatype, title, datalist, offset, index] ) - self.datatype = 'songs' - self.title = '网易云音乐 > 收藏' - self.datalist = self.collection - self.offset = 0 - self.index = 0 - - # 从当前列表移除 - elif key == ord('r'): - if datatype != 'main' and len(datalist) != 0: - self.datalist.pop(idx) - self.index = carousel(offset, min( len(datalist), offset + step) - 1, idx ) - - elif key == ord('m'): - if datatype != 'main': - self.stack.append( [datatype, title, datalist, offset, index] ) - self.datatype = self.stack[0][0] - self.title = self.stack[0][1] - self.datalist = self.stack[0][2] - self.offset = 0 - self.index = 0 - - elif key == ord('g'): - if datatype == 'help': - webbrowser.open_new_tab('https://github.com/vellow/NetEase-MusicBox') - - self.ui.build_menu(self.datatype, self.title, self.datalist, self.offset, self.index, self.step) - - - self.player.stop() - sfile = file(home + "/netease-musicbox/flavor.json", 'w') - data = { - 'account': self.account, - 'collection': self.collection - } - sfile.write(json.dumps(data)) - sfile.close() - curses.endwin() - - def dispatch_enter(self, idx): - # The end of stack - netease = self.netease - datatype = self.datatype - title = self.title - datalist = self.datalist - offset = self.offset - index = self.index - self.stack.append( [datatype, title, datalist, offset, index]) - - if datatype == 'main': - self.choice_channel(idx) - - # 该艺术家的热门歌曲 - elif datatype == 'artists': - artist_id = datalist[idx]['artist_id'] - songs = netease.artists(artist_id) - self.datatype = 'songs' - self.datalist = netease.dig_info(songs, 'songs') - self.title += ' > ' + datalist[idx]['artists_name'] - - # 该专辑包含的歌曲 - elif datatype == 'albums': - album_id = datalist[idx]['album_id'] - songs = netease.album(album_id) - self.datatype = 'songs' - self.datalist = netease.dig_info(songs, 'songs') - self.title += ' > ' + datalist[idx]['albums_name'] - - # 该歌单包含的歌曲 - elif datatype == 'playlists': - playlist_id = datalist[idx]['playlist_id'] - songs = netease.playlist_detail(playlist_id) - self.datatype = 'songs' - self.datalist = netease.dig_info(songs, 'songs') - self.title += ' > ' + datalist[idx]['playlists_name'] - - def choice_channel(self, idx): - # 排行榜 - netease = self.netease - if idx == 0: - songs = netease.top_songlist() - self.datalist = netease.dig_info(songs, 'songs') - self.title += ' > 排行榜' - self.datatype = 'songs' - - # 艺术家 - elif idx == 1: - artists = netease.top_artists() - self.datalist = netease.dig_info(artists, 'artists') - self.title += ' > 艺术家' - self.datatype = 'artists' - - # 新碟上架 - elif idx == 2: - albums = netease.new_albums() - self.datalist = netease.dig_info(albums, 'albums') - self.title += ' > 新碟上架' - self.datatype = 'albums' - - # 精选歌单 - elif idx == 3: - playlists = netease.top_playlists() - self.datalist = netease.dig_info(playlists, 'playlists') - self.title += ' > 精选歌单' - self.datatype = 'playlists' - - # 我的歌单 - elif idx == 4: - # 未登录 - if self.userid is None: - # 使用本地存储了账户登录 - if self.account: - user_info = netease.login(self.account[0], self.account[1]) - - # 本地没有存储账户,或本地账户失效,则引导录入 - if self.account == {} or user_info['code'] != 200: - data = self.ui.build_login() - # 取消登录 - if data == -1: - return - user_info = data[0] - self.account = data[1] - - self.username = user_info['profile']['nickname'] - self.userid = user_info['account']['id'] - # 读取登录之后的用户歌单 - myplaylist = netease.user_playlist( self.userid ) - self.datalist = netease.dig_info(myplaylist, 'playlists') - self.datatype = 'playlists' - self.title += ' > ' + self.username + ' 的歌单' - - # DJ节目 - elif idx == 5: - self.datatype = 'djchannels' - self.title += ' > DJ节目' - self.datalist = netease.djchannels() - - # 打碟 - elif idx == 6: - self.datatype = 'songs' - self.title += ' > 打碟' - self.datalist = self.djstack - - # 收藏 - elif idx == 7: - self.datatype = 'songs' - self.title += ' > 收藏' - self.datalist = self.collection - - # 搜索 - elif idx == 8: - self.search() - - # 帮助 - elif idx == 9: - self.datatype = 'help' - self.title += ' > 帮助' - self.datalist = shortcut - - self.offset = 0 - self.index = 0 - - def search(self): - ui = self.ui - x = ui.build_search_menu() - # if do search, push current info into stack - if x in range(ord('1'), ord('5')): - self.stack.append( [self.datatype, self.title, self.datalist, self.offset, self.index ]) - self.index = 0 - self.offset = 0 - - if x == ord('1'): - self.datatype = 'songs' - self.datalist = ui.build_search('songs') - self.title = '歌曲搜索列表' - - elif x == ord('2'): - self.datatype = 'artists' - self.datalist = ui.build_search('artists') - self.title = '艺术家搜索列表' - - elif x == ord('3'): - self.datatype = 'albums' - self.datalist = ui.build_search('albums') - self.title = '专辑搜索列表' - - elif x == ord('4'): - self.datatype = 'playlists' - self.datalist = ui.build_search('playlists') - self.title = '精选歌单搜索列表' - diff --git a/src/player.py b/src/player.py deleted file mode 100644 index 86338c1..0000000 --- a/src/player.py +++ /dev/null @@ -1,125 +0,0 @@ -#!/usr/bin/env python -#encoding: UTF-8 - -''' -网易云音乐 Player -''' -# Let's make some noise - -import subprocess -import threading -import time -import os -import signal -from ui import Ui - - -# carousel x in [left, right] -carousel = lambda left, right, x: left if (x>right) else (right if x same song :: pause/resume it - self.datatype = datatype - - if datatype == 'songs' or datatype == 'djchannels': - if idx == self.idx and songs == self.songs: - if self.pause_flag: - self.resume() - else: - self.pause() - - else: - if datatype == 'songs' or datatype == 'djchannels': - self.songs = songs - self.idx = idx - - # if it's playing - if self.playing_flag: - self.switch() - - # start new play - else: - self.recall() - # if current menu is not song, pause/resume - else: - if self.playing_flag: - if self.pause_flag: - self.resume() - else: - self.pause() - else: - pass - - # play another - def switch(self): - self.stop() - # wait process be killed - time.sleep(0.01) - self.recall() - - def stop(self): - if self.playing_flag and self.popen_handler: - self.playing_flag = False - self.popen_handler.kill() - - def pause(self): - self.pause_flag = True - os.kill(self.popen_handler.pid, signal.SIGSTOP) - item = self.songs[ self.idx ] - self.ui.build_playinfo(item['song_name'], item['artist'], item['album_name'], pause=True) - - def resume(self): - self.pause_flag = False - os.kill(self.popen_handler.pid, signal.SIGCONT) - item = self.songs[ self.idx ] - self.ui.build_playinfo(item['song_name'], item['artist'], item['album_name']) - - def next(self): - self.stop() - time.sleep(0.01) - self.idx = carousel(0, len(self.songs)-1, self.idx+1 ) - self.recall() - - def prev(self): - self.stop() - time.sleep(0.01) - self.idx = carousel(0, len(self.songs)-1, self.idx-1 ) - self.recall() diff --git a/src/ui.py b/src/ui.py deleted file mode 100644 index 92824e4..0000000 --- a/src/ui.py +++ /dev/null @@ -1,209 +0,0 @@ -#!/usr/bin/env python -#encoding: UTF-8 - -''' -网易云音乐 Ui -''' - -import curses -from api import NetEase - - -class Ui: - def __init__(self): - self.screen = curses.initscr() - # charactor break buffer - curses.cbreak() - self.screen.keypad(1) - self.netease = NetEase() - curses.start_color() - curses.init_pair(1, curses.COLOR_GREEN, curses.COLOR_BLACK) - curses.init_pair(2, curses.COLOR_CYAN, curses.COLOR_BLACK) - curses.init_pair(3, curses.COLOR_RED, curses.COLOR_BLACK) - curses.init_pair(4, curses.COLOR_YELLOW, curses.COLOR_BLACK) - - def build_playinfo(self, song_name, artist, album_name, pause=False): - # refresh top 2 line - self.screen.move(1,1) - self.screen.clrtoeol() - self.screen.move(2,1) - self.screen.clrtoeol() - if pause: - self.screen.addstr(1, 6, '_ _ z Z Z', curses.color_pair(3)) - else: - self.screen.addstr(1, 6, '♫ ♪ ♫ ♪', curses.color_pair(3)) - self.screen.addstr(1, 19, song_name + ' - ' + artist + ' < ' + album_name + ' >', curses.color_pair(4)) - self.screen.refresh() - - def build_loading(self): - self.screen.addstr(6, 19, '享受高品质音乐,loading...', curses.color_pair(1)) - self.screen.refresh() - - def build_menu(self, datatype, title, datalist, offset, index, step): - # keep playing info in line 1 - self.screen.move(4,1) - self.screen.clrtobot() - self.screen.addstr(4, 19, title, curses.color_pair(1)) - - if len(datalist) == 0: - self.screen.addstr(8, 19, '这里什么都没有 -,-') - - else: - if datatype == 'main': - for i in range( offset, min( len(datalist), offset+step) ): - if i == index: - self.screen.addstr(i - offset +8, 16, '-> ' + str(i) + '. ' + datalist[i], curses.color_pair(2)) - else: - self.screen.addstr(i - offset +8, 19, str(i) + '. ' + datalist[i]) - - elif datatype == 'songs': - for i in range(offset, min( len(datalist), offset+step) ): - # this item is focus - if i == index: - self.screen.addstr(i - offset +8, 16, '-> ' + str(i) + '. ' + datalist[i]['song_name'] + ' - ' + datalist[i]['artist'] + ' < ' + datalist[i]['album_name'] + ' >', curses.color_pair(2)) - else: - self.screen.addstr(i - offset +8, 19, str(i) + '. ' + datalist[i]['song_name'] + ' - ' + datalist[i]['artist'] + ' < ' + datalist[i]['album_name'] + ' >') - - elif datatype == 'artists': - for i in range(offset, min( len(datalist), offset+step) ): - if i == index: - self.screen.addstr(i - offset +8, 16, '-> ' + str(i) + '. ' + datalist[i]['artists_name'] + ' - ' + str(datalist[i]['alias']), curses.color_pair(2)) - else: - self.screen.addstr(i - offset +8, 19, str(i) + '. ' + datalist[i]['artists_name'] + ' - ' + datalist[i]['alias']) - - elif datatype == 'albums': - for i in range(offset, min( len(datalist), offset+step) ): - if i == index: - self.screen.addstr(i - offset +8, 16, '-> ' + str(i) + '. ' + datalist[i]['albums_name'] + ' - ' + datalist[i]['artists_name'], curses.color_pair(2)) - else: - self.screen.addstr(i - offset +8, 19, str(i) + '. ' + datalist[i]['albums_name'] + ' - ' + datalist[i]['artists_name']) - - elif datatype == 'playlists': - for i in range(offset, min( len(datalist), offset+step) ): - if i == index: - self.screen.addstr(i - offset +8, 16, '-> ' + str(i) + '. ' + datalist[i]['playlists_name'] + ' - ' + datalist[i]['creator_name'], curses.color_pair(2)) - else: - self.screen.addstr(i - offset +8, 19, str(i) + '. ' + datalist[i]['playlists_name'] + ' - ' + datalist[i]['creator_name']) - - elif datatype == 'djchannels': - for i in range(offset, min( len(datalist), offset+step) ): - if i == index: - self.screen.addstr(i - offset +8, 16, '-> ' + str(i) + '. ' + datalist[i]['song_name'], curses.color_pair(2)) - else: - self.screen.addstr(i - offset +8, 19, str(i) + '. ' + datalist[i]['song_name']) - - elif datatype == 'help': - for i in range(offset, min( len(datalist), offset+step) ): - if i == index: - self.screen.addstr(i - offset +8, 16, '-> ' + str(i) + '. \'' + datalist[i][0].upper() + '\' ' + datalist[i][1] + ' ' + datalist[i][2], curses.color_pair(2)) - else: - self.screen.addstr(i - offset +8, 19, str(i) + '. \'' + datalist[i][0].upper() + '\' ' + datalist[i][1] + ' ' + datalist[i][2]) - self.screen.addstr(20, 6, 'NetEase-MusicBox 基于Python,所有版权音乐来源于网易,本地不做任何保存') - self.screen.addstr(21, 10, '按 [G] 到 Github 了解更多信息,帮助改进,或者Star表示支持~~') - self.screen.addstr(22, 19, 'Build with love to music by @vellow') - - self.screen.refresh() - - def build_search(self, stype): - netease = self.netease - if stype == 'songs': - song_name = self.get_param('搜索歌曲:') - try: - data = netease.search(song_name, stype=1) - song_ids = [] - if 'songs' in data['result']: - if 'mp3Url' in data['result']['songs']: - songs = data['result']['songs'] - - # if search song result do not has mp3Url - # send ids to get mp3Url - else: - for i in range(0, len(data['result']['songs']) ): - song_ids.append( data['result']['songs'][i]['id'] ) - songs = netease.songs_detail(song_ids) - return netease.dig_info(songs, 'songs') - except: - return [] - - elif stype == 'artists': - artist_name = self.get_param('搜索艺术家:') - try: - data = netease.search(artist_name, stype=100) - if 'artists' in data['result']: - artists = data['result']['artists'] - return netease.dig_info(artists, 'artists') - except: - return [] - - elif stype == 'albums': - artist_name = self.get_param('搜索专辑:') - try: - data = netease.search(artist_name, stype=10) - if 'albums' in data['result']: - albums = data['result']['albums'] - return netease.dig_info(albums, 'albums') - except: - return [] - - elif stype == 'playlists': - artist_name = self.get_param('搜索网易精选集:') - try: - data = netease.search(artist_name, stype=1000) - if 'playlists' in data['result']: - playlists = data['result']['playlists'] - return netease.dig_info(playlists, 'playlists') - except: - return [] - - return [] - - def build_search_menu(self): - self.screen.move(4,1) - self.screen.clrtobot() - self.screen.addstr(8, 19, '选择搜索类型:', curses.color_pair(1)) - self.screen.addstr(10,19, '[1] 歌曲') - self.screen.addstr(11,19, '[2] 艺术家') - self.screen.addstr(12,19, '[3] 专辑') - self.screen.addstr(13,19, '[4] 网易精选集') - self.screen.addstr(16,19, '请键入对应数字:', curses.color_pair(2)) - self.screen.refresh() - x = self.screen.getch() - return x - - def build_login(self): - info = self.get_param('请输入登录信息, e.g: john@163.com 123456') - account = info.split(' ') - if len(account) != 2: - return self.build_login() - login_info = self.netease.login(account[0], account[1]) - if login_info['code'] != 200: - x = self.build_login_error() - if x == ord('1'): - return self.build_login() - else: - return -1 - else: - return [login_info, account] - - def build_login_error(self): - self.screen.move(4,1) - self.screen.clrtobot() - self.screen.addstr(8, 19, '艾玛,登录信息好像不对呢 (O_O)#', curses.color_pair(1)) - self.screen.addstr(10,19, '[1] 再试一次') - self.screen.addstr(11,19, '[2] 稍后再试') - self.screen.addstr(14,19, '请键入对应数字:', curses.color_pair(2)) - self.screen.refresh() - x = self.screen.getch() - return x - - def get_param(self, prompt_string): - # keep playing info in line 1 - self.screen.move(4,1) - self.screen.clrtobot() - self.screen.addstr(5, 19, prompt_string, curses.color_pair(1)) - self.screen.refresh() - info = self.screen.getstr(10, 19, 60) - if info.strip() is '': - return self.get_param(prompt_string) - else: - return info