コード例 #1
0
def change_user():
    #file = open('163.md')
    file = open('account.txt')
    try:
        alist = file.read()
    finally:
        file.close()
    account_list = alist.splitlines()
    account = random.choice(account_list)

    user = account.split(",")[0]
    passwd = md5(account.split(",")[1])

    joker = NetEase()
    login_info = joker.login(user, passwd)

    print login_info
    return login_info
コード例 #2
0
ファイル: higherapi.py プロジェクト: wangqin4377/NetEaseMusic
class User(object):
    def __init__(self):
        self.netease = NetEase()
        self.is_login = False
        self.uid = str()    # ''

    def login(self, username, password):
        data = self.netease.login(username, password)
        code = data['code']
        if code is 200:
            self.uid = data['profile']['userId']
            self.is_login = True
            return True
        else:   # 501
            return False

    def get_favorite_playlist_id(self):
        """
        login required
        success: return playlist id
        fail: return empty string ''
        """
        if self.is_login:
            playlist = self.netease.user_playlist(self.uid)
            for each in playlist:
                if each['specialType'] is 5:    # favorite playlist
                    return each['id']   # the favorite playlist id
            return ''
        return ''

    def get_music_title_and_url(self, pid):
        """
        :param pid: playlist id
        :return re: return list re
        """
        playlist = self.netease.playlist_detail(pid)
        re = list()
        if playlist is not []:
            for music in playlist:
                tmp = dict()
                tmp['title'] = music['name']
                tmp['url'] = music['mp3Url']
                re.append(tmp)
        return re
コード例 #3
0
ファイル: menu.py プロジェクト: dssljt/musicbox
class Menu:
    def __init__(self):
        reload(sys)
        sys.setdefaultencoding('UTF-8')
        self.config = Config()
        self.datatype = 'main'
        self.title = '网易云音乐'
        self.datalist = ['排行榜', '艺术家', '新碟上架', '精选歌单', '我的歌单', 'DJ节目', '每日推荐', '私人FM', '搜索', '帮助']
        self.offset = 0
        self.index = 0
        self.storage = Storage()
        self.storage.load()
        self.collection = self.storage.database['collections'][0]
        self.player = Player()
        self.player.playing_song_changed_callback = self.song_changed_callback
        self.cache = Cache()
        self.ui = Ui()
        self.netease = NetEase()
        self.screen = curses.initscr()
        self.screen.keypad(1)
        self.step = 10
        self.stack = []
        self.djstack = []
        self.userid = self.storage.database["user"]["user_id"]
        self.username = self.storage.database["user"]["nickname"]
        self.resume_play = True
        self.at_playing_list = False
        signal.signal(signal.SIGWINCH, self.change_term)
        signal.signal(signal.SIGINT, self.send_kill)
        self.START = time.time()

    def change_term(self, signum, frame):
        self.ui.screen.clear()
        self.ui.screen.refresh()

    def send_kill(self, signum, fram):
        self.player.stop()
        self.cache.quit()
        self.storage.save()
        curses.endwin()
        sys.exit()

    def update_alert(self, version):
        latest = Menu().check_version()
        if latest != version and latest != 0:
            if platform.system() == 'Darwin':
                os.system('/usr/bin/osascript -e \'display notification "MusicBox Update is available"sound name "/System/Library/Sounds/Ping.aiff"\'')
                time.sleep(0.5)
                os.system('/usr/bin/osascript -e \'display notification "NetEase-MusicBox installed version:' + version + '\nNetEase-MusicBox latest version:' + latest + '"\'')
            else:
                os.system('/usr/bin/notify-send "MusicBox Update is available"')

    def signin_alert(self, type):
        if type == 0:
            if platform.system() == 'Darwin':
                os.system('/usr/bin/osascript -e \'display notification "Mobile signin success"sound name "/System/Library/Sounds/Ping.aiff"\'')
            else:
                os.system('/usr/bin/notify-send "Mobile signin success"')
        else:
            if platform.system() == 'Darwin':
                os.system('/usr/bin/osascript -e \'display notification "PC signin success"sound name "/System/Library/Sounds/Ping.aiff"\'')
            else:
                os.system('/usr/bin/notify-send "PC signin success"')

    def check_version(self):
        # 检查更新 && 签到
        try:
            mobilesignin = self.netease.daily_signin(0)
            if  mobilesignin != -1 and mobilesignin['code'] != -2:
                self.signin_alert(0)
            time.sleep(0.5)
            pcsignin = self.netease.daily_signin(1)
            if pcsignin != -1 and pcsignin['code'] != -2:
                self.signin_alert(1)
            tree = ET.ElementTree(ET.fromstring(str(self.netease.get_version())))
            root = tree.getroot()
            return root[0][4][0][0].text
        except:
            return 0

    def start_fork(self, version):
        pid = os.fork()
        if pid == 0:
            Menu().update_alert(version)
        else:
            Menu().start()

    def play_pause(self):
        if len(self.storage.database["player_info"]["player_list"]) == 0:
            return
        if self.player.pause_flag:
            self.player.resume()
        else:
            self.player.pause()
        time.sleep(0.1)

    def next_song(self):
        if len(self.storage.database["player_info"]["player_list"]) == 0:
            return
        self.player.next()
        time.sleep(0.1)

    def previous_song(self):
        if len(self.storage.database["player_info"]["player_list"]) == 0:
            return
        self.player.prev()
        time.sleep(0.1)

    def start(self):
        self.START = time.time() // 1
        self.ui.build_menu(self.datatype, self.title, self.datalist, self.offset, self.index, self.step, self.START)
        self.ui.build_process_bar(self.player.process_location, self.player.process_length, self.player.playing_flag,
                                  self.player.pause_flag, self.storage.database['player_info']['playing_mode'])
        self.stack.append([self.datatype, self.title, self.datalist, self.offset, self.index])
        if bind_global:
            keybinder.bind(self.config.get_item("global_play_pause"), self.play_pause)
            keybinder.bind(self.config.get_item("global_next"), self.next_song)
            keybinder.bind(self.config.get_item("global_previous"), self.previous_song)
        while True:
            datatype = self.datatype
            title = self.title
            datalist = self.datalist
            offset = self.offset
            idx = index = self.index
            step = self.step
            stack = self.stack
            djstack = self.djstack
            self.screen.timeout(500)
            key = self.screen.getch()
            if bind_global:
                keybinder.gtk.main_iteration(False)
            self.ui.screen.refresh()

            # term resize
            if key == -1:
                self.ui.update_size()
                self.player.update_size()

            # 退出
            if key == ord('q'):
                break

            # 退出并清除用户信息
            if key == ord('w'):
                self.storage.database['user'] = {
                    "username": "",
                    "password": "",
                    "user_id": "",
                    "nickname": "",
                }
                try:
                    os.remove(self.storage.cookie_path)
                except:
                    break
                break

            # 上移
            elif key == ord('k'):
                # turn page if at beginning
                if idx == offset:
                    if offset == 0:
                        continue
                    self.offset -= step
                    # 移动光标到最后一列
                    self.index = offset - 1
                else:
                    self.index = carousel(offset, min( len(datalist), offset + step) - 1, idx - 1)
                self.START = time.time()

            # 下移
            elif key == ord('j'):
                # turn page if at end
                if idx == min( len(datalist), offset + step) - 1:
                    if offset + step >= len( datalist ):
                        continue
                    self.offset += step
                    # 移动光标到第一列
                    self.index = offset + step
                else:
                    self.index = carousel(offset, min( len(datalist), offset + step) - 1, idx + 1)
                self.START = time.time()

            # 数字快捷键
            elif ord('0') <= key <= ord('9'):
                if self.datatype == 'songs' or self.datatype == 'djchannels' or self.datatype == 'help':
                    continue
                idx = key - ord('0')
                self.ui.build_menu(self.datatype, self.title, self.datalist, self.offset, idx, self.step, self.START)
                self.ui.build_loading()
                self.dispatch_enter(idx)
                self.index = 0
                self.offset = 0

            # 向上翻页
            elif key == ord('u'):
                if offset == 0:
                    continue
                self.START = time.time()
                self.offset -= step

                # e.g. 23 - 10 = 13 --> 10
                self.index = (index - step) // step * step

            # 向下翻页
            elif key == ord('d'):
                if offset + step >= len(datalist):
                    continue
                self.START = time.time()
                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' or len(self.datalist) <= 0:
                    continue
                self.START = time.time()
                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
                self.START = time.time()
                up = stack.pop()
                self.datatype = up[0]
                self.title = up[1]
                self.datalist = up[2]
                self.offset = up[3]
                self.index = up[4]
                self.at_playing_list = False

            # 搜索
            elif key == ord('f'):
                # 8 is the 'search' menu
                self.dispatch_enter(8)

            # 播放下一曲
            elif key == ord(']'):
                self.next_song()

            # 播放上一曲
            elif key == ord('['):
                self.previous_song()

            # 增加音量
            elif key == ord('='):
                self.player.volume_up()

            # 减少音量
            elif key == ord('-'):
                self.player.volume_down()

            # 随机播放
            elif key == ord('?'):
                if len(self.storage.database["player_info"]["player_list"]) == 0:
                    continue
                self.player.shuffle()
                time.sleep(0.1)

            # 喜爱
            elif key == ord(','):
                return_data = self.request_api(self.netease.fm_like, self.player.get_playing_id())
                if return_data != -1:
                    if platform.system() == 'Darwin':
                        os.system('/usr/bin/osascript -e \'display notification "Added successfully"\'')
                    else:
                        os.system('/usr/bin/notify-send "Added successfully"')

            # 删除FM
            elif key == ord('.'):
                if self.datatype == 'fmsongs':
                    if len(self.storage.database["player_info"]["player_list"]) == 0:
                        continue
                    self.player.next()
                    return_data = self.request_api(self.netease.fm_trash, self.player.get_playing_id())
                    if return_data != -1:
                        if platform.system() == 'Darwin':
                            os.system('/usr/bin/osascript -e \'display notification "Deleted successfully"\'')
                        else:
                            os.system('/usr/bin/notify-send "Deleted successfully"')
                    time.sleep(0.1)

            # 下一FM
            elif key == ord('/'):
                if self.datatype == 'fmsongs':
                    if len(self.storage.database["player_info"]["player_list"]) == 0:
                        continue
                    self.player.next()
                    time.sleep(0.1)

            # 播放、暂停
            elif key == ord(' '):
                # If not open a new playing list, just play and pause.
                try:
                    if self.datalist[idx]['song_id'] == self.player.playing_id:
                        self.player.play_and_pause(self.storage.database['player_info']['idx'])
                        time.sleep(0.1)
                        continue
                except:
                    pass
                # If change to a new playing list. Add playing list and play.
                if datatype == 'songs':
                    self.resume_play = False
                    self.player.new_player_list('songs', self.title, self.datalist, -1)
                    self.player.end_callback = None
                    self.player.play_and_pause(idx)
                    self.at_playing_list = True
                elif datatype == 'djchannels':
                    self.resume_play = False
                    self.player.new_player_list('djchannels', self.title, self.datalist, -1)
                    self.player.end_callback = None
                    self.player.play_and_pause(idx)
                    self.at_playing_list = True
                elif datatype == 'fmsongs':
                    self.resume_play = False
                    self.storage.database['player_info']['playing_mode'] = 0
                    self.player.new_player_list('fmsongs', self.title, self.datalist, -1)
                    self.player.end_callback = self.fm_callback
                    self.player.play_and_pause(idx)
                    self.at_playing_list = True
                else:
                    self.player.play_and_pause(self.storage.database['player_info']['idx'])
                time.sleep(0.1)

            # 加载当前播放列表
            elif key == ord('p'):
                self.show_playing_song()


            # 播放模式切换
            elif key == ord('P'):
                self.storage.database['player_info']['playing_mode'] = \
                    (self.storage.database['player_info']['playing_mode'] + 1) % 5

            # 添加到打碟歌单
            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])
                    if platform.system() == 'Darwin':
                        os.system('/usr/bin/osascript -e \'display notification "Added successfully"\'')
                    else:
                        os.system('/usr/bin/notify-send "Added successfully"')

            # 加载收藏歌曲
            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 == 'songs' or datatype == 'djchannels') and len(datalist) != 0:
                    self.datalist.pop(idx)
                    self.index = carousel(offset, min(len(datalist), offset + step) - 1, idx)

            # 当前项目下移
            elif key == ord("J"):
                if datatype != 'main' and len(datalist) != 0 and idx + 1 != len(self.datalist):
                    self.START = time.time()
                    song = self.datalist.pop(idx)
                    self.datalist.insert(idx + 1, song)
                    self.index = idx + 1
                    # 翻页
                    if self.index >= offset + step:
                        self.offset = offset + step

            # 当前项目上移
            elif key == ord("K"):
                if datatype != 'main' and len(datalist) != 0 and idx != 0:
                    self.START = time.time()
                    song = self.datalist.pop(idx)
                    self.datalist.insert(idx - 1, song)
                    self.index = idx - 1
                    # 翻页
                    if self.index < offset:
                        self.offset = offset - step

            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/darknessomi/musicbox')

            # 开始下载
            elif key == ord("C"):
                s = self.datalist[idx]
                cache_thread = threading.Thread(target=self.player.cacheSong1time, args=(
                    s['song_id'], s['song_name'], s['artist'], s['mp3_url']))
                cache_thread.start()

            elif key == ord('i'):
                if self.player.playing_id != -1:
                    webbrowser.open_new_tab('http://music.163.com/#/song?id=' + str(self.player.playing_id))

            self.ui.build_process_bar(self.player.process_location, self.player.process_length,
                                      self.player.playing_flag,
                                      self.player.pause_flag, self.storage.database['player_info']['playing_mode'])
            self.ui.build_menu(self.datatype, self.title, self.datalist, self.offset, self.index, self.step, self.START)

        self.player.stop()
        self.cache.quit()
        self.storage.save()
        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 idx > len(self.datalist):
            return False

        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':
            data = self.datalist[idx]
            self.datatype = data['datatype']
            self.datalist = netease.dig_info(data['callback'](), self.datatype)
            self.title += ' > ' + data['title']

        # 全站置顶歌单包含的歌曲
        elif datatype == 'top_playlists':
            log.debug(datalist)
            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']

        # 分类精选
        elif datatype == 'playlist_classes':
            # 分类名称
            data = self.datalist[idx]
            self.datatype = 'playlist_class_detail'
            self.datalist = netease.dig_info(data, self.datatype)
            self.title += ' > ' + data
            log.debug(self.datalist)

        # 某一分类的详情
        elif datatype == 'playlist_class_detail':
            # 子类别
            data = self.datalist[idx]
            self.datatype = 'top_playlists'
            self.datalist = netease.dig_info(netease.top_playlists(data), self.datatype)
            log.debug(self.datalist)
            self.title += ' > ' + data

        # 歌曲榜单
        elif datatype == 'toplists':
            songs = netease.top_songlist(idx)
            self.title += ' > ' + self.datalist[idx]
            self.datalist = netease.dig_info(songs, 'songs')
            self.datatype = 'songs'

        # 搜索菜单
        elif datatype == 'search':
            ui = self.ui
            # no need to do stack.append, Otherwise there will be a bug when you input key 'h' to return
            # if idx in range(1, 5):
            # self.stack.append([self.datatype, self.title, self.datalist, self.offset, self.index])
            self.index = 0
            self.offset = 0
            if idx == 0:
                # 搜索结果可以用top_playlists处理
                self.datatype = 'top_playlists'
                self.datalist = ui.build_search('search_playlist')
                self.title = '精选歌单搜索列表'

            elif idx == 1:
                self.datatype = 'songs'
                self.datalist = ui.build_search('songs')
                self.title = '歌曲搜索列表'

            elif idx == 2:
                self.datatype = 'artists'
                self.datalist = ui.build_search('artists')
                self.title = '艺术家搜索列表'

            elif idx == 3:
                self.datatype = 'albums'
                self.datalist = ui.build_search('albums')
                self.title = '专辑搜索列表'


    def show_playing_song(self):
        if len(self.storage.database['player_info']['player_list']) == 0:
            return
        if not self.at_playing_list:
            self.stack.append([self.datatype, self.title, self.datalist, self.offset, self.index])
            self.at_playing_list = True
        self.datatype = self.storage.database['player_info']['player_list_type']
        self.title = self.storage.database['player_info']['player_list_title']
        self.datalist = []
        for i in self.storage.database['player_info']['player_list']:
            self.datalist.append(self.storage.database['songs'][i])
        self.index = self.storage.database['player_info']['idx']
        self.offset = self.storage.database['player_info']['idx'] / self.step * self.step
        if self.resume_play:
            if self.datatype == "fmsongs":
                self.player.end_callback = self.fm_callback
            else:
                self.player.end_callback = None
            self.storage.database['player_info']['idx'] = -1
            self.player.play_and_pause(self.index)
            self.resume_play = False

    def song_changed_callback(self):
        if self.at_playing_list:
            self.show_playing_song()

    def fm_callback(self):
        log.debug("FM CallBack.")
        data = self.get_new_fm()
        self.player.append_songs(data)
        if self.datatype == 'fmsongs':
            if len(self.storage.database['player_info']['player_list']) == 0:
                return
            self.datatype = self.storage.database['player_info']['player_list_type']
            self.title = self.storage.database['player_info']['player_list_title']
            self.datalist = []
            for i in self.storage.database['player_info']['player_list']:
                self.datalist.append(self.storage.database['songs'][i])
            self.index = self.storage.database['player_info']['idx']
            self.offset = self.storage.database['player_info']['idx'] / self.step * self.step

    def request_api(self, func, *args):
        if self.storage.database['user']['user_id'] != "":
            result = func(*args)
            if result != -1:
                return result
        log.debug("Re Login.")
        user_info = {}
        if self.storage.database['user']['username'] != "":
            user_info = self.netease.login(self.storage.database['user']['username'],
                                           self.storage.database['user']['password'])
        if self.storage.database['user']['username'] == "" or user_info['code'] != 200:
            data = self.ui.build_login()
            # 取消登录
            if data == -1:
                return -1
            user_info = data[0]
            self.storage.database['user']['username'] = data[1][0]
            self.storage.database['user']['password'] = data[1][1]
            self.storage.database['user']['user_id'] = user_info['account']['id']
            self.storage.database['user']['nickname'] = user_info['profile']['nickname']
        self.userid = self.storage.database["user"]["user_id"]
        self.username = self.storage.database["user"]["nickname"]
        return func(*args)

    def get_new_fm(self):
        myplaylist = []
        for count in range(0, 1):
            data = self.request_api(self.netease.personal_fm)
            if data == -1:
                break
            myplaylist += data
            time.sleep(0.2)
        return self.netease.dig_info(myplaylist, "fmsongs")

    def choice_channel(self, idx):
        # 排行榜
        netease = self.netease
        if idx == 0:
            self.datalist = netease.return_toplists()
            self.title += ' > 排行榜'
            self.datatype = 'toplists'

        # 艺术家
        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:
            self.datalist = [
                {
                    'title': '全站置顶',
                    'datatype': 'top_playlists',
                    'callback': netease.top_playlists
                },
                {
                    'title': '分类精选',
                    'datatype': 'playlist_classes',
                    'callback': netease.playlist_classes
                }
            ]
            self.title += ' > 精选歌单'
            self.datatype = 'playlists'

        # 我的歌单
        elif idx == 4:
            myplaylist = self.request_api(self.netease.user_playlist, self.userid)
            if myplaylist == -1:
                return
            self.datatype = 'top_playlists'
            self.datalist = netease.dig_info(myplaylist, self.datatype)
            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 += ' > 每日推荐'
            myplaylist = self.request_api(self.netease.recommend_playlist)
            if myplaylist == -1:
                return
            self.datalist = self.netease.dig_info(myplaylist, self.datatype)

        # 私人FM
        elif idx == 7:
            self.datatype = 'fmsongs'
            self.title += ' > 私人FM'
            self.datalist = self.get_new_fm()

        # 搜索
        elif idx == 8:
            self.datatype = 'search'
            self.title += ' > 搜索'
            self.datalist = ['歌曲', '艺术家', '专辑', '网易精选集']

        # 帮助
        elif idx == 9:
            self.datatype = 'help'
            self.title += ' > 帮助'
            self.datalist = shortcut

        self.offset = 0
        self.index = 0
