Beispiel #1
0
        public static async Task <QQMusicSearchJson> SearchAsync(string keyword)
        {
            var url    = string.Format(seachUrl, keyword, Settings.Current.PreferredSearchCount.ToString());
            var header = new Dictionary <string, string>()
            {
                ["Accept-Language"] = "zh-CN",
                ["Accept"]          = "application/json, text/plain, */*",
                ["Referer"]         = "http://y.qq.com/",
                ["Origin"]          = "http://y.qq.com/",
            };
            var result = await ApiRequestHelper.HttpGet(url, addHeader : header);

            try
            {
                if (result != null)
                {
                    var length = result.Length - 8;
                    return(JsonConvert.DeserializeObject <QQMusicSearchJson>(result.Substring(7, length)));
                }
                return(null);
            }
            catch (JsonReaderException)
            {
                return(null);
            }
        }
        public static async Task <string> GenerateFileUriByID(string media_ID, uint bitrate = 256)
        {
            if ((DateTime.Now - stamp).TotalMinutes > 1 || !key.IsNullorEmpty())
            {
                guid  = (Shared.Helpers.Tools.Random.Next() % 10000000000);
                stamp = DateTime.Now;
                var queryString = HttpUtility.ParseQueryString(string.Empty);
                queryString["json"]   = "3";
                queryString["guid"]   = guid.ToString();
                queryString["format"] = "json";
                var result = await ApiRequestHelper.HttpGet(fileUrl, queryString);

                if (result.IsNullorEmpty())
                {
                    return(null);
                }
                var stage = JsonConvert.DeserializeObject <QQMusicFileJson>(result);
                if (stage.Code != 0)
                {
                    return(null);
                }
                key = stage.Key;
            }

            var f = fileFormats.First(x => x.BitRate <= bitrate);

            var final = streamUrl + f.Prefix + media_ID + f.Format + "?vkey=" + key + "&guid=" + guid.ToString() + "&uid=0&fromtag=30";

            return(final);
        }
Beispiel #3
0
        public static async Task <QQMusicDiscJson> ShowPlaylist(string id)
        {
            var url    = string.Format(getPlaylistUrl, id);
            var header = new Dictionary <string, string>()
            {
                ["Accept-Language"] = "zh-CN",
                ["Accept"]          = "application/json, text/plain, */*",
                ["Referer"]         = "http://y.qq.com/",
                ["Origin"]          = "http://y.qq.com/",
            };
            var result = await ApiRequestHelper.HttpGet(url, addHeader : header);

            try
            {
                if (result != null)
                {
                    var length = result.Length - 14;
                    return(JsonConvert.DeserializeObject <QQMusicDiscJson>(result.Substring(13, length)));
                }
                return(null);
            }
            catch (JsonReaderException)
            {
                return(null);
            }
        }
        public static async Task <QQMusicSearchJson> SearchAsync(string keyword)
        {
            var queryString = HttpUtility.ParseQueryString(string.Empty);

            queryString["format"]   = "json";
            queryString["aggr"]     = "1";
            queryString["lossless"] = "1";
            queryString["cr"]       = "1";
            queryString["new_json"] = "1";
            queryString["p"]        = "1";
            queryString["n"]        = Settings.Current.PreferredSearchCount.ToString();
            queryString["w"]        = keyword;

            var result = await ApiRequestHelper.HttpGet(url, queryString);

            try
            {
                if (result != null)
                {
                    return(JsonConvert.DeserializeObject <QQMusicSearchJson>(result));
                }
                return(null);
            }
            catch (JsonReaderException)
            {
                return(null);
            }
        }
Beispiel #5
0
        public static async Task <List <OnlineMusicItem> > LookUp(string onlineAlbumID)
        {
            var res = await ApiRequestHelper.HttpGet(string.Format(lookupUrl, onlineAlbumID));

            var result = JsonConvert.DeserializeObject <ITunesSearchResult>(res);

            return(result.results.ConvertAll(a => new OnlineMusicItem(a.trackName, a.artistName, a.feedUrl, null, a.feedUrl, a.artworkUrl100)
            {
                InnerType = MediaType.Podcast,
            }));
        }
Beispiel #6
0
        public static async Task <ITunesTop> TopGenres(string key, int count)
        {
            try
            {
                var res = await ApiRequestHelper.HttpGet(string.Format(topUrl, CultureInfoHelper.CurrentRegionISO, count, key));

                return(JsonConvert.DeserializeObject <ITunesTop>(res));
            }
            catch (System.Exception)
            {
                return(null);
            }
        }
