private List <Img> ParsingImgs(HtmlNode mainNode, ReadyPost readyPost) { // История следующая. На странице с раздачей могут быть вставлены полноразмерные копии изображений // по прямым ссылкам, в целях оформления внешнего вида (1). И также могут быть вставлены миниатюры изображений // - скриншоты программы, которые обернуты снаружи ссылкой (2). Так же мы изначально получаем страницу, // в которой сверуты все спойлеры. Содержимое спойлера на странице - просто строка, поэтому мы не получаем // ссылки изображений, которые находяться под спойром. Этот случай нужно парсить отдельно (3). List <Img> imgs; // Парсим изображения для внешнего вида (1) HtmlNodeCollection nodesImg = mainNode.SelectNodes(@"//table[@id=""details""]/tr[1]/td[2]//img[not(parent::a)]"); imgs = GetImgs(nodesImg, TImg.View, readyPost); // Парсим изображения миниатюры/скриншоты (2) nodesImg = mainNode.SelectNodes(@"//table[@id=""details""]//tr[1]//td[2]//img[(parent::a)]"); var tmpImg = GetImgs(nodesImg, TImg.Screenshot, readyPost); imgs.AddRange(tmpImg); // Парсим изображения из спойлеров (3) if (readyPost.Spoilers != null) { tmpImg = GetImgsFromSpoilers(readyPost); imgs.AddRange(tmpImg); } return(imgs); }
/// <summary> /// Добавляет новую запись готового поста в бд /// </summary> /// <param name="readyPost">Готовый пост, который нужно добавить</param> /// <returns></returns> public int AddReady(ReadyPost readyPost) { Db.ReadyPost.Add(readyPost); int result = Db.SaveChanges(); return(result); }
private void DownloaderItem_FinishDownload(object sender, DownloaderHtmlPageArgs e) { HtmlNode mainNode = e.Page.DocumentNode.SelectSingleNode(@"//table[@id=""details""]/tr[1]/td[2]"); if (mainNode != null) { // Важно чтобы сначала вызывался парсинг спойлеров, а затем только парсинг описание // Порядок вызова остальных функций не важен. Читай комментарий в функции со спойлерами ReadyPost readyPost = new ReadyPost(); readyPost.Spoilers = ParsingSpoilers(mainNode, readyPost); readyPost.Imgs = ParsingImgs(mainNode, readyPost); readyPost.Description = HttpUtility.HtmlDecode(mainNode.InnerHtml); readyPost.Name = ParsingName(mainNode); readyPost.TorrentUrl = ParsingTorrentUrl(mainNode); readyPost.FoundPost = _parentItem; readyPost.FoundedTime = DateTime.Now; ReadyPostArgs eventArgs = new ReadyPostArgs(readyPost); ReadyPostsReceived?.Invoke(this, eventArgs); } else { MessageService.ShowError("Ошибка на этапе парсинга раздачи. mainNode = null"); } }
/// <summary> /// Выдергивает спойлеры со страницы /// </summary> /// <param name="mainNode">Кусок html, в которм будет производится поиск</param> /// <param name="readyPost">Пост, к которому будет относится спойлер</param> /// <returns></returns> private List <Spoiler> ParsingSpoilers(HtmlNode mainNode, ReadyPost readyPost) { // выбираем все спойлеры. В нодах оказывается храниться весь документ // вне зависимости от того, что и когда мы парсили // поэтому здесь поиск xpath опять идет от корня HtmlNodeCollection spoilersNode = mainNode.SelectNodes(@"//table[@id=""details""]/tr[1]/td[2]//div[@class=""hidewrap""]"); if (spoilersNode != null) { List <Spoiler> spoilers = new List <Spoiler>(); foreach (var item in spoilersNode) { Spoiler itemHtml = new Spoiler() { Header = item.FirstChild.InnerText, Body = item.LastChild.InnerHtml, ReadyPost = readyPost, }; spoilers.Add(itemHtml); // Чтобы корректно спарсить описание, необходимо удалить все спойлеры // По этой же причине не используется linq item.RemoveAll(); } return(spoilers); } else { MessageService.ShowError("Ошибка при парсинге спойлеров раздачи"); return(null); } }
/// <summary> /// Получает полноценный пост, по найденному посту /// </summary> /// <param name="item">Найденный пост</param> /// <returns></returns> public ReadyPost GetItem(FoundPost item) { DownloaderThroughTor downloader = new DownloaderThroughTor(); HtmlDocument document = downloader.Page(new Uri(item.Uri)); HtmlNode mainNode = document.DocumentNode.SelectSingleNode(@"//table[@id=""details""]/tr[1]/td[2]"); if (mainNode != null) { // Важно чтобы сначала вызывался парсинг спойлеров, а затем только парсинг описания // Порядок вызова остальных функций не важен. Читай комментарий в методе со спойлерами ReadyPost readyPost = new ReadyPost(); readyPost.Spoilers = ParsingSpoilers(mainNode, readyPost); readyPost.Imgs = ParsingImgs(mainNode, readyPost); readyPost.Description = HttpUtility.HtmlDecode(mainNode.InnerHtml); readyPost.Name = ParsingName(mainNode); readyPost.TorrentUrl = ParsingTorrentUrl(mainNode); readyPost.FoundPost = item; readyPost.FoundedTime = DateTime.Now; return(readyPost); } else { MessageService.ShowError("Ошибка на этапе парсинга раздачи. mainNode = null"); return(null); } }
private void _formSelectPost_GridNotPublishedClick(object sender, GridNotPublishedClickArgs e) { DataBaseSoftController dataBase = new DataBaseSoftController(); ReadyPost readyPost = dataBase.GetBrowserPost(e.IdReadyPost); PostController postController = new PostController(); postController.PostComplete += PostController_PostComplete; postController.GetBrowserPost(readyPost); }
/// <summary> /// Добавляет спойлеры к описанию /// </summary> /// <param name="readyPost">Пост из базы данных</param> private void SetSpoilers(ReadyPost readyPost) { string spoilersResult = ""; foreach (var item in readyPost.Spoilers) { spoilersResult += $"[spoiler={item.Header}]{item.Body}[/spoiler]"; } BrowserPostReady.Description += spoilersResult; }
/// <summary> /// Получает готовый пост по id /// </summary> /// <param name="idReadyPost">id поста который необходимо выложить</param> /// <returns>Готовый пост</returns> public ReadyPost GetBrowserPost(int idReadyPost) { var queryPost = from el in Db.ReadyPost where el.idReadyPost == idReadyPost select el; ReadyPost readyPost = queryPost.Single(); return(readyPost); }
public void GetBrowserPost(ReadyPost readyPost) { string description = DeleteImgs(readyPost.Description); description = DeleteSpace(description); BrowserPostReady.IdReadyPost = readyPost.idReadyPost; BrowserPostReady.Name = readyPost.Name; BrowserPostReady.Description = description; SetSpoilers(readyPost); SetPoster(readyPost.Imgs.ToList()); SetTorrentFile(readyPost); SetScreens(readyPost.Imgs.ToList()); }
/// <summary> /// Получаем скриншоты из указанных спойлеров /// </summary> /// <param name="spoilers">Спойлеры, из которых нужно взять скриншоты</param> /// <returns></returns> private List <Img> GetImgsFromSpoilers(ReadyPost readyPost) { List <Img> imgs = new List <Img>(); foreach (var item in readyPost.Spoilers) { HtmlDocument document = new HtmlDocument(); document.LoadHtml(item.Body); HtmlNodeCollection nodes = document.DocumentNode.SelectNodes(@"//img[(parent::a)]"); var imgsTmp = GetImgs(nodes, TImg.Screenshot, readyPost); imgs.AddRange(imgsTmp); } return(imgs); }
private void SetTorrentFile(ReadyPost readyPost) { string today = DateTime.Today.ToShortDateString(); string folderName = Environment.CurrentDirectory + $"\\storage\\{today}"; Directory.CreateDirectory(folderName); string fileName = GetSafeFilename(readyPost.Name); DownloaderThroughTor downloader = new DownloaderThroughTor(); Uri uriFile = new Uri(ParserRutor.Main.OriginalString + readyPost.TorrentUrl); downloader.FinishedDownoadFile += Downloader_FinishedDownoadFile; downloader.FileAsync(uriFile, $"{folderName}\\{fileName}.torrent"); BrowserPostReady.TorrentFile = $"{folderName}\\{fileName}.torrent"; }
/// <summary> /// Получаем изображения, из указанной ноды /// </summary> /// <param name="nodesImg">Выбранные ноды, в которых должны быть эти изображения</param> /// <param name="tImg">Тип изображения, котороый необходимо найти</param> /// <param name="readyPost">Пост, к которому необходимо добавить изображение</param> /// <returns>Возвращает список с изображениями</returns> private List <Img> GetImgs(HtmlNodeCollection nodesImg, TImg tImg, ReadyPost readyPost) { List <Img> imgs = new List <Img>(); if (nodesImg != null) { var imgQuery = from el in nodesImg select new Img { TypeImg_idTypeImg = (int)tImg, Uri = el.GetAttributeValue("src", null), Uri_Parent = el.ParentNode.GetAttributeValue("href", null), ReadyPost = readyPost, }; imgs = imgQuery.ToList(); } return(imgs); }
public void StartGetItemTest() { ParserRutor parser = new ParserRutor(); ReadyPost actual = null; bool eventCall = false; DataBaseControl db = new DataBaseControl(); List <FoundPost> list = db.GetLastFounded(TTrakers.Rutor, 10); FoundPost itemList = list.First(); parser.ReadyPostsReceived += delegate(object s, ReadyPostArgs e) { actual = e.ReadyPostRecieved; eventCall = true; }; parser.StartGetItem(itemList); CommonFunction.SleepTimer(12, ref eventCall); Assert.IsNotNull(actual); }
public void AddReadyTest() { autoParsingContext db = new autoParsingContext(); FoundPost foundPost = db.FoundPost.First(); ReadyPost readyPost = null; bool eventCall = false; ParserRutor parserRutor = new ParserRutor(); parserRutor.ReadyPostsReceived += delegate(object s, ReadyPostArgs e) { readyPost = e.ReadyPostRecieved; eventCall = true; }; parserRutor.StartGetItem(foundPost); CommonFunction.SleepTimer(12, ref eventCall); DataBaseControl dataBaseControl = new DataBaseControl(); Assert.IsNotNull(readyPost); int actual = dataBaseControl.AddReady(readyPost); Assert.AreEqual(9, actual); }
public ReadyPostArgs(ReadyPost readyPost) { ReadyPostRecieved = readyPost; }