コード例 #4
0
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):
        curses.noecho()
        # 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
        curses.noecho()
        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]['title'], curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset +8, 19, str(i) + '. ' + datalist[i]['title'])


            elif datatype == 'top_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 == 'playlist_classes' or datatype == 'playlist_class_detail':
                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 == '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 omi')

        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 == 'search_playlist':
            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, 'top_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):
        curses.noecho()
        info = self.get_param('请输入登录信息, e.g: [email protected] 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    	
        curses.echo()
        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
コード例 #5
0
pool = ThreadPool(10)

# 考虑到歌单最多10000首歌,故采用多个歌单
wait_song_list = [644264533, 644752348, 644765343, 644738922, 644776005, 644749639, 644756477, 644818427, 644835023, 644810557,
                  644806753, 644811524, 644800922, 644793786]
# wait_song_list = [644810557, 644806753, 644811524, 644800922, 644793786]
back_song_list = [583517654, 431743699]

joker = NetEase()
user_info = {}
local_account = '*****@*****.**'
local_password = '******'
#local_account = '*****@*****.**'
#local_password = '******'

login_info = joker.login(local_account, local_password)
print login_info

def track_log(i):
    song_info = joker.song_info(i)
    print song_info
    if song_info:
        #print song_info
        try:
            play_time = song_info[0]['bMusic']['playTime']/1000
        except IndexError:
            play_time = 60
        print 'finish %s %s' % (i, joker.track_log(i, play_time))
        #time.sleep(0.5)
    else:
        print 'no song %s' % (i)
コード例 #6
0
ファイル: ui.py プロジェクト: zyaphone/musicbox
class Ui:
    def __init__(self):
        self.screen = curses.initscr()
        self.screen.timeout(100)  # the screen refresh every 100ms
        # 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)
        # term resize handling
        size = terminalsize.get_terminal_size()
        self.x = max(size[0], 10)
        self.y = max(size[1], 25)
        self.startcol = int(float(self.x) / 5)
        self.indented_startcol = max(self.startcol - 3, 0)
        self.update_space()
        self.lyric = ""
        self.now_lyric = ""
        self.tlyric = ""
        self.storage = Storage()
        self.config = Config()
        self.newversion = False

    def notify(self, summary, song, album, artist):
        if summary != "disable":
            cmd = ""
            body = "%s\nin %s by %s" % (song, album, artist)
            if platform.system() == "Darwin":
                content = escape_quote(summary + ': ' + body)
                cmd = '/usr/bin/osascript -e $\'display notification "' + content + '"\''
            else:
                cmd = '/usr/bin/notify-send -a NetEase-MusicBox "%s" "%s"' % (summary, body)

            os.system(cmd)


    def build_playinfo(self, song_name, artist, album_name, quality, start, pause=False):
        curses.noecho()
        # 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, self.indented_startcol, '_ _ z Z Z ' + quality, curses.color_pair(3))
        else:
            self.screen.addstr(1, self.indented_startcol, '♫  ♪ ♫  ♪ ' + quality, curses.color_pair(3))

        self.screen.addstr(1, min(self.indented_startcol + 18, self.x - 1),
                           song_name + self.space + artist + '  < ' + album_name + ' >',
                           curses.color_pair(4))


        # The following script doesn't work. It is intended to scroll the playinfo
        # Scrollstring works by determining how long since it is created, but
        # playinfo is created everytime the screen refreshes (every 500ms), unlike
        # the menu. Is there a workaround?

        # name = song_name + self.space + artist + '  < ' + album_name + ' >'

        # decides whether to scoll
        # if truelen(name) <= self.x - self.indented_startcol - 18:
        #     self.screen.addstr(1, min(self.indented_startcol + 18, self.x-1),
        #                        name,
        #                        curses.color_pair(4))
        # else:
        #     name = scrollstring(name + '  ', start)
        #     self.screen.addstr(1, min(self.indented_startcol + 18, self.x-1),
        #                        str(name),
        #                        curses.color_pair(4))

        self.screen.refresh()

    def build_process_bar(self, now_playing, total_length, playing_flag, pause_flag, playing_mode):
        if (self.storage.database["player_info"]["idx"] >= len(self.storage.database["player_info"]["player_list"])):
            return
        curses.noecho()
        self.screen.move(3, 1)
        self.screen.clrtoeol()
        self.screen.move(4, 1)
        self.screen.clrtoeol()
        if not playing_flag:
            return
        if total_length <= 0:
            total_length = 1
        if now_playing > total_length or now_playing <= 0:
            now_playing = 0
        process = "["
        for i in range(0, 33):
            if i < now_playing / total_length * 33:
                if (i + 1) > now_playing / total_length * 33:
                    if not pause_flag:
                        process += ">"
                        continue
                process += "="
            else:
                process += " "
        process += "] "
        now_minute = int(now_playing / 60)
        if now_minute > 9:
            now_minute = str(now_minute)
        else:
            now_minute = "0" + str(now_minute)
        now_second = int(now_playing - int(now_playing / 60) * 60)
        if now_second > 9:
            now_second = str(now_second)
        else:
            now_second = "0" + str(now_second)
        total_minute = int(total_length / 60)
        if total_minute > 9:
            total_minute = str(total_minute)
        else:
            total_minute = "0" + str(total_minute)
        total_second = int(total_length - int(total_length / 60) * 60)
        if total_second > 9:
            total_second = str(total_second)
        else:
            total_second = "0" + str(total_second)
        process += "(" + now_minute + ":" + now_second + "/" + total_minute + ":" + total_second + ")"
        if playing_mode == 0:
            process = "顺序播放 " + process
        elif playing_mode == 1:
            process = "顺序循环 " + process
        elif playing_mode == 2:
            process = "单曲循环 " + process
        elif playing_mode == 3:
            process = "随机播放 " + process
        elif playing_mode == 4:
            process = "随机循环 " + process
        else:
            pass
        self.screen.addstr(3, self.startcol - 2, process, curses.color_pair(1))
        song = self.storage.database["songs"][
            self.storage.database["player_info"]["player_list"][self.storage.database["player_info"]["idx"]]
        ]
        if 'lyric' not in song.keys() or len(song["lyric"]) <= 0:
            self.now_lyric = "[00:00.00]暂无歌词 ~>_<~ \n"
        else:
            key = now_minute + ":" + now_second
            for line in song["lyric"]:
                if key in line:
                    if 'tlyric' not in song.keys() or len(song["tlyric"]) <= 0:
                        self.now_lyric = line
                    else:
                        self.now_lyric = line
                        for tline in song["tlyric"]:
                            if key in tline and self.config.get_item("translation"):
                                self.now_lyric = tline + " || " + self.now_lyric
        self.now_lyric = re.sub('\[.*?\]', "", self.now_lyric)
        self.screen.addstr(4, self.startcol - 2, str(self.now_lyric), curses.color_pair(3))
        self.screen.refresh()

    def build_loading(self):
        self.screen.addstr(7, self.startcol, '享受高品质音乐,loading...', curses.color_pair(1))
        self.screen.refresh()

    # start is the timestamp of this function being called
    def build_menu(self, datatype, title, datalist, offset, index, step, start):
        # keep playing info in line 1
        curses.noecho()
        self.screen.move(5, 1)
        self.screen.clrtobot()
        self.screen.addstr(5, self.startcol, title, curses.color_pair(1))

        if len(datalist) == 0:
            self.screen.addstr(8, self.startcol, '这里什么都没有 -,-')

        else:
            if datatype == 'main':
                for i in range(offset, min(len(datalist), offset + step)):
                    if i == index:
                        self.screen.addstr(i - offset + 9, self.indented_startcol, '-> ' + str(i) + '. ' + datalist[i],
                                           curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset + 9, self.startcol, str(i) + '. ' + datalist[i])

            elif datatype == 'songs' or datatype == 'fmsongs':
                iter_range = min(len(datalist), offset + step)
                for i in range(offset, iter_range):
                    # this item is focus
                    if i == index:
                        self.screen.addstr(i - offset + 8, 0, ' ' * self.startcol)
                        lead = '-> ' + str(i) + '. '
                        self.screen.addstr(i - offset + 8, self.indented_startcol, lead, curses.color_pair(2))
                        name = str(datalist[i]['song_name'] + self.space + datalist[i][
                            'artist'] + '  < ' + datalist[i]['album_name'] + ' >')

                        # the length decides whether to scoll
                        if truelen(name) < self.x - self.startcol - 1:
                            self.screen.addstr(i - offset + 8, self.indented_startcol + len(lead),
                                               name,
                                               curses.color_pair(2))
                        else:
                            name = scrollstring(name + '  ', start)
                            self.screen.addstr(i - offset + 8, self.indented_startcol + len(lead),
                                               str(name),
                                               curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset + 8, 0, ' ' * self.startcol)
                        self.screen.addstr(i - offset + 8, self.startcol,
                                           str(str(i) + '. ' + datalist[i]['song_name'] + self.space + datalist[i][
                                               'artist'] + '  < ' + datalist[i]['album_name'] + ' >')[:int(self.x * 2)])
                    self.screen.addstr(iter_range - offset + 9, 0, ' ' * self.x)

            elif datatype == 'artists':
                for i in range(offset, min(len(datalist), offset + step)):
                    if i == index:
                        self.screen.addstr(i - offset + 9, self.indented_startcol,
                                           '-> ' + str(i) + '. ' + datalist[i]['artists_name'] + self.space + str(
                                               datalist[i]['alias']), curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset + 9, self.startcol,
                                           str(i) + '. ' + datalist[i]['artists_name'] + self.space + datalist[i][
                                               'alias'])

            elif datatype == 'albums':
                for i in range(offset, min(len(datalist), offset + step)):
                    if i == index:
                        self.screen.addstr(i - offset + 9, self.indented_startcol,
                                           '-> ' + str(i) + '. ' + datalist[i]['albums_name'] + self.space +
                                           datalist[i][
                                               'artists_name'], curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset + 9, self.startcol,
                                           str(i) + '. ' + datalist[i]['albums_name'] + self.space + 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 + 9, self.indented_startcol,
                                           '-> ' + str(i) + '. ' + datalist[i]['title'],
                                           curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset + 9, self.startcol, str(i) + '. ' + datalist[i]['title'])


            elif datatype == 'top_playlists':
                for i in range(offset, min(len(datalist), offset + step)):
                    if i == index:
                        self.screen.addstr(i - offset + 9, self.indented_startcol,
                                           '-> ' + str(i) + '. ' + datalist[i]['playlists_name'] + self.space +
                                           datalist[i]['creator_name'], curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset + 9, self.startcol,
                                           str(i) + '. ' + datalist[i]['playlists_name'] + self.space + datalist[i][
                                               'creator_name'])


            elif datatype == 'toplists':
                for i in range(offset, min(len(datalist), offset + step)):
                    if i == index:
                        self.screen.addstr(i - offset + 9, self.indented_startcol, '-> ' + str(i) + '. ' + datalist[i],
                                           curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset + 9, self.startcol, str(i) + '. ' + datalist[i])


            elif datatype == 'playlist_classes' or datatype == 'playlist_class_detail':
                for i in range(offset, min(len(datalist), offset + step)):
                    if i == index:
                        self.screen.addstr(i - offset + 9, self.indented_startcol, '-> ' + str(i) + '. ' + datalist[i],
                                           curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset + 9, self.startcol, str(i) + '. ' + datalist[i])

            elif datatype == 'djchannels':
                for i in range(offset, min(len(datalist), offset + step)):
                    if i == index:
                        self.screen.addstr(i - offset + 8, self.indented_startcol,
                                           '-> ' + str(i) + '. ' + datalist[i]['song_name'],
                                           curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset + 8, self.startcol, str(i) + '. ' + datalist[i]['song_name'])

            elif datatype == 'search':
                self.screen.move(6, 1)
                self.screen.clrtobot()
                self.screen.timeout(-1)
                self.screen.addstr(8, self.startcol, '选择搜索类型:', curses.color_pair(1))
                for i in range(offset, min(len(datalist), offset + step)):
                    if i == index:
                        self.screen.addstr(i - offset + 10, self.indented_startcol,
                                           '-> ' + str(i) + '.' + datalist[i - 1],
                                           curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset + 10, self.startcol, str(i) + '.' + datalist[i - 1])
                self.screen.timeout(100)

            elif datatype == 'help':
                for i in range(offset, min(len(datalist), offset + step)):
                    if i == index:
                        self.screen.addstr(i - offset + 9, self.indented_startcol,
                                           '-> ' + str(i) + '. \'' + (datalist[i][0].upper() + '\'').ljust(11) +
                                           datalist[i][
                                               1] + '   ' + datalist[i][2], curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset + 9, self.startcol,
                                           str(i) + '. \'' + (datalist[i][0].upper() + '\'').ljust(11) + 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, self.startcol, 'Build with love to music by omi')

        self.screen.refresh()

    def build_search(self, stype):
        self.screen.timeout(-1)
        netease = self.netease
        if stype == 'songs':
            song_name = self.get_param('搜索歌曲:')
            if song_name == '/return':
                return []
            else:
                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('搜索艺术家:')
            if artist_name == '/return':
                return []
            else:
                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':
            albums_name = self.get_param('搜索专辑:')
            if albums_name == '/return':
                return []
            else:
                try:
                    data = netease.search(albums_name, stype=10)
                    if 'albums' in data['result']:
                        albums = data['result']['albums']
                        return netease.dig_info(albums, 'albums')
                except:
                    return []

        elif stype == 'search_playlist':
            search_playlist = self.get_param('搜索网易精选集:')
            if search_playlist == '/return':
                return []
            else:
                try:
                    data = netease.search(search_playlist, stype=1000)
                    if 'playlists' in data['result']:
                        playlists = data['result']['playlists']
                        return netease.dig_info(playlists, 'top_playlists')
                except:
                    return []

        return []

    def build_login(self):
        self.build_login_bar()
        local_account = self.get_account()
        local_password = hashlib.md5(self.get_password()).hexdigest()
        login_info = self.netease.login(local_account, local_password)
        account = [local_account, local_password]
        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_bar(self):
        curses.noecho()
        self.screen.move(4, 1)
        self.screen.clrtobot()
        self.screen.addstr(5, self.startcol, '请输入登录信息(支持手机登陆)', curses.color_pair(1))
        self.screen.addstr(8, self.startcol, "账号:", curses.color_pair(1))
        self.screen.addstr(9, self.startcol, "密码:", curses.color_pair(1))
        self.screen.move(8, 24)
        self.screen.refresh()

    def build_login_error(self):
        self.screen.move(4, 1)
        self.screen.timeout(-1)  # disable the screen timeout
        self.screen.clrtobot()
        self.screen.addstr(8, self.startcol, '艾玛,登录信息好像不对呢 (O_O)#', curses.color_pair(1))
        self.screen.addstr(10, self.startcol, '[1] 再试一次')
        self.screen.addstr(11, self.startcol, '[2] 稍后再试')
        self.screen.addstr(14, self.startcol, '请键入对应数字:', curses.color_pair(2))
        self.screen.refresh()
        x = self.screen.getch()
        self.screen.timeout(100)  # restore the screen timeout
        return x

    def get_account(self):
        self.screen.timeout(-1)  # disable the screen timeout
        curses.echo()
        account = self.screen.getstr(8, self.startcol + 6, 60)
        self.screen.timeout(100)  # restore the screen timeout
        return account

    def get_password(self):
        self.screen.timeout(-1)  # disable the screen timeout
        curses.noecho()
        password = self.screen.getstr(9, self.startcol + 6, 60)
        self.screen.timeout(100)  # restore the screen timeout
        return password

    def get_param(self, prompt_string):
        # keep playing info in line 1
        curses.echo()
        self.screen.move(4, 1)
        self.screen.clrtobot()
        self.screen.addstr(5, self.startcol, prompt_string, curses.color_pair(1))
        self.screen.refresh()
        info = self.screen.getstr(10, self.startcol, 60)
        if info == '':
            return '/return'
        elif info.strip() is '':
            return self.get_param(prompt_string)
        else:
            return info

    def update_size(self):
        # get terminal size
        size = terminalsize.get_terminal_size()
        self.x = max(size[0], 10)
        self.y = max(size[1], 25)

        # update intendations
        curses.resizeterm(self.y, self.x)
        self.startcol = int(float(self.x) / 5)
        self.indented_startcol = max(self.startcol - 3, 0)
        self.update_space()
        self.screen.clear()
        self.screen.refresh()

    def update_space(self):
        if self.x > 140:
            self.space = "   -   "
        elif self.x > 80:
            self.space = "  -  "
        else:
            self.space = " - "
        self.screen.refresh()
コード例 #7
0
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, 'Waiting for you,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, 'Nothing -,-')

        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 Based on Python, all rights revesred by NetEase')
                self.screen.addstr(21, 10, 'Input [G] to GitHub')
                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('Search by Songs:')
            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('Search by Artists:')
            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('Search by Artists:')
            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('Search by Playlists:')
            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, 'Search Type:', curses.color_pair(1))
        self.screen.addstr(10, 19, '[1] Songs')
        self.screen.addstr(11, 19, '[2] Artists')
        self.screen.addstr(12, 19, '[3] Albums')
        self.screen.addstr(13, 19, '[4] Playist')
        self.screen.addstr(16, 19, 'Please input the option:', curses.color_pair(2))
        self.screen.refresh()
        x = self.screen.getch()
        return x

    def build_login(self):
        info = self.get_param('Log In, e.g: [email protected] 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, 'Something wrong(O_O)#', curses.color_pair(1))
        self.screen.addstr(10, 19, '[1] Try Again')
        self.screen.addstr(11, 19, '[2] Later')
        self.screen.addstr(14, 19, 'Please input the option', 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
コード例 #8
0
ファイル: ui.py プロジェクト: hoyho/musicbox
class Ui:
    def __init__(self):
        self.screen = curses.initscr()
        # charactor break buffer
        curses.cbreak()
        #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)
        # term resize handling
        size = terminalsize.get_terminal_size()
        self.x = max(size[0], 10)
        self.y = max(size[1], 25)
        self.startcol = int(float(self.x)/5)
        self.indented_startcol = max(self.startcol - 3, 0)
        self.update_space()
        

    def build_playinfo(self, song_name, artist, album_name, quality, pause=False):
        curses.noecho()
        # 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, self.indented_startcol, '_ _ z Z Z ' + quality, curses.color_pair(3))
        else:
            self.screen.addstr(1, self.indented_startcol, '♫  ♪ ♫  ♪ ' + quality, curses.color_pair(3))
        self.screen.addstr(1, min(self.indented_startcol + 18, self.x-1), song_name + self.space + artist + '  < ' + album_name + ' >', curses.color_pair(4))
        self.screen.refresh()

    def build_loading(self):
        self.screen.addstr(6, self.startcol, '享受高品质音乐,loading...', curses.color_pair(1))
        self.screen.refresh()


    def build_menu(self, datatype, title, datalist, offset, index, step):
        # keep playing info in line 1
        curses.noecho()
        self.screen.move(4, 1)
        self.screen.clrtobot()
        self.screen.addstr(4, self.startcol, title, curses.color_pair(1))

        if len(datalist) == 0:
            self.screen.addstr(8, self.startcol, '这里什么都没有 -,-')

        else:
            if datatype == 'main':
                for i in range(offset, min(len(datalist), offset + step)):
                    if i == index:
                        self.screen.addstr(i - offset + 8, self.indented_startcol, '-> ' + str(i) + '. ' + datalist[i],
                                           curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset + 8, self.startcol, str(i) + '. ' + datalist[i])

            elif datatype == 'songs':
                iter_range = min(len(datalist), offset + step)
                for i in range(offset, iter_range):
                    # this item is focus
                    if i == index:
                        self.screen.addstr(i - offset + 8, 0, ' ' * self.startcol)
                        self.screen.addstr(i - offset + 8, self.indented_startcol,
                                           str('-> ' + str(i) + '. ' + datalist[i]['song_name'] + self.space + datalist[i][
                                               'artist'] + '  < ' + datalist[i]['album_name'] + ' >')[:int(self.x*2)],
                                           curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset + 8, 0, ' ' * self.startcol)
                        self.screen.addstr(i - offset + 8, self.startcol,
                                           str(str(i) + '. ' + datalist[i]['song_name'] + self.space + datalist[i][
                                               'artist'] + '  < ' + datalist[i]['album_name'] + ' >')[:int(self.x*2)])
                    self.screen.addstr(iter_range - offset + 8, 0, ' ' * self.x)

            elif datatype == 'artists':
                for i in range(offset, min(len(datalist), offset + step)):
                    if i == index:
                        self.screen.addstr(i - offset + 8, self.indented_startcol,
                                           '-> ' + str(i) + '. ' + datalist[i]['artists_name'] + self.space + str(
                                               datalist[i]['alias']), curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset + 8, self.startcol,
                                           str(i) + '. ' + datalist[i]['artists_name'] + self.space + 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, self.indented_startcol,
                                           '-> ' + str(i) + '. ' + datalist[i]['albums_name'] + self.space + datalist[i][
                                               'artists_name'], curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset + 8, self.startcol,
                                           str(i) + '. ' + datalist[i]['albums_name'] + self.space + 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, self.indented_startcol, '-> ' + str(i) + '. ' + datalist[i]['title'],
                                           curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset + 8, self.startcol, str(i) + '. ' + datalist[i]['title'])


            elif datatype == 'top_playlists':
                for i in range(offset, min(len(datalist), offset + step)):
                    if i == index:
                        self.screen.addstr(i - offset + 8, self.indented_startcol,
                                           '-> ' + str(i) + '. ' + datalist[i]['playlists_name'] + self.space +
                                           datalist[i]['creator_name'], curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset + 8, self.startcol,
                                           str(i) + '. ' + datalist[i]['playlists_name'] + self.space + datalist[i][
                                               'creator_name'])


            elif datatype == 'toplists':
                for i in range(offset, min(len(datalist), offset + step)):
                    if i == index:
                        self.screen.addstr(i - offset + 8, self.indented_startcol, '-> ' + str(i) + '. ' + datalist[i], curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset + 8, self.startcol, str(i) + '. ' + datalist[i])


            elif datatype == 'playlist_classes' or datatype == 'playlist_class_detail':
                for i in range(offset, min(len(datalist), offset + step)):
                    if i == index:
                        self.screen.addstr(i - offset + 8, self.indented_startcol, '-> ' + str(i) + '. ' + datalist[i],
                                           curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset + 8, self.startcol, str(i) + '. ' + datalist[i])

            elif datatype == 'djchannels':
                for i in range(offset, min(len(datalist), offset + step)):
                    if i == index:
                        self.screen.addstr(i - offset + 8, self.indented_startcol, '-> ' + str(i) + '. ' + datalist[i]['song_name'],
                                           curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset + 8, self.startcol, str(i) + '. ' + datalist[i]['song_name'])

            elif datatype == 'search':
                self.screen.move(4, 1)
                self.screen.clrtobot()
                self.screen.addstr(8, self.startcol, '选择搜索类型:', curses.color_pair(1))
                for i in range(offset, min(len(datalist), offset + step)):
                    if i == index:
                        self.screen.addstr(i - offset + 10, self.indented_startcol, '-> ' + str(i) + '.' + datalist[i - 1],
                                           curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset + 10, self.startcol, str(i) + '.' + datalist[i - 1])
            elif datatype == 'help':
                for i in range(offset, min(len(datalist), offset + step)):
                    if i == index:
                        self.screen.addstr(i - offset + 8, self.indented_startcol,
                                           '-> ' + str(i) + '. \'' + (datalist[i][0].upper() + '\'').ljust(11) + datalist[i][
                                               1] + '   ' + datalist[i][2], curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset + 8, self.startcol,
                                           str(i) + '. \'' + (datalist[i][0].upper() + '\'').ljust(11) + 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, self.startcol, 'Build with love to music by omi')

        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 == 'search_playlist':
            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, 'top_playlists')
            except:
                return []

        return []

    def build_login(self):
        self.build_login_bar()
        local_account = self.get_account()
        local_password = hashlib.md5(self.get_password()).hexdigest()
        login_info = self.netease.login(local_account, local_password)
        account = [local_account,local_password]
        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_bar(self):
        curses.noecho()
        self.screen.move(4, 1)
        self.screen.clrtobot()
        self.screen.addstr(5, self.startcol, '请输入登录信息(支持手机登陆)',curses.color_pair(1))
        self.screen.addstr(8, self.startcol, "账号:", curses.color_pair(1))
        self.screen.addstr(9, self.startcol, "密码:", curses.color_pair(1))
        self.screen.move(8,24)
        self.screen.refresh()

    def build_login_error(self):
        self.screen.move(4, 1)
        self.screen.clrtobot()
        self.screen.addstr(8, self.startcol, '艾玛,登录信息好像不对呢 (O_O)#', curses.color_pair(1))
        self.screen.addstr(10, self.startcol, '[1] 再试一次')
        self.screen.addstr(11, self.startcol, '[2] 稍后再试')
        self.screen.addstr(14, self.startcol, '请键入对应数字:', curses.color_pair(2))
        self.screen.refresh()
        x = self.screen.getch()
        return x

    def get_account(self):
        curses.echo()
        account = self.screen.getstr(8, self.startcol+6,60)
        return account

    def get_password(self):
        curses.noecho()
        password = self.screen.getstr(9, self.startcol+6,60)
        return password

    def get_param(self, prompt_string):
        # keep playing info in line 1
        curses.echo()
        self.screen.move(4, 1)
        self.screen.clrtobot()
        self.screen.addstr(5, self.startcol, prompt_string, curses.color_pair(1))
        self.screen.refresh()
        info = self.screen.getstr(10, self.startcol, 60)
        if info.strip() is '':
            return self.get_param(prompt_string)
        else:
            return info

    def update_size(self):
        # get terminal size
        size = terminalsize.get_terminal_size()
        self.x = max(size[0], 10)
        self.y = max(size[1], 25)
        
        # update intendations
        curses.resizeterm(self.y, self.x)
        self.startcol = int(float(self.x)/5)
        self.indented_startcol = max(self.startcol - 3, 0)
        self.update_space()
        self.screen.clear()
        self.screen.refresh()

    def update_space(self):
        if self.x > 140:
            self.space = "   -   "
        elif self.x > 80:
            self.space = "  -  "
        else:
            self.space = " - "
        self.screen.refresh()
コード例 #9
0
ファイル: ui.py プロジェクト: Zorgodon/musicbox
class Ui(object):
    def __init__(self):
        self.screen = curses.initscr()
        self.screen.timeout(100)  # the screen refresh every 100ms
        # 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)
        # term resize handling
        size = terminalsize.get_terminal_size()
        self.x = max(size[0], 10)
        self.y = max(size[1], 25)
        self.startcol = int(float(self.x) / 5)
        self.indented_startcol = max(self.startcol - 3, 0)
        self.update_space()
        self.lyric = ''
        self.now_lyric = ''
        self.tlyric = ''
        self.storage = Storage()
        self.config = Config()
        self.newversion = False

    def notify(self, summary, song, album, artist):
        if summary != 'disable':
            body = '%s\nin %s by %s' % (song, album, artist)
            content = escape_quote(summary + ': ' + body)
            notify(content)

    def build_playinfo(self,
                       song_name,
                       artist,
                       album_name,
                       quality,
                       start,
                       pause=False):
        curses.noecho()
        # 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, self.indented_startcol,
                               '_ _ z Z Z ' + quality, curses.color_pair(3))
        else:
            self.screen.addstr(1, self.indented_startcol,
                               '♫  ♪ ♫  ♪ ' + quality, curses.color_pair(3))

        self.screen.addstr(
            1, min(self.indented_startcol + 18, self.x - 1),
            song_name + self.space + artist + '  < ' + album_name + ' >',
            curses.color_pair(4))

        self.screen.refresh()

    def build_process_bar(self, now_playing, total_length, playing_flag,
                          pause_flag, playing_mode):
        if (self.storage.database['player_info']['idx'] >=
                len(self.storage.database['player_info']['player_list'])):
            return
        curses.noecho()
        self.screen.move(3, 1)
        self.screen.clrtoeol()
        self.screen.move(4, 1)
        self.screen.clrtoeol()
        if not playing_flag:
            return
        if total_length <= 0:
            total_length = 1
        if now_playing > total_length or now_playing <= 0:
            now_playing = 0
        process = '['
        for i in range(0, 33):
            if i < now_playing / total_length * 33:
                if (i + 1) > now_playing / total_length * 33:
                    if not pause_flag:
                        process += '>'
                        continue
                process += '='
            else:
                process += ' '
        process += '] '
        now_minute = int(now_playing / 60)
        if now_minute > 9:
            now_minute = str(now_minute)
        else:
            now_minute = '0' + str(now_minute)
        now_second = int(now_playing - int(now_playing / 60) * 60)
        if now_second > 9:
            now_second = str(now_second)
        else:
            now_second = '0' + str(now_second)
        total_minute = int(total_length / 60)
        if total_minute > 9:
            total_minute = str(total_minute)
        else:
            total_minute = '0' + str(total_minute)
        total_second = int(total_length - int(total_length / 60) * 60)
        if total_second > 9:
            total_second = str(total_second)
        else:
            total_second = '0' + str(total_second)
        process += '(' + now_minute + ':' + now_second + '/' + total_minute + ':' + total_second + ')'  # NOQA
        if playing_mode == 0:
            process = 'No Repeat ' + process
        elif playing_mode == 1:
            process = 'Repeat All ' + process
        elif playing_mode == 2:
            process = 'Repeat Song ' + process
        elif playing_mode == 3:
            process = 'Shuffle ' + process
        elif playing_mode == 4:
            process = 'Random ' + process
        else:
            pass
        self.screen.addstr(3, self.startcol - 2, process, curses.color_pair(1))
        song = self.storage.database['songs'][
            self.storage.database['player_info']['player_list'][
                self.storage.database['player_info']['idx']]]
        if 'lyric' not in song.keys() or len(song['lyric']) <= 0:
            self.now_lyric = 'No Lyrics ~>_<~ \n'
            if dbus_activity and self.config.get_item('osdlyrics'):
                self.now_playing = song['song_name'] + ' - ' + song[
                    'artist'] + '\n'

        else:
            key = now_minute + ':' + now_second
            for line in song['lyric']:
                if key in line:
                    if 'tlyric' not in song.keys() or len(song['tlyric']) <= 0:
                        self.now_lyric = line
                    else:
                        self.now_lyric = line
                        for tline in song['tlyric']:
                            if key in tline and self.config.get_item(
                                    'translation'):
                                self.now_lyric = tline + ' || ' + self.now_lyric  # NOQA
        self.now_lyric = re.sub('\[.*?\]', '', self.now_lyric)
        if dbus_activity and self.config.get_item('osdlyrics'):
            try:
                bus = dbus.SessionBus().get_object('org.musicbox.Bus', '/')
                if self.now_lyric == 'No Lyrics ~>_<~ \n':
                    bus.refresh_lyrics(self.now_playing,
                                       dbus_interface='local.musicbox.Lyrics')
                else:
                    bus.refresh_lyrics(self.now_lyric,
                                       dbus_interface='local.musicbox.Lyrics')
            except Exception as e:
                log.error(e)
                pass
        self.screen.addstr(4, self.startcol - 2, str(self.now_lyric),
                           curses.color_pair(3))
        self.screen.refresh()

    def build_loading(self):
        self.screen.addstr(7, self.startcol, 'Enjoy Music,loading...',
                           curses.color_pair(1))
        self.screen.refresh()

    # start is the timestamp of this function being called
    def build_menu(self, datatype, title, datalist, offset, index, step,
                   start):
        # keep playing info in line 1
        curses.noecho()
        self.screen.move(5, 1)
        self.screen.clrtobot()
        self.screen.addstr(5, self.startcol, title, curses.color_pair(1))

        if len(datalist) == 0:
            self.screen.addstr(8, self.startcol, 'Nothing Here! -,-')

        else:
            if datatype == 'main':
                for i in range(offset, min(len(datalist), offset + step)):
                    if i == index:
                        self.screen.addstr(i - offset + 9,
                                           self.indented_startcol,
                                           '-> ' + str(i) + '. ' + datalist[i],
                                           curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset + 9, self.startcol,
                                           str(i) + '. ' + datalist[i])

            elif datatype == 'songs' or datatype == 'fmsongs':
                iter_range = min(len(datalist), offset + step)
                for i in range(offset, iter_range):
                    # this item is focus
                    if i == index:
                        self.screen.addstr(i - offset + 8, 0,
                                           ' ' * self.startcol)
                        lead = '-> ' + str(i) + '. '
                        self.screen.addstr(i - offset + 8,
                                           self.indented_startcol, lead,
                                           curses.color_pair(2))
                        name = '{}{}{}  < {} >'.format(
                            datalist[i]['song_name'], self.space,
                            datalist[i]['artist'], datalist[i]['album_name'])

                        # the length decides whether to scoll
                        if truelen(name) < self.x - self.startcol - 1:
                            self.screen.addstr(
                                i - offset + 8,
                                self.indented_startcol + len(lead), name,
                                curses.color_pair(2))
                        else:
                            name = scrollstring(name + '  ', start)
                            self.screen.addstr(
                                i - offset + 8,
                                self.indented_startcol + len(lead), str(name),
                                curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset + 8, 0,
                                           ' ' * self.startcol)
                        self.screen.addstr(
                            i - offset + 8, self.startcol,
                            '{}. {}{}{}  < {} >'.format(
                                i, datalist[i]['song_name'], self.space,
                                datalist[i]['artist'],
                                datalist[i]['album_name'])[:int(self.x * 2)])

                self.screen.addstr(iter_range - offset + 8, 0, ' ' * self.x)

            elif datatype == 'artists':
                for i in range(offset, min(len(datalist), offset + step)):
                    if i == index:
                        self.screen.addstr(
                            i - offset + 9, self.indented_startcol,
                            '-> ' + str(i) + '. ' + datalist[i]['artists_name']
                            + self.space + str(datalist[i]['alias']),
                            curses.color_pair(2))
                    else:
                        self.screen.addstr(
                            i - offset + 9, self.startcol,
                            str(i) + '. ' + datalist[i]['artists_name'] +
                            self.space + datalist[i][
                                'alias'])

            elif datatype == 'albums':
                for i in range(offset, min(len(datalist), offset + step)):
                    if i == index:
                        self.screen.addstr(
                            i - offset + 9, self.indented_startcol,
                            '-> ' + str(i) + '. ' + datalist[i]['albums_name']
                            + self.space + datalist[i][
                                'artists_name'], curses.color_pair(2))
                    else:
                        self.screen.addstr(
                            i - offset + 9, self.startcol,
                            str(i) + '. ' + datalist[i]['albums_name'] +
                            self.space + 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 + 9, self.indented_startcol,
                            '-> ' + str(i) + '. ' + datalist[i]['title'],
                            curses.color_pair(2))
                    else:
                        self.screen.addstr(
                            i - offset + 9, self.startcol,
                            str(i) + '. ' + datalist[i]['title'])

            elif datatype == 'top_playlists':
                for i in range(offset, min(len(datalist), offset + step)):
                    if i == index:
                        self.screen.addstr(
                            i - offset + 9, self.indented_startcol, '-> ' +
                            str(i) + '. ' + datalist[i]['playlists_name'] +
                            self.space + datalist[i]['creator_name'],
                            curses.color_pair(2))
                    else:
                        self.screen.addstr(
                            i - offset + 9, self.startcol,
                            str(i) + '. ' + datalist[i]['playlists_name'] +
                            self.space + datalist[i][
                                'creator_name'])

            elif datatype == 'toplists':
                for i in range(offset, min(len(datalist), offset + step)):
                    if i == index:
                        self.screen.addstr(i - offset + 9,
                                           self.indented_startcol,
                                           '-> ' + str(i) + '. ' + datalist[i],
                                           curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset + 9, self.startcol,
                                           str(i) + '. ' + datalist[i])

            elif datatype in ('playlist_classes', 'playlist_class_detail'):
                for i in range(offset, min(len(datalist), offset + step)):
                    if i == index:
                        self.screen.addstr(i - offset + 9,
                                           self.indented_startcol,
                                           '-> ' + str(i) + '. ' + datalist[i],
                                           curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset + 9, self.startcol,
                                           str(i) + '. ' + datalist[i])

            elif datatype == 'djchannels':
                for i in range(offset, min(len(datalist), offset + step)):
                    if i == index:
                        self.screen.addstr(
                            i - offset + 8, self.indented_startcol,
                            '-> ' + str(i) + '. ' + datalist[i]['song_name'],
                            curses.color_pair(2))
                    else:
                        self.screen.addstr(
                            i - offset + 8, self.startcol,
                            str(i) + '. ' + datalist[i]['song_name'])

            elif datatype == 'search':
                self.screen.move(6, 1)
                self.screen.clrtobot()
                self.screen.timeout(-1)
                self.screen.addstr(8, self.startcol, 'Select Search Type:',
                                   curses.color_pair(1))
                for i in range(offset, min(len(datalist), offset + step)):
                    if i == index:
                        self.screen.addstr(
                            i - offset + 10, self.indented_startcol,
                            '-> ' + str(i) + '.' + datalist[i - 1],
                            curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset + 10, self.startcol,
                                           str(i) + '.' + datalist[i - 1])
                self.screen.timeout(100)

            elif datatype == 'help':
                for i in range(offset, min(len(datalist), offset + step)):
                    if i == index:
                        self.screen.addstr(
                            i - offset + 9, self.indented_startcol,
                            '-> {}. \'{}{}   {}'.format(
                                i, (datalist[i][0].upper() + '\'').ljust(11),
                                datalist[i][1], datalist[i][2]),
                            curses.color_pair(2))
                    else:
                        self.screen.addstr(
                            i - offset + 9, self.startcol,
                            '{}. \'{}{}   {}'.format(
                                i, (datalist[i][0].upper() + '\'').ljust(11),
                                datalist[i][1], datalist[i][2]))

                self.screen.addstr(
                    20, 6, 'NetEase-MusicBox is written in Python. All copyrighted content is is not hosted by me!')
                self.screen.addstr(21, 10,
                                   'Press [G] tp go to Github fot more information and to support the project~~')
                self.screen.addstr(22, self.startcol,
                                   'Built with love to music by omi ENGLISH BY IVAN')

        self.screen.refresh()

    def build_search(self, stype):
        self.screen.timeout(-1)
        netease = self.netease
        if stype == 'songs':
            song_name = self.get_param('Search Songs :')
            if song_name == '/return':
                return []
            else:
                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 Exception as e:
                    log.error(e)
                    return []

        elif stype == 'artists':
            artist_name = self.get_param('Search Artists :')
            if artist_name == '/return':
                return []
            else:
                try:
                    data = netease.search(artist_name, stype=100)
                    if 'artists' in data['result']:
                        artists = data['result']['artists']
                        return netease.dig_info(artists, 'artists')
                except Exception as e:
                    log.error(e)
                    return []

        elif stype == 'albums':
            albums_name = self.get_param('Search Albums :')
            if albums_name == '/return':
                return []
            else:
                try:
                    data = netease.search(albums_name, stype=10)
                    if 'albums' in data['result']:
                        albums = data['result']['albums']
                        return netease.dig_info(albums, 'albums')
                except Exception as e:
                    log.error(e)
                    return []

        elif stype == 'search_playlist':
            search_playlist = self.get_param('Search Playlists :')
            if search_playlist == '/return':
                return []
            else:
                try:
                    data = netease.search(search_playlist, stype=1000)
                    if 'playlists' in data['result']:
                        playlists = data['result']['playlists']
                        return netease.dig_info(playlists, 'top_playlists')
                except Exception as e:
                    log.error(e)
                    return []

        return []

    def build_login(self):
        self.build_login_bar()
        local_account = self.get_account()
        local_password = hashlib.md5(self.get_password()).hexdigest()
        login_info = self.netease.login(local_account, local_password)
        account = [local_account, local_password]
        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_bar(self):
        curses.noecho()
        self.screen.move(4, 1)
        self.screen.clrtobot()
        self.screen.addstr(5, self.startcol, 'Enter your login information(支持手机登陆)',
                           curses.color_pair(1))
        self.screen.addstr(8, self.startcol, 'Username :'******'Password :'******'Sorry, the login information was invalid (O_O)#',
                           curses.color_pair(1))
        self.screen.addstr(10, self.startcol, '[1] Try Again')
        self.screen.addstr(11, self.startcol, '[2] Later')
        self.screen.addstr(14, self.startcol, 'Enter the Captcha :', curses.color_pair(2))
        self.screen.refresh()
        x = self.screen.getch()
        self.screen.timeout(100)  # restore the screen timeout
        return x

    def get_account(self):
        self.screen.timeout(-1)  # disable the screen timeout
        curses.echo()
        account = self.screen.getstr(8, self.startcol + 6, 60)
        self.screen.timeout(100)  # restore the screen timeout
        return account

    def get_password(self):
        self.screen.timeout(-1)  # disable the screen timeout
        curses.noecho()
        password = self.screen.getstr(9, self.startcol + 6, 60)
        self.screen.timeout(100)  # restore the screen timeout
        return password

    def get_param(self, prompt_string):
        # keep playing info in line 1
        curses.echo()
        self.screen.move(4, 1)
        self.screen.clrtobot()
        self.screen.addstr(5, self.startcol, prompt_string,
                           curses.color_pair(1))
        self.screen.refresh()
        info = self.screen.getstr(10, self.startcol, 60)
        if info == '':
            return '/return'
        elif info.strip() is '':
            return self.get_param(prompt_string)
        else:
            return info

    def update_size(self):
        # get terminal size
        size = terminalsize.get_terminal_size()
        self.x = max(size[0], 10)
        self.y = max(size[1], 25)

        # update intendations
        curses.resizeterm(self.y, self.x)
        self.startcol = int(float(self.x) / 5)
        self.indented_startcol = max(self.startcol - 3, 0)
        self.update_space()
        self.screen.clear()
        self.screen.refresh()

    def update_space(self):
        if self.x > 140:
            self.space = '   -   '
        elif self.x > 80:
            self.space = '  -  '
        else:
            self.space = ' - '
        self.screen.refresh()