Beispiel #7
0
        internal static async Task <ITunesSearchResult> Search(string keyword)
        {
            var parameter = HttpUtility.ParseQueryString("");

            parameter["term"]    = keyword;
            parameter["country"] = CultureInfoHelper.CurrentRegionISO;
            parameter["media"]   = "podcast";
            parameter["limit"]   = "10";
            try
            {
                var res = await ApiRequestHelper.HttpGet(queryUrl, parameter);

                return(JsonConvert.DeserializeObject <ITunesSearchResult>(res));
            }
            catch (System.Exception)
            {
                return(null);
            }
        }
        public static async Task <QQMusicSearchJson> SearchAsync(string keyword, int?page = 1, int?count = 10)
        {
            var queryString = HttpUtility.ParseQueryString(string.Empty);

            queryString["format"]   = "json";
            queryString["aggr"]     = "1";
            queryString["lossless"] = "1";
            queryString["cr"]       = "1";
            queryString["new_json"] = "1";
            if (page.HasValue)
            {
                queryString["p"] = page.ToString();
            }
            else
            {
                queryString["p"] = "1";
            }
            if (count.HasValue)
            {
                queryString["n"] = count.ToString();
            }
            else
            {
                queryString["n"] = "10";
            }
            queryString["w"] = keyword;

            var result = await ApiRequestHelper.HttpGet(url, queryString);

            try
            {
                if (result != null)
                {
                    return(JsonConvert.DeserializeObject <QQMusicSearchJson>(result));
                }
                return(null);
            }
            catch (JsonReaderException)
            {
                return(null);
            }
        }
Beispiel #9
0
        public static async Task <string> GenerateFileUriByID(string media_ID, uint bitrate)
        {
            var result = await ApiRequestHelper.HttpGet(string.Format(fileUrl, media_ID));

            if (result.IsNullorEmpty())
            {
                return(null);
            }
            var data = JsonConvert.DeserializeObject <QQMusicFileJson>(result);

            try
            {
                var final = data.req_0.data.Sip[0] + data.req_0.data.MidUrlInfo[0].purl;
                return(final);
            }
            catch
            {
                return(null);
            }
        }
Beispiel #10
0
        public async Task Refresh()
        {
            var resXML = await ApiRequestHelper.HttpGet(XMLUrl);

            await ReadXML(resXML);

            try
            {
                var folder = await ApplicationData.Current.LocalFolder.CreateFolderAsync("Podcasts", CreationCollisionOption.OpenIfExists);

                var file = await folder.CreateFileAsync($"{XMLPath}.xml", CreationCollisionOption.OpenIfExists);

                await FileIO.WriteTextAsync(file, resXML);
            }
            catch (Exception)
            {
            }

            await SaveAsync();
        }
        public static async Task <QQMusicSongJson> GetSongAsync(string song_mid)
        {
            var queryString = HttpUtility.ParseQueryString(string.Empty);

            queryString["songmid"]  = song_mid;
            queryString["platform"] = "yqq";
            queryString["format"]   = "json";
            var response = await ApiRequestHelper.HttpGet(songUrl, queryString);

            if (response.IsNullorEmpty())
            {
                return(null);
            }
            try
            {
                return(JsonConvert.DeserializeObject <QQMusicSongJson>(response));
            }
            catch (JsonReaderException)
            {
                return(null);
            }
        }
Beispiel #12
0
        public async Task <bool> FindUpdated()
        {
            string resXML = string.Empty;
            bool   b      = false;

            for (int i = 0; i < 3; i++)
            {
                resXML = await ApiRequestHelper.HttpGet(XMLUrl);

                try
                {
                    FindUpdated(resXML);
                    b = true;
                    break;
                }
                catch (Exception)
                {
                }
            }
            if (!b)
            {
                return(false);
            }
            try
            {
                var folder = await ApplicationData.Current.LocalFolder.CreateFolderAsync("Podcasts", CreationCollisionOption.OpenIfExists);

                var file = await folder.CreateFileAsync($"{XMLPath}.xml", CreationCollisionOption.OpenIfExists);

                await FileIO.WriteTextAsync(file, resXML);
            }
            catch (Exception)
            {
            }
            await SaveAsync();

            return(Count > 0);
        }
