/// <summary> /// Пытается скачать и распарсить страницу альбома или песни по указаннному URI, после чего возвратить результат /// </summary> /// <param name="PageURI">URI страницы, по которой должен выполняться запрос</param> /// <param name="UserAgent">User-Agent, с которым будет исполнен запрос</param> /// <param name="DownloadCover">Определяет, необходимо ли загружать обложку альбома или песни</param> /// <param name="InvokeEvents">Определяет, необходимо ли вызывать события в процессе выполнения</param> /// <param name="CancToken"></param> /// <returns>Модель, соответсующая альбому или песни, или же NULL в случае провала парсинга</returns> public static ACommonData TryGrabAndParsePage (Uri PageURI, String UserAgent, Boolean DownloadCover, Boolean InvokeEvents, CancellationToken CancToken) { Task<HtmlAgilityPack.HtmlDocument> temp_task = Task.Run<HtmlAgilityPack.HtmlDocument> (() => CoreInternal.TryGrabPageWithCancellation(PageURI, UserAgent, CancToken), CancToken); try { temp_task.Wait(CancToken); } catch (InvalidOperationException ioex) { if (InvokeEvents == true) { Core.OnException.Invoke(ioex.InnerException); } return null; } catch (AggregateException aex) { if (InvokeEvents == true) { Core.OnException.Invoke(aex.InnerException); } return null; } catch (OperationCanceledException ocex) { var temp = ocex.TotalMessage(); CancToken.ThrowIfCancellationRequested(); } HtmlAgilityPack.HtmlDocument HTML_doc = temp_task.Result; if (InvokeEvents == true) { Core.PageWasDownloaded.Invoke(HTML_doc); } ParsedItemType album_or_song = CoreInternal.DetectItemType(HTML_doc); if (album_or_song == ParsedItemType.Unknown) { if (InvokeEvents == true) { Core.OnException.Invoke(new InvalidOperationException(String.Format( "Страница, полученная по URI '{0}' с кодировкой '{1}', не может быть распознана как страница альбома или песни", PageURI.ToString(), HTML_doc.Encoding.ToString()))); } return null; } if (InvokeEvents == true) { Core.ItemWasDetected.Invoke(album_or_song); } CancToken.ThrowIfCancellationRequested(); ICommonHeader header; if (album_or_song == ParsedItemType.Album) { try { header = CoreInternal.ParseAlbumHeader(HTML_doc); } catch (Exception ex) { if (InvokeEvents == true) { Core.OnException.Invoke(new InvalidOperationException( String.Format("Произошла ошибка при парсинге страницы альбома, полученной по URI '{0}'", PageURI), ex)); } return null; } } else { try { header = CoreInternal.ParseOneSongHeader(HTML_doc); } catch (Exception ex) { if (InvokeEvents == true) { Core.OnException.Invoke(new InvalidOperationException( String.Format("Произошла ошибка при парсинге страницы песни, полученной по URI '{0}'", PageURI), ex)); } return null; } } if (InvokeEvents == true) { Core.HeaderWasParsed.Invoke(header); } CancToken.ThrowIfCancellationRequested(); DownloadedFile cover_file = null; Bitmap cover_image = null; if (DownloadCover == true && header.CoverImageURI != null) { String err_mess; cover_file = CoreInternal.TryDownloadFile(header.CoverImageURI, header.PageURI, UserAgent, out err_mess); if (cover_file != null) { cover_image = CoreInternal.TryConvertFileToImage(cover_file); if (InvokeEvents == true) { Core.CoverWasAcquired.Invoke(cover_file, cover_image); } } } CancToken.ThrowIfCancellationRequested(); ACommonData output; if (album_or_song == ParsedItemType.Album) { AlbumHeader ah = (AlbumHeader) header; List<OneSongHeader> songs; try { songs = CoreInternal.ParseAllSongsInAlbum(HTML_doc, ah); } catch (Exception ex) { if (InvokeEvents == true) { Core.OnException.Invoke(new InvalidOperationException( String.Format("Произошла ошибка при парсинге списка песен для альбома, полученного по URI '{0}'", PageURI), ex)); } return null; } output = new ParsedAlbum(ah, songs, cover_file, cover_image); } else { OneSongHeader sh = (OneSongHeader) header; Uri song_URI; try { song_URI = CoreInternal.ExtractDownloadSongURI(HTML_doc); } catch (Exception ex) { if (InvokeEvents == true) { Core.OnException.Invoke(new InvalidOperationException(String.Format( "Произошла ошибка при парсинге ссылки на скачку файла песни, страница которой получена по URI '{0}'", PageURI), ex)); } return null; } Uri album_URI; try { album_URI = CoreInternal.ExtractAlbumURIFromSongPage(HTML_doc); } catch (Exception ex) { if (InvokeEvents == true) { Core.OnException.Invoke(new InvalidOperationException(String.Format( "Произошла ошибка при парсинге ссылки на страницу альбома песни, страница которой получена по URI '{0}'", PageURI), ex)); } return null; } output = new ParsedSong(sh, song_URI, album_URI, cover_file, cover_image); } if (InvokeEvents == true) { Core.WorkIsDone.Invoke(output); } return output; }
private void RenderSong(ParsedSong song) { if (this.InvokeRequired == false) { this.gb_Album_Header.Visible = false; this.gb_SongHeader.Visible = true; this.btn_GoToAlbumPage.Enabled = true; this.tb_RO_Title.Text = song.Header.Album; this.tb_RO_Genre.Text = song.Genre; this.tb_RO_Artist.Text = song.Artist; this.tb_RO_Format.Text = song.Header.Format; this.tb_RO_Uploader.Text = song.Uploader; this.tb_RO_AlbumURI.Text = song.AlbumLink.ToString(); this.RenderImage(song); this.dgv_List.Rows.Clear(); this.dgv_List.Rows.Add(song.Header.Number, song.Header.Artist, song.Header.Name, song.Header.Duration, song.Header.Size, song.Header.Bitrate, true); if (song.Header.IsAvailableForDownload == false) { this.gb_FooterButtons.Enabled = false; DataGridViewRow drvr = this.dgv_List.Rows[0]; drvr.DefaultCellStyle = new DataGridViewCellStyle() { BackColor = Color.LightPink }; drvr.Cells["col_Download"].ReadOnly = true; drvr.Cells["col_Download"].Value = false; this.SetOrAppendMessage(true, String.Format( "Песня '{0}. {1}' помечена на сайте как таковая, файл которой утерян", song.Header.Number, song.Header.Name)); this.UpdateStatus(5); } } else { this.Invoke((Action<ParsedSong>)this.RenderSong, song); } }
/// <summary> /// Пытается асинхронно, не блокируя основной поток выполнения, скачать одну указанную песню, /// информация о которой получена в процессе парсинга страницы песни. В случае ошибки возвращает NULL. /// </summary> /// <param name="Song"></param> /// <param name="UserAgent"></param> /// <returns></returns> public static async Task<DownloadedFile> DownloadOneSongAsync(ParsedSong Song, String UserAgent) { if (Song == null) { throw new ArgumentNullException("Song"); } if (UserAgent == null) { throw new ArgumentNullException("UserAgent"); } return await CoreInternal.TryDownloadFileAsync(Song.DownloadLink, Song.Header.SongPageURI, UserAgent); }