コード例 #10
0
class Menu:
    def __init__(self):
        reload(sys)
        sys.setdefaultencoding('UTF-8')
        self.config = Config()
        self.datatype = 'main'
        self.title = '网易云音乐'
        self.datalist = [
            '排行榜', '艺术家', '新碟上架', '精选歌单', '我的歌单', '主播电台', '每日推荐', '私人FM', '搜索',
            '帮助'
        ]
        self.offset = 0
        self.index = 0
        self.storage = Storage()
        self.storage.load()
        self.collection = self.storage.database['collections'][0]
        self.player = Player()
        self.player.playing_song_changed_callback = self.song_changed_callback
        self.cache = Cache()
        self.ui = Ui()
        self.netease = NetEase()
        self.screen = curses.initscr()
        self.screen.keypad(1)
        self.step = 10
        self.stack = []
        self.djstack = []
        self.userid = self.storage.database['user']['user_id']
        self.username = self.storage.database['user']['nickname']
        self.resume_play = True
        self.at_playing_list = False
        signal.signal(signal.SIGWINCH, self.change_term)
        signal.signal(signal.SIGINT, self.send_kill)
        self.START = time.time()

    def change_term(self, signum, frame):
        self.ui.screen.clear()
        self.ui.screen.refresh()

    def send_kill(self, signum, fram):
        self.player.stop()
        self.cache.quit()
        self.storage.save()
        curses.endwin()
        sys.exit()

    def update_alert(self, version):
        latest = Menu().check_version()
        if latest != version and latest != 0:
            notify('MusicBox Update is available', 1)
            time.sleep(0.5)
            notify(
                'NetEase-MusicBox installed version:' + version +
                '\nNetEase-MusicBox latest version:' + latest, 0)

    def check_version(self):
        # 检查更新 && 签到
        try:
            mobilesignin = self.netease.daily_signin(0)
            if mobilesignin != -1 and mobilesignin['code'] != -2:
                notify('Mobile signin success', 1)
            time.sleep(0.5)
            pcsignin = self.netease.daily_signin(1)
            if pcsignin != -1 and pcsignin['code'] != -2:
                notify('PC signin success', 1)
            tree = ET.ElementTree(
                ET.fromstring(str(self.netease.get_version())))
            root = tree.getroot()
            return root[0][4][0][0].text
        except TypeError as e:
            log.error(e)
            return 0

    def start_fork(self, version):
        pid = os.fork()
        if pid == 0:
            Menu().update_alert(version)
        else:
            Menu().start()

    def play_pause(self):
        if len(self.storage.database['player_info']['player_list']) == 0:
            return
        if self.player.pause_flag:
            self.player.resume()
        else:
            self.player.pause()
        time.sleep(0.1)

    def next_song(self):
        if len(self.storage.database['player_info']['player_list']) == 0:
            return
        self.player.next()
        time.sleep(0.1)

    def previous_song(self):
        if len(self.storage.database['player_info']['player_list']) == 0:
            return
        self.player.prev()
        time.sleep(0.1)

    # 全局加星歌曲
    def star_song(self):
        return_data = self.request_api(self.netease.fm_like,
                                       self.player.get_playing_id())
        if return_data != -1:
            notify("Added successfully!", 0)
        else:
            notify("Existing song!", 0)

    def bind_keys(self):
        if bind_global:
            keybinder.bind(self.config.get_item('global_play_pause'),
                           self.play_pause)
            keybinder.bind(self.config.get_item('global_next'), self.next_song)
            keybinder.bind(self.config.get_item('global_previous'),
                           self.previous_song)
            keybinder.bind(self.config.get_item('global_star'), self.star_song)

    def unbind_keys(self):
        if bind_global:
            keybinder.unbind(self.config.get_item('global_play_pause'))
            keybinder.unbind(self.config.get_item('global_next'))
            keybinder.unbind(self.config.get_item('global_previous'))
            keybinder.unbind(self.config.get_item('global_star'))

    def start(self):
        self.START = time.time() // 1
        self.ui.build_menu(self.datatype, self.title, self.datalist,
                           self.offset, self.index, self.step, self.START)
        self.ui.build_process_bar(
            self.player.process_location, self.player.process_length,
            self.player.playing_flag, self.player.pause_flag,
            self.storage.database['player_info']['playing_mode'])
        self.stack.append([
            self.datatype, self.title, self.datalist, self.offset, self.index
        ])
        if bind_global:
            try:
                self.bind_keys()
            except KeyError as e:
                log.warning(e)
        show_lyrics_new_process()
        while True:
            datatype = self.datatype
            title = self.title
            datalist = self.datalist
            offset = self.offset
            idx = index = self.index
            step = self.step
            stack = self.stack
            self.screen.timeout(500)
            key = self.screen.getch()
            if bind_global:
                keybinder.gtk.main_iteration(False)
            self.ui.screen.refresh()

            # term resize
            if key == -1:
                self.ui.update_size()
                self.player.update_size()

            # 退出
            if key == ord('q'):
                try:
                    self.unbind_keys()
                except KeyError as e:
                    log.warning(e)
                break

            # 退出并清除用户信息
            if key == ord('w'):
                self.storage.database['user'] = {
                    'username': '',
                    'password': '',
                    'user_id': '',
                    'nickname': '',
                }
                try:
                    os.remove(self.storage.cookie_path)
                except OSError as e:
                    log.error(e)
                    break
                break

            # 上移
            elif key == ord('k'):
                # turn page if at beginning
                if idx == offset:
                    if offset == 0:
                        continue
                    self.offset -= step
                    # 移动光标到最后一列
                    self.index = offset - 1
                else:
                    self.index = carousel(
                        offset,
                        min(len(datalist), offset + step) - 1, idx - 1)
                self.START = time.time()

            # 下移
            elif key == ord('j'):
                # turn page if at end
                if idx == min(len(datalist), offset + step) - 1:
                    if offset + step >= len(datalist):
                        continue
                    self.offset += step
                    # 移动光标到第一列
                    self.index = offset + step
                else:
                    self.index = carousel(
                        offset,
                        min(len(datalist), offset + step) - 1, idx + 1)
                self.START = time.time()

            # 数字快捷键
            elif ord('0') <= key <= ord('9'):
                if self.datatype == ('songs', 'djchannels', 'help'):
                    continue
                idx = key - ord('0')
                self.ui.build_menu(self.datatype, self.title, self.datalist,
                                   self.offset, idx, self.step, self.START)
                self.ui.build_loading()
                self.dispatch_enter(idx)
                self.index = 0
                self.offset = 0

            # 向上翻页
            elif key == ord('u'):
                if offset == 0:
                    continue
                self.START = time.time()
                self.offset -= step

                # e.g. 23 - 10 = 13 --> 10
                self.index = (index - step) // step * step

            # 向下翻页
            elif key == ord('d'):
                if offset + step >= len(datalist):
                    continue
                self.START = time.time()
                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', 'djchannels',
                                     'help') or len(self.datalist) <= 0:
                    continue
                self.START = time.time()
                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
                self.START = time.time()
                up = stack.pop()
                self.datatype = up[0]
                self.title = up[1]
                self.datalist = up[2]
                self.offset = up[3]
                self.index = up[4]
                self.at_playing_list = False

            # 搜索
            elif key == ord('f'):
                # 8 is the 'search' menu
                self.dispatch_enter(8)

            # 播放下一曲
            elif key == ord(']'):
                self.next_song()

            # 播放上一曲
            elif key == ord('['):
                self.previous_song()

            # 增加音量
            elif key == ord('='):
                self.player.volume_up()

            # 减少音量
            elif key == ord('-'):
                self.player.volume_down()

            # 随机播放
            elif key == ord('?'):
                if len(self.storage.database['player_info']
                       ['player_list']) == 0:
                    continue
                self.player.shuffle()
                time.sleep(0.1)

            # 喜爱
            elif key == ord(','):
                return_data = self.request_api(self.netease.fm_like,
                                               self.player.get_playing_id())
                if return_data != -1:
                    notify('Added successfully!', 0)
                else:
                    notify('Existing song!', 0)

            # 删除FM
            elif key == ord('.'):
                if self.datatype == 'fmsongs':
                    if len(self.storage.database['player_info']
                           ['player_list']) == 0:
                        continue
                    self.player.next()
                    return_data = self.request_api(
                        self.netease.fm_trash, self.player.get_playing_id())
                    if return_data != -1:
                        notify('Deleted successfully!', 0)
                    time.sleep(0.1)

            # 下一FM
            elif key == ord('/'):
                if self.datatype == 'fmsongs':
                    if len(self.storage.database['player_info']
                           ['player_list']) == 0:
                        continue
                    self.player.next()
                    time.sleep(0.1)

            # 播放、暂停
            elif key == ord(' '):
                # If not open a new playing list, just play and pause.
                try:
                    if self.datalist[idx]['song_id'] == self.player.playing_id:
                        self.player.play_and_pause(
                            self.storage.database['player_info']['idx'])
                        time.sleep(0.1)
                        continue
                except (TypeError, KeyError) as e:
                    log.error(e)
                    pass
                # If change to a new playing list. Add playing list and play.
                if datatype == 'songs':
                    self.resume_play = False
                    self.player.new_player_list('songs', self.title,
                                                self.datalist, -1)
                    self.player.end_callback = None
                    self.player.play_and_pause(idx)
                    self.at_playing_list = True
                elif datatype == 'djchannels':
                    self.resume_play = False
                    self.player.new_player_list('djchannels', self.title,
                                                self.datalist, -1)
                    self.player.end_callback = None
                    self.player.play_and_pause(idx)
                    self.at_playing_list = True
                elif datatype == 'fmsongs':
                    self.resume_play = False
                    self.storage.database['player_info']['playing_mode'] = 0
                    self.player.new_player_list('fmsongs', self.title,
                                                self.datalist, -1)
                    self.player.end_callback = self.fm_callback
                    self.player.play_and_pause(idx)
                    self.at_playing_list = True
                else:
                    self.player.play_and_pause(
                        self.storage.database['player_info']['idx'])
                time.sleep(0.1)

            # 加载当前播放列表
            elif key == ord('p'):
                self.show_playing_song()

            # 播放模式切换
            elif key == ord('P'):
                self.storage.database['player_info']['playing_mode'] = (
                    self.storage.database['player_info']['playing_mode'] +
                    1) % 5

            # 添加到打碟歌单
            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])
                    notify('Added successfully', 0)

            # 加载本地收藏
            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 == 'songs'
                        or datatype == 'djchannels') and len(datalist) != 0:
                    self.datalist.pop(idx)
                    self.index = carousel(
                        offset,
                        min(len(datalist), offset + step) - 1, idx)

            # 当前项目下移
            elif key == ord('J'):
                if datatype != 'main' and len(
                        datalist) != 0 and idx + 1 != len(self.datalist):
                    self.START = time.time()
                    song = self.datalist.pop(idx)
                    self.datalist.insert(idx + 1, song)
                    self.index = idx + 1
                    # 翻页
                    if self.index >= offset + step:
                        self.offset = offset + step

            # 当前项目上移
            elif key == ord('K'):
                if datatype != 'main' and len(datalist) != 0 and idx != 0:
                    self.START = time.time()
                    song = self.datalist.pop(idx)
                    self.datalist.insert(idx - 1, song)
                    self.index = idx - 1
                    # 翻页
                    if self.index < offset:
                        self.offset = offset - step

            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/darknessomi/musicbox')

            # 开始下载
            elif key == ord('C'):
                s = self.datalist[idx]
                cache_thread = threading.Thread(
                    target=self.player.cacheSong1time,
                    args=(s['song_id'], s['song_name'], s['artist'],
                          s['mp3_url']))
                cache_thread.start()

            elif key == ord('i'):
                if self.player.playing_id != -1:
                    webbrowser.open_new_tab('http://music.163.com/#/song?id=' +
                                            str(self.player.playing_id))

            self.ui.build_process_bar(
                self.player.process_location, self.player.process_length,
                self.player.playing_flag, self.player.pause_flag,
                self.storage.database['player_info']['playing_mode'])
            self.ui.build_menu(self.datatype, self.title, self.datalist,
                               self.offset, self.index, self.step, self.START)

        self.player.stop()
        self.cache.quit()
        self.storage.save()
        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 idx > len(self.datalist):
            return False

        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':
            data = self.datalist[idx]
            self.datatype = data['datatype']
            self.datalist = netease.dig_info(data['callback'](), self.datatype)
            self.title += ' > ' + data['title']

        # 全站置顶歌单包含的歌曲
        elif datatype == 'top_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']

        # 分类精选
        elif datatype == 'playlist_classes':
            # 分类名称
            data = self.datalist[idx]
            self.datatype = 'playlist_class_detail'
            self.datalist = netease.dig_info(data, self.datatype)
            self.title += ' > ' + data

        # 某一分类的详情
        elif datatype == 'playlist_class_detail':
            # 子类别
            data = self.datalist[idx]
            self.datatype = 'top_playlists'
            self.datalist = netease.dig_info(netease.top_playlists(data),
                                             self.datatype)
            self.title += ' > ' + data

        # 歌曲榜单
        elif datatype == 'toplists':
            songs = netease.top_songlist(idx)
            self.title += ' > ' + self.datalist[idx]
            self.datalist = netease.dig_info(songs, 'songs')
            self.datatype = 'songs'

        # 搜索菜单
        elif datatype == 'search':
            ui = self.ui
            self.index = 0
            self.offset = 0
            if idx == 0:
                # 搜索结果可以用top_playlists处理
                self.datatype = 'top_playlists'
                self.datalist = ui.build_search('search_playlist')
                self.title = '精选歌单搜索列表'

            elif idx == 1:
                self.datatype = 'songs'
                self.datalist = ui.build_search('songs')
                self.title = '歌曲搜索列表'

            elif idx == 2:
                self.datatype = 'artists'
                self.datalist = ui.build_search('artists')
                self.title = '艺术家搜索列表'

            elif idx == 3:
                self.datatype = 'albums'
                self.datalist = ui.build_search('albums')
                self.title = '专辑搜索列表'

    def show_playing_song(self):
        if len(self.storage.database['player_info']['player_list']) == 0:
            return
        if not self.at_playing_list:
            self.stack.append([
                self.datatype, self.title, self.datalist, self.offset,
                self.index
            ])
            self.at_playing_list = True
        self.datatype = self.storage.database['player_info'][
            'player_list_type']
        self.title = self.storage.database['player_info']['player_list_title']
        self.datalist = []
        for i in self.storage.database['player_info']['player_list']:
            self.datalist.append(self.storage.database['songs'][i])
        self.index = self.storage.database['player_info']['idx']
        self.offset = self.storage.database['player_info'][
            'idx'] / self.step * self.step
        if self.resume_play:
            if self.datatype == 'fmsongs':
                self.player.end_callback = self.fm_callback
            else:
                self.player.end_callback = None
            self.storage.database['player_info']['idx'] = -1
            self.player.play_and_pause(self.index)
            self.resume_play = False

    def song_changed_callback(self):
        if self.at_playing_list:
            self.show_playing_song()

    def fm_callback(self):
        log.debug('FM CallBack.')
        data = self.get_new_fm()
        self.player.append_songs(data)
        if self.datatype == 'fmsongs':
            if len(self.storage.database['player_info']['player_list']) == 0:
                return
            self.datatype = self.storage.database['player_info'][
                'player_list_type']
            self.title = self.storage.database['player_info'][
                'player_list_title']
            self.datalist = []
            for i in self.storage.database['player_info']['player_list']:
                self.datalist.append(self.storage.database['songs'][i])
            self.index = self.storage.database['player_info']['idx']
            self.offset = self.storage.database['player_info'][
                'idx'] / self.step * self.step

    def request_api(self, func, *args):
        if self.storage.database['user']['user_id'] != '':
            result = func(*args)
            if result != -1:
                return result
        log.debug('Re Login.')
        user_info = {}
        if self.storage.database['user']['username'] != '':
            user_info = self.netease.login(
                self.storage.database['user']['username'],
                self.storage.database['user']['password'])
        if self.storage.database['user'][
                'username'] == '' or user_info['code'] != 200:
            data = self.ui.build_login()
            # 取消登录
            if data == -1:
                return -1
            user_info = data[0]
            self.storage.database['user']['username'] = data[1][0]
            self.storage.database['user']['password'] = data[1][1]
            self.storage.database['user']['user_id'] = user_info['account'][
                'id']
            self.storage.database['user']['nickname'] = user_info['profile'][
                'nickname']
        self.userid = self.storage.database['user']['user_id']
        self.username = self.storage.database['user']['nickname']
        return func(*args)

    def get_new_fm(self):
        myplaylist = []
        for count in range(0, 1):
            data = self.request_api(self.netease.personal_fm)
            if data == -1:
                break
            myplaylist += data
            time.sleep(0.2)
        return self.netease.dig_info(myplaylist, 'fmsongs')

    def choice_channel(self, idx):
        # 排行榜
        netease = self.netease
        if idx == 0:
            self.datalist = netease.return_toplists()
            self.title += ' > 排行榜'
            self.datatype = 'toplists'

        # 艺术家
        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:
            self.datalist = [{
                'title': '全站置顶',
                'datatype': 'top_playlists',
                'callback': netease.top_playlists
            }, {
                'title': '分类精选',
                'datatype': 'playlist_classes',
                'callback': netease.playlist_classes
            }]
            self.title += ' > 精选歌单'
            self.datatype = 'playlists'

        # 我的歌单
        elif idx == 4:
            myplaylist = self.request_api(self.netease.user_playlist,
                                          self.userid)
            if myplaylist == -1:
                return
            self.datatype = 'top_playlists'
            self.datalist = netease.dig_info(myplaylist, self.datatype)
            self.title += ' > ' + self.username + ' 的歌单'

        # 主播电台
        elif idx == 5:
            self.datatype = 'djchannels'
            self.title += ' > 主播电台'
            self.datalist = netease.djchannels()

        # 每日推荐
        elif idx == 6:
            self.datatype = 'songs'
            self.title += ' > 每日推荐'
            myplaylist = self.request_api(self.netease.recommend_playlist)
            if myplaylist == -1:
                return
            self.datalist = self.netease.dig_info(myplaylist, self.datatype)

        # 私人FM
        elif idx == 7:
            self.datatype = 'fmsongs'
            self.title += ' > 私人FM'
            self.datalist = self.get_new_fm()

        # 搜索
        elif idx == 8:
            self.datatype = 'search'
            self.title += ' > 搜索'
            self.datalist = ['歌曲', '艺术家', '专辑', '网易精选集']

        # 帮助
        elif idx == 9:
            self.datatype = 'help'
            self.title += ' > 帮助'
            self.datalist = shortcut

        self.offset = 0
        self.index = 0