Beispiel #13
0
        public static async Task <string> GetSongLrcByID(string mid)
        {
            var s = await OnlineMusicSearcher.GetSongAsync(mid);

            if (s != null && !s.DataItems.IsNullorEmpty())
            {
                try
                {
                    string result = await ApiRequestHelper.HttpGet(string.Format(qqLyric, s.DataItems[0].Id));

                    result = result.Split('(')[1].TrimEnd(')');
                    if (result != null)
                    {
                        return(HttpUtility.HtmlDecode(CryptoHelper.FromBase64(Newtonsoft.Json.JsonConvert.DeserializeAnonymousType(result, new { lyric = "" }).lyric)));
                    }
                }
                catch (Exception)
                {
                    return(null);
                }
            }
            return(null);
        }
Beispiel #14
0
        public static async Task <IEnumerable <KeyValuePair <string, string> > > GetSongLrcListAsync(string title, string performer = null)
        {
            string res;

            if (!performer.IsNullorEmpty())
            {
                res = await ApiRequestHelper.HttpGet($"http://gecimi.com/api/lyric/{title}/{performer}");
            }
            else
            {
                res = await ApiRequestHelper.HttpGet($"http://gecimi.com/api/lyric/{title}");
            }
            if (res.IsNullorEmpty())
            {
                return(null);
            }
            var json = Newtonsoft.Json.JsonConvert.DeserializeObject <GecimiJson>(res);

            if (json.Count > 0)
            {
                return(json.ResultItems.Select(x => new KeyValuePair <string, string>(x.Song, x.Lrc)));
            }
            return(null);
        }
Beispiel #15
0
        public static async Task <Artist> GetArtistInfo(string art)
        {
            try
            {
                var param = HttpUtility.ParseQueryString(string.Empty);
                param["method"]      = "artist.getinfo";
                param["api_key"]     = API_KEY;
                param["artist"]      = art;
                param["lang"]        = CultureInfoHelper.CurrentCulture.TwoLetterISOLanguageName;
                param["autocorrect"] = "1";
                var result = await ApiRequestHelper.HttpGet(API_URL, param);

                var xml = new XmlDocument(); xml.LoadXml(result);
                if (xml.SelectSingleNode("/lfm/@status").InnerText == "ok")
                {
                    var artist = new Artist
                    {
                        Name = xml.SelectSingleNode("/lfm/artist/name").InnerText
                    };
                    var imageNode = xml.SelectSingleNode("/lfm/artist/image[@size='']");
                    if (imageNode == null)
                    {
                    }
                    else
                    {
                        if (Uri.TryCreate(imageNode.InnerText, UriKind.Absolute, out var u))
                        {
                            artist.AvatarUri = u;
                        }
                    }

                    var list = new List <string>();

                    foreach (var item in xml.SelectNodes("/lfm/artist/tags/tag"))
                    {
                        list.Add($"[{item.SelectSingleNode("./name").InnerText}]({item.SelectSingleNode("./url").InnerText})");
                    }

                    if (list.Count == 0)
                    {
                        list.Add("None");
                    }

                    var listener = xml.SelectSingleNode("/lfm/artist/stats/listeners").InnerText;
                    var played   = xml.SelectSingleNode("/lfm/artist/stats/playcount").InnerText;

                    var bioNode = xml.SelectSingleNode("/lfm/artist/bio");
                    if (bioNode != null)
                    {
                        artist.Description = $"# {artist.Name}\r\n\r\n{listener} listeners and played {played} times.\r\n\r\n## Tags\r\n\r\n\r\n{string.Join(Consts.CommaSeparator, list)}.\r\n\r\n---\r\n\r\n## Wiki\r\n{bioNode.SelectSingleNode("./content").InnerText.Replace("\n", "\r\n\r\n")}\r\n\r\n---\r\n\r\nSee [Last.FM]({xml.SelectSingleNode("/lfm/artist/url").InnerText}).";
                    }
                    else
                    {
                        artist.Description = $"# {artist.Name}\r\n\r\n{listener} listeners and played {played} times.\r\n\r\n## Tags\r\n\r\n\r\n{string.Join(Consts.CommaSeparator, list)}.\r\n\r\n---\r\n\r\nSee [Last.FM]({xml.SelectSingleNode("/lfm/artist/url").InnerText}).";
                    }

                    return(artist);
                }
                else
                {
                    return(null);
                }
            }
            catch (Exception)
            {
                return(null);
            }
        }
