Exemplo n.º 1
0
def search_music(q, limit):
	netease = NetEase()
	r = netease.search(q, limit=limit)
	if r['code'] != 200:
		return jsonify({
			"error"		:	True
			})
	else:
		ids = []
		for song in r['result']['songs']:
			ids.append(song['id'])
		musics = netease.songs_detail(ids)
		outputs = []
		for music in musics:
			outputs.append({
				"error"	:	False,
				"name"	:	music['name'],
				"cover"	:	music['album']['blurPicUrl'],
				"album_name":	music['album']['name'],
				"author": 	music['artists'][0]['name'],
				"url"	:	music['mp3Url']
				})
		outputs = {
			"error"		:	False,
			"type"		:	"music",
			"musics"	:	outputs
		}
		return jsonify(outputs)
Exemplo n.º 2
0
 def on_get(self, req, resp):
     query = req.get_param('q', True)
     limit = req.get_param_as_int('limit') or 60
     offset = req.get_param_as_int('offset') or 0
     ne = NetEase()
     # 搜索单曲(1),歌手(100),专辑(10),歌单(1000),用户(1002) *(type)*
     resp.body = json.dumps(ne.search(query, 1, offset, 'true', limit))
Exemplo n.º 3
0
    def __init__(self, song_name):
        self.mp3_date = None
        netease = NetEase()
        data = netease.search(song_name, stype=1, offset=0, total='true', limit=60)
#        print data
        song_ids = []
        if 'songs' in data['result']:
            if 'mp3Url' in data['result']['songs']:
                songs = data['result']['songs']

            else:
                for i in range(0, len(data['result']['songs']) ):
                    song_ids.append( data['result']['songs'][i]['id'] )
                songs = netease.songs_detail(song_ids)
        self.mp3_data = netease.dig_info(songs, 'songs')   #歌曲信息,album, artist, song_name, mp3_url
Exemplo n.º 4
0
    def __init__(self, song_name):
        self.mp3_date = None
        netease = NetEase()
        data = netease.search(song_name,
                              stype=1,
                              offset=0,
                              total='true',
                              limit=60)
        #        print data
        song_ids = []
        if 'songs' in data['result']:
            if 'mp3Url' in data['result']['songs']:
                songs = data['result']['songs']

            else:
                for i in range(0, len(data['result']['songs'])):
                    song_ids.append(data['result']['songs'][i]['id'])
                songs = netease.songs_detail(song_ids)
        self.mp3_data = netease.dig_info(
            songs, 'songs')  #歌曲信息,album, artist, song_name, mp3_url
Exemplo n.º 5
0
def search_music(q, limit):
    netease = NetEase()
    r = netease.search(q, limit=limit)
    if r['code'] != 200:
        return jsonify({"error": True})
    else:
        ids = []
        for song in r['result']['songs']:
            ids.append(song['id'])
        musics = netease.songs_detail(ids)
        outputs = []
        for music in musics:
            outputs.append({
                "error": False,
                "name": music['name'],
                "cover": music['album']['blurPicUrl'],
                "album_name": music['album']['name'],
                "author": music['artists'][0]['name'],
                "url": music['mp3Url']
            })
        outputs = {"error": False, "type": "music", "musics": outputs}
        return jsonify(outputs)
Exemplo n.º 6
0
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
Exemplo n.º 7
0
#coding=utf-8
#import player
from api import NetEase
import mp3play
import time

netease = NetEase()
data = netease.search(u'南山南', stype=1, offset=0, total='true', limit=60)
print data
song_ids = []
if 'songs' in data['result']:
    if 'mp3Url' in data['result']['songs']:
        songs = data['result']['songs']
        print songs
        
    else:
        for i in range(0, len(data['result']['songs']) ):
            song_ids.append( data['result']['songs'][i]['id'] )
        songs = netease.songs_detail(song_ids)
mp3_url_data = netease.dig_info(songs, 'songs') 
print mp3_url_data

for mp3_url  in mp3_url_data:
    print mp3_url['album_name']
    print mp3_url['artist']
    print mp3_url['song_name']
    print mp3_url['mp3_url']
    print '---------------------------'
#{'mp3_url': u'http://m2.music.126.net/GkFXC6qt6rEU2q9KYU-6yQ==/1373290025677371.mp3', 'song_id': 41462137, 'album_name': u'\u6587\u6b66\u8d1d\u94a2\u7434\u6539\u7f16\u4f5c\u54c1\u96c6\uff082015\u5e74\u5168\u96c6\uff09', 'song_name': u'\u5357\u5c71\u5357-\u6587\u6b66\u8d1d\u94a2\u7434\u7248', 'artist': u'\u6587\u6b66\u8d1d'}