コード例 #11
0
ファイル: menu.py プロジェクト: Ghayn/musicbox
class Menu:
    def __init__(self):
        reload(sys)
        sys.setdefaultencoding('UTF-8')
        self.config = Config()
        self.datatype = 'main'
        self.title = '网易云音乐'
        self.datalist = ['排行榜', '艺术家', '新碟上架', '精选歌单', '我的歌单', 'DJ节目', '每日推荐', '私人FM', '搜索', '帮助']
        self.offset = 0
        self.index = 0
        self.storage = Storage()
        self.storage.load()
        self.collection = self.storage.database['collections'][0]
        self.player = Player()
        self.cache = Cache()
        self.ui = Ui()
        self.netease = NetEase()
        self.screen = curses.initscr()
        self.screen.keypad(1)
        self.step = 10
        self.stack = []
        self.djstack = []
        self.userid = None
        self.username = None
        self.resume_play = True
        self.at_playing_list = False
        signal.signal(signal.SIGWINCH, self.change_term)
        signal.signal(signal.SIGINT, self.send_kill)
        self.START = time.time()

    def change_term(self, signum, frame):
        self.ui.screen.clear()
        self.ui.screen.refresh()

    def send_kill(self, signum, fram):
        self.player.stop()
        self.cache.quit()
        self.storage.save()
        curses.endwin()
        sys.exit()

    def start(self):
        self.START = time.time() // 1
        self.ui.build_menu(self.datatype, self.title, self.datalist, self.offset, self.index, self.step, self.START)
        self.ui.build_process_bar(self.player.process_location, self.player.process_length, self.player.playing_flag,
                                  self.player.pause_flag, self.storage.database['player_info']['playing_mode'])
        self.stack.append([self.datatype, self.title, self.datalist, self.offset, self.index])
        while True:
            datatype = self.datatype
            title = self.title
            datalist = self.datalist
            offset = self.offset
            idx = index = self.index
            step = self.step
            stack = self.stack
            djstack = self.djstack
            self.screen.timeout(500)
            key = self.screen.getch()
            self.ui.screen.refresh()

            # term resize
            if key == -1:
                self.ui.update_size()
                self.player.update_size()

            # 退出
            if key == ord('q'):
                break

            # 退出并清除用户信息
            if key == ord('w'):
                self.storage.database['user'] = {
                    "username": "",
                    "password": "",
                    "user_id": "",
                    "nickname": "",
                }
                os.remove(self.storage.cookie_path)
                break

            # 上移
            elif key == ord('k'):
                self.index = carousel(offset, min(len(datalist), offset + step) - 1, idx - 1)
                self.START = time.time()

            # 下移
            elif key == ord('j'):
                self.index = carousel(offset, min(len(datalist), offset + step) - 1, idx + 1)
                self.START = time.time()

            # 数字快捷键
            elif ord('0') <= key <= ord('9'):
                if self.datatype == 'songs' or self.datatype == 'djchannels' or self.datatype == 'help':
                    continue
                idx = key - ord('0')
                self.ui.build_menu(self.datatype, self.title, self.datalist, self.offset, idx, self.step, self.START)
                self.ui.build_loading()
                self.dispatch_enter(idx)
                self.index = 0
                self.offset = 0

            # 向上翻页
            elif key == ord('u'):
                if offset == 0:
                    continue
                self.START = time.time()
                self.offset -= step

                # e.g. 23 - 10 = 13 --> 10
                self.index = (index - step) // step * step

            # 向下翻页
            elif key == ord('d'):
                if offset + step >= len(datalist):
                    continue
                self.START = time.time()
                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.START = time.time()
                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
                self.START = time.time()
                up = stack.pop()
                self.datatype = up[0]
                self.title = up[1]
                self.datalist = up[2]
                self.offset = up[3]
                self.index = up[4]
                self.at_playing_list = False;

            # 搜索
            elif key == ord('f'):
                # 8 is the 'search' menu
                self.dispatch_enter(8)

            # 播放下一曲
            elif key == ord(']'):
                if len(self.storage.database["player_info"]["player_list"]) == 0:
                    continue
                self.player.next()
                time.sleep(0.1)

            # 播放上一曲
            elif key == ord('['):
                if len(self.storage.database["player_info"]["player_list"]) == 0:
                    continue
                self.player.prev()
                time.sleep(0.1)

            # 增加音量
            elif key == ord('='):
                self.player.volume_up()

            # 减少音量
            elif key == ord('-'):
                self.player.volume_down()

            # 随机播放
            elif key == ord('?'):
                if len(self.storage.database["player_info"]["player_list"]) == 0:
                    continue
                self.player.shuffle()
                time.sleep(0.1)

            # 喜爱
            elif key == ord(','):
                self.netease.fm_like(self.player.get_playing_id())

            # 删除FM
            elif key == ord('.'):
                if self.datatype == 'fmsongs':
                    if len(self.storage.database["player_info"]["player_list"]) == 0:
                        continue
                    self.player.next()
                    self.netease.fm_trash(self.player.get_playing_id())
                    time.sleep(0.1)

            # 下一FM
            elif key == ord('/'):
                if self.datatype == 'fmsongs':
                    if len(self.storage.database["player_info"]["player_list"]) == 0:
                        continue
                    self.player.next()
                    time.sleep(0.1)

            # 播放、暂停
            elif key == ord(' '):
                # If not open a new playing list, just play and pause.
                try:
                    if self.datalist[idx] == self.storage.database["songs"][str(self.player.playing_id)]:
                        self.player.play_and_pause(self.storage.database['player_info']['idx'])
                        time.sleep(0.1)
                        continue
                except:
                    pass
                # If change to a new playing list. Add playing list and play.
                if datatype == 'songs':
                    self.resume_play = False
                    self.player.new_player_list('songs', self.title, self.datalist, -1)
                    self.player.end_callback = None
                    self.player.play_and_pause(idx)
                    self.at_playing_list = True
                elif datatype == 'djchannels':
                    self.resume_play = False
                    self.player.new_player_list('djchannels', self.title, self.datalist, -1)
                    self.player.end_callback = None
                    self.player.play_and_pause(idx)
                    self.at_playing_list = True
                elif datatype == 'fmsongs':
                    self.resume_play = False
                    self.storage.database['player_info']['playing_mode'] = 0
                    self.player.new_player_list('fmsongs', self.title, self.datalist, -1)
                    self.player.end_callback = self.fm_callback
                    self.player.play_and_pause(idx)
                    self.at_playing_list = True
                else:
                    self.player.play_and_pause(self.storage.database['player_info']['idx'])
                time.sleep(0.1)

            # 加载当前播放列表
            elif key == ord('p'):
                if len(self.storage.database['player_info']['player_list']) == 0:
                    continue
                if not self.at_playing_list:
                    self.stack.append([self.datatype, self.title, self.datalist, self.offset, self.index])
                    self.at_playing_list = True
                self.datatype = self.storage.database['player_info']['player_list_type']
                self.title = self.storage.database['player_info']['player_list_title']
                self.datalist = []
                for i in self.storage.database['player_info']['player_list']:
                    self.datalist.append(self.storage.database['songs'][i])
                self.index = self.storage.database['player_info']['idx']
                self.offset = self.storage.database['player_info']['idx'] / self.step * self.step
                if self.resume_play:
                    if self.datatype == "fmsongs":
                        self.player.end_callback = self.fm_callback
                    else:
                        self.player.end_callback = None
                    self.storage.database['player_info']['idx'] = -1
                    self.player.play_and_pause(self.index)
                    self.resume_play = False

            # 播放模式切换
            elif key == ord('P'):
                self.storage.database['player_info']['playing_mode'] = \
                    (self.storage.database['player_info']['playing_mode'] + 1) % 5

            # 添加到打碟歌单
            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("J"):
                if datatype != 'main' and len(datalist) != 0 and idx + 1 != len(self.datalist):
                    self.START = time.time()
                    song = self.datalist.pop(idx)
                    self.datalist.insert(idx + 1, song)
                    self.index = idx + 1
                    # 翻页
                    if self.index >= offset + step:
                        self.offset = offset + step

            # 当前项目上移
            elif key == ord("K"):
                if datatype != 'main' and len(datalist) != 0 and idx != 0:
                    self.START = time.time()
                    song = self.datalist.pop(idx)
                    self.datalist.insert(idx - 1, song)
                    self.index = idx - 1
                    # 翻页
                    if self.index < offset:
                        self.offset = offset - step

            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/darknessomi/musicbox')

            self.ui.build_process_bar(self.player.process_location, self.player.process_length,
                                      self.player.playing_flag,
                                      self.player.pause_flag, self.storage.database['player_info']['playing_mode'])
            self.ui.build_menu(self.datatype, self.title, self.datalist, self.offset, self.index, self.step, self.START)

        self.player.stop()
        self.cache.quit()
        self.storage.save()
        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':
            data = self.datalist[idx]
            self.datatype = data['datatype']
            self.datalist = netease.dig_info(data['callback'](), self.datatype)
            self.title += ' > ' + data['title']

        # 全站置顶歌单包含的歌曲
        elif datatype == 'top_playlists':
            log.debug(datalist)
            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']

        # 分类精选
        elif datatype == 'playlist_classes':
            # 分类名称
            data = self.datalist[idx]
            self.datatype = 'playlist_class_detail'
            self.datalist = netease.dig_info(data, self.datatype)
            self.title += ' > ' + data
            log.debug(self.datalist)

        # 某一分类的详情
        elif datatype == 'playlist_class_detail':
            # 子类别
            data = self.datalist[idx]
            self.datatype = 'top_playlists'
            self.datalist = netease.dig_info(netease.top_playlists(data), self.datatype)
            log.debug(self.datalist)
            self.title += ' > ' + data

        # 歌曲榜单
        elif datatype == 'toplists':
            songs = netease.top_songlist(idx)
            self.title += ' > ' + self.datalist[idx]
            self.datalist = netease.dig_info(songs, 'songs')
            self.datatype = 'songs'

        # 搜索菜单
        elif datatype == 'search':
            ui = self.ui
            # no need to do stack.append, Otherwise there will be a bug when you input key 'h' to return
            # if idx in range(1, 5):
            # self.stack.append([self.datatype, self.title, self.datalist, self.offset, self.index])
            self.index = 0
            self.offset = 0
            if idx == 0:
                # 搜索结果可以用top_playlists处理
                self.datatype = 'top_playlists'
                self.datalist = ui.build_search('search_playlist')
                self.title = '精选歌单搜索列表'

            elif idx == 1:
                self.datatype = 'songs'
                self.datalist = ui.build_search('songs')
                self.title = '歌曲搜索列表'

            elif idx == 2:
                self.datatype = 'artists'
                self.datalist = ui.build_search('artists')
                self.title = '艺术家搜索列表'

            elif idx == 3:
                self.datatype = 'albums'
                self.datalist = ui.build_search('albums')
                self.title = '专辑搜索列表'

    def fm_callback(self):
        log.debug("FM CallBack.")
        data = self.get_new_fm()
        self.player.append_songs(data)
        if self.datatype == 'fmsongs':
            if len(self.storage.database['player_info']['player_list']) == 0:
                return
            self.datatype = self.storage.database['player_info']['player_list_type']
            self.title = self.storage.database['player_info']['player_list_title']
            self.datalist = []
            for i in self.storage.database['player_info']['player_list']:
                self.datalist.append(self.storage.database['songs'][i])
            self.index = self.storage.database['player_info']['idx']
            self.offset = self.storage.database['player_info']['idx'] / self.step * self.step

    def get_new_fm(self):
        if self.userid is None:
            if self.storage.database['user']['user_id'] == "":
                # 使用本地存储了账户登录
                if self.storage.database['user']['username'] != "":
                    user_info = self.netease.login(self.storage.database['user']['username'],
                                              self.storage.database['user']['password'])
                # 本地没有存储账户,或本地账户失效,则引导录入
                if self.storage.database['user']['username'] == "" or user_info['code'] != 200:
                    data = self.ui.build_login()
                    # 取消登录
                    if data == -1:
                        return
                    user_info = data[0]
                    self.storage.database['user']['username'] = data[1][0]
                    self.storage.database['user']['password'] = data[1][1]
                    self.storage.database['user']['user_id'] = user_info['account']['id']
                    self.storage.database['user']['nickname'] = user_info['profile']['nickname']

                self.username = user_info['profile']['nickname']
                self.userid = user_info['account']['id']
            else:
                self.userid = self.storage.database['user']['user_id']
        myplaylist = []
        for count in range(0, 1):
            myplaylist += self.netease.personal_fm()
            time.sleep(0.2)
        return self.netease.dig_info(myplaylist, "fmsongs")

    def choice_channel(self, idx):
        # 排行榜
        netease = self.netease
        if idx == 0:
            self.datalist = netease.return_toplists()
            self.title += ' > 排行榜'
            self.datatype = 'toplists'

        # 艺术家
        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:
            self.datalist = [
                {
                    'title': '全站置顶',
                    'datatype': 'top_playlists',
                    'callback': netease.top_playlists
                },
                {
                    'title': '分类精选',
                    'datatype': 'playlist_classes',
                    'callback': netease.playlist_classes
                }
            ]
            self.title += ' > 精选歌单'
            self.datatype = 'playlists'

        # 我的歌单
        elif idx == 4:
            # 未登录
            if self.userid is None:
                if self.storage.database['user']['user_id'] == "":
                    # 使用本地存储了账户登录
                    if self.storage.database['user']['username'] != "":
                        user_info = netease.login(self.storage.database['user']['username'],
                                                  self.storage.database['user']['password'])
                    # 本地没有存储账户,或本地账户失效,则引导录入
                    if self.storage.database['user']['username'] == "" or user_info['code'] != 200:
                        data = self.ui.build_login()
                        # 取消登录
                        if data == -1:
                            return
                        user_info = data[0]
                        self.storage.database['user']['username'] = data[1][0]
                        self.storage.database['user']['password'] = data[1][1]
                        self.storage.database['user']['user_id'] = user_info['account']['id']
                        self.storage.database['user']['nickname'] = user_info['profile']['nickname']

                    self.username = user_info['profile']['nickname']
                    self.userid = user_info['account']['id']
                else:
                    self.userid = self.storage.database['user']['user_id']
            # 读取登录之后的用户歌单
            self.username = self.storage.database['user']['nickname']
            myplaylist = netease.user_playlist(self.userid)
            self.datatype = 'top_playlists'
            self.datalist = netease.dig_info(myplaylist, self.datatype)
            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 += ' > 每日推荐'
            if self.userid is None:
                if self.storage.database['user']['user_id'] == "":
                    # 使用本地存储了账户登录
                    if self.storage.database['user']['username'] != "":
                        user_info = netease.login(self.storage.database['user']['username'],
                                                  self.storage.database['user']['password'])
                    # 本地没有存储账户,或本地账户失效,则引导录入
                    if self.storage.database['user']['username'] == "" or user_info['code'] != 200:
                        data = self.ui.build_login()
                        # 取消登录
                        if data == -1:
                            return
                        user_info = data[0]
                        self.storage.database['user']['username'] = data[1][0]
                        self.storage.database['user']['password'] = data[1][1]
                        self.storage.database['user']['user_id'] = user_info['account']['id']
                        self.storage.database['user']['nickname'] = user_info['profile']['nickname']

                    self.username = user_info['profile']['nickname']
                    self.userid = user_info['account']['id']
                else:
                    self.userid = self.storage.database['user']['user_id']
            #
            myplaylist = self.netease.recommend_playlist()
            self.datalist = self.netease.dig_info(myplaylist, self.datatype)

        # 私人FM
        elif idx == 7:
            self.datatype = 'fmsongs'
            self.title += ' > 私人FM'
            self.datalist = self.get_new_fm()

        # 搜索
        elif idx == 8:
            self.datatype = 'search'
            self.title += ' > 搜索'
            self.datalist = ['歌曲', '艺术家', '专辑', '网易精选集']

        # 帮助
        elif idx == 9:
            self.datatype = 'help'
            self.title += ' > 帮助'
            self.datalist = shortcut

        self.offset = 0
        self.index = 0
コード例 #12
0
ファイル: menu.py プロジェクト: Zorgodon/musicbox
class Menu(object):
    def __init__(self):
        reload(sys)
        sys.setdefaultencoding('UTF-8')
        self.config = Config()
        self.datatype = 'main'
        self.title = 'NetEase Music'
        self.datalist = ['Charts', 'Artists', 'New Songs', 'Songs', 'My Songs', 'Radio Stations', 'Recommended',
                         'Personal Radio', 'Search', 'Help']
        self.offset = 0
        self.index = 0
        self.storage = Storage()
        self.storage.load()
        self.collection = self.storage.database['collections'][0]
        self.player = Player()
        self.player.playing_song_changed_callback = self.song_changed_callback
        self.cache = Cache()
        self.ui = Ui()
        self.netease = NetEase()
        self.screen = curses.initscr()
        self.screen.keypad(1)
        self.step = 10
        self.stack = []
        self.djstack = []
        self.userid = self.storage.database['user']['user_id']
        self.username = self.storage.database['user']['nickname']
        self.resume_play = True
        self.at_playing_list = False
        signal.signal(signal.SIGWINCH, self.change_term)
        signal.signal(signal.SIGINT, self.send_kill)
        self.START = time.time()

    def change_term(self, signum, frame):
        self.ui.screen.clear()
        self.ui.screen.refresh()

    def send_kill(self, signum, fram):
        self.player.stop()
        self.cache.quit()
        self.storage.save()
        curses.endwin()
        sys.exit()

    def update_alert(self, version):
        latest = Menu().check_version()
        if latest != version and latest != 0:
            notify('MusicBox Update is available', 1)
            time.sleep(0.5)
            notify('NetEase-MusicBox installed version:' + version +
                   '\nNetEase-MusicBox latest version:' + latest, 0)

    def check_version(self):
        # 检查更新 && 签到
        try:
            mobilesignin = self.netease.daily_signin(0)
            if mobilesignin != -1 and mobilesignin['code'] != -2:
                notify('Mobile signin success', 1)
            time.sleep(0.5)
            pcsignin = self.netease.daily_signin(1)
            if pcsignin != -1 and pcsignin['code'] != -2:
                notify('PC signin success', 1)
            tree = ET.ElementTree(ET.fromstring(str(self.netease.get_version(
            ))))
            root = tree.getroot()
            return root[0][4][0][0].text
        except TypeError as e:
            log.error(e)
            return 0

    def start_fork(self, version):
        pid = os.fork()
        if pid == 0:
            Menu().update_alert(version)
        else:
            Menu().start()

    def _is_playlist_empty(self):
        return len(self.storage.database['player_info']['player_list']) == 0

    def play_pause(self):
        if self._is_playlist_empty():
            return
        if self.player.pause_flag:
            self.player.resume()
        else:
            self.player.pause()
        time.sleep(0.1)

    def next_song(self):
        if self._is_playlist_empty():
            return
        self.player.next()
        time.sleep(0.5)

    def previous_song(self):
        if self._is_playlist_empty():
            return
        self.player.prev()
        time.sleep(0.5)

    def bind_keys(self):
        if BINDABLE:
            keybinder.bind(
                self.config.get_item('global_play_pause'), self.play_pause)
            keybinder.bind(self.config.get_item('global_next'), self.next_song)
            keybinder.bind(
                self.config.get_item('global_previous'), self.previous_song)

    def unbind_keys(self):
        if BINDABLE:
            keybinder.unbind(self.config.get_item('global_play_pause'))
            keybinder.unbind(self.config.get_item('global_next'))
            keybinder.unbind(self.config.get_item('global_previous'))

    def start(self):
        self.START = time.time() // 1
        self.ui.build_menu(self.datatype, self.title, self.datalist,
                           self.offset, self.index, self.step, self.START)
        self.ui.build_process_bar(
            self.player.process_location, self.player.process_length,
            self.player.playing_flag, self.player.pause_flag,
            self.storage.database['player_info']['playing_mode'])
        self.stack.append([self.datatype, self.title, self.datalist,
                           self.offset, self.index])
        try:
            self.bind_keys()
        except KeyError as e:
            log.warning(e)
        show_lyrics_new_process()
        while True:
            datatype = self.datatype
            title = self.title
            datalist = self.datalist
            offset = self.offset
            idx = index = self.index
            step = self.step
            stack = self.stack
            self.screen.timeout(500)
            key = self.screen.getch()
            if BINDABLE:
                keybinder.gtk.main_iteration(False)
            self.ui.screen.refresh()

            # term resize
            if key == -1:
                self.ui.update_size()
                self.player.update_size()

            # 退出
            if key == ord('q'):
                try:
                    self.unbind_keys()
                except KeyError as e:
                    log.warning(e)
                break

            # 退出并清除用户信息
            if key == ord('w'):
                self.storage.database['user'] = {
                    'username': '',
                    'password': '',
                    'user_id': '',
                    'nickname': '',
                }
                try:
                    os.remove(self.storage.cookie_path)
                except OSError as e:
                    log.error(e)
                    break
                break

            # 上移
            elif key == ord('k'):
                # turn page if at beginning
                if idx == offset:
                    if offset == 0:
                        continue
                    self.offset -= step
                    # 移动光标到最后一列
                    self.index = offset - 1
                else:
                    self.index = carousel(offset, min(
                        len(datalist), offset + step) - 1, idx - 1)
                self.START = time.time()

            # 下移
            elif key == ord('j'):
                # turn page if at end
                if idx == min(len(datalist), offset + step) - 1:
                    if offset + step >= len(datalist):
                        continue
                    self.offset += step
                    # 移动光标到第一列
                    self.index = offset + step
                else:
                    self.index = carousel(offset, min(
                        len(datalist), offset + step) - 1, idx + 1)
                self.START = time.time()

            # 数字快捷键
            elif ord('0') <= key <= ord('9'):
                if self.datatype == ('songs', 'djchannels', 'help'):
                    continue
                idx = key - ord('0')
                self.ui.build_menu(self.datatype, self.title, self.datalist,
                                   self.offset, idx, self.step, self.START)
                self.ui.build_loading()
                self.dispatch_enter(idx)
                self.index = 0
                self.offset = 0

            # 向上翻页
            elif key == ord('u'):
                if offset == 0:
                    continue
                self.START = time.time()
                self.offset -= step

                # e.g. 23 - 10 = 13 --> 10
                self.index = (index - step) // step * step

            # 向下翻页
            elif key == ord('d'):
                if offset + step >= len(datalist):
                    continue
                self.START = time.time()
                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', 'djchannels',
                                     'help') or len(self.datalist) <= 0:
                    continue
                self.START = time.time()
                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
                self.START = time.time()
                up = stack.pop()
                self.datatype = up[0]
                self.title = up[1]
                self.datalist = up[2]
                self.offset = up[3]
                self.index = up[4]
                self.at_playing_list = False

            # 搜索
            elif key == ord('f'):
                # 8 is the 'search' menu
                self.dispatch_enter(8)

            # 播放下一曲
            elif key == ord(']'):
                self.next_song()

            # 播放上一曲
            elif key == ord('['):
                self.previous_song()

            # 增加音量
            elif key == ord('='):
                self.player.volume_up()

            # 减少音量
            elif key == ord('-'):
                self.player.volume_down()

            # 随机播放
            elif key == ord('?'):
                if len(self.storage.database['player_info'][
                        'player_list']) == 0:
                    continue
                self.player.shuffle()
                time.sleep(0.1)

            # 喜爱
            elif key == ord(','):
                return_data = self.request_api(self.netease.fm_like,
                                               self.player.get_playing_id())
                if return_data != -1:
                    notify('Added successfully!', 0)
                else:
                    notify('Existing song!', 0)

            # 删除FM
            elif key == ord('.'):
                if self.datatype == 'fmsongs':
                    if len(self.storage.database['player_info'][
                            'player_list']) == 0:
                        continue
                    self.player.next()
                    return_data = self.request_api(
                        self.netease.fm_trash, self.player.get_playing_id())
                    if return_data != -1:
                        notify('Deleted successfully!', 0)
                    time.sleep(0.1)

            # 下一FM
            elif key == ord('/'):
                if self.datatype == 'fmsongs':
                    if len(self.storage.database['player_info'][
                            'player_list']) == 0:
                        continue
                    if self.player.end_callback:
                        self.player.end_callback()
                    time.sleep(0.1)

            # 播放、暂停
            elif key == ord(' '):
                # If not open a new playing list, just play and pause.
                try:
                    if self.datalist[idx]['song_id'] == self.player.playing_id:
                        self.player.play_and_pause(self.storage.database[
                            'player_info']['idx'])
                        time.sleep(0.1)
                        continue
                except (TypeError, KeyError) as e:
                    log.error(e)
                    pass
                # If change to a new playing list. Add playing list and play.
                if datatype == 'songs':
                    self.resume_play = False
                    self.player.new_player_list('songs', self.title,
                                                self.datalist, -1)
                    self.player.end_callback = None
                    self.player.play_and_pause(idx)
                    self.at_playing_list = True
                elif datatype == 'djchannels':
                    self.resume_play = False
                    self.player.new_player_list('djchannels', self.title,
                                                self.datalist, -1)
                    self.player.end_callback = None
                    self.player.play_and_pause(idx)
                    self.at_playing_list = True
                elif datatype == 'fmsongs':
                    self.resume_play = False
                    self.storage.database['player_info']['playing_mode'] = 0
                    self.player.new_player_list('fmsongs', self.title,
                                                self.datalist, -1)
                    self.player.end_callback = self.fm_callback
                    self.player.play_and_pause(idx)
                    self.at_playing_list = True
                else:
                    self.player.play_and_pause(self.storage.database[
                        'player_info']['idx'])
                time.sleep(0.1)

            # 加载当前播放列表
            elif key == ord('p'):
                self.show_playing_song()

            # 播放模式切换
            elif key == ord('P'):
                self.storage.database['player_info']['playing_mode'] = (
                    self.storage.database['player_info']['playing_mode'] +
                    1) % 5

            # 添加到打碟歌单
            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])
                    notify('Added successfully', 0)

            # 加载本地收藏
            elif key == ord('c'):
                self.stack.append([datatype, title, datalist, offset, index])
                self.datatype = 'songs'
                self.title = 'NetEase Music > Local Music'
                self.datalist = self.collection
                self.offset = 0
                self.index = 0

            # 从当前列表移除
            elif key == ord('r'):
                if (datatype == 'songs' or
                        datatype == 'djchannels') and len(datalist) != 0:
                    self.datalist.pop(idx)
                    self.index = carousel(offset, min(
                        len(datalist), offset + step) - 1, idx)

            # 当前项目下移
            elif key == ord('J'):
                if datatype != 'main' and len(
                        datalist) != 0 and idx + 1 != len(self.datalist):
                    self.START = time.time()
                    song = self.datalist.pop(idx)
                    self.datalist.insert(idx + 1, song)
                    self.index = idx + 1
                    # 翻页
                    if self.index >= offset + step:
                        self.offset = offset + step

            # 当前项目上移
            elif key == ord('K'):
                if datatype != 'main' and len(datalist) != 0 and idx != 0:
                    self.START = time.time()
                    song = self.datalist.pop(idx)
                    self.datalist.insert(idx - 1, song)
                    self.index = idx - 1
                    # 翻页
                    if self.index < offset:
                        self.offset = offset - step

            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/darknessomi/musicbox')

            # 开始下载
            elif key == ord('C'):
                s = self.datalist[idx]
                cache_thread = threading.Thread(
                    target=self.player.cacheSong1time,
                    args=(s['song_id'], s['song_name'], s['artist'], s[
                        'mp3_url']))
                cache_thread.start()

            elif key == ord('i'):
                if self.player.playing_id != -1:
                    webbrowser.open_new_tab('http://music.163.com/#/song?id=' +
                                            str(self.player.playing_id))

            self.ui.build_process_bar(
                self.player.process_location, self.player.process_length,
                self.player.playing_flag, self.player.pause_flag,
                self.storage.database['player_info']['playing_mode'])
            self.ui.build_menu(self.datatype, self.title, self.datalist,
                               self.offset, self.index, self.step, self.START)

        self.player.stop()
        self.cache.quit()
        self.storage.save()
        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 idx > len(self.datalist):
            return False

        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':
            data = self.datalist[idx]
            self.datatype = data['datatype']
            self.datalist = netease.dig_info(data['callback'](), self.datatype)
            self.title += ' > ' + data['title']

        # 全站置顶歌单包含的歌曲
        elif datatype == 'top_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']

        # 分类精选
        elif datatype == 'playlist_classes':
            # 分类名称
            data = self.datalist[idx]
            self.datatype = 'playlist_class_detail'
            self.datalist = netease.dig_info(data, self.datatype)
            self.title += ' > ' + data

        # 某一分类的详情
        elif datatype == 'playlist_class_detail':
            # 子类别
            data = self.datalist[idx]
            self.datatype = 'top_playlists'
            self.datalist = netease.dig_info(
                netease.top_playlists(data), self.datatype)
            self.title += ' > ' + data

        # 歌曲榜单
        elif datatype == 'toplists':
            songs = netease.top_songlist(idx)
            self.title += ' > ' + self.datalist[idx]
            self.datalist = netease.dig_info(songs, 'songs')
            self.datatype = 'songs'

        # 搜索菜单
        elif datatype == 'search':
            ui = self.ui
            self.index = 0
            self.offset = 0
            if idx == 0:
                # 搜索结果可以用top_playlists处理
                self.datatype = 'top_playlists'
                self.datalist = ui.build_search('search_playlist')
                self.title = 'Playlist Search'

            elif idx == 1:
                self.datatype = 'songs'
                self.datalist = ui.build_search('songs')
                self.title = 'Song Search'

            elif idx == 2:
                self.datatype = 'artists'
                self.datalist = ui.build_search('artists')
                self.title = 'Artist Search'

            elif idx == 3:
                self.datatype = 'albums'
                self.datalist = ui.build_search('albums')
                self.title = 'Album Search'

    def show_playing_song(self):
        if self._is_playlist_empty():
            return
        if not self.at_playing_list:
            self.stack.append([self.datatype, self.title, self.datalist,
                               self.offset, self.index])
            self.at_playing_list = True
        self.datatype = self.storage.database['player_info'][
            'player_list_type']
        self.title = self.storage.database['player_info']['player_list_title']
        self.datalist = []
        for i in self.storage.database['player_info']['player_list']:
            self.datalist.append(self.storage.database['songs'][i])
        self.index = self.storage.database['player_info']['idx']
        self.offset = self.storage.database['player_info'][
            'idx'] / self.step * self.step
        if self.resume_play:
            if self.datatype == 'fmsongs':
                self.player.end_callback = self.fm_callback
            else:
                self.player.end_callback = None
            self.storage.database['player_info']['idx'] = -1
            self.player.play_and_pause(self.index)
            self.resume_play = False

    def song_changed_callback(self):
        if self.at_playing_list:
            self.show_playing_song()

    def fm_callback(self):
        log.debug('FM CallBack.')
        data = self.get_new_fm()
        self.player.append_songs(data)
        if self.datatype == 'fmsongs':
            if self._is_playlist_empty():
                return
            self.datatype = self.storage.database['player_info'][
                'player_list_type']
            self.title = self.storage.database['player_info'][
                'player_list_title']
            self.datalist = []
            for i in self.storage.database['player_info']['player_list']:
                self.datalist.append(self.storage.database['songs'][i])
            self.index = self.storage.database['player_info']['idx']
            self.offset = self.storage.database['player_info'][
                'idx'] / self.step * self.step

    def request_api(self, func, *args):
        if self.storage.database['user']['user_id'] != '':
            result = func(*args)
            if result != -1:
                return result
        log.debug('Re Login.')
        user_info = {}
        if self.storage.database['user']['username'] != '':
            user_info = self.netease.login(
                self.storage.database['user']['username'],
                self.storage.database['user']['password'])
        if self.storage.database['user']['username'] == '' or user_info[
                'code'] != 200:
            data = self.ui.build_login()
            # 取消登录
            if data == -1:
                return -1
            user_info = data[0]
            self.storage.database['user']['username'] = data[1][0]
            self.storage.database['user']['password'] = data[1][1]
            self.storage.database['user']['user_id'] = user_info['account'][
                'id']
            self.storage.database['user']['nickname'] = user_info['profile'][
                'nickname']
        self.userid = self.storage.database['user']['user_id']
        self.username = self.storage.database['user']['nickname']
        return func(*args)

    def get_new_fm(self):
        myplaylist = []
        for count in range(0, 1):
            data = self.request_api(self.netease.personal_fm)
            if data == -1:
                break
            myplaylist += data
            time.sleep(0.2)
        return self.netease.dig_info(myplaylist, 'fmsongs')

    def choice_channel(self, idx):
        # 排行榜
        netease = self.netease
        if idx == 0:
            self.datalist = netease.return_toplists()
            self.title += ' > Charts'
            self.datatype = 'toplists'

        # 艺术家
        elif idx == 1:
            artists = netease.top_artists()
            self.datalist = netease.dig_info(artists, 'artists')
            self.title += ' > Artists'
            self.datatype = 'artists'

        # 新碟上架
        elif idx == 2:
            albums = netease.new_albums()
            self.datalist = netease.dig_info(albums, 'albums')
            self.title += ' > Albums'
            self.datatype = 'albums'

        # 精选歌单
        elif idx == 3:
            self.datalist = [
                {
                    'title': 'Top Playlists',
                    'datatype': 'top_playlists',
                    'callback': netease.top_playlists
                }, {
                    'title': 'Playlists (By Category)',
                    'datatype': 'playlist_classes',
                    'callback': netease.playlist_classes
                }
            ]
            self.title += ' > Playlists'
            self.datatype = 'playlists'

        # 我的歌单
        elif idx == 4:
            myplaylist = self.request_api(self.netease.user_playlist,
                                          self.userid)
            if myplaylist == -1:
                return
            self.datatype = 'top_playlists'
            self.datalist = netease.dig_info(myplaylist, self.datatype)
            self.title += ' > ' + self.username + ' 的歌单'

        # 主播电台
        elif idx == 5:
            self.datatype = 'djchannels'
            self.title += ' > Radio Stations'
            self.datalist = netease.djchannels()

        # 每日推荐
        elif idx == 6:
            self.datatype = 'songs'
            self.title += ' > Songs'
            myplaylist = self.request_api(self.netease.recommend_playlist)
            if myplaylist == -1:
                return
            self.datalist = self.netease.dig_info(myplaylist, self.datatype)

        # 私人FM
        elif idx == 7:
            self.datatype = 'fmsongs'
            self.title += ' > Personal Radio'
            self.datalist = self.get_new_fm()

        # 搜索
        elif idx == 8:
            self.datatype = 'search'
            self.title += ' > Search'
            self.datalist = ['Songs', 'Artists', 'Albums', 'Playlists']

        # 帮助
        elif idx == 9:
            self.datatype = 'help'
            self.title += ' > Help'
            self.datalist = shortcut

        self.offset = 0
        self.index = 0