Beispiel #16
0
        public static async Task <Podcast> GetiTunesPodcast(string url)
        {
            var resXML = await ApiRequestHelper.HttpGet(url);

            return(await BuildFromXMLAsync(resXML, url));
        }
Beispiel #17
0
        private async void OnRequestReceived(AppServiceConnection sender, AppServiceRequestReceivedEventArgs args)
        {
            // Get a deferral because we use an awaitable API below to respond to the message
            // and we don't want this call to get cancelled while we are waiting.
            var messageDeferral = args.GetDeferral();

            ValueSet message    = args.Request.Message;
            ValueSet returnData = new ValueSet();

            string command = message["q"] as string;

            switch (command)
            {
            case "lyric":
                var title = message["title"] as string;
                message.TryGetValue("artist", out object art);
                var artists = art as string;

                var localLrc = await LyricSearcher.SearchLrcLocalAsync(title, artists);

                if (!localLrc.IsNullorEmpty())
                {
                    returnData.Add("result", localLrc);

                    returnData.Add("status", 1);
                    break;
                }

                var substitutes = await LyricSearcher.GetSongLrcListAsync(title, artists);

                if (!substitutes.IsNullorEmpty())
                {
                    var result = await ApiRequestHelper.HttpGet(substitutes.First().Value);

                    if (!result.IsNullorEmpty())
                    {
                        await LyricSearcher.SaveLrcLocalAsync(title, artists, result);
                    }
                    returnData.Add("result", result);
                }
                else
                {
                    returnData.Add("result", null);
                }
                returnData.Add("status", 1);
                break;

            case "online_music":
                var action = message["action"] as string;
                switch (action)
                {
                case "search":
                    message.TryGetValue("page", out object page);
                    message.TryGetValue("count", out object count);
                    var result = await OnlineMusicSearcher.SearchAsync(message["keyword"] as string, page as int?, count as int?);

                    var resultList = new List <PropertySet>();
                    if (result == null && result.Data != null)
                    {
                        returnData.Add("status", 0);
                        break;
                    }

                    foreach (var item in result.Data.Song.ListItems)
                    {
                        var set = new PropertySet
                        {
                            ["title"]        = item.Title,
                            ["description"]  = item.SingerItems[0]?.Title,
                            ["addtional"]    = item.Album.Title,
                            ["picture_path"] = OnlineMusicSearcher.GeneratePicturePathByID(item.Album.Mid),
                            ["type"]         = "song",
                            ["id"]           = new string[] { item.Mid },
                            ["album_id"]     = item.Album.Mid
                        };
                        resultList.Add(set);
                    }


                    if (!resultList.IsNullorEmpty())
                    {
                        returnData.Add("search_result", JsonConvert.SerializeObject(resultList.ToArray()));
                        returnData.Add("status", 1);
                    }
                    break;

                case "song":
                    var song = await OnlineMusicSearcher.GetSongAsync(message["id"] as string);

                    if (song != null && !song.DataItems.IsNullorEmpty())
                    {
                        DateTime.TryParseExact(song.DataItems[0].Album.Time_Public, "yyyy-MM-dd", CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime t);

                        // TODO: property
                        var songRes = new PropertySet
                        {
                            ["title"]       = song.DataItems[0].Title,
                            ["id"]          = song.DataItems[0].Mid,
                            ["album"]       = song.DataItems[0].Album.Name,
                            ["album_id"]    = song.DataItems[0].Album.Mid,
                            ["performers"]  = song.DataItems[0].SingerItems.Select(x => x.Name).ToArray(),
                            ["year"]        = t.Year,
                            ["bit_rate"]    = (uint)message["bit_rate"] * 1000,
                            ["track"]       = song.DataItems[0].Index_Album,
                            ["track_count"] = 0,
                            ["duration"]    = TimeSpan.Zero.ToString()
                        };
                        songRes["album_artists"] = songRes["performers"];
                        var picture = OnlineMusicSearcher.GeneratePicturePathByID(song.DataItems[0].Album.Mid);
                        songRes["picture_path"] = picture;
                        songRes["file_url"]     = await OnlineMusicSearcher.GenerateFileUriByID(message["id"] as string, (uint)message["bit_rate"]);

                        songRes["file_type"] = OnlineMusicSearcher.GenerateFileTypeByID(message["id"] as string, (uint)message["bit_rate"]);
                        returnData.Add("song_result", JsonConvert.SerializeObject(songRes));
                        returnData.Add("status", 1);
                    }

                    break;

                case "album":
                    var album = await OnlineMusicSearcher.GetAlbumAsync(message["id"] as string);

                    if (album != null && album.Data != null)
                    {
                        DateTime.TryParseExact(album.Data.GetAlbumInfo.Fpublic_Time, "yyyy-MM-dd", CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime t);
                        var albumRes = new PropertySet
                        {
                            ["name"]         = album.Data.GetAlbumInfo.Falbum_Name,
                            ["desription"]   = album.Data.GetAlbumDesc.Falbum_Desc.Replace("\n", "\r\n\r\n"),
                            ["year"]         = t.Year,
                            ["track_count"]  = album.Data.GetSongInfoItems.Count,
                            ["disc_count"]   = album.Data.GetSongInfoItems.Max(x => x.Index_Cd) + 1,
                            ["picture_path"] = OnlineMusicSearcher.GeneratePicturePathByID(message["id"] as string),
                            ["genres"]       = new string[] { album.Data.Genre }
                        };
                        returnData.Add("album_result", JsonConvert.SerializeObject(albumRes));
                        returnData.Add("songs", JsonConvert.SerializeObject(album.Data.GetSongInfoItems.Select(x =>
                        {
                            var p = new PropertySet()
                            {
                                ["id"]           = x.Mid,
                                ["title"]        = x.Name,
                                ["album"]        = x.Album.Name,
                                ["album_id"]     = x.Album.Mid,
                                ["performers"]   = x.SingerItems.Select(y => y.Name).ToArray(),
                                ["year"]         = t.Year,
                                ["bit_rate"]     = Settings.Current.GetPreferredBitRate() * 1000,
                                ["picture_path"] = OnlineMusicSearcher.GeneratePicturePathByID(x.Album.Mid),
                                ["track"]        = x.Index_Album,
                                ["duration"]     = TimeSpan.Zero.ToString(),
                                ["file_url"]     = AsyncHelper.RunSync(async() => await OnlineMusicSearcher.GenerateFileUriByID(x.Mid, (uint)message["bit_rate"])),
                                ["file_type"]    = OnlineMusicSearcher.GenerateFileTypeByID(x.Mid, (uint)message["bit_rate"])
                            };
                            p["album_artists"] = p["performers"];
                            return(p);
                        })));
                        returnData.Add("album_artists", JsonConvert.SerializeObject(album.Data.SingerInfoItems.Select(x =>
                        {
                            return(new PropertySet()
                            {
                                ["name"] = x.Fsinger_Name,
                                ["id"] = x.Fsinger_Mid,
                            });
                        })));
                        returnData.Add("status", 1);
                    }
                    break;

                case "artist":
                    var artist = await OnlineMusicSearcher.GetArtistAsync(message["id"] as string);

                    break;

                default:
                    break;
                }
                break;

            case "online_meta":
                var meta_action = message["action"] as string;
                switch (meta_action)
                {
                case "album":
                    var meta_album = await LastfmSearcher.GetAlbumInfo(message["album"] as string, message["artist"] as string);

                    if (meta_album != null)
                    {
                        returnData.Add("status", 1);
                        returnData.Add("album_result", JsonConvert.SerializeObject(new PropertySet()
                        {
                            ["name"]    = meta_album.Name,
                            ["artwork"] = meta_album.AltArtwork?.OriginalString,
                            ["desc"]    = meta_album.Description,
                            ["artist"]  = meta_album.Artist,
                            ["year"]    = meta_album.Year
                        }));
                    }
                    break;

                case "artist":
                    var meta_artist = await LastfmSearcher.GetArtistInfo(message["artist"] as string);

                    if (meta_artist != null)
                    {
                        returnData.Add("status", 1);
                        returnData.Add("artist_result", JsonConvert.SerializeObject(new PropertySet()
                        {
                            ["name"]   = meta_artist.Name,
                            ["avatar"] = meta_artist.AvatarUri.OriginalString,
                            ["desc"]   = meta_artist.Description,
                        }));
                    }
                    break;
                }
                break;

            default:
                returnData.Add("status", 0);
                break;
            }


            await args.Request.SendResponseAsync(returnData);

            // Return the data to the caller.
            // Complete the deferral so that the platform knows that we're done responding to the app service call.
            // Note for error handling: this must be called even if SendResponseAsync() throws an exception.
            messageDeferral.Complete();
        }
