/// <summary> /// HttpWebRequest POST request - Recursively fetches all the songs of an artist from YouTube Music's 'Upload' section /// </summary> /// <param name="cookieValue">Cookie from a previous YouTube Music sign in via this application (stored in the database)</param> /// <param name="browseId">YouTube Music's navigation ID for an individual artist, retreived from 'GetArtists' request</param> /// <param name="songs">Input ArtistCache 'Songs' object (should be empty when initialising - this is a recursive method)</param> /// <param name="continuationToken">Token from YouTube Music indicated more results to fetch, and the token to get them /// (shoult be empty when initialising - this is a recursive method)</param> /// <returns>ArtistCache object</returns> public static AlbumSongCollection GetArtistSongs( string cookieValue, string browseId, AlbumSongCollection albumSongCollection = null, string continuationToken = null) { if (albumSongCollection == null) { albumSongCollection = new AlbumSongCollection(); } if (albumSongCollection.Songs == null) { albumSongCollection.Songs = new SongCollection(); } if (albumSongCollection.Albums == null) { albumSongCollection.Albums = new AlbumCollection(); } try { var request = (HttpWebRequest)WebRequest.Create(Global.YTMusicBaseUrl + "browse" + (string.IsNullOrEmpty(continuationToken) ? "" : "?ctoken=" + continuationToken + "&continuation=" + continuationToken) + (string.IsNullOrEmpty(continuationToken) ? Global.YTMusicParams : Global.YTMusicParams.Replace('?', '&'))); request = AddStandardHeaders(request, cookieValue); request.ContentType = "application/json; charset=UTF-8"; request.Headers["X-Goog-AuthUser"] = "******"; request.Headers["x-origin"] = "https://music.youtube.com"; request.Headers["X-Goog-Visitor-Id"] = Global.GoogleVisitorId; request.Headers["Authorization"] = GetAuthorisation(GetSAPISIDFromCookie(cookieValue)); var context = JsonConvert.DeserializeObject <BrowseArtistRequestContext>( SafeFileStream.ReadAllText( Path.Combine( Global.WorkingDirectory, @"AppData\get_artist_context.json"))); context.browseId = string.Format("{0}", browseId); byte[] postBytes = GetPostBytes(JsonConvert.SerializeObject(context)); request.ContentLength = postBytes.Length; using (var requestStream = request.GetRequestStream()) { requestStream.Write(postBytes, 0, postBytes.Length); requestStream.Close(); } postBytes = null; using (var response = (HttpWebResponse)request.GetResponse()) { string result; using (var brotli = new Brotli.BrotliStream(response.GetResponseStream(), System.IO.Compression.CompressionMode.Decompress, true)) { var streamReader = new StreamReader(brotli); result = streamReader.ReadToEnd(); } if (string.IsNullOrEmpty(continuationToken)) { albumSongCollection = GetInitalArtistSongs(albumSongCollection, result, out string continuation); if (!string.IsNullOrEmpty(continuation)) { return(GetArtistSongs(cookieValue, browseId, albumSongCollection, continuation)); } } else { albumSongCollection = GetContinuationArtistSongs(albumSongCollection, result, out string continuation); if (!string.IsNullOrEmpty(continuation)) { return(GetArtistSongs(cookieValue, browseId, albumSongCollection, continuation)); } } } } catch (Exception e) { var _ = e; #if DEBUG Console.Out.WriteLine("GetArtistSongs: " + e.Message); #endif } return(albumSongCollection); }
private void BindAlbumNodesFromSelect( TreeNode artistNode, AlbumSongCollection albumSongCollection, bool expand = true, bool showFetchedMessage = true, bool isDeleting = false) { if (tvUploads.InvokeRequired) { var d = new BindAlbumNodesFromSelectDelegate(BindAlbumNodesFromSelect); Invoke(d, new object[] { artistNode, albumSongCollection, expand, showFetchedMessage, isDeleting }); } else { SetTreeViewEnabled(false); if (artistNode != null) { var albumNodes = new List <TreeNode>(); foreach (var album in albumSongCollection.Albums) { var songNodes = new List <TreeNode>(); string releaseMbId = string.Empty; foreach (var song in album.Songs) { var musicFile = MainForm.MusicFileRepo.LoadFromEntityId(song.EntityId).Result; string databaseExistenceText = "Not found or not mapped"; if (musicFile != null && musicFile.Id != 0 && musicFile.Id != -1) { databaseExistenceText = $"Exists ({musicFile.Id})"; releaseMbId = string.IsNullOrEmpty(musicFile.ReleaseMbId) ? releaseMbId : musicFile.ReleaseMbId; } songNodes.Add(new TreeNode { Name = song.EntityId, Text = song.Title, Tag = Tag = new MusicManageTreeNodeModel { NodeType = MusicManageTreeNodeModel.NodeTypeEnum.Song, ArtistTitle = ((MusicManageTreeNodeModel)artistNode.Tag).ArtistTitle, AlbumTitle = album.Title, SongTitleOrDescription = song.Title, Duration = song.Duration, CovertArtUrl = song.CoverArtUrl, DatabaseExistence = databaseExistenceText, MbId = musicFile == null || string.IsNullOrEmpty(musicFile.MbId) ? "-" : musicFile.MbId, EntityOrBrowseId = song.EntityId, Uploaded = musicFile == null ? "-" : musicFile.LastUpload.ToString("dd/MM/yyyy HH:mm") } }); } var albumNode = new TreeNode { Name = Guid.NewGuid().ToString(), Text = album.Title, Tag = Tag = new MusicManageTreeNodeModel { NodeType = MusicManageTreeNodeModel.NodeTypeEnum.Album, ArtistTitle = ((MusicManageTreeNodeModel)artistNode.Tag).ArtistTitle, AlbumTitle = album.Title, CovertArtUrl = album.CoverArtUrl, DatabaseExistence = string.IsNullOrEmpty(releaseMbId) ? "Not found or not mapped" : "Tracks exists for this album", MbId = string.IsNullOrEmpty(releaseMbId) ? "-" : releaseMbId, EntityOrBrowseId = album.EntityId, Uploaded = "-" } }; albumNode.Nodes.AddRange(songNodes.ToArray()); albumNode.Text = albumNode.Text + " (" + songNodes.Count + ")"; albumNodes.Add(albumNode); } ; AddChildNodes(artistNode, albumNodes); int albumCount = albumSongCollection.Albums.Count; int songCount = albumSongCollection.Songs.Count; string albumText = "albums"; string songText = "tracks"; if (albumCount == 1) { albumText = "album"; } if (songCount == 1) { songText = "track"; } if (showFetchedMessage) { AppendUpdatesText($"Fetched {albumCount} {albumText}, {songCount} {songText}.", ColourHelper.HexStringToColor("#0d5601")); } artistNode.Text = artistNode.Text + " (" + artistNode.Nodes.Count + ")"; if (expand) { artistNode.Expand(); } if (artistNode.Checked) { CheckAllChildNodes(artistNode, true); } if (!isDeleting) { SetMusicDetails((MusicManageTreeNodeModel)artistNode.Tag); } } if (!isDeleting) { ShowPreloader(false); SetTreeViewEnabled(true); DisableAllActionButtons(false); } } }
private static AlbumSongCollection GetContinuationArtistSongs( AlbumSongCollection albumSongCollection, string httpResponseResults, out string continuation) { continuation = string.Empty; var jo = JObject.Parse(httpResponseResults); var musicShelfRendererTokens = jo.Descendants().Where(t => t.Type == JTokenType.Property && ((JProperty)t).Name == "musicShelfContinuation") .Select(p => ((JProperty)p).Value) .ToList(); var result = JsonConvert.DeserializeObject <BrowseArtistResultsContinuationContext>(httpResponseResults); foreach (var token in musicShelfRendererTokens) { var msr = token.ToObject <BrowseArtistResultsContext.Musicshelfrenderer>(); if (msr.continuations != null && msr.continuations.Length > 0 && msr.continuations[0].nextContinuationData != null && msr.continuations[0].nextContinuationData.continuation != null) { continuation = msr.continuations[0].nextContinuationData.continuation; } foreach (var content in msr.contents) { try { string coverArtUrl = content.musicResponsiveListItemRenderer .thumbnail .musicThumbnailRenderer .thumbnail .thumbnails[0].url; var song = new Song { Title = content.musicResponsiveListItemRenderer .flexColumns[0] .musicResponsiveListItemFlexColumnRenderer .text .runs[0] .text, CoverArtUrl = coverArtUrl, Duration = content.musicResponsiveListItemRenderer .fixedColumns[0] .musicResponsiveListItemFixedColumnRenderer .text .runs[0] .text, VideoId = content.musicResponsiveListItemRenderer .flexColumns[0] .musicResponsiveListItemFlexColumnRenderer .text .runs[0] .navigationEndpoint .watchEndpoint .videoId, EntityId = GetTrackEntityID(content.musicResponsiveListItemRenderer .menu .menuRenderer) }; bool isSingle = true; string albumTitle = "[Singles]"; if (content.musicResponsiveListItemRenderer .flexColumns[2] .musicResponsiveListItemFlexColumnRenderer .text .runs != null) { isSingle = false; albumTitle = content.musicResponsiveListItemRenderer .flexColumns[2] .musicResponsiveListItemFlexColumnRenderer .text .runs[0] .text; } if (!albumSongCollection.Albums.AlbumHashSet.Contains(albumTitle)) { albumSongCollection.Albums.AlbumHashSet.Add(albumTitle); albumSongCollection.Albums.Add(new Alumb { Title = albumTitle, CoverArtUrl = coverArtUrl, Songs = new SongCollection(), EntityId = isSingle ? "[Single]" : GetAlbumEntityID(content.musicResponsiveListItemRenderer .flexColumns[2] .musicResponsiveListItemFlexColumnRenderer) }); } albumSongCollection.Songs.Add(song); if (albumSongCollection.Albums.Where(m => m.Title == albumTitle).Any()) { albumSongCollection.Albums.Where(m => m.Title == albumTitle).FirstOrDefault().Songs.Add(song); } } catch (Exception e) { var _ = e; #if DEBUG Console.Out.WriteLine(e.Message); #endif } } } return(albumSongCollection); }
private void BindAlbumNodesFromArtistBind( TreeNode artistNode, AlbumSongCollection albumSongCollection, bool expand = true, bool showFetchedMessage = true) { var albumNodes = new List <TreeNode>(); foreach (var album in albumSongCollection.Albums) { var songNodes = new List <TreeNode>(); string releaseMbId = string.Empty; album.Songs.AsParallel().ForAllInApproximateOrder(song => { var musicFile = MainForm.MusicFileRepo.LoadFromEntityId(song.EntityId).Result; string databaseExistenceText = "Not found or not mapped"; if (musicFile != null && musicFile.Id != 0 && musicFile.Id != -1) { databaseExistenceText = $"Exists ({musicFile.Id})"; releaseMbId = string.IsNullOrEmpty(musicFile.ReleaseMbId) ? releaseMbId : musicFile.ReleaseMbId; } songNodes.Add(new TreeNode { Name = song.EntityId, Text = song.Title, Tag = Tag = new MusicManageTreeNodeModel { NodeType = MusicManageTreeNodeModel.NodeTypeEnum.Song, ArtistTitle = ((MusicManageTreeNodeModel)artistNode.Tag).ArtistTitle, AlbumTitle = album.Title, SongTitle = song.Title, Duration = song.Duration, CovertArtUrl = song.CoverArtUrl, DatabaseExistence = databaseExistenceText, MbId = musicFile == null || string.IsNullOrEmpty(musicFile.MbId) ? "-" : musicFile.MbId, EntityOrBrowseId = song.EntityId, Uploaded = musicFile == null ? "-" : musicFile.LastUpload.ToString("dd/MM/yyyy HH:mm") } }); }); var albumNode = new TreeNode { Name = Guid.NewGuid().ToString(), Text = album.Title, Tag = Tag = new MusicManageTreeNodeModel { NodeType = MusicManageTreeNodeModel.NodeTypeEnum.Album, ArtistTitle = ((MusicManageTreeNodeModel)artistNode.Tag).ArtistTitle, AlbumTitle = album.Title, CovertArtUrl = album.CoverArtUrl, DatabaseExistence = string.IsNullOrEmpty(releaseMbId) ? "Not found or not mapped" : "Tracks exists for this album", MbId = string.IsNullOrEmpty(releaseMbId) ? "-" : releaseMbId, EntityOrBrowseId = album.EntityId, Uploaded = "-" } }; albumNode.Nodes.AddRange(songNodes.ToArray()); albumNode.Text = albumNode.Text + " (" + songNodes.Count + ")"; albumNodes.Add(albumNode); } AddChildNodesFromArtistBind(artistNode, albumNodes); int albumCount = albumSongCollection.Albums.Count; int songCount = albumSongCollection.Songs.Count; string albumText = "albums"; string songText = "tracks"; if (albumCount == 1) { albumText = "album"; } if (songCount == 1) { songText = "track"; } if (showFetchedMessage) { AppendUpdatesText($"Fetched {albumCount} {albumText}, {songCount} {songText}.", ColourHelper.HexStringToColor("#0d5601")); } artistNode.Text = artistNode.Text + " (" + artistNode.Nodes.Count + ")"; if (expand) { artistNode.Expand(); } if (artistNode.Checked) { CheckAllChildNodes(artistNode, true); } }