コード例 #13
0
class Ui:
    def __init__(self):
        self.screen = curses.initscr()
        self.screen.timeout(500)  # the screen refresh every 500ms
        # 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)
        # term resize handling
        size = terminalsize.get_terminal_size()
        self.x = max(size[0], 10)
        self.y = max(size[1], 25)
        self.startcol = int(float(self.x) / 5)
        self.indented_startcol = max(self.startcol - 3, 0)
        self.update_space()

    def build_playinfo(self,
                       song_name,
                       artist,
                       album_name,
                       quality,
                       start,
                       pause=False):
        curses.noecho()
        # 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, self.indented_startcol,
                               '_ _ z Z Z ' + quality, curses.color_pair(3))
        else:
            self.screen.addstr(1, self.indented_startcol,
                               '♫  ♪ ♫  ♪ ' + quality, curses.color_pair(3))

        self.screen.addstr(
            1, min(self.indented_startcol + 18, self.x - 1),
            song_name + self.space + artist + '  < ' + album_name + ' >',
            curses.color_pair(4))

        # The following script doesn't work. It is intended to scroll the playinfo
        # Scrollstring works by determining how long since it is created, but
        # playinfo is created everytime the screen refreshes (every 500ms), unlike
        # the menu. Is there a workaround?

        # name = song_name + self.space + artist + '  < ' + album_name + ' >'

        # decides whether to scoll
        # if truelen(name) <= self.x - self.indented_startcol - 18:
        #     self.screen.addstr(1, min(self.indented_startcol + 18, self.x-1),
        #                        name,
        #                        curses.color_pair(4))
        # else:
        #     name = scrollstring(name + '  ', start)
        #     self.screen.addstr(1, min(self.indented_startcol + 18, self.x-1),
        #                        str(name),
        #                        curses.color_pair(4))

        self.screen.refresh()

    def build_loading(self):
        self.screen.addstr(6, self.startcol, '享受高品质音乐,loading...',
                           curses.color_pair(1))
        self.screen.refresh()

    # start is the timestamp of this function being called
    def build_menu(self, datatype, title, datalist, offset, index, step,
                   start):
        # keep playing info in line 1
        curses.noecho()
        self.screen.move(4, 1)
        self.screen.clrtobot()
        self.screen.addstr(4, self.startcol, title, curses.color_pair(1))

        if len(datalist) == 0:
            self.screen.addstr(8, self.startcol, '这里什么都没有 -,-')

        else:
            if datatype == 'main':
                for i in range(offset, min(len(datalist), offset + step)):
                    if i == index:
                        self.screen.addstr(i - offset + 8,
                                           self.indented_startcol,
                                           '-> ' + str(i) + '. ' + datalist[i],
                                           curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset + 8, self.startcol,
                                           str(i) + '. ' + datalist[i])

            elif datatype == 'songs':
                iter_range = min(len(datalist), offset + step)
                for i in range(offset, iter_range):
                    # this item is focus
                    if i == index:
                        self.screen.addstr(i - offset + 8, 0,
                                           ' ' * self.startcol)
                        lead = '-> ' + str(i) + '. '
                        self.screen.addstr(i - offset + 8,
                                           self.indented_startcol, lead,
                                           curses.color_pair(2))
                        name = str(datalist[i]['song_name'] + self.space +
                                   datalist[i]['artist'] + '  < ' +
                                   datalist[i]['album_name'] + ' >')

                        # the length decides whether to scoll
                        if truelen(name) < self.x - self.startcol - 1:
                            self.screen.addstr(
                                i - offset + 8,
                                self.indented_startcol + len(lead), name,
                                curses.color_pair(2))
                        else:
                            name = scrollstring(name + '  ', start)
                            self.screen.addstr(
                                i - offset + 8,
                                self.indented_startcol + len(lead), str(name),
                                curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset + 8, 0,
                                           ' ' * self.startcol)
                        self.screen.addstr(
                            i - offset + 8, self.startcol,
                            str(
                                str(i) + '. ' + datalist[i]['song_name'] +
                                self.space + datalist[i]['artist'] + '  < ' +
                                datalist[i]['album_name'] + ' >')[:int(self.x *
                                                                       2)])
                    self.screen.addstr(iter_range - offset + 8, 0,
                                       ' ' * self.x)

            elif datatype == 'artists':
                for i in range(offset, min(len(datalist), offset + step)):
                    if i == index:
                        self.screen.addstr(
                            i - offset + 8, self.indented_startcol, '-> ' +
                            str(i) + '. ' + datalist[i]['artists_name'] +
                            self.space + str(datalist[i]['alias']),
                            curses.color_pair(2))
                    else:
                        self.screen.addstr(
                            i - offset + 8, self.startcol,
                            str(i) + '. ' + datalist[i]['artists_name'] +
                            self.space + 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, self.indented_startcol, '-> ' +
                            str(i) + '. ' + datalist[i]['albums_name'] +
                            self.space + datalist[i]['artists_name'],
                            curses.color_pair(2))
                    else:
                        self.screen.addstr(
                            i - offset + 8, self.startcol,
                            str(i) + '. ' + datalist[i]['albums_name'] +
                            self.space + 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, self.indented_startcol,
                            '-> ' + str(i) + '. ' + datalist[i]['title'],
                            curses.color_pair(2))
                    else:
                        self.screen.addstr(
                            i - offset + 8, self.startcol,
                            str(i) + '. ' + datalist[i]['title'])

            elif datatype == 'top_playlists':
                for i in range(offset, min(len(datalist), offset + step)):
                    if i == index:
                        self.screen.addstr(
                            i - offset + 8, self.indented_startcol, '-> ' +
                            str(i) + '. ' + datalist[i]['playlists_name'] +
                            self.space + datalist[i]['creator_name'],
                            curses.color_pair(2))
                    else:
                        self.screen.addstr(
                            i - offset + 8, self.startcol,
                            str(i) + '. ' + datalist[i]['playlists_name'] +
                            self.space + datalist[i]['creator_name'])

            elif datatype == 'toplists':
                for i in range(offset, min(len(datalist), offset + step)):
                    if i == index:
                        self.screen.addstr(i - offset + 8,
                                           self.indented_startcol,
                                           '-> ' + str(i) + '. ' + datalist[i],
                                           curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset + 8, self.startcol,
                                           str(i) + '. ' + datalist[i])

            elif datatype == 'playlist_classes' or datatype == 'playlist_class_detail':
                for i in range(offset, min(len(datalist), offset + step)):
                    if i == index:
                        self.screen.addstr(i - offset + 8,
                                           self.indented_startcol,
                                           '-> ' + str(i) + '. ' + datalist[i],
                                           curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset + 8, self.startcol,
                                           str(i) + '. ' + datalist[i])

            elif datatype == 'djchannels':
                for i in range(offset, min(len(datalist), offset + step)):
                    if i == index:
                        self.screen.addstr(
                            i - offset + 8, self.indented_startcol,
                            '-> ' + str(i) + '. ' + datalist[i]['song_name'],
                            curses.color_pair(2))
                    else:
                        self.screen.addstr(
                            i - offset + 8, self.startcol,
                            str(i) + '. ' + datalist[i]['song_name'])

            elif datatype == 'search':
                self.screen.move(4, 1)
                self.screen.clrtobot()
                self.screen.timeout(-1)
                self.screen.addstr(8, self.startcol, '选择搜索类型:',
                                   curses.color_pair(1))
                for i in range(offset, min(len(datalist), offset + step)):
                    if i == index:
                        self.screen.addstr(
                            i - offset + 10, self.indented_startcol,
                            '-> ' + str(i) + '.' + datalist[i - 1],
                            curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset + 10, self.startcol,
                                           str(i) + '.' + datalist[i - 1])
                self.screen.timeout(500)

            elif datatype == 'help':
                for i in range(offset, min(len(datalist), offset + step)):
                    if i == index:
                        self.screen.addstr(
                            i - offset + 8, self.indented_startcol,
                            '-> ' + str(i) + '. \'' +
                            (datalist[i][0].upper() + '\'').ljust(11) +
                            datalist[i][1] + '   ' + datalist[i][2],
                            curses.color_pair(2))
                    else:
                        self.screen.addstr(
                            i - offset + 8, self.startcol,
                            str(i) + '. \'' +
                            (datalist[i][0].upper() + '\'').ljust(11) +
                            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, self.startcol,
                                   'Build with love to music by omi')

        self.screen.refresh()

    def build_search(self, stype):
        self.screen.timeout(-1)
        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 == 'search_playlist':
            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, 'top_playlists')
            except:
                return []

        return []

    def build_login(self):
        self.build_login_bar()
        local_account = self.get_account()
        local_password = hashlib.md5(self.get_password()).hexdigest()
        login_info = self.netease.login(local_account, local_password)
        account = [local_account, local_password]
        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_bar(self):
        curses.noecho()
        self.screen.move(4, 1)
        self.screen.clrtobot()
        self.screen.addstr(5, self.startcol, '请输入登录信息(支持手机登陆)',
                           curses.color_pair(1))
        self.screen.addstr(8, self.startcol, "账号:", curses.color_pair(1))
        self.screen.addstr(9, self.startcol, "密码:", curses.color_pair(1))
        self.screen.move(8, 24)
        self.screen.refresh()

    def build_login_error(self):
        self.screen.move(4, 1)
        self.screen.timeout(-1)  # disable the screen timeout
        self.screen.clrtobot()
        self.screen.addstr(8, self.startcol, '艾玛,登录信息好像不对呢 (O_O)#',
                           curses.color_pair(1))
        self.screen.addstr(10, self.startcol, '[1] 再试一次')
        self.screen.addstr(11, self.startcol, '[2] 稍后再试')
        self.screen.addstr(14, self.startcol, '请键入对应数字:', curses.color_pair(2))
        self.screen.refresh()
        x = self.screen.getch()
        self.screen.timeout(500)  # restore the screen timeout
        return x

    def get_account(self):
        self.screen.timeout(-1)  # disable the screen timeout
        curses.echo()
        account = self.screen.getstr(8, self.startcol + 6, 60)
        self.screen.timeout(500)  # restore the screen timeout
        return account

    def get_password(self):
        self.screen.timeout(-1)  # disable the screen timeout
        curses.noecho()
        password = self.screen.getstr(9, self.startcol + 6, 60)
        self.screen.timeout(500)  # restore the screen timeout
        return password

    def get_param(self, prompt_string):
        # keep playing info in line 1
        curses.echo()
        self.screen.move(4, 1)
        self.screen.clrtobot()
        self.screen.addstr(5, self.startcol, prompt_string,
                           curses.color_pair(1))
        self.screen.refresh()
        info = self.screen.getstr(10, self.startcol, 60)
        if info.strip() is '':
            return self.get_param(prompt_string)
        else:
            return info

    def update_size(self):
        # get terminal size
        size = terminalsize.get_terminal_size()
        self.x = max(size[0], 10)
        self.y = max(size[1], 25)

        # update intendations
        curses.resizeterm(self.y, self.x)
        self.startcol = int(float(self.x) / 5)
        self.indented_startcol = max(self.startcol - 3, 0)
        self.update_space()
        self.screen.clear()
        self.screen.refresh()

    def update_space(self):
        if self.x > 140:
            self.space = "   -   "
        elif self.x > 80:
            self.space = "  -  "
        else:
            self.space = " - "
        self.screen.refresh()