Exemplo n.º 8
0
#coding=utf-8
#import player
from api import NetEase
import mp3play
import time

netease = NetEase()
data = netease.search(u'南山南', stype=1, offset=0, total='true', limit=60)
print data
song_ids = []
if 'songs' in data['result']:
    if 'mp3Url' in data['result']['songs']:
        songs = data['result']['songs']
        print songs

    else:
        for i in range(0, len(data['result']['songs'])):
            song_ids.append(data['result']['songs'][i]['id'])
        songs = netease.songs_detail(song_ids)
mp3_url_data = netease.dig_info(songs, 'songs')
print mp3_url_data

for mp3_url in mp3_url_data:
    print mp3_url['album_name']
    print mp3_url['artist']
    print mp3_url['song_name']
    print mp3_url['mp3_url']
    print '---------------------------'
#{'mp3_url': u'http://m2.music.126.net/GkFXC6qt6rEU2q9KYU-6yQ==/1373290025677371.mp3', 'song_id': 41462137, 'album_name': u'\u6587\u6b66\u8d1d\u94a2\u7434\u6539\u7f16\u4f5c\u54c1\u96c6\uff082015\u5e74\u5168\u96c6\uff09', 'song_name': u'\u5357\u5c71\u5357-\u6587\u6b66\u8d1d\u94a2\u7434\u7248', 'artist': u'\u6587\u6b66\u8d1d'}
Exemplo n.º 9
0
class MainWidget(QWidget):
    def __init__(self, parent=None):
        super(MainWidget, self).__init__(parent)
        # set app name before mediaObject was created to avoid phonon problem
        QCoreApplication.setApplicationName("NetEaseMusic-ThirdParty")
        self.ui = UiMainWidget()
        self.ui.setup_ui(self)

        self.signal_mapper = QSignalMapper(self)
        self.player = Phonon.createPlayer(Phonon.MusicCategory)
        self.net_manager = QNetworkAccessManager()
        self.searchShortcut = QShortcut(QKeySequence("Ctrl+F"), self)
        self.sources = []
        self.net_ease = NetEase()
        self.model = DataModel()

        self.set_self_prop()
        self.set_signal_binding()
        self.init_table_widget()

    def init_table_widget(self):
        self.ui.info_widget.music_table_widget.close()
        self.ui.info_widget.music_search_widget.close()
        self.ui.info_widget.current_playing_widget.close()

    def set_self_prop(self):
        self.setWindowTitle('NetEaseMusic For Linux')
        self.setObjectName('main_widget')
        self.resize(960, 580)
        self.setWindowIcon(QIcon('icons/format.ico'))

    def paintEvent(self, QPaintEvent):
        """
        self is derived from QWidget, Stylesheets don't work unless \
        paintEvent is reimplemented.
        at the same time, if self is derived from QFrame, this isn't needed.
        """
        option = QStyleOption()
        option.init(self)
        painter = QPainter(self)
        style = self.style()
        style.drawPrimitive(QStyle.PE_Widget, option, painter, self)

    def set_signal_binding(self):
        self.searchShortcut.activated.connect(self.set_search_focus)
        self.ui.info_widget.music_table_widget.itemDoubleClicked.connect(
            self.play_userplaylist_music)
        self.ui.info_widget.music_search_widget.itemDoubleClicked.connect(
            self.play_search_music)
        self.ui.info_widget.current_playing_widget.itemDoubleClicked.connect(
            self.play_currentplayinglist_music)
        self.ui.user_widget.list_widget.itemDoubleClicked.connect(
            self.play_userlist)
        self.ui.user_widget.list_widget.itemClicked.connect(
            self.set_tablewidget_userplaylist)
        self.player.setTickInterval(1000)
        self.player.tick.connect(self.tick)
        self.player.stateChanged.connect(self.state_changed)
        self.player.currentSourceChanged.connect(self.source_changed)
        self.player.aboutToFinish.connect(self.about_to_finish)
        self.ui.play_widget.play_pause_btn.clicked.connect(self.play_pause)
        self.ui.play_widget.last_music_btn.clicked.connect(
            self.last_music)
        self.ui.play_widget.next_music_btn.clicked.connect(
            self.next_music)
        self.ui.play_widget.seek_slider.setMediaObject(self.player)
        self.ui.play_widget.login_btn.clicked.connect(self.show_login_widget)
        self.ui.play_widget.search_btn.clicked.connect(self.search)
        self.ui.play_widget.search_edit.returnPressed.connect(self.search)
        self.ui.play_widget.show_current_list.clicked.connect(self.set_tablewidget_currentplayinglist)
        self.ui.play_widget.help_btn.clicked.connect(self.show_help_info)
        self.net_manager.finished.connect(self.albumimg_load_finish)

    def show_help_info(self):
        print 'show help info'
        with open('data/help.html') as f:
            text = f.read()
            text = text.decode('utf8')
            message = QMessageBox(self)
            message.setText(text)
            message.setTextFormat(Qt.RichText)
            message.show()
        pass

    def play_userlist(self, item):
        userplaylist_widget = self.ui.user_widget.list_widget
        data = item.data(Qt.UserRole)
        playlist = data.toPyObject()[0]
        pid = playlist['id']
        res = self.net_ease.playlist_detail(pid)
        # table_widget.clear()
        if res is not []:
            current_playing = self.ui.info_widget.current_playing_widget

            # 清空当前播放列表
            self.sources = []
            current_playing.setRowCount(0)

            # 把歌曲全部加入列表
            for music in res:
                datamodel = self.model.music()
                music_model = self.model.set_datamodel_from_data(music, datamodel)

                source = Phonon.MediaSource(music_model['mp3Url'])
                self.add_music_to_sources(source)
                self.add_music_to_currentplayinglist(music_model)

            # 播放列表第一首歌
            item = current_playing.item(0, 0)
            self.play_currentplayinglist_music(item)

            # 显示当前播放列表
            self.init_table_widget()
            current_playing.show()
        else:
            # 具体详细提示信息需要根据后台返回进行判断
            # 以后可以进行优化
            self.ui.status.showMessage(u'当前列表为空', 3000)

    def play_currentplayinglist_music(self, item):
        current_playing = self.ui.info_widget.current_playing_widget
        current_row = current_playing.row(item)
        self.player.stop()
        self.player.setCurrentSource(self.sources[current_row])
        self.player.play()

    def set_search_focus(self):
        self.ui.play_widget.search_edit.setFocus(True)

    def play_pause(self):
        if self.player.state() == Phonon.PlayingState:
            self.player.pause()
        elif self.player.state() == Phonon.PausedState:
            self.player.play()

    def show_login_widget(self):
        d = LoginDialog(self)
        self.connect(d, SIGNAL('loginsuccess'), self.login)
        d.show()

    def login(self, data):
        if data is False:
            uid = '18731323'
        else:
            uid = data['account']['id']
            try:
                self.ui.status.showMessage(u'准备加载头像')
                avatarUrl = data['profile']['avatarUrl']
                self.net_manager.finished.connect(self.avatar_load_finish)
                self.net_manager.finished.disconnect(self.albumimg_load_finish)
                self.load_user_playlist(uid)
                self.net_manager.get(QNetworkRequest(QUrl(avatarUrl)))
                return
            except:
                self.ui.status.showMessage(u'加载头像失败', 2000)
        self.load_user_playlist(uid)

    def load_user_playlist(self, uid):
        playlists = self.net_ease.user_playlist(uid)
        list_widget = self.ui.user_widget.list_widget
        list_widget.clear()
        if playlists is not []:
            for playlist in playlists:
                datamodel = self.model.playlist()
                datamodel = self.model.set_datamodel_from_data(playlist, datamodel)
                item = QListWidgetItem(QIcon('icons/playlist_1.png'), datamodel['name'])
                list_widget.addItem(item)
                data = QVariant((datamodel, ))
                item.setData(Qt.UserRole, data)
        else:
            print 'network error'

    def search(self):
        search_edit = self.ui.play_widget.search_edit
        text= search_edit.text()
        self.ui.status.showMessage(u'正在搜索: ' + text)
        if text != '':
            s = unicode(text.toUtf8(), 'utf8', 'ignore')
            data = self.net_ease.search(s.encode('utf8'))
            songs = list()
            if data['result']['songCount'] != 0:
                songs = data['result']['songs']
                length = len(songs)
                self.set_search_widget(songs)
                self.ui.status.showMessage(u'搜索到 ' + str(length) + u' 首 ' +
                                           text +u' 相关歌曲', 2000)
                return
            else:
                self.ui.status.showMessage(u'很抱歉,没有找到相关歌曲', 2000)
                return

    def set_search_widget(self, songs):
        self.init_table_widget()
        music_search = self.ui.info_widget.music_search_widget
        music_search.show()

        row_count = len(songs)
        music_search.setRowCount(0)
        music_search.setRowCount(row_count)
        row = 0
        for song in songs:
            datamodel = self.model.search_result()
            datamodel = self.model.set_datamodel_from_data(song, datamodel)
            musicItem = QTableWidgetItem(datamodel['name'])
            albumItem = QTableWidgetItem(datamodel['album']['name'])
            if len(song['artists']) > 0:
                artistName = song['artists'][0]['name']
            artistItem = QTableWidgetItem(artistName)

            music = QVariant((datamodel, ))
            musicItem.setData(Qt.UserRole, music)

            musicItem.setTextAlignment(Qt.AlignCenter)
            artistItem.setTextAlignment(Qt.AlignCenter)
            albumItem.setTextAlignment(Qt.AlignCenter)

            music_search.setItem(row, 0, musicItem)
            music_search.setItem(row, 1, artistItem)
            music_search.setItem(row, 2, albumItem)
            row += 1


    def set_tablewidget_userplaylist(self, item):
        self.init_table_widget()
        table_widget = self.ui.info_widget.music_table_widget
        table_widget.show()

        data = item.data(Qt.UserRole)
        playlist = data.toPyObject()[0]
        plid = playlist['id']

        data = [{'title': 'way back into love',
                 'url': 'http://m1.music.126.net/KfNqSlCW2eoJ1LXtvpLThg==/1995613604419370.mp3'}]

        # data = self.user.get_music_title_and_url(pid)
        data = self.net_ease.playlist_detail(plid)
        # table_widget.clear()
        if data is not []:
            row_count = len(data)
            table_widget.setRowCount(0)
            table_widget.setRowCount(row_count)
            row = 0
            for music in data:
                datamodel = self.model.music()
                datamodel = self.model.set_datamodel_from_data(music, datamodel)
                musicItem = QTableWidgetItem(datamodel['name'])
                musicItem = QTableWidgetItem(datamodel['name'])
                albumItem = QTableWidgetItem(datamodel['album']['name'])
                if len(datamodel['artists']) > 0:
                    artistName = datamodel['artists'][0]['name']
                artistItem = QTableWidgetItem(artistName)
                # to get pure dict from qvariant, so pay attension !
                # stackoverflow: how to get the original python data from qvariant
                music = QVariant((datamodel, ))
                musicItem.setData(Qt.UserRole, music)

                musicItem.setTextAlignment(Qt.AlignCenter)
                artistItem.setTextAlignment(Qt.AlignCenter)
                albumItem.setTextAlignment(Qt.AlignCenter)

                table_widget.setItem(row, 0, musicItem)
                table_widget.setItem(row, 1, artistItem)
                table_widget.setItem(row, 2, albumItem)
                row += 1
        else:
            print 'network, no music, error plid'

    def play_specific_music(self, source):
        """
        播放一首特定的歌曲(通常是搜索到的歌曲和用户列表中的歌曲)
        :param source: phonon media source
        """
        self.player.stop()
        self.player.setCurrentSource(source)
        self.player.play()

    def add_music_to_sources(self, source):
        self.sources.append(source)

    def add_music_to_currentplayinglist(self, music_model):
        """向当前播放列表中加入一首歌
        1. 向sources列表中加入相应的 media source
        2. 更新当前播放列表(current_play_widget)
        :param music_model: music 的标准数据model
        """
        current_playing = self.ui.info_widget.current_playing_widget
        rowCount = current_playing.rowCount()
        current_playing.setRowCount(rowCount + 1)

        # 更新 current play widget
        musicItem = QTableWidgetItem(music_model['name'])
        albumItem = QTableWidgetItem(music_model['album']['name'])
        if len(music_model['artists']) > 0:
            artistName = music_model['artists'][0]['name']
        artistItem = QTableWidgetItem(artistName)
        # to get pure dict from qvariant, so pay attension !
        # stackoverflow: how to get the original python data from qvariant
        music = QVariant((music_model, ))
        musicItem.setData(Qt.UserRole, music)

        musicItem.setTextAlignment(Qt.AlignCenter)
        artistItem.setTextAlignment(Qt.AlignCenter)
        albumItem.setTextAlignment(Qt.AlignCenter)

        current_playing.setItem(rowCount, 0, musicItem)
        current_playing.setItem(rowCount, 1, artistItem)
        current_playing.setItem(rowCount, 2, albumItem)

    def play_search_music(self, item):
        music_search = self.ui.info_widget.music_search_widget
        current_row = music_search.row(item)
        item = music_search.item(current_row, 0)    # only item 0 contain url
        data = item.data(Qt.UserRole)
        song = data.toPyObject()[0]
        musics = self.net_ease.song_detail(song['id'])
        datamodel = self.model.music()
        music_model = self.model.set_datamodel_from_data(musics[0], datamodel)

        source = Phonon.MediaSource(music_model['mp3Url'])

        self.add_music_to_sources(source)
        self.add_music_to_currentplayinglist(music_model)
        self.play_specific_music(source)

    def play_userplaylist_music(self, item):
        music_table = self.ui.info_widget.music_table_widget
        current_row = music_table.row(item)
        data = item.data(Qt.UserRole)
        music_model = data.toPyObject()[0]

        source = Phonon.MediaSource(music_model['mp3Url'])
        self.add_music_to_sources(source)

        self.add_music_to_currentplayinglist(music_model)
        self.play_specific_music(source)

    def tick(self, time):
        time_lcd = self.ui.play_widget.time_lcd
        displayTime = QTime(0, (time / 60000) % 60, (time / 1000) % 60)
        time_lcd.setText(displayTime.toString('mm:ss'))

    def state_changed(self, new_state, old_state):
        time_lcd = self.ui.play_widget.time_lcd
        play_pause_btn = self.ui.play_widget.play_pause_btn
        if new_state == Phonon.ErrorState:
            if self.player.errorType() == Phonon.FatalError:
                QMessageBox.warning(self, "Fatal Error",
                        self.player.errorString())
            else:
                QMessageBox.warning(self, "Error",
                        self.player.errorString())
        elif new_state == Phonon.PlayingState:
            play_pause_btn.setIcon(QIcon('icons/play_hover.png'))
        elif new_state == Phonon.StoppedState:
            time_lcd.setText("00:00")
        elif new_state == Phonon.PausedState:
            play_pause_btn.setIcon(QIcon('icons/pause_hover.png'))

    def source_changed(self, source):
        """
        """
        # set time lcd
        time_lcd = self.ui.play_widget.time_lcd
        time_lcd.setText('00:00')

        # set text label
        current_playing = self.ui.info_widget.current_playing_widget
        row = self.sources.index(source)
        item = current_playing.item(row, 0)
        current_playing.scrollToItem(item)
        current_playing.setCurrentItem(item)

        data = item.data(Qt.UserRole)
        music = data.toPyObject()[0]
        text_label = self.ui.play_widget.text_label
        text_label.setText(music['name'])
        self.net_manager.get(QNetworkRequest(QUrl(music['album']['picUrl'])))

    def albumimg_load_finish(self, res):
        img_label = self.ui.play_widget.img_label
        img = QImage()
        img.loadFromData(res.readAll())
        img_label.setPixmap(QPixmap(img).scaled(50, 50))

    def avatar_load_finish(self, res):
        login_btn = self.ui.play_widget.login_btn
        img = QImage()
        img.loadFromData(res.readAll())
        login_btn.setIcon(QIcon(QPixmap(img).scaled(40, 40)))
        self.net_manager.finished.disconnect(self.avatar_load_finish)
        self.net_manager.finished.connect(self.albumimg_load_finish)
        self.ui.status.showMessage(u'加载头像成功', 2000)

    def about_to_finish(self):
        index = self.sources.index(self.player.currentSource()) + 1
        if len(self.sources) > index:
            self.player.enqueue(self.sources[index])
        else:
            self.player.enqueue(self.sources[0])

    def last_music(self):
        try:
            index = self.sources.index(self.player.currentSource()) - 1
        except ValueError:
            self.ui.status.showMessage(u'当前播放列表为空', 2000)
            return
        if index >= 0:
            self.player.setCurrentSource(self.sources[index])
        else:
            self.player.setCurrentSource(self.sources[0])
        self.player.play()

    def next_music(self):
        try:
            index = self.sources.index(self.player.currentSource()) + 1
        except ValueError:
            self.ui.status.showMessage(u'当前播放列表为空', 2000)
            return
        if len(self.sources) > index:
            self.player.setCurrentSource(self.sources[index])
        else:
            self.player.setCurrentSource(self.sources[0])
        self.player.play()

    def set_tablewidget_currentplayinglist(self):
        self.init_table_widget()
        self.ui.info_widget.current_playing_widget.show()