/// <summary> /// Парсить частичные данные треда. /// </summary> /// <param name="data">Данные.</param> /// <param name="link">Ссылка.</param> /// <returns>Результат.</returns> public ThreadTreePartial ParseThreadPartial(BoardPost2[] data, ThreadPartLink link) { var threadLink = new ThreadLink() { Engine = CoreConstants.Engine.Makaba, Board = link.Board, Thread = link.Thread }; var result = new ThreadTreePartial() { Link = threadLink, Posts = data.OrderBy(p => p.Number.TryParseWithDefault()).Select(p => Parse(p, threadLink, false)).ToList(), Extensions = new List<PostTreeCollectionExtension>(), ParentLink = new BoardLink() { Engine = CoreConstants.Engine.Makaba, Board = link.Board, }, }; return result; }
/// <summary> /// Разобрать HTML в посте. /// </summary> /// <param name="data">Данные.</param> /// <param name="link">Ссылка.</param> /// <param name="isPreview">Предварительный просмотр треда.</param> /// <returns>Результат разбора.</returns> private PostTree Parse(BoardPost2 data, ThreadLink link, bool isPreview) { var ipIdRegex = Services.GetServiceOrThrow<IRegexCacheService>().CreateRegex(IpIdRegexText); var ipIdRegex2 = Services.GetServiceOrThrow<IRegexCacheService>().CreateRegex(IpIdRegexText2); var colorRegex = Services.GetServiceOrThrow<IRegexCacheService>().CreateRegex(ColorRegexText); PostFlags flags = 0; if (data.Banned != "0" && !string.IsNullOrWhiteSpace(data.Banned)) { flags |= PostFlags.Banned; } if (data.Closed != "0" && !string.IsNullOrWhiteSpace(data.Closed)) { flags |= PostFlags.Closed; } if (data.Sticky != "0" && !string.IsNullOrWhiteSpace(data.Sticky)) { flags |= PostFlags.Sticky; } if (isPreview) { flags |= PostFlags.ThreadPreview; } if (data.Op != "0" && !string.IsNullOrWhiteSpace(data.Op)) { flags |= PostFlags.Op; } if ("mailto:sage".Equals((data.Email ?? "").Trim(), StringComparison.OrdinalIgnoreCase)) { flags |= PostFlags.Sage; } if (data.Edited != "0" && !string.IsNullOrWhiteSpace(data.Edited)) { flags |= PostFlags.IsEdited; } string admName = null; if (data.Tripcode != null) { if (data.Tripcode.StartsWith("!!%") && data.Tripcode.EndsWith("%!!")) { if ("!!%mod%!!".Equals(data.Tripcode)) { admName = "## Mod ##"; } else if ("!!%adm%!!".Equals(data.Tripcode)) { admName = "## Abu ##"; } else if ("!!%Inquisitor%!!".Equals(data.Tripcode)) { admName = "## Applejack ##"; } else if ("!!%coder%!!".Equals(data.Tripcode)) { admName = "## Кодер ##"; } else admName = data.Tripcode.Replace("!!%", "## ").Replace("%!!", " ##"); flags |= PostFlags.AdminTrip; } } var number = data.Number.TryParseWithDefault(); var postNodes = Services.GetServiceOrThrow<IMakabaHtmlPostParseService>().GetPostNodes(data.Comment ?? ""); var name = admName != null && string.IsNullOrWhiteSpace(data.Name) ? admName : WebUtility.HtmlDecode(data.Name ?? string.Empty).Replace(" ", " "); var result = new PostTree() { Link = new PostLink() { Engine = CoreConstants.Engine.Makaba, Board = link.Board, Thread = link.Thread, Post = number }, ParentLink = new ThreadLink() { Engine = CoreConstants.Engine.Makaba, Board = link.Board, Thread = link.Thread }, Subject = WebUtility.HtmlDecode(data.Subject ?? string.Empty), BoardSpecificDate = data.Date, Date = Services.GetServiceOrThrow<IDateService>().FromUnixTime(data.Timestamp.TryParseWithDefault()), Flags = flags, Quotes = new List<BoardLinkBase>(), Comment = new PostNodes() { Nodes = postNodes.ToList() }, Hash = data.Md5, Extensions = new List<PostTreeExtension>(), Email = data.Email, Media = new List<PostMediaBase>(), }; result.GeneratePostStamp(); if (string.IsNullOrWhiteSpace(result.Subject) && number == link.Thread) { try { var lines = ToPlainText(result); if (lines.Count > 0) { var s = lines.Where(l => !string.IsNullOrWhiteSpace(l)).FirstOrDefault(); if (s != null) { if (s.Length >= 50) { s = s.Substring(0, 50 - 3) + "..."; } result.Subject = s; } } } catch { } } string nameColor = null; PostColor color = null; var match = ipIdRegex.Match(name); var match2 = ipIdRegex2.Match(name); if (match.Success) { name = match.Groups["id"].Captures[0].Value; } else if (match2.Success) { name = match2.Groups["id"].Captures[0].Value; nameColor = match2.Groups["style"].Captures[0].Value; var cmatch = colorRegex.Match(nameColor); if (cmatch.Success) { try { var r = byte.Parse(cmatch.Groups["r"].Captures[0].Value, CultureInfo.InvariantCulture.NumberFormat); var g = byte.Parse(cmatch.Groups["g"].Captures[0].Value, CultureInfo.InvariantCulture.NumberFormat); var b = byte.Parse(cmatch.Groups["b"].Captures[0].Value, CultureInfo.InvariantCulture.NumberFormat); color = new PostColor() { R = r, G = g, B = b }; } catch (Exception) { color = null; } } } else if (name.StartsWith("Аноним ID:", StringComparison.OrdinalIgnoreCase)) { name = name.Remove(0, "Аноним ID:".Length).Trim(); } if (!string.IsNullOrEmpty(name) || !string.IsNullOrWhiteSpace(data.Tripcode)) { result.Extensions.Add(new PostTreePosterExtension() { Name = HtmlToText(name ?? ""), /* Windows.Data.Html.HtmlUtilities.ConvertToText работает очень медленно, потому что вызывает EDGE через COM, не годится для массовых обработок*/ //Name = Windows.Data.Html.HtmlUtilities.ConvertToText(name ?? ""), Tripcode = data.Tripcode, NameColorStr = nameColor, NameColor = color }); } var flagAndIcon = ParseFlagAndIcon(data.Icon); if (flagAndIcon.Icon != null) { result.Extensions.Add(flagAndIcon.Icon); } if (flagAndIcon.Country != null) { result.Extensions.Add(flagAndIcon.Country); } if (!string.IsNullOrWhiteSpace(data.Tags)) { result.Extensions.Add(new PostTreeTagsExtension() { TagString = data.Tags, Tags = new List<string>() { data.Tags } }); } if (data.Files != null) { foreach (var f in data.Files) { BoardLinkBase mediaLink, tnLink; if (IsBoardLink(f.Path, link.Board)) { mediaLink = new BoardMediaLink() { Engine = CoreConstants.Engine.Makaba, Board = link.Board, RelativeUri = RemoveBoardFromLink(f.Path), KnownMediaType = f.Type == MakabaMediaTypes.Webm ? KnownMediaType.Webm : KnownMediaType.Default }; tnLink = new BoardMediaLink() { Engine = CoreConstants.Engine.Makaba, Board = link.Board, RelativeUri = RemoveBoardFromLink(f.Thumbnail), KnownMediaType = KnownMediaType.Default }; } else { mediaLink = new MediaLink() { Engine = CoreConstants.Engine.Makaba, RelativeUri = f.Path, IsAbsolute = false, }; tnLink = new MediaLink() { Engine = CoreConstants.Engine.Makaba, RelativeUri = f.Thumbnail, IsAbsolute = false }; } var media = new PostImageWithThumbnail() { Link = mediaLink, ParentLink = result.Link, Size = f.Size * 1024, Height = f.Heigth, Width = f.Width, Name = f.Name, Thumbnail = new PostImage() { Link = tnLink, ParentLink = mediaLink, Height = f.TnHeight, Width = f.TnWidth, Size = null, Name = f.Name } }; result.Media.Add(media); } } return result; }