コード例 #14
0
ファイル: menu.py プロジェクト: salvete/Light-Musicbox
class Menu(object):
    def __init__(self):
        self.config = Config()
        self.datatype = "main"
        self.title = "网易云音乐"
        self.datalist = [
            "排行榜",
            "艺术家",
            "新碟上架",
            "精选歌单",
            "我的歌单",
            "主播电台",
            "每日推荐歌曲",
            "每日推荐歌单",
            "私人FM",
            "搜索",
            "帮助",
        ]
        self.offset = 0
        self.index = 0
        self.storage = Storage()
        self.storage.load()
        self.collection = self.storage.database["collections"]
        self.player = Player()
        self.player.playing_song_changed_callback = self.song_changed_callback
        self.cache = Cache()
        # self.ui = Ui()
        self.api = NetEase()
        # self.screen = curses.initscr()
        # self.screen.keypad(1)
        self.step = 10
        self.stack = []
        self.djstack = []
        self.at_playing_list = False
        self.enter_flag = True
        # signal.signal(signal.SIGWINCH, self.change_term)
        # signal.signal(signal.SIGINT, self.send_kill)
        self.menu_starts = time.time()
        self.countdown_start = time.time()
        self.countdown = -1
        self.is_in_countdown = False

        self.keyword = ''

    @property
    def user(self):
        return self.storage.database["user"]

    @property
    def account(self):
        return self.user["username"]

    @property
    def md5pass(self):
        return self.user["password"]

    @property
    def userid(self):
        return self.user["user_id"]

    @property
    def username(self):
        return self.user["nickname"]

    def login(self):
        if self.account and self.md5pass:
            account, md5pass = self.account, self.md5pass
        else:
            #modified
            account = str(input('name:'))
            password = str(input('password:'******'that is right........')
            return True
        else:
            self.storage.logout()
            # x = self.ui.build_login_error()
            # if x != ord("1"):
            #     return False

            return self.login()

    def to_login(self, username, passwd):
        if self.account and self.md5pass:
            account, md5pass = self.account, self.md5pass
        else:
            # modified
            # account = str(input('name:'))
            # password = str(input('password:'******'that is right........')
            return True
        else:
            self.storage.logout()
            # x = self.ui.build_login_error()
            # if x != ord("1"):
            #     return False

            # return self.login()
            return False

    def search(self, category):
        # self.ui.screen.timeout(-1)
        SearchArg = namedtuple("SearchArg",
                               ["prompt", "api_type", "post_process"])
        category_map = {
            "songs": SearchArg("搜索歌曲:", 1, lambda datalist: datalist),
            "albums": SearchArg("搜索专辑:", 10, lambda datalist: datalist),
            "artists": SearchArg("搜索艺术家:", 100, lambda datalist: datalist),
            "playlists": SearchArg("搜索网易精选集:", 1000,
                                   lambda datalist: datalist),
        }

        prompt, api_type, post_process = category_map[category]
        # keyword = self.ui.get_param(prompt)
        # keyword = str(input('Input the song\'s name:'))
        keyword = self.keyword
        if not keyword:
            return []

        data = self.api.search(keyword, api_type)
        if not data:
            return data

        datalist = post_process(data.get(category, []))
        return self.api.dig_info(datalist, category)

    def change_term(self, signum, frame):
        self.ui.screen.clear()
        self.ui.screen.refresh()

    def send_kill(self, signum, fram):
        self.player.stop()
        self.cache.quit()
        self.storage.save()
        # curses.endwin()
        sys.exit()

    def update_alert(self, version):
        latest = Menu().check_version()
        if latest != version and latest != 0:
            notify("MusicBox Update is available", 1)
            time.sleep(0.5)
            notify(
                "NetEase-MusicBox installed version:" + version +
                "\nNetEase-MusicBox latest version:" + latest,
                0,
            )

    def check_version(self):
        # 检查更新 && 签到
        try:
            mobile = self.api.daily_task(is_mobile=True)
            pc = self.api.daily_task(is_mobile=False)

            if mobile["code"] == 200:
                notify("移动端签到成功", 1)
            if pc["code"] == 200:
                notify("PC端签到成功", 1)

            data = self.api.get_version()
            return data["info"]["version"]
        except KeyError as e:
            return 0

    def start_fork(self, version):
        pid = os.fork()
        if pid == 0:
            Menu().update_alert(version)
        else:
            Menu().start()

    def play_pause(self):
        if self.player.is_empty:
            return
        if not self.player.playing_flag:
            self.player.resume()
        else:
            self.player.pause()

    def next_song(self):
        if self.player.is_empty:
            return
        self.player.next()

    def previous_song(self):
        if self.player.is_empty:
            return
        self.player.prev()

    def start(self):

        # while True:

        #     print('input 1:login,2:search,100:break')
        #     num = int(input('Please input your choice:'))
        #     print('you input {}'.format(num))

        #     if (num == 1):
        #         print('username before: {}'.format(self.user))
        #         myplaylist = self.request_api(self.api.user_playlist, self.userid)
        #         print(myplaylist)
        #         print('username: {}'.format(self.user))
        #     elif num == 2:
        #         datalist = self.search('songs')
        #         print('search result:')
        #         for idxx,val in enumerate(datalist):
        #             print('{}:{}-{}'.format(idxx,val['song_name'],val['artist']))
        #             if idxx > 10:
        #                 break;

        #     elif num == 100:
        #         break

        #############################################################afer:

        def print_info():
            print('----------------------------')
            print('1:清空信息并退出')
            print('2:上移')
            print('3:下移')
            print('4:搜索')
            print('5:播放')
            print('6:登录')
            print('7:个人歌单')
            print('100:直接退出')
            print('----------------------------')

        while True:
            datatype = self.datatype
            title = self.title
            datalist = self.datalist
            offset = self.offset
            idx = self.index
            step = self.step

            print_info()

            key = int(input('请输入你的选择:'))

            if key == 100:
                print('正在退出....')
                self.player.stop()
                self.storage.save()
                break

            elif key == 1:
                self.api.logout()
                print('正在退出....')
                self.player.stop()
                break

            elif key == 2:
                if idx == offset:
                    if offset == 0:
                        continue
                    self.offset -= step
                    # 移动光标到最后一列
                    self.index = offset - 1
                else:
                    self.index = carousel(
                        offset,
                        min(len(datalist), offset + step) - 1, idx - 1)
                self.menu_starts = time.time()
            elif key == 3:
                if idx == min(len(datalist), offset + step) - 1:
                    if offset + step >= len(datalist):
                        continue
                    self.offset += step
                    # 移动光标到第一列
                    self.index = offset + step
                else:
                    self.index = carousel(
                        offset,
                        min(len(datalist), offset + step) - 1, idx + 1)
                self.menu_starts = time.time()
            elif key == 4:
                self.index = 0
                self.offset = 0
                idx = 1
                SearchCategory = namedtuple("SearchCategory",
                                            ["type", "title"])
                idx_map = {
                    0: SearchCategory("playlists", "精选歌单搜索列表"),
                    1: SearchCategory("songs", "歌曲搜索列表"),
                    2: SearchCategory("artists", "艺术家搜索列表"),
                    3: SearchCategory("albums", "专辑搜索列表"),
                }
                self.datatype, self.title = idx_map[idx]
                self.datalist = self.search(self.datatype)

                print('search result:')
                for idxx, val in enumerate(self.datalist):
                    print('{}:{}-{}'.format(idxx, val['song_name'],
                                            val['artist']))
                    if idxx > 10:
                        break

                which_one = int(input('输入想要播放的序号:'))

                while which_one > 10 or which_one < 0:
                    which_one = int(input('序号不合理,重新输入:'))

                self.player.new_player_list('songs', self.title, self.datalist,
                                            -1)
                self.idx = which_one
                self.player.play_or_pause(self.idx, self.at_playing_list)

            elif key == 5:
                print('当前的歌单:')
                cnt = 0
                for key in self.player.songs.keys():
                    print('{}.{}----{}'.format(
                        cnt, self.player.songs[key]['song_name'],
                        self.player.songs[key]['artist']))
                    cnt += 1
                    if cnt > 10:
                        break

                which_one = int(input('输入想要播放的序号:'))
                while which_one > 10 or which_one < 0:
                    which_one = int(input('序号不合理,重新输入:'))
                self.idx = which_one
                self.player.play_or_pause(self.idx, self.at_playing_list)
            elif key == 6:
                myplaylist = self.request_api(self.api.user_playlist,
                                              self.userid)
                self.datatype = 'top_playlists'
                myplaylist = self.api.dig_info(myplaylist, self.datatype)
                notify('登录成功')
            elif key == 7:
                myplaylist = self.request_api(self.api.user_playlist,
                                              self.userid)
                self.datatype = 'top_playlists'
                myplaylist = self.api.dig_info(myplaylist, self.datatype)
                print('{}的歌单:'.format(self.username))
                for x, y in enumerate(myplaylist):
                    print('{}.{}'.format(x, y['playlist_name']))

    def get_songs_info(self, search_info, choice):
        self.keyword = search_info

        if choice < 0 or choice > 3:
            notify('选择有误')
            return

        idx = choice
        SearchCategory = namedtuple("SearchCategory", ["type", "title"])
        idx_map = {
            0: SearchCategory("playlists", "精选歌单搜索列表"),
            1: SearchCategory("songs", "歌曲搜索列表"),
            2: SearchCategory("artists", "艺术家搜索列表"),
            3: SearchCategory("albums", "专辑搜索列表"),
        }
        self.datatype, self.title = idx_map[idx]
        self.datalist = self.search(self.datatype)
        res = []
        if choice == 1:
            for idxx, val in enumerate(self.datalist):
                res.append('{}(歌曲名)-{}(艺术家))'.format(val['song_name'],
                                                     val['artist']))
                # if idxx > 10:
                #     break;
        elif choice == 2:
            for idxx, val in enumerate(self.datalist):
                res.append('艺术家:{}'.format(val['artists_name']))
                # if idxx > 10:
                #     break;

        elif choice == 3:
            # print(self.datalist)
            for idxx, val in enumerate(self.datalist):
                res.append('{}(专辑)-{}(艺术家)'.format(val['albums_name'],
                                                   val['artists_name']))
                # if idxx > 10:
                #     break;
        else:
            pass

        return res

    def play_which_song(self, which):
        # self.player.new_player_list('songs', self.title, self.datalist, -1)
        #         #  self.idx = which
        # self.player.play_or_pause(self.idx, self.at_playing_list)

        # print('self.at...',self.at_playing_list)

        self.player.new_player_list("songs", self.title, self.datalist, -1)

        # self.player.end_callback = None
        self.player.play_or_pause(which, self.at_playing_list)
        # self.at_playing_list = True

    def now_total_time(self):
        return self.player.process_location, self.player.process_length

    def dispatch_enter(self, idx):
        # The end of stack
        netease = self.api
        datatype = self.datatype
        title = self.title
        datalist = self.datalist
        offset = self.offset
        index = self.index
        self.stack.append([datatype, title, datalist, offset, index])

        if idx >= len(self.datalist):
            return False

        if datatype == "main":
            self.choice_channel(idx)

        # 该艺术家的热门歌曲
        elif datatype == "artists":
            artist_name = datalist[idx]["artists_name"]
            artist_id = datalist[idx]["artist_id"]

            self.datatype = "artist_info"
            self.title += " > " + artist_name
            self.datalist = [
                {
                    "item": "{}的热门歌曲".format(artist_name),
                    "id": artist_id
                },
                {
                    "item": "{}的所有专辑".format(artist_name),
                    "id": artist_id
                },
            ]

        elif datatype == "artist_info":
            self.title += " > " + datalist[idx]["item"]
            artist_id = datalist[0]["id"]
            if idx == 0:
                self.datatype = "songs"
                songs = netease.artists(artist_id)
                self.datalist = netease.dig_info(songs, "songs")

            elif idx == 1:
                albums = netease.get_artist_album(artist_id)
                self.datatype = "albums"
                self.datalist = netease.dig_info(albums, "albums")

        elif datatype == "djchannels":
            radio_id = datalist[idx]["id"]
            programs = netease.djprograms(radio_id)
            self.title += " > " + datalist[idx]["name"]
            self.datatype = "songs"
            self.datalist = netease.dig_info(programs, "songs")

        # 该专辑包含的歌曲
        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 == "recommend_lists":
            data = self.datalist[idx]
            self.datatype = data["datatype"]
            self.datalist = netease.dig_info(data["callback"](), self.datatype)
            self.title += " > " + data["title"]

        # 全站置顶歌单包含的歌曲
        elif datatype in ["top_playlists", "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]["playlist_name"]

        # 分类精选
        elif datatype == "playlist_classes":
            # 分类名称
            data = self.datalist[idx]
            self.datatype = "playlist_class_detail"
            self.datalist = netease.dig_info(data, self.datatype)
            self.title += " > " + data

        # 某一分类的详情
        elif datatype == "playlist_class_detail":
            # 子类别
            data = self.datalist[idx]
            self.datatype = "top_playlists"
            log.error(data)
            self.datalist = netease.dig_info(netease.top_playlists(data),
                                             self.datatype)
            self.title += " > " + data

        # 歌曲评论
        elif datatype in ["songs", "fmsongs"]:
            song_id = datalist[idx]["song_id"]
            comments = self.api.song_comments(song_id, limit=100)
            try:
                hotcomments = comments["hotComments"]
                comcomments = comments["comments"]
            except KeyError:
                hotcomments = comcomments = []
            self.datalist = []
            for one_comment in hotcomments:
                self.datalist.append("(热评 %s❤️ ️)%s:%s" % (
                    one_comment["likedCount"],
                    one_comment["user"]["nickname"],
                    one_comment["content"],
                ))
            for one_comment in comcomments:
                self.datalist.append(one_comment["content"])
            self.datatype = "comments"
            self.title = "网易云音乐 > 评论:%s" % datalist[idx]["song_name"]
            self.offset = 0
            self.index = 0

        # 歌曲榜单
        elif datatype == "toplists":
            songs = netease.top_songlist(idx)
            self.title += " > " + self.datalist[idx]
            self.datalist = netease.dig_info(songs, "songs")
            self.datatype = "songs"

        # 搜索菜单
        elif datatype == "search":
            self.index = 0
            self.offset = 0
            SearchCategory = namedtuple("SearchCategory", ["type", "title"])
            idx_map = {
                0: SearchCategory("playlists", "精选歌单搜索列表"),
                1: SearchCategory("songs", "歌曲搜索列表"),
                2: SearchCategory("artists", "艺术家搜索列表"),
                3: SearchCategory("albums", "专辑搜索列表"),
            }
            self.datatype, self.title = idx_map[idx]
            self.datalist = self.search(self.datatype)
        else:
            self.enter_flag = False

    def show_playing_song(self):
        if self.player.is_empty:
            return

        if not self.at_playing_list:
            self.stack.append([
                self.datatype, self.title, self.datalist, self.offset,
                self.index
            ])
            self.at_playing_list = True

        self.datatype = self.player.info["player_list_type"]
        self.title = self.player.info["player_list_title"]
        self.datalist = [
            self.player.songs[i] for i in self.player.info["player_list"]
        ]
        self.index = self.player.info["idx"]
        self.offset = self.index // self.step * self.step

    def song_changed_callback(self):
        if self.at_playing_list:
            self.show_playing_song()

    def fm_callback(self):
        # log.debug('FM CallBack.')
        data = self.get_new_fm()
        self.player.append_songs(data)
        if self.datatype == "fmsongs":
            if self.player.is_empty:
                return
            self.datatype = self.player.info["player_list_type"]
            self.title = self.player.info["player_list_title"]
            self.datalist = []
            for i in self.player.info["player_list"]:
                self.datalist.append(self.player.songs[i])
            self.index = self.player.info["idx"]
            self.offset = self.index // self.step * self.step
            if not self.player.playing_flag:
                switch_flag = False
                self.player.play_or_pause(self.index, switch_flag)

    def request_api(self, func, *args):
        result = func(*args)
        if result:
            return result
        if not self.login():
            print('you really need to login')
            notify("You need to log in")
            return False
        return func(*args)

    def get_new_fm(self):
        data = self.request_api(self.api.personal_fm)
        if not data:
            return []
        return self.api.dig_info(data, "fmsongs")

    def choice_channel(self, idx):
        self.offset = 0
        self.index = 0

        if idx == 0:
            self.datalist = self.api.toplists
            self.title += " > 排行榜"
            self.datatype = "toplists"
        elif idx == 1:
            artists = self.api.top_artists()
            self.datalist = self.api.dig_info(artists, "artists")
            self.title += " > 艺术家"
            self.datatype = "artists"
        elif idx == 2:
            albums = self.api.new_albums()
            self.datalist = self.api.dig_info(albums, "albums")
            self.title += " > 新碟上架"
            self.datatype = "albums"
        elif idx == 3:
            self.datalist = [
                {
                    "title": "全站置顶",
                    "datatype": "top_playlists",
                    "callback": self.api.top_playlists,
                },
                {
                    "title": "分类精选",
                    "datatype": "playlist_classes",
                    "callback": lambda: [],
                },
            ]
            self.title += " > 精选歌单"
            self.datatype = "recommend_lists"
        elif idx == 4:
            myplaylist = self.request_api(self.api.user_playlist, self.userid)
            self.datatype = "top_playlists"
            self.datalist = self.api.dig_info(myplaylist, self.datatype)
            self.title += " > " + self.username + " 的歌单"
        elif idx == 5:
            self.datatype = "djchannels"
            self.title += " > 主播电台"
            self.datalist = self.api.djchannels()
        elif idx == 6:
            self.datatype = "songs"
            self.title += " > 每日推荐歌曲"
            myplaylist = self.request_api(self.api.recommend_playlist)
            if myplaylist == -1:
                return
            self.datalist = self.api.dig_info(myplaylist, self.datatype)
        elif idx == 7:
            myplaylist = self.request_api(self.api.recommend_resource)
            self.datatype = "top_playlists"
            self.title += " > 每日推荐歌单"
            self.datalist = self.api.dig_info(myplaylist, self.datatype)
        elif idx == 8:
            self.datatype = "fmsongs"
            self.title += " > 私人FM"
            self.datalist = self.get_new_fm()
        elif idx == 9:
            self.datatype = "search"
            self.title += " > 搜索"
            self.datalist = ["歌曲", "艺术家", "专辑", "网易精选集"]
        elif idx == 10:
            self.datatype = "help"
            self.title += " > 帮助"
            self.datalist = shortcut
コード例 #15
0
ファイル: ui.py プロジェクト: dream1986/musicbox-1
class Ui:
    def __init__(self):
        curses.setupterm()  #初始化终端
        self.screen = curses.initscr()
        self.LINES=curses.tigetnum('lines') #终端行数
        self.COLS=curses.tigetnum('cols')  #列数
        self.show_begin_line=int((int(self.LINES)-22)/2-1)
        # 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):
        curses.noecho()
        # refresh top 2 line
        self.screen.move(1+self.show_begin_line,1)
        self.screen.clrtoeol()
        self.screen.move(2+self.show_begin_line,1)
        self.screen.clrtoeol()
        if pause:
            self.screen.addstr(1+self.show_begin_line, 6, '_ _ z Z Z', curses.color_pair(3))
        else:
            self.screen.addstr(1+self.show_begin_line, 6, '♫  ♪ ♫  ♪', curses.color_pair(3))
        self.screen.addstr(1+self.show_begin_line, 17, song_name + ' - ' + artist + ' < ' + album_name + ' >', curses.color_pair(4))
        self.screen.refresh()     

    def build_loading(self,i=1):
        if i==1:
            self.screen.addstr(6+self.show_begin_line, 16, '享受高品质音乐,loading...', curses.color_pair(1))
        elif i==2:
            self.screen.addstr(6+self.show_begin_line, 16, 'loading...', curses.color_pair(3))
        self.screen.refresh()        

    def build_menu(self, datatype, title, datalist, offset, index, step,album_name_P=False):
        # keep playing info in line 1
        curses.noecho()
        self.screen.move(4+self.show_begin_line,1)
        self.screen.clrtobot()
        if datatype=='main':  #调整标题位置
            self.screen.addstr(4+self.show_begin_line, 19, title, curses.color_pair(1))
        else:
            self.screen.addstr(4+self.show_begin_line, 9, title, curses.color_pair(1))

        if len(datalist) == 0:
            self.screen.addstr(8+self.show_begin_line, 19, '这里什么都没有 -,-')

        else:
            if datatype == 'main':
                for i in range( offset, min( len(datalist), offset+step) ):
                    if i == index:
                        self.screen.addstr(i - offset +8+self.show_begin_line, 16, '-> ' + str(i) + '. ' + datalist[i], curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset +8+self.show_begin_line, 19, str(i) + '. ' + datalist[i])

            elif datatype == 'songs':
                for i in range(offset, min( len(datalist), offset+step) ):
                    # this item is focus
                    if album_name_P:   #显示专辑名 
                        if i == index:
                            self.screen.addstr(i - offset +8+self.show_begin_line, 6, '-> ' + str(i) + '. ' + datalist[i]['song_name'] + '  -  ' + datalist[i]['artist'] + '  < ' + datalist[i]['album_name'] + ' >', curses.color_pair(2))
                        else:
                            self.screen.addstr(i - offset +8+self.show_begin_line, 9, str(i) + '. ' + datalist[i]['song_name'] + '  -  ' + datalist[i]['artist'] + '  < ' + datalist[i]['album_name'] + ' >')
                    else:  #不显示专辑名
                        if i==index:
                            self.screen.addstr(i - offset +8+self.show_begin_line, 6, '-> ' + str(i) + '. ' + datalist[i]['song_name'] + '  -  ' + datalist[i]['artist'], curses.color_pair(2))
                        else:
                            self.screen.addstr(i - offset +8+self.show_begin_line, 9, str(i) + '. ' + datalist[i]['song_name'] + '  -  ' + datalist[i]['artist'] )

            
            elif datatype == 'artists':
                for i in range(offset, min( len(datalist), offset+step) ):
                    if i == index:
                        self.screen.addstr(i - offset +8+self.show_begin_line, 16, '-> ' + str(i) + '. ' + datalist[i]['artists_name'] + '   -   ' + str(datalist[i]['alias']), curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset +8+self.show_begin_line, 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+self.show_begin_line, 6, '-> ' + str(i) + '. ' + datalist[i]['albums_name'] + '   -   ' + datalist[i]['artists_name'], curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset +8+self.show_begin_line, 9, 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+self.show_begin_line, 6, '-> ' + str(i) + '. ' + datalist[i]['title'], curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset +8+self.show_begin_line, 9, str(i) + '. ' + datalist[i]['title'])


            elif datatype == 'top_playlists':
                for i in range(offset, min( len(datalist), offset+step) ):
                    if i == index:
                        self.screen.addstr(i - offset +8+self.show_begin_line, 6, '-> ' + str(i) + '. ' + datalist[i]['playlists_name'] + '   -   ' + datalist[i]['creator_name'], curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset +8+self.show_begin_line, 9, str(i) + '. ' + datalist[i]['playlists_name'] + '   -   ' + datalist[i]['creator_name'])

            elif datatype == 'toplists': #排行榜榜名
                for i in range(offset, min(len(datalist),offset+step)):
                    if i == index:
                        self.screen.addstr(i-offset+8+self.show_begin_line, 7, '->' + str(i) + '. ' + datalist[i], curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset + 8 + self.show_begin_line, 9 ,str(i) + '. ' + datalist[i])


            elif datatype == 'playlist_classes' or datatype == 'playlist_class_detail':
                for i in range(offset, min( len(datalist), offset+step) ):
                    if i == index:
                        self.screen.addstr(i - offset +8+self.show_begin_line, 6, '-> ' + str(i) + '. ' + datalist[i], curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset +8+self.show_begin_line, 9, str(i) + '. ' + datalist[i])

            elif datatype == 'djchannels':
                for i in range(offset, min( len(datalist), offset+step) ):
                    if i == index:
                        self.screen.addstr(i - offset +8+self.show_begin_line, 6, '-> ' + str(i) + '. ' + datalist[i]['song_name'], curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset +8+self.show_begin_line, 9, 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+self.show_begin_line, 16, '-> ' + str(i) + '. \'' + datalist[i][0].upper() + '\'   ' + datalist[i][1] + '   ' + datalist[i][2], curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset +8+self.show_begin_line, 19, str(i) + '. \'' + datalist[i][0].upper() + '\'   ' + datalist[i][1] + '   ' + datalist[i][2])                
                self.screen.addstr(18+self.show_begin_line, 6, 'MusicBox 基于Python,所有版权音乐来源于网易,本地不做任何保存')
                self.screen.addstr(21+self.show_begin_line, 6, '按 [G] 到 Github 了解更多信息,帮助改进,或者Star表示支持~~')

        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 == 'search_playlist':
            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, 'top_playlists')
            except:
                return []

        return []

    def build_search_menu(self):
        self.screen.move(4+self.show_begin_line,1)
        self.screen.clrtobot()
        self.screen.addstr(8+self.show_begin_line, 19, '选择搜索类型:', curses.color_pair(1))
        self.screen.addstr(10+self.show_begin_line,19, '[1] 歌曲')
        self.screen.addstr(11+self.show_begin_line,19, '[2] 艺术家')
        self.screen.addstr(12+self.show_begin_line,19, '[3] 专辑')
        self.screen.addstr(13+self.show_begin_line,19, '[4] 网易精选集')
        self.screen.addstr(16+self.show_begin_line,19, '请键入对应数字:', curses.color_pair(2))
        self.screen.refresh()
        x = self.screen.getch()
        return x

    def build_login(self):
        self.screen.move(7+self.show_begin_line,1)
        self.screen.clrtobot()
        curses.noecho()
        info = self.get_param('请输入登录信息(q or Q 退出登陆), e.g: [email protected] 123456')
        if str(info) in ('q','Q'):
            return -1
        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+self.show_begin_line,1)
        self.screen.clrtobot()
        self.screen.addstr(8+self.show_begin_line, 19, '艾玛,登录信息好像不对呢 (O_O)#', curses.color_pair(1))
        self.screen.addstr(10+self.show_begin_line,19, '[1] 再试一次')
        self.screen.addstr(11+self.show_begin_line,19, '[2] 稍后再试')
        self.screen.addstr(14+self.show_begin_line,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        
        curses.echo()
        self.screen.move(4+self.show_begin_line,1)
        self.screen.clrtobot()
        self.screen.addstr(5+self.show_begin_line, 3, 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

    def progress_bar(self,time_now,length):  #进度条
        cols=int(self.COLS)-18
        time_now=int(ceil(float(time_now)))
        length=int(ceil(float(length)))
        if time_now>length:
            time_now=length
        surplus=length-time_now
        if length!=0 and length!=0:
            t_now="%2d:%02d" % (int(time_now//60),int(time_now%60))
            t_surplus="%2d:%02d" % (int(surplus//60),int(surplus%60))
            dutyfactor_1=int(ceil(float(time_now)/length*cols))
            line=t_now+' '+'*'*dutyfactor_1+'>'+'-'*(cols-dutyfactor_1)+' '+t_surplus
            self.screen.addstr(20+self.show_begin_line,2,line,curses.color_pair(3))
            self.screen.refresh()


    def notifySend(self,name,artist,other=''):   #发送桌面通知
        s=other+name+' -- <'+artist+'>'
        subprocess.call(['notify-send',s])
コード例 #16
0
ファイル: ui.py プロジェクト: naredbuddha/musicbox
class Ui:
    def __init__(self):
        self.screen = curses.initscr()
        self.screen.timeout(100)  # the screen refresh every 100ms
        # 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)
        # term resize handling
        size = terminalsize.get_terminal_size()
        self.x = max(size[0], 10)
        self.y = max(size[1], 25)
        self.startcol = int(float(self.x) / 5)
        self.indented_startcol = max(self.startcol - 3, 0)
        self.update_space()
        self.lyric = ""
        self.now_lyric = ""
        self.storage = Storage()
        self.newversion = False

    def notify(self, summary, song, album, artist):
        if platform.system() == "Darwin":
            os.system('/usr/bin/osascript -e \'display notification "' + summary + ' ' + song + '\nin ' + album + ' by ' + artist +'"\'')
        else:
            os.system('/usr/bin/notify-send "' + summary + song + ' in ' + album + ' by ' + artist + '"')

    def build_playinfo(self, song_name, artist, album_name, quality, start, pause=False):
        curses.noecho()
        # 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, self.indented_startcol, '_ _ z Z Z ' + quality, curses.color_pair(3))
        else:
            self.screen.addstr(1, self.indented_startcol, '♫  ♪ ♫  ♪ ' + quality, curses.color_pair(3))

        self.screen.addstr(1, min(self.indented_startcol + 18, self.x - 1),
                           song_name + self.space + artist + '  < ' + album_name + ' >',
                           curses.color_pair(4))


        # The following script doesn't work. It is intended to scroll the playinfo
        # Scrollstring works by determining how long since it is created, but
        # playinfo is created everytime the screen refreshes (every 500ms), unlike
        # the menu. Is there a workaround?

        # name = song_name + self.space + artist + '  < ' + album_name + ' >'

        # decides whether to scoll
        # if truelen(name) <= self.x - self.indented_startcol - 18:
        #     self.screen.addstr(1, min(self.indented_startcol + 18, self.x-1),
        #                        name,
        #                        curses.color_pair(4))
        # else:
        #     name = scrollstring(name + '  ', start)
        #     self.screen.addstr(1, min(self.indented_startcol + 18, self.x-1),
        #                        str(name),
        #                        curses.color_pair(4))

        self.screen.refresh()

    def build_process_bar(self, now_playing, total_length, playing_flag, pause_flag, playing_mode):
        if (self.storage.database["player_info"]["idx"] >= len(self.storage.database["player_info"]["player_list"])):
            return
        curses.noecho()
        self.screen.move(3, 1)
        self.screen.clrtoeol()
        self.screen.move(4, 1)
        self.screen.clrtoeol()
        if not playing_flag:
            return
        if total_length <= 0:
            total_length = 1
        if now_playing > total_length or now_playing <= 0:
            now_playing = 0
        process = "["
        for i in range(0, 33):
            if i < now_playing / total_length * 33:
                if (i + 1) > now_playing / total_length * 33:
                    if not pause_flag:
                        process += ">"
                        continue
                process += "="
            else:
                process += " "
        process += "] "
        now_minute = int(now_playing / 60)
        if now_minute > 9:
            now_minute = str(now_minute)
        else:
            now_minute = "0" + str(now_minute)
        now_second = int(now_playing - int(now_playing / 60) * 60)
        if now_second > 9:
            now_second = str(now_second)
        else:
            now_second = "0" + str(now_second)
        total_minute = int(total_length / 60)
        if total_minute > 9:
            total_minute = str(total_minute)
        else:
            total_minute = "0" + str(total_minute)
        total_second = int(total_length - int(total_length / 60) * 60)
        if total_second > 9:
            total_second = str(total_second)
        else:
            total_second = "0" + str(total_second)
        process += "(" + now_minute + ":" + now_second + "/" + total_minute + ":" + total_second + ")"
        if playing_mode == 0:
            process = "顺序播放 " + process
        elif playing_mode == 1:
            process = "顺序循环 " + process
        elif playing_mode == 2:
            process = "单曲循环 " + process
        elif playing_mode == 3:
            process = "随机播放 " + process
        elif playing_mode == 4:
            process = "随机循环 " + process
        else:
            pass
        self.screen.addstr(3, self.startcol - 2, process, curses.color_pair(1))

        song = self.storage.database["songs"][
            self.storage.database["player_info"]["player_list"][self.storage.database["player_info"]["idx"]]
        ]
        if 'lyric' not in song.keys() or len(song["lyric"]) <= 0:
            self.now_lyric = "[00:00.00]暂无歌词 ~>_<~ \n"
        else:
            key = now_minute + ":" + now_second
            for line in song["lyric"]:
                if key in line:
                    self.now_lyric = line
        self.now_lyric = re.sub('\[.*?\]', "", self.now_lyric)
        self.screen.addstr(4, self.startcol - 2, str(self.now_lyric), curses.color_pair(3))
        self.screen.refresh()

    def build_loading(self):
        self.screen.addstr(7, self.startcol, '享受高品质音乐,loading...', curses.color_pair(1))
        self.screen.refresh()

    # start is the timestamp of this function being called
    def build_menu(self, datatype, title, datalist, offset, index, step, start):
        # keep playing info in line 1
        curses.noecho()
        self.screen.move(5, 1)
        self.screen.clrtobot()
        self.screen.addstr(5, self.startcol, title, curses.color_pair(1))

        if len(datalist) == 0:
            self.screen.addstr(8, self.startcol, '这里什么都没有 -,-')

        else:
            if datatype == 'main':
                for i in range(offset, min(len(datalist), offset + step)):
                    if i == index:
                        self.screen.addstr(i - offset + 9, self.indented_startcol, '-> ' + str(i) + '. ' + datalist[i],
                                           curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset + 9, self.startcol, str(i) + '. ' + datalist[i])

            elif datatype == 'songs' or datatype == 'fmsongs':
                iter_range = min(len(datalist), offset + step)
                for i in range(offset, iter_range):
                    # this item is focus
                    if i == index:
                        self.screen.addstr(i - offset + 8, 0, ' ' * self.startcol)
                        lead = '-> ' + str(i) + '. '
                        self.screen.addstr(i - offset + 8, self.indented_startcol, lead, curses.color_pair(2))
                        name = str(datalist[i]['song_name'] + self.space + datalist[i][
                            'artist'] + '  < ' + datalist[i]['album_name'] + ' >')

                        # the length decides whether to scoll
                        if truelen(name) < self.x - self.startcol - 1:
                            self.screen.addstr(i - offset + 8, self.indented_startcol + len(lead),
                                               name,
                                               curses.color_pair(2))
                        else:
                            name = scrollstring(name + '  ', start)
                            self.screen.addstr(i - offset + 8, self.indented_startcol + len(lead),
                                               str(name),
                                               curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset + 8, 0, ' ' * self.startcol)
                        self.screen.addstr(i - offset + 8, self.startcol,
                                           str(str(i) + '. ' + datalist[i]['song_name'] + self.space + datalist[i][
                                               'artist'] + '  < ' + datalist[i]['album_name'] + ' >')[:int(self.x * 2)])
                    self.screen.addstr(iter_range - offset + 9, 0, ' ' * self.x)

            elif datatype == 'artists':
                for i in range(offset, min(len(datalist), offset + step)):
                    if i == index:
                        self.screen.addstr(i - offset + 9, self.indented_startcol,
                                           '-> ' + str(i) + '. ' + datalist[i]['artists_name'] + self.space + str(
                                               datalist[i]['alias']), curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset + 9, self.startcol,
                                           str(i) + '. ' + datalist[i]['artists_name'] + self.space + datalist[i][
                                               'alias'])

            elif datatype == 'albums':
                for i in range(offset, min(len(datalist), offset + step)):
                    if i == index:
                        self.screen.addstr(i - offset + 9, self.indented_startcol,
                                           '-> ' + str(i) + '. ' + datalist[i]['albums_name'] + self.space +
                                           datalist[i][
                                               'artists_name'], curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset + 9, self.startcol,
                                           str(i) + '. ' + datalist[i]['albums_name'] + self.space + 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 + 9, self.indented_startcol,
                                           '-> ' + str(i) + '. ' + datalist[i]['title'],
                                           curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset + 9, self.startcol, str(i) + '. ' + datalist[i]['title'])


            elif datatype == 'top_playlists':
                for i in range(offset, min(len(datalist), offset + step)):
                    if i == index:
                        self.screen.addstr(i - offset + 9, self.indented_startcol,
                                           '-> ' + str(i) + '. ' + datalist[i]['playlists_name'] + self.space +
                                           datalist[i]['creator_name'], curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset + 9, self.startcol,
                                           str(i) + '. ' + datalist[i]['playlists_name'] + self.space + datalist[i][
                                               'creator_name'])


            elif datatype == 'toplists':
                for i in range(offset, min(len(datalist), offset + step)):
                    if i == index:
                        self.screen.addstr(i - offset + 9, self.indented_startcol, '-> ' + str(i) + '. ' + datalist[i],
                                           curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset + 9, self.startcol, str(i) + '. ' + datalist[i])


            elif datatype == 'playlist_classes' or datatype == 'playlist_class_detail':
                for i in range(offset, min(len(datalist), offset + step)):
                    if i == index:
                        self.screen.addstr(i - offset + 9, self.indented_startcol, '-> ' + str(i) + '. ' + datalist[i],
                                           curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset + 9, self.startcol, str(i) + '. ' + datalist[i])

            elif datatype == 'djchannels':
                for i in range(offset, min(len(datalist), offset + step)):
                    if i == index:
                        self.screen.addstr(i - offset + 8, self.indented_startcol,
                                           '-> ' + str(i) + '. ' + datalist[i]['song_name'],
                                           curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset + 8, self.startcol, str(i) + '. ' + datalist[i]['song_name'])

            elif datatype == 'search':
                self.screen.move(4, 1)
                self.screen.clrtobot()
                self.screen.timeout(-1)
                self.screen.addstr(8, self.startcol, '选择搜索类型:', curses.color_pair(1))
                for i in range(offset, min(len(datalist), offset + step)):
                    if i == index:
                        self.screen.addstr(i - offset + 10, self.indented_startcol,
                                           '-> ' + str(i) + '.' + datalist[i - 1],
                                           curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset + 10, self.startcol, str(i) + '.' + datalist[i - 1])
                self.screen.timeout(100)

            elif datatype == 'help':
                for i in range(offset, min(len(datalist), offset + step)):
                    if i == index:
                        self.screen.addstr(i - offset + 9, self.indented_startcol,
                                           '-> ' + str(i) + '. \'' + (datalist[i][0].upper() + '\'').ljust(11) +
                                           datalist[i][
                                               1] + '   ' + datalist[i][2], curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset + 9, self.startcol,
                                           str(i) + '. \'' + (datalist[i][0].upper() + '\'').ljust(11) + 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, self.startcol, 'Build with love to music by omi')

        self.screen.refresh()

    def build_search(self, stype):
        self.screen.timeout(-1)
        netease = self.netease
        if stype == 'songs':
            song_name = self.get_param('搜索歌曲:')
            if song_name == '/return':
                return []
            else:
                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('搜索艺术家:')
            if artist_name == '/return':
                return []
            else:
                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':
            albums_name = self.get_param('搜索专辑:')
            if albums_name == '/return':
                return []
            else:
                try:
                    data = netease.search(albums_name, stype=10)
                    if 'albums' in data['result']:
                        albums = data['result']['albums']
                        return netease.dig_info(albums, 'albums')
                except:
                    return []

        elif stype == 'search_playlist':
            search_playlist = self.get_param('搜索网易精选集:')
            if search_playlist == '/return':
                return []
            else:
                try:
                    data = netease.search(search_playlist, stype=1000)
                    if 'playlists' in data['result']:
                        playlists = data['result']['playlists']
                        return netease.dig_info(playlists, 'top_playlists')
                except:
                    return []

        return []

    def build_login(self):
        self.build_login_bar()
        local_account = self.get_account()
        local_password = hashlib.md5(self.get_password()).hexdigest()
        login_info = self.netease.login(local_account, local_password)
        account = [local_account, local_password]
        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_bar(self):
        curses.noecho()
        self.screen.move(4, 1)
        self.screen.clrtobot()
        self.screen.addstr(5, self.startcol, '请输入登录信息(支持手机登陆)', curses.color_pair(1))
        self.screen.addstr(8, self.startcol, "账号:", curses.color_pair(1))
        self.screen.addstr(9, self.startcol, "密码:", curses.color_pair(1))
        self.screen.move(8, 24)
        self.screen.refresh()

    def build_login_error(self):
        self.screen.move(4, 1)
        self.screen.timeout(-1)  # disable the screen timeout
        self.screen.clrtobot()
        self.screen.addstr(8, self.startcol, '艾玛,登录信息好像不对呢 (O_O)#', curses.color_pair(1))
        self.screen.addstr(10, self.startcol, '[1] 再试一次')
        self.screen.addstr(11, self.startcol, '[2] 稍后再试')
        self.screen.addstr(14, self.startcol, '请键入对应数字:', curses.color_pair(2))
        self.screen.refresh()
        x = self.screen.getch()
        self.screen.timeout(100)  # restore the screen timeout
        return x

    def get_account(self):
        self.screen.timeout(-1)  # disable the screen timeout
        curses.echo()
        account = self.screen.getstr(8, self.startcol + 6, 60)
        self.screen.timeout(100)  # restore the screen timeout
        return account

    def get_password(self):
        self.screen.timeout(-1)  # disable the screen timeout
        curses.noecho()
        password = self.screen.getstr(9, self.startcol + 6, 60)
        self.screen.timeout(100)  # restore the screen timeout
        return password

    def get_param(self, prompt_string):
        # keep playing info in line 1
        curses.echo()
        self.screen.move(4, 1)
        self.screen.clrtobot()
        self.screen.addstr(5, self.startcol, prompt_string, curses.color_pair(1))
        self.screen.refresh()
        info = self.screen.getstr(10, self.startcol, 60)
        if info == '':
            return '/return'
        elif info.strip() is '':
            return self.get_param(prompt_string)
        else:
            return info

    def update_size(self):
        # get terminal size
        size = terminalsize.get_terminal_size()
        self.x = max(size[0], 10)
        self.y = max(size[1], 25)

        # update intendations
        curses.resizeterm(self.y, self.x)
        self.startcol = int(float(self.x) / 5)
        self.indented_startcol = max(self.startcol - 3, 0)
        self.update_space()
        self.screen.clear()
        self.screen.refresh()

    def update_space(self):
        if self.x > 140:
            self.space = "   -   "
        elif self.x > 80:
            self.space = "  -  "
        else:
            self.space = " - "
        self.screen.refresh()
コード例 #17
0
class Menu:
    def __init__(self):
        reload(sys)
        sys.setdefaultencoding('UTF-8')
        self.config = Config()
        self.datatype = 'main'
        self.title = '网易云音乐'
        self.datalist = [
            '排行榜', '艺术家', '新碟上架', '精选歌单', '我的歌单', 'DJ节目', '每日推荐', '私人FM', '搜索',
            '帮助'
        ]
        self.offset = 0
        self.index = 0
        self.storage = Storage()
        self.storage.load()
        self.collection = self.storage.database['collections'][0]
        self.player = Player()
        self.cache = Cache()
        self.ui = Ui()
        self.netease = NetEase()
        self.screen = curses.initscr()
        self.screen.keypad(1)
        self.step = 10
        self.stack = []
        self.djstack = []
        self.userid = self.storage.database["user"]["user_id"]
        self.username = self.storage.database["user"]["nickname"]
        self.resume_play = True
        self.at_playing_list = False
        signal.signal(signal.SIGWINCH, self.change_term)
        signal.signal(signal.SIGINT, self.send_kill)
        self.START = time.time()

    def change_term(self, signum, frame):
        self.ui.screen.clear()
        self.ui.screen.refresh()

    def send_kill(self, signum, fram):
        self.player.stop()
        self.cache.quit()
        self.storage.save()
        curses.endwin()
        sys.exit()

    def alert(self, version):
        latest = Menu().check_version()
        if latest != version:
            if platform.system() == 'Darwin':
                os.system(
                    '/usr/bin/osascript -e \'display notification "MusicBox Update is available"sound name "/System/Library/Sounds/Ping.aiff"\''
                )
                time.sleep(0.5)
                os.system(
                    '/usr/bin/osascript -e \'display notification "NetEase-MusicBox installed version:'
                    + version + '\nNetEase-MusicBox latest version:' + latest +
                    '"\'')
            else:
                os.system(
                    '/usr/bin/notify-send "MusicBox Update is available"')

    def check_version(self):
        # 检查更新
        tree = ET.ElementTree(ET.fromstring(str(self.netease.get_version())))
        root = tree.getroot()
        return root[0][4][0][0].text

    def start_fork(self, version):
        pid = os.fork()
        if pid == 0:
            Menu().alert(version)
        else:
            Menu().start()

    def play_pause(self):
        if len(self.storage.database["player_info"]["player_list"]) == 0:
            return
        if self.player.pause_flag:
            self.player.resume()
        else:
            self.player.pause()
        time.sleep(0.1)

    def next_song(self):
        if len(self.storage.database["player_info"]["player_list"]) == 0:
            return
        self.player.next()
        time.sleep(0.1)

    def previous_song(self):
        if len(self.storage.database["player_info"]["player_list"]) == 0:
            return
        self.player.prev()
        time.sleep(0.1)

    def start(self):
        self.START = time.time() // 1
        self.ui.build_menu(self.datatype, self.title, self.datalist,
                           self.offset, self.index, self.step, self.START)
        self.ui.build_process_bar(
            self.player.process_location, self.player.process_length,
            self.player.playing_flag, self.player.pause_flag,
            self.storage.database['player_info']['playing_mode'])
        self.stack.append([
            self.datatype, self.title, self.datalist, self.offset, self.index
        ])
        if bind_global:
            keybinder.bind(self.config.get_item("global_play_pause"),
                           self.play_pause)
            keybinder.bind(self.config.get_item("global_next"), self.next_song)
            keybinder.bind(self.config.get_item("global_previous"),
                           self.previous_song)
        while True:
            datatype = self.datatype
            title = self.title
            datalist = self.datalist
            offset = self.offset
            idx = index = self.index
            step = self.step
            stack = self.stack
            djstack = self.djstack
            self.screen.timeout(500)
            key = self.screen.getch()
            if bind_global:
                keybinder.gtk.main_iteration(False)
            self.ui.screen.refresh()

            # term resize
            if key == -1:
                self.ui.update_size()
                self.player.update_size()

            # 退出
            if key == ord('q'):
                break

            # 退出并清除用户信息
            if key == ord('w'):
                self.storage.database['user'] = {
                    "username": "",
                    "password": "",
                    "user_id": "",
                    "nickname": "",
                }
                try:
                    os.remove(self.storage.cookie_path)
                except:
                    break
                break

            # 上移
            elif key == ord('k'):
                self.index = carousel(offset,
                                      min(len(datalist), offset + step) - 1,
                                      idx - 1)
                self.START = time.time()

            # 下移
            elif key == ord('j'):
                self.index = carousel(offset,
                                      min(len(datalist), offset + step) - 1,
                                      idx + 1)
                self.START = time.time()

            # 数字快捷键
            elif ord('0') <= key <= ord('9'):
                if self.datatype == 'songs' or self.datatype == 'djchannels' or self.datatype == 'help':
                    continue
                idx = key - ord('0')
                self.ui.build_menu(self.datatype, self.title, self.datalist,
                                   self.offset, idx, self.step, self.START)
                self.ui.build_loading()
                self.dispatch_enter(idx)
                self.index = 0
                self.offset = 0

            # 向上翻页
            elif key == ord('u'):
                if offset == 0:
                    continue
                self.START = time.time()
                self.offset -= step

                # e.g. 23 - 10 = 13 --> 10
                self.index = (index - step) // step * step

            # 向下翻页
            elif key == ord('d'):
                if offset + step >= len(datalist):
                    continue
                self.START = time.time()
                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.START = time.time()
                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
                self.START = time.time()
                up = stack.pop()
                self.datatype = up[0]
                self.title = up[1]
                self.datalist = up[2]
                self.offset = up[3]
                self.index = up[4]
                self.at_playing_list = False

            # 搜索
            elif key == ord('f'):
                # 8 is the 'search' menu
                self.dispatch_enter(8)

            # 播放下一曲
            elif key == ord(']'):
                self.next_song()

            # 播放上一曲
            elif key == ord('['):
                self.previous_song()

            # 增加音量
            elif key == ord('='):
                self.player.volume_up()

            # 减少音量
            elif key == ord('-'):
                self.player.volume_down()

            # 随机播放
            elif key == ord('?'):
                if len(self.storage.database["player_info"]
                       ["player_list"]) == 0:
                    continue
                self.player.shuffle()
                time.sleep(0.1)

            # 喜爱
            elif key == ord(','):
                self.request_api(self.netease.fm_like,
                                 self.player.get_playing_id())

            # 删除FM
            elif key == ord('.'):
                if self.datatype == 'fmsongs':
                    if len(self.storage.database["player_info"]
                           ["player_list"]) == 0:
                        continue
                    self.player.next()
                    self.request_api(self.netease.fm_trash,
                                     self.player.get_playing_id())
                    time.sleep(0.1)

            # 下一FM
            elif key == ord('/'):
                if self.datatype == 'fmsongs':
                    if len(self.storage.database["player_info"]
                           ["player_list"]) == 0:
                        continue
                    self.player.next()
                    time.sleep(0.1)

            # 播放、暂停
            elif key == ord(' '):
                # If not open a new playing list, just play and pause.
                try:
                    if self.datalist[idx]['song_id'] == self.player.playing_id:
                        self.player.play_and_pause(
                            self.storage.database['player_info']['idx'])
                        time.sleep(0.1)
                        continue
                except:
                    pass
                # If change to a new playing list. Add playing list and play.
                if datatype == 'songs':
                    self.resume_play = False
                    self.player.new_player_list('songs', self.title,
                                                self.datalist, -1)
                    self.player.end_callback = None
                    self.player.play_and_pause(idx)
                    self.at_playing_list = True
                elif datatype == 'djchannels':
                    self.resume_play = False
                    self.player.new_player_list('djchannels', self.title,
                                                self.datalist, -1)
                    self.player.end_callback = None
                    self.player.play_and_pause(idx)
                    self.at_playing_list = True
                elif datatype == 'fmsongs':
                    self.resume_play = False
                    self.storage.database['player_info']['playing_mode'] = 0
                    self.player.new_player_list('fmsongs', self.title,
                                                self.datalist, -1)
                    self.player.end_callback = self.fm_callback
                    self.player.play_and_pause(idx)
                    self.at_playing_list = True
                else:
                    self.player.play_and_pause(
                        self.storage.database['player_info']['idx'])
                time.sleep(0.1)

            # 加载当前播放列表
            elif key == ord('p'):
                if len(self.storage.database['player_info']
                       ['player_list']) == 0:
                    continue
                if not self.at_playing_list:
                    self.stack.append([
                        self.datatype, self.title, self.datalist, self.offset,
                        self.index
                    ])
                    self.at_playing_list = True
                self.datatype = self.storage.database['player_info'][
                    'player_list_type']
                self.title = self.storage.database['player_info'][
                    'player_list_title']
                self.datalist = []
                for i in self.storage.database['player_info']['player_list']:
                    self.datalist.append(self.storage.database['songs'][i])
                self.index = self.storage.database['player_info']['idx']
                self.offset = self.storage.database['player_info'][
                    'idx'] / self.step * self.step
                if self.resume_play:
                    if self.datatype == "fmsongs":
                        self.player.end_callback = self.fm_callback
                    else:
                        self.player.end_callback = None
                    self.storage.database['player_info']['idx'] = -1
                    self.player.play_and_pause(self.index)
                    self.resume_play = False

            # 播放模式切换
            elif key == ord('P'):
                self.storage.database['player_info']['playing_mode'] = \
                    (self.storage.database['player_info']['playing_mode'] + 1) % 5

            # 添加到打碟歌单
            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 == 'songs'
                        or datatype == 'djchannels') and len(datalist) != 0:
                    self.datalist.pop(idx)
                    self.index = carousel(
                        offset,
                        min(len(datalist), offset + step) - 1, idx)

            # 当前项目下移
            elif key == ord("J"):
                if datatype != 'main' and len(
                        datalist) != 0 and idx + 1 != len(self.datalist):
                    self.START = time.time()
                    song = self.datalist.pop(idx)
                    self.datalist.insert(idx + 1, song)
                    self.index = idx + 1
                    # 翻页
                    if self.index >= offset + step:
                        self.offset = offset + step

            # 当前项目上移
            elif key == ord("K"):
                if datatype != 'main' and len(datalist) != 0 and idx != 0:
                    self.START = time.time()
                    song = self.datalist.pop(idx)
                    self.datalist.insert(idx - 1, song)
                    self.index = idx - 1
                    # 翻页
                    if self.index < offset:
                        self.offset = offset - step

            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/darknessomi/musicbox')

            self.ui.build_process_bar(
                self.player.process_location, self.player.process_length,
                self.player.playing_flag, self.player.pause_flag,
                self.storage.database['player_info']['playing_mode'])
            self.ui.build_menu(self.datatype, self.title, self.datalist,
                               self.offset, self.index, self.step, self.START)

        self.player.stop()
        self.cache.quit()
        self.storage.save()
        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':
            data = self.datalist[idx]
            self.datatype = data['datatype']
            self.datalist = netease.dig_info(data['callback'](), self.datatype)
            self.title += ' > ' + data['title']

        # 全站置顶歌单包含的歌曲
        elif datatype == 'top_playlists':
            log.debug(datalist)
            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']

        # 分类精选
        elif datatype == 'playlist_classes':
            # 分类名称
            data = self.datalist[idx]
            self.datatype = 'playlist_class_detail'
            self.datalist = netease.dig_info(data, self.datatype)
            self.title += ' > ' + data
            log.debug(self.datalist)

        # 某一分类的详情
        elif datatype == 'playlist_class_detail':
            # 子类别
            data = self.datalist[idx]
            self.datatype = 'top_playlists'
            self.datalist = netease.dig_info(netease.top_playlists(data),
                                             self.datatype)
            log.debug(self.datalist)
            self.title += ' > ' + data

        # 歌曲榜单
        elif datatype == 'toplists':
            songs = netease.top_songlist(idx)
            self.title += ' > ' + self.datalist[idx]
            self.datalist = netease.dig_info(songs, 'songs')
            self.datatype = 'songs'

        # 搜索菜单
        elif datatype == 'search':
            ui = self.ui
            # no need to do stack.append, Otherwise there will be a bug when you input key 'h' to return
            # if idx in range(1, 5):
            # self.stack.append([self.datatype, self.title, self.datalist, self.offset, self.index])
            self.index = 0
            self.offset = 0
            if idx == 0:
                # 搜索结果可以用top_playlists处理
                self.datatype = 'top_playlists'
                self.datalist = ui.build_search('search_playlist')
                self.title = '精选歌单搜索列表'

            elif idx == 1:
                self.datatype = 'songs'
                self.datalist = ui.build_search('songs')
                self.title = '歌曲搜索列表'

            elif idx == 2:
                self.datatype = 'artists'
                self.datalist = ui.build_search('artists')
                self.title = '艺术家搜索列表'

            elif idx == 3:
                self.datatype = 'albums'
                self.datalist = ui.build_search('albums')
                self.title = '专辑搜索列表'

    def fm_callback(self):
        log.debug("FM CallBack.")
        data = self.get_new_fm()
        self.player.append_songs(data)
        if self.datatype == 'fmsongs':
            if len(self.storage.database['player_info']['player_list']) == 0:
                return
            self.datatype = self.storage.database['player_info'][
                'player_list_type']
            self.title = self.storage.database['player_info'][
                'player_list_title']
            self.datalist = []
            for i in self.storage.database['player_info']['player_list']:
                self.datalist.append(self.storage.database['songs'][i])
            self.index = self.storage.database['player_info']['idx']
            self.offset = self.storage.database['player_info'][
                'idx'] / self.step * self.step

    def request_api(self, func, *args):
        if self.storage.database['user']['user_id'] != "":
            result = func(*args)
            if result != -1:
                return result
        log.debug("Re Login.")
        user_info = {}
        if self.storage.database['user']['username'] != "":
            user_info = self.netease.login(
                self.storage.database['user']['username'],
                self.storage.database['user']['password'])
        if self.storage.database['user'][
                'username'] == "" or user_info['code'] != 200:
            data = self.ui.build_login()
            # 取消登录
            if data == -1:
                return -1
            user_info = data[0]
            self.storage.database['user']['username'] = data[1][0]
            self.storage.database['user']['password'] = data[1][1]
            self.storage.database['user']['user_id'] = user_info['account'][
                'id']
            self.storage.database['user']['nickname'] = user_info['profile'][
                'nickname']
        self.userid = self.storage.database["user"]["user_id"]
        self.username = self.storage.database["user"]["nickname"]
        return func(*args)

    def get_new_fm(self):
        myplaylist = []
        for count in range(0, 1):
            data = self.request_api(self.netease.personal_fm)
            if data == -1:
                break
            myplaylist += data
            time.sleep(0.2)
        return self.netease.dig_info(myplaylist, "fmsongs")

    def choice_channel(self, idx):
        # 排行榜
        netease = self.netease
        if idx == 0:
            self.datalist = netease.return_toplists()
            self.title += ' > 排行榜'
            self.datatype = 'toplists'

        # 艺术家
        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:
            self.datalist = [{
                'title': '全站置顶',
                'datatype': 'top_playlists',
                'callback': netease.top_playlists
            }, {
                'title': '分类精选',
                'datatype': 'playlist_classes',
                'callback': netease.playlist_classes
            }]
            self.title += ' > 精选歌单'
            self.datatype = 'playlists'

        # 我的歌单
        elif idx == 4:
            myplaylist = self.request_api(self.netease.user_playlist,
                                          self.userid)
            if myplaylist == -1:
                return
            self.datatype = 'top_playlists'
            self.datalist = netease.dig_info(myplaylist, self.datatype)
            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 += ' > 每日推荐'
            myplaylist = self.request_api(self.netease.recommend_playlist)
            if myplaylist == -1:
                return
            self.datalist = self.netease.dig_info(myplaylist, self.datatype)

        # 私人FM
        elif idx == 7:
            self.datatype = 'fmsongs'
            self.title += ' > 私人FM'
            self.datalist = self.get_new_fm()

        # 搜索
        elif idx == 8:
            self.datatype = 'search'
            self.title += ' > 搜索'
            self.datalist = ['歌曲', '艺术家', '专辑', '网易精选集']

        # 帮助
        elif idx == 9:
            self.datatype = 'help'
            self.title += ' > 帮助'
            self.datalist = shortcut

        self.offset = 0
        self.index = 0
コード例 #18
0
ファイル: ui.py プロジェクト: manfred-exz/musicbox
class Ui:
    def __init__(self):
        # Initializing curses
        # initialize window object to curses.initscr()
        self.screen = curses.initscr()
        # character break buffer, to read in any key without the need to press 'Enter'.
        curses.cbreak()
        # make those navigation keys to normal key that can be processed in program.
        self.screen.keypad(1)
        #   initialize the some color pair
        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)


        # Initializing NetEase object to communicate with NetEase server.
        self.netease = NetEase()


    def build_playinfo(self, song_name, artist, album_name, pause=False, play_mode='normal'):
        curses.noecho()
        # 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, 0, play_mode + '  ' + '_ _ z Z Z', curses.color_pair(3))
        else:
            self.screen.addstr(1, 0, play_mode + '  ' + '♫  ♪ ♫  ♪', 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()

    # draw the all types of menu according to data_type
    def build_menu(self, data_type, title, data_list, offset, index, step):
        # keep playing info in line 1

        # do not echo the input key-code
        curses.noecho()
        # clear the content after (4,1)
        # move cursor to (4,1)
        self.screen.move(4, 1)
        # clear the content under line-4, erase from cursor to the end of the window: all lines below the cursor are deleted,
        #  and then the equivalent of clrtoeol() is performed.
        self.screen.clrtobot()
        # draw the title with color pair 1 (GREEN, BLACK)
        self.screen.addstr(4, 19, title, curses.color_pair(1))

        # If there's nothing in the data_list
        if len(data_list) == 0:
            self.screen.addstr(8, 19, '这里什么都没有 -,-')

        else:
            if data_type == 'main':

                for i in range(offset, min(len(data_list), offset + step)):
                    content = str(i) + '. ' + data_list[i]
                    self.print_menu_line(i, offset, content, i == index)

            elif data_type == 'songs':
                for i in range(offset, min(len(data_list), offset + step)):
                    content = str(i) + '. ' + data_list[i]['song_name'] \
                              + '   -   ' + data_list[i]['artist'] + '  < ' + data_list[i]['album_name'] + ' >'
                    self.print_menu_line(i, offset, content, i == index)

            elif data_type == 'artists':
                for i in range(offset, min(len(data_list), offset + step)):
                    content = str(i) + '. ' + data_list[i]['artists_name'] + '   -   ' + str(data_list[i]['alias'])
                    self.print_menu_line(i, offset, content, i == index)


            elif data_type == 'albums':
                for i in range(offset, min(len(data_list), offset + step)):
                    content = str(i) + '. ' + data_list[i]['albums_name'] + '   -   ' + data_list[i]['artists_name']
                    self.print_menu_line(i, offset, content, i == index)

            elif data_type == 'playlists':
                for i in range(offset, min(len(data_list), offset + step)):
                    content = str(i) + '. ' + data_list[i]['title']
                    self.print_menu_line(i, offset, content, i == index)

            elif data_type == 'top_playlists':
                for i in range(offset, min(len(data_list), offset + step)):
                    content = str(i) + '. ' + data_list[i]['playlists_name'] + '   -   ' + data_list[i]['creator_name']
                    self.print_menu_line(i, offset, content, i == index)

            elif data_type == 'playlist_classes' or data_type == 'playlist_class_detail':
                for i in range(offset, min(len(data_list), offset + step)):
                    content = str(i) + '. ' + data_list[i]
                    self.print_menu_line(i, offset, content, i == index)

            elif data_type == 'djchannels':
                for i in range(offset, min(len(data_list), offset + step)):
                    content = str(i) + '. ' + data_list[i]['song_name']
                    self.print_menu_line(i, offset, content, i == index)

            elif data_type == 'help':
                for i in range(offset, min(len(data_list), offset + step)):
                    content = str(i) + '. \'' + data_list[i][0].upper() + '\'   ' + data_list[i][1] + '   ' + \
                              data_list[i][2]
                    self.print_menu_line(i, offset, content, i == index)
                self.screen.addstr(20, 6, 'NetEase-MusicBox 基于Python,所有版权音乐来源于网易,本地不做任何保存')
                self.screen.addstr(21, 10, '按 [G] 到 Git-hub 了解更多信息,帮助改进,或者Star表示支持~~')
                self.screen.addstr(22, 19, 'Build with love to music by omi')

        self.screen.refresh()

    # print the specified line at certain place
    def print_menu_line(self, i, offset, content, chosen=False):
        y = i - offset + 8

        if chosen == True:
            x = 16
            color = curses.color_pair(2)
            self.screen.addstr(y, x, '-> ' + content, color)
        else:
            x = 19
            self.screen.addstr(y, x, content)

    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 == 'search_playlist':
            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, 'top_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

    # build login interface and login
    def build_login(self):
        curses.noecho()
        info = self.get_param('请输入登录信息, e.g: [email protected] 123456')
        account = info.split(' ')
        # if both user-name and password is got.
        if len(account) != 2:
            return self.build_login()
        # login
        login_info = self.netease.login(account[0], account[1])
        self.screen.refresh()

        # if login successfully
        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):
        # When getting the user-name and password, we need to echo the letter user typed in.
        curses.echo()
        # clear the content after the 4th line
        self.screen.move(4, 1)
        self.screen.clrtobot()
        # print and display the prompt message to input user-name
        self.screen.addstr(5, 19, prompt_string, curses.color_pair(1))
        self.screen.addstr(9, 19, "Please input the user-name: ")
        self.screen.refresh()
        info = self.screen.getstr(10, 19, 60)

        # print the prompt to enter password
        self.screen.move(11, 19)
        # close curses mode to get password without display it
        self.end_curses()
        info = info + " " + getpass.getpass('                   Password:'******'':
            return self.get_param(prompt_string)
        else:
            return info

    def start_curses(self):
        curses.noecho()
        curses.cbreak()
        self.screen.keypad(1)

    def end_curses(self):
        curses.nocbreak()
        self.screen.keypad(0)
        curses.echo()

    def redraw(self):
        self.screen.clear()
        self.screen.addstr(4, 19, '网易云音乐', curses.color_pair(1))
        self.screen.refresh()
コード例 #19
0
ファイル: ui.py プロジェクト: Alexis374/NetEase-MusicBox
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: [email protected] 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
コード例 #20
0
class Menu:
    def __init__(self):
        reload(sys)
        sys.setdefaultencoding("UTF-8")
        self.config = Config()
        self.datatype = "main"
        self.title = "网易云音乐"
        self.datalist = ["排行榜", "艺术家", "新碟上架", "精选歌单", "我的歌单", "DJ节目", "每日推荐", "私人FM", "搜索", "帮助"]
        self.offset = 0
        self.index = 0
        self.storage = Storage()
        self.storage.load()
        self.collection = self.storage.database["collections"][0]
        self.player = Player()
        self.player.playing_song_changed_callback = self.song_changed_callback
        self.cache = Cache()
        self.ui = Ui()
        self.netease = NetEase()
        self.screen = curses.initscr()
        self.screen.keypad(1)
        self.step = 10
        self.stack = []
        self.djstack = []
        self.userid = self.storage.database["user"]["user_id"]
        self.username = self.storage.database["user"]["nickname"]
        self.resume_play = True
        self.at_playing_list = False
        signal.signal(signal.SIGWINCH, self.change_term)
        signal.signal(signal.SIGINT, self.send_kill)
        self.START = time.time()

    def change_term(self, signum, frame):
        self.ui.screen.clear()
        self.ui.screen.refresh()

    def send_kill(self, signum, fram):
        self.player.stop()
        self.cache.quit()
        self.storage.save()
        curses.endwin()
        sys.exit()

    def alert(self, version):
        latest = Menu().check_version()
        if latest != version:
            if platform.system() == "Darwin":
                os.system(
                    '/usr/bin/osascript -e \'display notification "MusicBox Update is available"sound name "/System/Library/Sounds/Ping.aiff"\''
                )
                time.sleep(0.5)
                os.system(
                    "/usr/bin/osascript -e 'display notification \"NetEase-MusicBox installed version:"
                    + version
                    + "\nNetEase-MusicBox latest version:"
                    + latest
                    + "\"'"
                )
            else:
                os.system('/usr/bin/notify-send "MusicBox Update is available"')

    def check_version(self):
        # 检查更新
        tree = ET.ElementTree(ET.fromstring(str(self.netease.get_version())))
        root = tree.getroot()
        return root[0][4][0][0].text

    def start_fork(self, version):
        # Hong, Fork a child process.
        # Return 0 in the child and the child’s process id in the parent.
        pid = os.fork()
        if pid == 0:
            Menu().alert(version)
        else:
            Menu().start()

    def play_pause(self):
        if len(self.storage.database["player_info"]["player_list"]) == 0:
            return
        if self.player.pause_flag:
            self.player.resume()
        else:
            self.player.pause()
        time.sleep(0.1)

    def next_song(self):
        if len(self.storage.database["player_info"]["player_list"]) == 0:
            return
        self.player.next()
        time.sleep(0.1)

    def previous_song(self):
        if len(self.storage.database["player_info"]["player_list"]) == 0:
            return
        self.player.prev()
        time.sleep(0.1)

    def start(self):
        # Hong, Return the time in seconds since the epoch as a floating point number.
        self.START = time.time() // 1
        self.ui.build_menu(self.datatype, self.title, self.datalist, self.offset, self.index, self.step, self.START)
        self.ui.build_process_bar(
            self.player.process_location,
            self.player.process_length,
            self.player.playing_flag,
            self.player.pause_flag,
            self.storage.database["player_info"]["playing_mode"],
        )
        self.stack.append([self.datatype, self.title, self.datalist, self.offset, self.index])
        if bind_global:
            keybinder.bind(self.config.get_item("global_play_pause"), self.play_pause)
            keybinder.bind(self.config.get_item("global_next"), self.next_song)
            keybinder.bind(self.config.get_item("global_previous"), self.previous_song)
        while True:
            datatype = self.datatype
            title = self.title
            datalist = self.datalist
            offset = self.offset
            idx = index = self.index
            step = self.step
            stack = self.stack
            djstack = self.djstack
            self.screen.timeout(500)
            key = self.screen.getch()
            if bind_global:
                keybinder.gtk.main_iteration(False)
            self.ui.screen.refresh()

            # term resize
            if key == -1:
                self.ui.update_size()
                self.player.update_size()

            # 退出
            # Hong, ord(), Given a string of length one, return an integer representing the Unicode code point of the character when the argument is a unicode object,
            # or the value of the byte when the argument is an 8-bit string.
            if key == ord("q"):
                break

            # 退出并清除用户信息
            if key == ord("w"):
                self.storage.database["user"] = {"username": "", "password": "", "user_id": "", "nickname": ""}
                try:
                    os.remove(self.storage.cookie_path)
                except:
                    break
                break

            # 上移
            elif key == ord("k"):
                # turn page if at beginning
                if idx == offset:
                    if offset == 0:
                        continue
                    self.offset -= step
                    # 移动光标到最后一列
                    self.index = offset - 1
                else:
                    self.index = carousel(offset, min(len(datalist), offset + step) - 1, idx - 1)
                self.START = time.time()

            # 下移
            elif key == ord("j"):
                # turn page if at end
                if idx == min(len(datalist), offset + step) - 1:
                    if offset + step >= len(datalist):
                        continue
                    self.offset += step
                    # 移动光标到第一列
                    self.index = offset + step
                else:
                    self.index = carousel(offset, min(len(datalist), offset + step) - 1, idx + 1)
                self.START = time.time()

            # 数字快捷键
            elif ord("0") <= key <= ord("9"):
                if self.datatype == "songs" or self.datatype == "djchannels" or self.datatype == "help":
                    continue
                idx = key - ord("0")
                self.ui.build_menu(self.datatype, self.title, self.datalist, self.offset, idx, self.step, self.START)
                self.ui.build_loading()
                self.dispatch_enter(idx)
                self.index = 0
                self.offset = 0

            # 向上翻页
            elif key == ord("u"):
                if offset == 0:
                    continue
                self.START = time.time()
                self.offset -= step

                # e.g. 23 - 10 = 13 --> 10
                self.index = (index - step) // step * step

            # 向下翻页
            elif key == ord("d"):
                if offset + step >= len(datalist):
                    continue
                self.START = time.time()
                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"
                    or len(self.datalist) <= 0
                ):
                    continue
                self.START = time.time()
                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
                self.START = time.time()
                up = stack.pop()
                self.datatype = up[0]
                self.title = up[1]
                self.datalist = up[2]
                self.offset = up[3]
                self.index = up[4]
                self.at_playing_list = False

            # 搜索
            elif key == ord("f"):
                # 8 is the 'search' menu
                self.dispatch_enter(8)

            # 播放下一曲
            elif key == ord("]"):
                self.next_song()

            # 播放上一曲
            elif key == ord("["):
                self.previous_song()

            # 增加音量
            elif key == ord("="):
                self.player.volume_up()

            # 减少音量
            elif key == ord("-"):
                self.player.volume_down()

            # 随机播放
            elif key == ord("?"):
                if len(self.storage.database["player_info"]["player_list"]) == 0:
                    continue
                self.player.shuffle()
                time.sleep(0.1)

            # 喜爱
            elif key == ord(","):
                return_data = self.request_api(self.netease.fm_like, self.player.get_playing_id())
                if return_data != -1:
                    if platform.system() == "Darwin":
                        os.system("/usr/bin/osascript -e 'display notification \"Added successfully\"'")
                    else:
                        os.system('/usr/bin/notify-send "Added successfully"')

            # 删除FM
            elif key == ord("."):
                if self.datatype == "fmsongs":
                    if len(self.storage.database["player_info"]["player_list"]) == 0:
                        continue
                    self.player.next()
                    return_data = self.request_api(self.netease.fm_trash, self.player.get_playing_id())
                    if return_data != -1:
                        if platform.system() == "Darwin":
                            os.system("/usr/bin/osascript -e 'display notification \"Deleted successfully\"'")
                        else:
                            os.system('/usr/bin/notify-send "Deleted successfully"')
                    time.sleep(0.1)

            # 下一FM
            elif key == ord("/"):
                if self.datatype == "fmsongs":
                    if len(self.storage.database["player_info"]["player_list"]) == 0:
                        continue
                    self.player.next()
                    time.sleep(0.1)

            # 播放、暂停
            elif key == ord(" "):
                # If not open a new playing list, just play and pause.
                try:
                    if self.datalist[idx]["song_id"] == self.player.playing_id:
                        self.player.play_and_pause(self.storage.database["player_info"]["idx"])
                        time.sleep(0.1)
                        continue
                except:
                    pass
                # If change to a new playing list. Add playing list and play.
                if datatype == "songs":
                    self.resume_play = False
                    self.player.new_player_list("songs", self.title, self.datalist, -1)
                    self.player.end_callback = None
                    self.player.play_and_pause(idx)
                    self.at_playing_list = True
                elif datatype == "djchannels":
                    self.resume_play = False
                    self.player.new_player_list("djchannels", self.title, self.datalist, -1)
                    self.player.end_callback = None
                    self.player.play_and_pause(idx)
                    self.at_playing_list = True
                elif datatype == "fmsongs":
                    self.resume_play = False
                    self.storage.database["player_info"]["playing_mode"] = 0
                    self.player.new_player_list("fmsongs", self.title, self.datalist, -1)
                    self.player.end_callback = self.fm_callback
                    self.player.play_and_pause(idx)
                    self.at_playing_list = True
                else:
                    self.player.play_and_pause(self.storage.database["player_info"]["idx"])
                time.sleep(0.1)

            # 加载当前播放列表
            elif key == ord("p"):
                self.show_playing_song()

            # 播放模式切换
            elif key == ord("P"):
                self.storage.database["player_info"]["playing_mode"] = (
                    self.storage.database["player_info"]["playing_mode"] + 1
                ) % 5

            # 添加到打碟歌单
            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])
                    if platform.system() == "Darwin":
                        os.system("/usr/bin/osascript -e 'display notification \"Added successfully\"'")
                    else:
                        os.system('/usr/bin/notify-send "Added successfully"')

            # 加载收藏歌曲
            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 == "songs" or datatype == "djchannels") and len(datalist) != 0:
                    self.datalist.pop(idx)
                    self.index = carousel(offset, min(len(datalist), offset + step) - 1, idx)

            # 当前项目下移
            elif key == ord("J"):
                if datatype != "main" and len(datalist) != 0 and idx + 1 != len(self.datalist):
                    self.START = time.time()
                    song = self.datalist.pop(idx)
                    self.datalist.insert(idx + 1, song)
                    self.index = idx + 1
                    # 翻页
                    if self.index >= offset + step:
                        self.offset = offset + step

            # 当前项目上移
            elif key == ord("K"):
                if datatype != "main" and len(datalist) != 0 and idx != 0:
                    self.START = time.time()
                    song = self.datalist.pop(idx)
                    self.datalist.insert(idx - 1, song)
                    self.index = idx - 1
                    # 翻页
                    if self.index < offset:
                        self.offset = offset - step

            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/darknessomi/musicbox")

            # 开始下载
            elif key == ord("C"):
                s = self.datalist[idx]
                cache_thread = threading.Thread(
                    target=self.player.cacheSong1time, args=(s["song_id"], s["song_name"], s["artist"], s["mp3_url"])
                )
                cache_thread.start()

            elif key == ord("i"):
                if self.player.playing_id != -1:
                    webbrowser.open_new_tab("http://music.163.com/#/song?id=" + str(self.player.playing_id))

            self.ui.build_process_bar(
                self.player.process_location,
                self.player.process_length,
                self.player.playing_flag,
                self.player.pause_flag,
                self.storage.database["player_info"]["playing_mode"],
            )
            self.ui.build_menu(self.datatype, self.title, self.datalist, self.offset, self.index, self.step, self.START)

        self.player.stop()
        self.cache.quit()
        self.storage.save()
        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":
            data = self.datalist[idx]
            self.datatype = data["datatype"]
            self.datalist = netease.dig_info(data["callback"](), self.datatype)
            self.title += " > " + data["title"]

        # 全站置顶歌单包含的歌曲
        elif datatype == "top_playlists":
            log.debug(datalist)
            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"]

        # 分类精选
        elif datatype == "playlist_classes":
            # 分类名称
            data = self.datalist[idx]
            self.datatype = "playlist_class_detail"
            self.datalist = netease.dig_info(data, self.datatype)
            self.title += " > " + data
            log.debug(self.datalist)

        # 某一分类的详情
        elif datatype == "playlist_class_detail":
            # 子类别
            data = self.datalist[idx]
            self.datatype = "top_playlists"
            self.datalist = netease.dig_info(netease.top_playlists(data), self.datatype)
            log.debug(self.datalist)
            self.title += " > " + data

        # 歌曲榜单
        elif datatype == "toplists":
            songs = netease.top_songlist(idx)
            self.title += " > " + self.datalist[idx]
            self.datalist = netease.dig_info(songs, "songs")
            self.datatype = "songs"

        # 搜索菜单
        elif datatype == "search":
            ui = self.ui
            # no need to do stack.append, Otherwise there will be a bug when you input key 'h' to return
            # if idx in range(1, 5):
            # self.stack.append([self.datatype, self.title, self.datalist, self.offset, self.index])
            self.index = 0
            self.offset = 0
            if idx == 0:
                # 搜索结果可以用top_playlists处理
                self.datatype = "top_playlists"
                self.datalist = ui.build_search("search_playlist")
                self.title = "精选歌单搜索列表"

            elif idx == 1:
                self.datatype = "songs"
                self.datalist = ui.build_search("songs")
                self.title = "歌曲搜索列表"

            elif idx == 2:
                self.datatype = "artists"
                self.datalist = ui.build_search("artists")
                self.title = "艺术家搜索列表"

            elif idx == 3:
                self.datatype = "albums"
                self.datalist = ui.build_search("albums")
                self.title = "专辑搜索列表"

    def show_playing_song(self):
        if len(self.storage.database["player_info"]["player_list"]) == 0:
            return
        if not self.at_playing_list:
            self.stack.append([self.datatype, self.title, self.datalist, self.offset, self.index])
            self.at_playing_list = True
        self.datatype = self.storage.database["player_info"]["player_list_type"]
        self.title = self.storage.database["player_info"]["player_list_title"]
        self.datalist = []
        for i in self.storage.database["player_info"]["player_list"]:
            self.datalist.append(self.storage.database["songs"][i])
        self.index = self.storage.database["player_info"]["idx"]
        self.offset = self.storage.database["player_info"]["idx"] / self.step * self.step
        if self.resume_play:
            if self.datatype == "fmsongs":
                self.player.end_callback = self.fm_callback
            else:
                self.player.end_callback = None
            self.storage.database["player_info"]["idx"] = -1
            self.player.play_and_pause(self.index)
            self.resume_play = False

    def song_changed_callback(self):
        if self.at_playing_list:
            self.show_playing_song()

    def fm_callback(self):
        log.debug("FM CallBack.")
        data = self.get_new_fm()
        self.player.append_songs(data)
        if self.datatype == "fmsongs":
            if len(self.storage.database["player_info"]["player_list"]) == 0:
                return
            self.datatype = self.storage.database["player_info"]["player_list_type"]
            self.title = self.storage.database["player_info"]["player_list_title"]
            self.datalist = []
            for i in self.storage.database["player_info"]["player_list"]:
                self.datalist.append(self.storage.database["songs"][i])
            self.index = self.storage.database["player_info"]["idx"]
            self.offset = self.storage.database["player_info"]["idx"] / self.step * self.step

    def request_api(self, func, *args):
        if self.storage.database["user"]["user_id"] != "":
            result = func(*args)
            if result != -1:
                return result
        log.debug("Re Login.")
        user_info = {}
        if self.storage.database["user"]["username"] != "":
            user_info = self.netease.login(
                self.storage.database["user"]["username"], self.storage.database["user"]["password"]
            )
        if self.storage.database["user"]["username"] == "" or user_info["code"] != 200:
            data = self.ui.build_login()
            # 取消登录
            if data == -1:
                return -1
            user_info = data[0]
            self.storage.database["user"]["username"] = data[1][0]
            self.storage.database["user"]["password"] = data[1][1]
            self.storage.database["user"]["user_id"] = user_info["account"]["id"]
            self.storage.database["user"]["nickname"] = user_info["profile"]["nickname"]
        self.userid = self.storage.database["user"]["user_id"]
        self.username = self.storage.database["user"]["nickname"]
        return func(*args)

    def get_new_fm(self):
        myplaylist = []
        for count in range(0, 1):
            data = self.request_api(self.netease.personal_fm)
            if data == -1:
                break
            myplaylist += data
            time.sleep(0.2)
        return self.netease.dig_info(myplaylist, "fmsongs")

    def choice_channel(self, idx):
        # 排行榜
        netease = self.netease
        if idx == 0:
            self.datalist = netease.return_toplists()
            self.title += " > 排行榜"
            self.datatype = "toplists"

        # 艺术家
        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:
            self.datalist = [
                {"title": "全站置顶", "datatype": "top_playlists", "callback": netease.top_playlists},
                {"title": "分类精选", "datatype": "playlist_classes", "callback": netease.playlist_classes},
            ]
            self.title += " > 精选歌单"
            self.datatype = "playlists"

        # 我的歌单
        elif idx == 4:
            myplaylist = self.request_api(self.netease.user_playlist, self.userid)
            if myplaylist == -1:
                return
            self.datatype = "top_playlists"
            self.datalist = netease.dig_info(myplaylist, self.datatype)
            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 += " > 每日推荐"
            myplaylist = self.request_api(self.netease.recommend_playlist)
            if myplaylist == -1:
                return
            self.datalist = self.netease.dig_info(myplaylist, self.datatype)

        # 私人FM
        elif idx == 7:
            self.datatype = "fmsongs"
            self.title += " > 私人FM"
            self.datalist = self.get_new_fm()

        # 搜索
        elif idx == 8:
            self.datatype = "search"
            self.title += " > 搜索"
            self.datalist = ["歌曲", "艺术家", "专辑", "网易精选集"]

        # 帮助
        elif idx == 9:
            self.datatype = "help"
            self.title += " > 帮助"
            self.datalist = shortcut

        self.offset = 0
        self.index = 0
コード例 #21
0
class Ui:
    def __init__(self):
        self.screen = curses.initscr()
        self.screen.timeout(100)  # the screen refresh every 100ms
        # 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)
        # term resize handling
        size = terminalsize.get_terminal_size()
        self.x = max(size[0], 10)
        self.y = max(size[1], 25)
        self.startcol = int(float(self.x) / 5)
        self.indented_startcol = max(self.startcol - 3, 0)
        self.update_space()
        self.lyric = ''
        self.now_lyric = ''
        self.tlyric = ''
        self.storage = Storage()
        self.config = Config()
        self.newversion = False

    def notify(self, summary, song, album, artist):
        if summary != 'disable':
            body = '%s\nin %s by %s' % (song, album, artist)
            content = escape_quote(summary + ': ' + body)
            notify(content)

    def build_playinfo(self,
                       song_name,
                       artist,
                       album_name,
                       quality,
                       start,
                       pause=False):
        curses.noecho()
        # 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, self.indented_startcol,
                               '_ _ z Z Z ' + quality, curses.color_pair(3))
        else:
            self.screen.addstr(1, self.indented_startcol,
                               '♫  ♪ ♫  ♪ ' + quality, curses.color_pair(3))

        self.screen.addstr(
            1, min(self.indented_startcol + 18, self.x - 1),
            song_name + self.space + artist + '  < ' + album_name + ' >',
            curses.color_pair(4))

        self.screen.refresh()

    def build_process_bar(self, now_playing, total_length, playing_flag,
                          pause_flag, playing_mode):
        if (self.storage.database['player_info']['idx'] >= len(
                self.storage.database['player_info']['player_list'])):
            return
        curses.noecho()
        self.screen.move(3, 1)
        self.screen.clrtoeol()
        self.screen.move(4, 1)
        self.screen.clrtoeol()
        if not playing_flag:
            return
        if total_length <= 0:
            total_length = 1
        if now_playing > total_length or now_playing <= 0:
            now_playing = 0
        process = '['
        for i in range(0, 33):
            if i < now_playing / total_length * 33:
                if (i + 1) > now_playing / total_length * 33:
                    if not pause_flag:
                        process += '>'
                        continue
                process += '='
            else:
                process += ' '
        process += '] '
        now_minute = int(now_playing / 60)
        if now_minute > 9:
            now_minute = str(now_minute)
        else:
            now_minute = '0' + str(now_minute)
        now_second = int(now_playing - int(now_playing / 60) * 60)
        if now_second > 9:
            now_second = str(now_second)
        else:
            now_second = '0' + str(now_second)
        total_minute = int(total_length / 60)
        if total_minute > 9:
            total_minute = str(total_minute)
        else:
            total_minute = '0' + str(total_minute)
        total_second = int(total_length - int(total_length / 60) * 60)
        if total_second > 9:
            total_second = str(total_second)
        else:
            total_second = '0' + str(total_second)
        process += '(' + now_minute + ':' + now_second + '/' + total_minute + ':' + total_second + ')'  # NOQA
        if playing_mode == 0:
            process = '顺序播放 ' + process
        elif playing_mode == 1:
            process = '顺序循环 ' + process
        elif playing_mode == 2:
            process = '单曲循环 ' + process
        elif playing_mode == 3:
            process = '随机播放 ' + process
        elif playing_mode == 4:
            process = '随机循环 ' + process
        else:
            pass
        self.screen.addstr(3, self.startcol - 2, process, curses.color_pair(1))
        song = self.storage.database['songs'][
            self.storage.database['player_info']['player_list'][
                self.storage.database['player_info']['idx']]]
        if 'lyric' not in song.keys() or len(song['lyric']) <= 0:
            self.now_lyric = '暂无歌词 ~>_<~ \n'
            if dbus_activity and self.config.get_item('osdlyrics'):
                self.now_playing = song['song_name'] + ' - ' + song[
                    'artist'] + '\n'

        else:
            key = now_minute + ':' + now_second
            for line in song['lyric']:
                if key in line:
                    if 'tlyric' not in song.keys() or len(song['tlyric']) <= 0:
                        self.now_lyric = line
                    else:
                        self.now_lyric = line
                        for tline in song['tlyric']:
                            if key in tline and self.config.get_item(
                                    'translation'):
                                self.now_lyric = tline + ' || ' + self.now_lyric  # NOQA
        self.now_lyric = re.sub('\[.*?\]', '', self.now_lyric)
        if dbus_activity and self.config.get_item('osdlyrics'):
            try:
                bus = dbus.SessionBus().get_object('org.musicbox.Bus', '/')
                if self.now_lyric == '暂无歌词 ~>_<~ \n':
                    bus.refresh_lyrics(self.now_playing,
                                       dbus_interface='local.musicbox.Lyrics')
                else:
                    bus.refresh_lyrics(self.now_lyric,
                                       dbus_interface='local.musicbox.Lyrics')
            except Exception as e:
                log.error(e)
                pass
        self.screen.addstr(4, self.startcol - 2, str(self.now_lyric),
                           curses.color_pair(3))
        self.screen.refresh()

    def build_loading(self):
        self.screen.addstr(7, self.startcol, '享受高品质音乐,loading...',
                           curses.color_pair(1))
        self.screen.refresh()

    # start is the timestamp of this function being called
    def build_menu(self, datatype, title, datalist, offset, index, step,
                   start):
        # keep playing info in line 1
        curses.noecho()
        self.screen.move(5, 1)
        self.screen.clrtobot()
        self.screen.addstr(5, self.startcol, title, curses.color_pair(1))

        if len(datalist) == 0:
            self.screen.addstr(8, self.startcol, '这里什么都没有 -,-')

        else:
            if datatype == 'main':
                for i in range(offset, min(len(datalist), offset + step)):
                    if i == index:
                        self.screen.addstr(i - offset + 9,
                                           self.indented_startcol,
                                           '-> ' + str(i) + '. ' + datalist[i],
                                           curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset + 9, self.startcol,
                                           str(i) + '. ' + datalist[i])

            elif datatype == 'songs' or datatype == 'fmsongs':
                iter_range = min(len(datalist), offset + step)
                for i in range(offset, iter_range):
                    # this item is focus
                    if i == index:
                        self.screen.addstr(i - offset + 8, 0,
                                           ' ' * self.startcol)
                        lead = '-> ' + str(i) + '. '
                        self.screen.addstr(i - offset + 8,
                                           self.indented_startcol, lead,
                                           curses.color_pair(2))
                        name = '{}{}{}  < {} >'.format(
                            datalist[i]['song_name'], self.space,
                            datalist[i]['artist'], datalist[i]['album_name'])

                        # the length decides whether to scoll
                        if truelen(name) < self.x - self.startcol - 1:
                            self.screen.addstr(
                                i - offset + 8,
                                self.indented_startcol + len(lead), name,
                                curses.color_pair(2))
                        else:
                            name = scrollstring(name + '  ', start)
                            self.screen.addstr(
                                i - offset + 8,
                                self.indented_startcol + len(lead), str(name),
                                curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset + 8, 0,
                                           ' ' * self.startcol)
                        self.screen.addstr(
                            i - offset + 8, self.startcol,
                            str(
                                str(i) + '. ' + datalist[i]['song_name'] +
                                self.space + datalist[i]['artist'] + '  < ' +
                                datalist[i]['album_name'] + ' >')[:int(self.x *
                                                                       2)])
                    self.screen.addstr(iter_range - offset + 9, 0,
                                       ' ' * self.x)

            elif datatype == 'artists':
                for i in range(offset, min(len(datalist), offset + step)):
                    if i == index:
                        self.screen.addstr(
                            i - offset + 9, self.indented_startcol, '-> ' +
                            str(i) + '. ' + datalist[i]['artists_name'] +
                            self.space + str(datalist[i]['alias']),
                            curses.color_pair(2))
                    else:
                        self.screen.addstr(
                            i - offset + 9, self.startcol,
                            str(i) + '. ' + datalist[i]['artists_name'] +
                            self.space + datalist[i]['alias'])

            elif datatype == 'albums':
                for i in range(offset, min(len(datalist), offset + step)):
                    if i == index:
                        self.screen.addstr(
                            i - offset + 9, self.indented_startcol, '-> ' +
                            str(i) + '. ' + datalist[i]['albums_name'] +
                            self.space + datalist[i]['artists_name'],
                            curses.color_pair(2))
                    else:
                        self.screen.addstr(
                            i - offset + 9, self.startcol,
                            str(i) + '. ' + datalist[i]['albums_name'] +
                            self.space + 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 + 9, self.indented_startcol,
                            '-> ' + str(i) + '. ' + datalist[i]['title'],
                            curses.color_pair(2))
                    else:
                        self.screen.addstr(
                            i - offset + 9, self.startcol,
                            str(i) + '. ' + datalist[i]['title'])

            elif datatype == 'top_playlists':
                for i in range(offset, min(len(datalist), offset + step)):
                    if i == index:
                        self.screen.addstr(
                            i - offset + 9, self.indented_startcol, '-> ' +
                            str(i) + '. ' + datalist[i]['playlists_name'] +
                            self.space + datalist[i]['creator_name'],
                            curses.color_pair(2))
                    else:
                        self.screen.addstr(
                            i - offset + 9, self.startcol,
                            str(i) + '. ' + datalist[i]['playlists_name'] +
                            self.space + datalist[i]['creator_name'])

            elif datatype == 'toplists':
                for i in range(offset, min(len(datalist), offset + step)):
                    if i == index:
                        self.screen.addstr(i - offset + 9,
                                           self.indented_startcol,
                                           '-> ' + str(i) + '. ' + datalist[i],
                                           curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset + 9, self.startcol,
                                           str(i) + '. ' + datalist[i])

            elif datatype in ('playlist_classes', 'playlist_class_detail'):
                for i in range(offset, min(len(datalist), offset + step)):
                    if i == index:
                        self.screen.addstr(i - offset + 9,
                                           self.indented_startcol,
                                           '-> ' + str(i) + '. ' + datalist[i],
                                           curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset + 9, self.startcol,
                                           str(i) + '. ' + datalist[i])

            elif datatype == 'djchannels':
                for i in range(offset, min(len(datalist), offset + step)):
                    if i == index:
                        self.screen.addstr(
                            i - offset + 8, self.indented_startcol,
                            '-> ' + str(i) + '. ' + datalist[i]['song_name'],
                            curses.color_pair(2))
                    else:
                        self.screen.addstr(
                            i - offset + 8, self.startcol,
                            str(i) + '. ' + datalist[i]['song_name'])

            elif datatype == 'search':
                self.screen.move(6, 1)
                self.screen.clrtobot()
                self.screen.timeout(-1)
                self.screen.addstr(8, self.startcol, '选择搜索类型:',
                                   curses.color_pair(1))
                for i in range(offset, min(len(datalist), offset + step)):
                    if i == index:
                        self.screen.addstr(
                            i - offset + 10, self.indented_startcol,
                            '-> ' + str(i) + '.' + datalist[i - 1],
                            curses.color_pair(2))
                    else:
                        self.screen.addstr(i - offset + 10, self.startcol,
                                           str(i) + '.' + datalist[i - 1])
                self.screen.timeout(100)

            elif datatype == 'help':
                for i in range(offset, min(len(datalist), offset + step)):
                    if i == index:
                        self.screen.addstr(
                            i - offset + 9, self.indented_startcol,
                            '-> ' + str(i) + '. \'' +
                            (datalist[i][0].upper() + '\'').ljust(11) +
                            datalist[i][1] + '   ' + datalist[i][2],
                            curses.color_pair(2))
                    else:
                        self.screen.addstr(
                            i - offset + 9, self.startcol,
                            str(i) + '. \'' +
                            (datalist[i][0].upper() + '\'').ljust(11) +
                            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, self.startcol,
                                   'Build with love to music by omi')

        self.screen.refresh()

    def build_search(self, stype):
        self.screen.timeout(-1)
        netease = self.netease
        if stype == 'songs':
            song_name = self.get_param('搜索歌曲:')
            if song_name == '/return':
                return []
            else:
                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 Exception as e:
                    log.error(e)
                    return []

        elif stype == 'artists':
            artist_name = self.get_param('搜索艺术家:')
            if artist_name == '/return':
                return []
            else:
                try:
                    data = netease.search(artist_name, stype=100)
                    if 'artists' in data['result']:
                        artists = data['result']['artists']
                        return netease.dig_info(artists, 'artists')
                except Exception as e:
                    log.error(e)
                    return []

        elif stype == 'albums':
            albums_name = self.get_param('搜索专辑:')
            if albums_name == '/return':
                return []
            else:
                try:
                    data = netease.search(albums_name, stype=10)
                    if 'albums' in data['result']:
                        albums = data['result']['albums']
                        return netease.dig_info(albums, 'albums')
                except Exception as e:
                    log.error(e)
                    return []

        elif stype == 'search_playlist':
            search_playlist = self.get_param('搜索网易精选集:')
            if search_playlist == '/return':
                return []
            else:
                try:
                    data = netease.search(search_playlist, stype=1000)
                    if 'playlists' in data['result']:
                        playlists = data['result']['playlists']
                        return netease.dig_info(playlists, 'top_playlists')
                except Exception as e:
                    log.error(e)
                    return []

        return []

    def build_login(self):
        self.build_login_bar()
        local_account = self.get_account()
        local_password = hashlib.md5(self.get_password()).hexdigest()
        login_info = self.netease.login(local_account, local_password)
        account = [local_account, local_password]
        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_bar(self):
        curses.noecho()
        self.screen.move(4, 1)
        self.screen.clrtobot()
        self.screen.addstr(5, self.startcol, '请输入登录信息(支持手机登陆)',
                           curses.color_pair(1))
        self.screen.addstr(8, self.startcol, '账号:', curses.color_pair(1))
        self.screen.addstr(9, self.startcol, '密码:', curses.color_pair(1))
        self.screen.move(8, 24)
        self.screen.refresh()

    def build_login_error(self):
        self.screen.move(4, 1)
        self.screen.timeout(-1)  # disable the screen timeout
        self.screen.clrtobot()
        self.screen.addstr(8, self.startcol, '艾玛,登录信息好像不对呢 (O_O)#',
                           curses.color_pair(1))
        self.screen.addstr(10, self.startcol, '[1] 再试一次')
        self.screen.addstr(11, self.startcol, '[2] 稍后再试')
        self.screen.addstr(14, self.startcol, '请键入对应数字:', curses.color_pair(2))
        self.screen.refresh()
        x = self.screen.getch()
        self.screen.timeout(100)  # restore the screen timeout
        return x

    def get_account(self):
        self.screen.timeout(-1)  # disable the screen timeout
        curses.echo()
        account = self.screen.getstr(8, self.startcol + 6, 60)
        self.screen.timeout(100)  # restore the screen timeout
        return account

    def get_password(self):
        self.screen.timeout(-1)  # disable the screen timeout
        curses.noecho()
        password = self.screen.getstr(9, self.startcol + 6, 60)
        self.screen.timeout(100)  # restore the screen timeout
        return password

    def get_param(self, prompt_string):
        # keep playing info in line 1
        curses.echo()
        self.screen.move(4, 1)
        self.screen.clrtobot()
        self.screen.addstr(5, self.startcol, prompt_string,
                           curses.color_pair(1))
        self.screen.refresh()
        info = self.screen.getstr(10, self.startcol, 60)
        if info == '':
            return '/return'
        elif info.strip() is '':
            return self.get_param(prompt_string)
        else:
            return info

    def update_size(self):
        # get terminal size
        size = terminalsize.get_terminal_size()
        self.x = max(size[0], 10)
        self.y = max(size[1], 25)

        # update intendations
        curses.resizeterm(self.y, self.x)
        self.startcol = int(float(self.x) / 5)
        self.indented_startcol = max(self.startcol - 3, 0)
        self.update_space()
        self.screen.clear()
        self.screen.refresh()

    def update_space(self):
        if self.x > 140:
            self.space = '   -   '
        elif self.x > 80:
            self.space = '  -  '
        else:
            self.space = ' - '
        self.screen.refresh()