Beispiel #18
0
        private async void OnRequestReceived(AppServiceConnection sender, AppServiceRequestReceivedEventArgs args)
        {
            // Get a deferral because we use an awaitable API below to respond to the message
            // and we don't want this call to get cancelled while we are waiting.
            var messageDeferral = args.GetDeferral();

            var message    = args.Request.Message;
            var returnData = new ValueSet();

            string command = message["q"] as string;

            switch (command)
            {
            case "lyric":
                var title = message["title"] as string;
                message.TryGetValue("artist", out object art);
                var artists = art as string;
                message.TryGetValue("album", out object alb);
                var lyalbum = alb as string;

                var localLrc = await LyricSearcher.SearchLrcLocalAsync(title, artists, lyalbum);

                if (!localLrc.IsNullorEmpty())
                {
                    returnData.Add("result", localLrc);

                    returnData.Add("status", 1);
                    break;
                }
                if (message.ContainsKey("ID") && message.ContainsKey("service") && message["service"] as string == "Aurora.Music.Services")
                {
                    var result = await LyricSearcher.GetSongLrcByID(message["ID"] as string);

                    if (!result.IsNullorEmpty())
                    {
                        await LyricSearcher.SaveLrcLocalAsync(title, artists, lyalbum, result);

                        returnData.Add("result", result);
                        returnData.Add("status", 1);
                        break;
                    }
                }
                var substitutes = await LyricSearcher.GetSongLrcListAsync(title, artists);

                if (!substitutes.IsNullorEmpty())
                {
                    var result = await ApiRequestHelper.HttpGet(substitutes.First().Value);

                    if (!result.IsNullorEmpty())
                    {
                        result = HttpUtility.HtmlDecode(result);
                        await LyricSearcher.SaveLrcLocalAsync(title, artists, lyalbum, result);

                        returnData.Add("result", result);
                        returnData.Add("status", 1);
                    }
                    else
                    {
                        returnData.Add("result", null);
                        returnData.Add("status", 0);
                    }
                }
                else
                {
                    returnData.Add("result", null);
                    returnData.Add("status", 0);
                }
                break;

            case "online_music":
                var action = message["action"] as string;
                switch (action)
                {
                case "search":
                    var result = await OnlineMusicSearcher.SearchAsync(message["keyword"] as string);

                    var resultList = new List <PropertySet>();
                    if (result == null || result.Data == null)
                    {
                        returnData.Add("status", 0);
                        break;
                    }

                    foreach (var item in result.Data.Song.ListItems)
                    {
                        var set = new PropertySet
                        {
                            ["title"]        = item.Title,
                            ["description"]  = item.SingerItems[0]?.Name,
                            ["addtional"]    = item.AlbumName,
                            ["picture_path"] = OnlineMusicSearcher.GeneratePicturePathByID(item.AlbumMid),
                            ["type"]         = "song",
                            ["id"]           = new string[] { item.Mid },
                            ["album_id"]     = item.AlbumMid
                        };
                        resultList.Add(set);
                    }


                    if (!resultList.IsNullorEmpty())
                    {
                        returnData.Add("search_result", JsonConvert.SerializeObject(resultList.ToArray()));
                        returnData.Add("status", 1);
                    }
                    break;

                case "song":
                    var song = await OnlineMusicSearcher.GetSongAsync(message["id"] as string);

                    if (song != null && !song.DataItems.IsNullorEmpty())
                    {
                        DateTime.TryParseExact(song.DataItems[0].Album.Time_Public, "yyyy-MM-dd", CultureInfo.InvariantCulture, DateTimeStyles.None, out var t);

                        // TODO: property
                        var songRes = new PropertySet
                        {
                            ["title"]       = song.DataItems[0].Title,
                            ["id"]          = song.DataItems[0].Mid,
                            ["album"]       = song.DataItems[0].Album.Name,
                            ["album_id"]    = song.DataItems[0].Album.Mid,
                            ["performers"]  = song.DataItems[0].SingerItems.Select(x => x.Name).ToArray(),
                            ["year"]        = t.Year,
                            ["bit_rate"]    = Settings.Current.GetPreferredBitRate() * 1000,
                            ["track"]       = song.DataItems[0].Index_Album,
                            ["track_count"] = 0,
                            ["duration"]    = TimeSpan.FromSeconds(song.DataItems[0].Interval).ToString()
                        };
                        songRes["album_artists"] = songRes["performers"];
                        var picture = OnlineMusicSearcher.GeneratePicturePathByID(song.DataItems[0].Album.Mid);
                        songRes["picture_path"] = picture;
                        songRes["file_url"]     = await OnlineMusicSearcher.GenerateFileUriByID(message["id"] as string, Settings.Current.GetPreferredBitRate());

                        songRes["file_type"] = OnlineMusicSearcher.GenerateFileTypeByID(message["id"] as string, Settings.Current.GetPreferredBitRate());
                        returnData.Add("song_result", JsonConvert.SerializeObject(songRes));
                        returnData.Add("status", 1);
                    }

                    break;

                case "album":
                    var album = await OnlineMusicSearcher.GetAlbumAsync(message["id"] as string);

                    if (album != null && album.Data != null)
                    {
                        DateTime.TryParseExact(album.Data.GetAlbumInfo.Fpublic_Time, "yyyy-MM-dd", CultureInfo.InvariantCulture, DateTimeStyles.None, out var t);
                        var albumRes = new PropertySet
                        {
                            ["name"]         = album.Data.GetAlbumInfo.Falbum_Name,
                            ["description"]  = album.Data.GetAlbumDesc.Falbum_Desc.Replace("\n", "\r\n\r\n"),
                            ["year"]         = t.Year,
                            ["track_count"]  = album.Data.GetSongInfoItems.Count,
                            ["disc_count"]   = album.Data.GetSongInfoItems.Max(x => x.Index_Cd) + 1,
                            ["picture_path"] = OnlineMusicSearcher.GeneratePicturePathByID(message["id"] as string),
                            ["genres"]       = new string[] { album.Data.Genre }
                        };
                        returnData.Add("album_result", JsonConvert.SerializeObject(albumRes));
                        returnData.Add("songs", JsonConvert.SerializeObject(album.Data.GetSongInfoItems.Select(x =>
                        {
                            var p = new PropertySet()
                            {
                                ["id"]           = x.Mid,
                                ["title"]        = x.Name,
                                ["album"]        = x.Album.Name,
                                ["album_id"]     = x.Album.Mid,
                                ["performers"]   = x.SingerItems.Select(y => y.Name).ToArray(),
                                ["year"]         = t.Year,
                                ["bit_rate"]     = Settings.Current.GetPreferredBitRate() * 1000,
                                ["picture_path"] = OnlineMusicSearcher.GeneratePicturePathByID(x.Album.Mid),
                                ["track"]        = x.Index_Album,
                                ["duration"]     = TimeSpan.FromSeconds(x.Interval).ToString(),
                                ["file_url"]     = AsyncHelper.RunSync(async() => await OnlineMusicSearcher.GenerateFileUriByID(x.Mid, Settings.Current.GetPreferredBitRate())),
                                ["file_type"]    = OnlineMusicSearcher.GenerateFileTypeByID(x.Mid, Settings.Current.GetPreferredBitRate())
                            };
                            p["album_artists"] = p["performers"];
                            return(p);
                        })));
                        returnData.Add("album_artists", JsonConvert.SerializeObject(album.Data.SingerInfoItems.Select(x =>
                        {
                            return(new PropertySet()
                            {
                                ["name"] = x.Fsinger_Name,
                                ["id"] = x.Fsinger_Mid,
                            });
                        })));
                        returnData.Add("status", 1);
                    }
                    break;

                case "artist":
                    var artist = await OnlineMusicSearcher.GetArtistAsync(message["id"] as string);

                    break;

                case "require_playlist":
                    var playlists = await OnlineMusicSearcher.GetPlaylist((int)message["offset"], (int)message["count"]);

                    if (playlists != null && playlists.Data != null)
                    {
                        returnData.Add("status", 1);
                        returnData.Add("playlists", JsonConvert.SerializeObject(playlists.Data.ListItems.Select(a =>
                        {
                            return(new PropertySet()
                            {
                                ["title"] = a.Dissname,
                                ["addtional"] = DateTime.ParseExact(a.Createtime, "yyyy-M-dd", CultureInfo.InvariantCulture).PubDatetoString(Consts.Today, "ddd", "M/dd ddd", "yy/M/dd", Consts.Next, Consts.Last),
                                ["description"] = a.Creator.Name,
                                ["id"] = a.Dissid,
                                ["picture_path"] = a.Imgurl
                            });
                        })));
                    }
                    break;

                case "show_playlist":
                    var playlist = await OnlineMusicSearcher.ShowPlaylist(message["id"] as string);

                    if (playlist != null && playlist.CdlistItems != null)
                    {
                        returnData.Add("status", 1);
                        returnData.Add("playlist_result", JsonConvert.SerializeObject(new PropertySet()
                        {
                            ["name"]         = playlist.CdlistItems[0].Dissname,
                            ["description"]  = System.Net.WebUtility.HtmlDecode(playlist.CdlistItems[0].Desc).Replace("<br>", Environment.NewLine + Environment.NewLine).Replace("<br/>", Environment.NewLine + Environment.NewLine).Replace("<br >", Environment.NewLine + Environment.NewLine).Replace("<br />", Environment.NewLine + Environment.NewLine),
                            ["id"]           = playlist.CdlistItems[0].Disstid,
                            ["picture_path"] = playlist.CdlistItems[0].Logo,
                            ["year"]         = 0,
                            ["disc_count"]   = 1,
                            ["track_count"]  = playlist.CdlistItems[0].SongList.Count,
                            ["genres"]       = playlist.CdlistItems[0].TagsItems.Select(a => a.Name)
                        }
                                                                                      ));

                        returnData.Add("songs", JsonConvert.SerializeObject(playlist.CdlistItems[0].SongList.Select((x, index) =>
                        {
                            var p = new PropertySet()
                            {
                                ["id"]           = x.Songmid,
                                ["title"]        = x.Songname,
                                ["album"]        = x.Albumname,
                                ["album_id"]     = x.Albumid,
                                ["performers"]   = x.SingerItems.Select(y => y.Name).ToArray(),
                                ["year"]         = 0,
                                ["bit_rate"]     = Settings.Current.GetPreferredBitRate() * 1000,
                                ["picture_path"] = OnlineMusicSearcher.GeneratePicturePathByID(x.Albummid),
                                ["track"]        = index + 1,
                                ["duration"]     = TimeSpan.FromSeconds(x.Interval).ToString(),
                                ["file_url"]     = AsyncHelper.RunSync(async() => await OnlineMusicSearcher.GenerateFileUriByID(x.Songmid, Settings.Current.GetPreferredBitRate())),
                                ["file_type"]    = OnlineMusicSearcher.GenerateFileTypeByID(x.Songmid, Settings.Current.GetPreferredBitRate())
                            };
                            p["album_artists"] = p["performers"];
                            return(p);
                        })));
                        returnData.Add("album_artists", JsonConvert.SerializeObject(
                                           new PropertySet[] {
                            new PropertySet()
                            {
                                ["name"] = playlist.CdlistItems[0].Nickname,
                                ["id"]   = playlist.CdlistItems[0].Singerid,
                            }
                        }
                                           ));
                    }
                    break;

                default:
                    break;
                }
                break;

            case "online_meta":
                var meta_action = message["action"] as string;
                switch (meta_action)
                {
                case "album":
                    var meta_album = await LastfmSearcher.GetAlbumInfo(message["album"] as string, message["artist"] as string);

                    if (meta_album != null)
                    {
                        returnData.Add("status", 1);
                        returnData.Add("album_result", JsonConvert.SerializeObject(new PropertySet()
                        {
                            ["name"]    = meta_album.Name,
                            ["artwork"] = meta_album.AltArtwork?.OriginalString,
                            ["desc"]    = meta_album.Description,
                            ["artist"]  = meta_album.Artist,
                            ["year"]    = meta_album.Year
                        }));
                    }
                    break;

                case "artist":
                    var meta_artist = await LastfmSearcher.GetArtistInfo(message["artist"] as string);

                    if (meta_artist != null)
                    {
                        returnData.Add("status", 1);
                        returnData.Add("artist_result", JsonConvert.SerializeObject(new PropertySet()
                        {
                            ["name"]   = meta_artist.Name,
                            ["avatar"] = meta_artist.AvatarUri?.OriginalString,
                            ["desc"]   = meta_artist.Description,
                        }));
                    }
                    break;
                }
                break;

            default:
                returnData.Add("status", 0);
                break;
            }


            await args.Request.SendResponseAsync(returnData);

            // Return the data to the caller.
            // Complete the deferral so that the platform knows that we're done responding to the app service call.
            // Note for error handling: this must be called even if SendResponseAsync() throws an exception.
            messageDeferral.Complete();
        }