コード例 #22
0
class LoginDialog(QDialog):
    """登录对话框
    描述: 弹出登录对话框,用户输入用户名和密码,点击登录按钮调用login函数。
        登录成功则发射("loginsuccess")信号,失败则显示相关提示信息

    调用: 1. 在用户登录成功时,会发射("loginsuccess")信号
    
    """
    def __init__(self, parent=None):
        super(LoginDialog, self).__init__(parent)
        self.username_lable = QLabel()
        self.password_lable = QLabel()
        self.hint_label = QLabel()
        self.username_widget = QLineEdit()
        self.password_widget = QLineEdit()
        self.login_btn = QPushButton()
        self.layout = QVBoxLayout()
        self.ne = NetEase()

        self.__set_signal_binding()
        self.__set_widgets_prop()
        self.__set_layouts_prop()
        self.__set_me()

    def __set_signal_binding(self):
        self.login_btn.clicked.connect(self.__login)

    def __login(self):
        """登录

        在用户登录成功时,会发射("loginsuccess")信号
        """
        phone_login = False      # 0: 网易通行证, 1: 手机号登陆
        username = str(self.username_widget.text())     # 包含中文会出错
        password = str(self.password_widget.text())

        # judget if logining by using phone number
        try:
            int(username)
            phone_login = True
        except ValueError:
            pass

        data = self.ne.login(username, password, phone_login)

        # judge if __login successfully
        # if not, why
        print data['code'], type(data['code'])
        if data['code'] == 200:
            self.hint_label.setText(u'登陆成功')
            self.emit(SIGNAL('loginsuccess'), data)
            self.close()
        elif data['code'] == 408:
            self.hint_label.setText(u'网络连接超时')
        elif data['code'] == 501:
            self.hint_label.setText(u'用户名错误')
        elif data['code'] == 502:
            self.hint_label.setText(u'密码错误')
        else:
            self.hint_label.setText(u'未知错误')

    def __set_me(self):
        self.setObjectName('login_dialog')
        self.setLayout(self.layout)

    def __set_widgets_prop(self):
        self.login_btn.setText(u'登陆')

        self.username_lable.setText(u'网易邮箱或者手机号')
        self.password_lable.setText(u'密码')
        self.username_widget.setPlaceholderText(u'请输入用户名')
        self.password_widget.setPlaceholderText(u'请输入密码')
        self.password_widget.setEchoMode(QLineEdit.Password)

    def __set_layouts_prop(self):
        self.layout.addWidget(self.username_lable)
        self.layout.addWidget(self.username_widget)
        self.layout.addWidget(self.password_lable)
        self.layout.addWidget(self.password_widget)
        self.layout.addWidget(self.hint_label)
        self.layout.addWidget(self.login_btn)
        self.layout.addStretch(1)