コード例 #1
0
ファイル: MangaPage.cs プロジェクト: joonhochoi/DaruDaru
        protected override bool GetInfomationPriv(HttpClientEx hc, ref int count)
        {
            MangaInfomation mangaInfo  = null;
            HttpStatusCode  statusCode = 0;

            var retrySuccess = Utility.Retry((retries) => (mangaInfo = this.GetInfomationWorker(hc, retries, out statusCode)) != null);

            if (!retrySuccess)
            {
                this.SetStatusFromHttpStatusCode(statusCode);
                return(false);
            }

            this.Uri = mangaInfo.NewUri;

            this.ProgressValue   = 0;
            this.ProgressMaximum = mangaInfo.Images.Count;

            this.m_images = mangaInfo.Images.ToArray();

            // 다운로드 시작
            this.State = MaruComicState.Working_2_WaitDownload;

            count = 1;

            return(true);
        }
コード例 #2
0
ファイル: MangaPage.cs プロジェクト: joonhochoi/DaruDaru
        private MangaInfomation GetInfomationWorker(HttpClientEx hc, int retries, out HttpStatusCode statusCode)
        {
            var mangaInfo = new MangaInfomation();

            var    doc = new HtmlDocument();
            string html;

            using (var res = hc.GetAsync(this.Uri).Exec())
            {
                statusCode = res.StatusCode;
                if (this.WaitFromHttpStatusCode(retries, statusCode))
                {
                    return(null);
                }

                html = res.Content.ReadAsStringAsync().Exec();
                if (string.IsNullOrWhiteSpace(html))
                {
                    return(null);
                }

                mangaInfo.NewUri = res.RequestMessage.RequestUri ?? this.Uri;
            }

            doc.LoadHtml(html);

            #region 폴더 이름은 Detail 에서 설정
            {
                // /bbs/page.php?hid=manga_detail&manga_id=9495
                var toonNav = doc.DocumentNode.SelectSingleNode("//div[contains(@class, 'toon-nav')]");
                if (toonNav == null)
                {
                    return(null);
                }

                string detailCode = null;
                foreach (HtmlNode node in toonNav.SelectNodes(".//a[@href]").ToArray())
                {
                    var href = node.GetAttributeValue("href", "");
                    if (string.IsNullOrWhiteSpace(href))
                    {
                        continue;
                    }

                    var code = DaruUriParser.Detail.GetCode(new Uri(this.Uri, href));
                    if (string.IsNullOrWhiteSpace(code))
                    {
                        continue;
                    }

                    detailCode = code;
                    break;
                }

                var detailEntry = ArchiveManager.GetDetail(detailCode);

                if (detailEntry == null)
                {
                    var detailUri = DaruUriParser.Detail.GetUri(detailCode);

                    DetailPage.DetailInfomation detailInfo = null;

                    var detailResult = Utility.Retry((retries2) =>
                    {
                        using (var res = hc.GetAsync(detailUri).Exec())
                        {
                            if (this.WaitFromHttpStatusCode(retries2, res.StatusCode))
                            {
                                return(false);
                            }

                            var htmlDetail = res.Content.ReadAsStringAsync().Exec();
                            if (string.IsNullOrWhiteSpace(html))
                            {
                                return(false);
                            }

                            detailInfo = DetailPage.GetDetailInfomation(hc, detailUri, htmlDetail);
                            return(detailInfo != null);
                        }
                    });

                    if (!detailResult)
                    {
                        return(null);
                    }

                    ArchiveManager.UpdateDetail(detailCode, detailInfo.Title, detailInfo.MangaList.Select(e => e.MangaCode).ToArray());

                    detailEntry = ArchiveManager.GetDetail(detailCode);

                    if (detailEntry == null)
                    {
                        return(null);
                    }
                }

                this.Title = detailEntry.Title;
            }
            #endregion

            #region Detail.Title + xx화
            {
                var titleNode = doc.DocumentNode.SelectSingleNode(".//div[contains(@class, 'toon-title')]");
                if (titleNode == null)
                {
                    return(null);
                }

                foreach (var titleNodeChild in titleNode.ChildNodes.ToArray())
                {
                    if (titleNodeChild.NodeType == HtmlNodeType.Element)
                    {
                        titleNodeChild.Remove();
                    }
                }

                var title = Utility.ReplaceHtmlTagAndRemoveTab(titleNode.InnerText ?? string.Empty);
                if (string.IsNullOrWhiteSpace(title))
                {
                    return(null);
                }

                if (string.IsNullOrWhiteSpace(title))
                {
                    return(null);
                }
                this.TitleWithNo = title;
            }
            #endregion

            #region 이미지 정보 가져오는 부분
            {
                // /js/viewer.b.js?v=90
                var chapter = int.Parse(Regex.Match(doc.DocumentNode.InnerHtml, "var *chapter *= *(\\d+)")?.Groups[1].Value ?? "0");

                var catchArr = new Func <string, IEnumerable <string> >(e =>
                {
                    var m = Regex.Match(doc.DocumentNode.InnerHtml, $"var {e} *= *((?:[^;\\\\]|\\\\.)*)");
                    if (!m.Success)
                    {
                        return(new string[0]);
                    }

                    return(Regex.Matches(m.Groups[1].Value, @"""((?:[^""\\]|\\.)*)""")
                           .Cast <Match>()
                           .Select(le => Regex.Replace(le.Groups[1].Value, @"\\(.)", lm => lm.Groups[1].Value)));
                });

                var cdnList = catchArr("cdn_domains")
                              .ToArray();

                var imgList = catchArr("img_list")
                              .Select(e => new Uri(this.Uri, e + "?quick"))
                              .ToArray();

                var imgList1 = catchArr("img_list1")
                               .Select(e => new Uri(this.Uri, e))
                               .ToArray();

                var lst = new HashSet <Uri>(new UriIEqualityComparer());
                for (var i = 0; i < imgList.Length; i++)
                {
                    lst.Clear();

                    var addList = new Action <Uri>(uri =>
                    {
                        var host = uri.Host;

                        if (cdnList?.Length > 0)
                        {
                            if (host.Contains("cdntigermask.xyz") || host.Contains("cdnmadmax.xyz") || host.Contains("filecdn.xyz"))
                            {
                                lst.Add(new UriBuilder(uri)
                                {
                                    Host = cdnList[(chapter + 4 * i) % cdnList.Length]
                                }.Uri);

                                for (var cdnPeek = 0; cdnPeek < CDNPeekCount; cdnPeek++)
                                {
                                    lst.Add(new UriBuilder(uri)
                                    {
                                        Host = cdnList[Random.Next(cdnList.Length)]
                                    }.Uri);
                                    lst.Add(new UriBuilder(uri)
                                    {
                                        Host = cdnList[Random.Next(cdnList.Length)]
                                    }.Uri);
                                    lst.Add(new UriBuilder(uri)
                                    {
                                        Host = cdnList[Random.Next(cdnList.Length)]
                                    }.Uri);
                                }
                            }
                        }

                        lst.Add(imgList[i]);

                        if (!host.Contains("google.") | !host.Contains("blogspot."))
                        {
                            lst.Add(new UriBuilder(uri)
                            {
                                Host = "s3." + host
                            }.Uri);
                            lst.Add(new UriBuilder(uri)
                            {
                                Host = host.Replace("img.", "s3.")
                            }.Uri);
                        }
                    });

                    if (i < imgList1.Length)
                    {
                        addList(imgList1[i]);
                    }

                    addList(imgList[i]);

                    var imageInfo = new ImageInfomation()
                    {
                        Index    = i + 1,
                        ImageUri = lst.Distinct().ToArray(),
                    };

                    mangaInfo.Images.Add(imageInfo);
                }
            }
            #endregion

            this.m_decryptor = new ImageDecryptor(html, mangaInfo.NewUri);

            return(mangaInfo);
        }
コード例 #3
0
        private MangaInfomation GetInfomationWorker(HttpClientEx hc, int retries, out HttpStatusCode statusCode)
        {
            var mangaInfo = new MangaInfomation();

            var    doc = new HtmlDocument();
            string html;

            using (var req = new HttpRequestMessage(HttpMethod.Get, this.Uri))
                using (var res = this.CallRequest(hc, req))
                {
                    statusCode = res.StatusCode;
                    if (this.WaitFromHttpStatusCode(retries, statusCode))
                    {
                        return(null);
                    }

                    html = res.Content.ReadAsStringAsync().Exec();
                    if (string.IsNullOrWhiteSpace(html))
                    {
                        return(null);
                    }

                    mangaInfo.NewUri = res.RequestMessage.RequestUri ?? this.Uri;
                }

            doc.LoadHtml(html);

            #region 폴더 이름은 Detail 에서 설정
            {
                // /bbs/page.php?hid=manga_detail&manga_id=9495
                var toonNav = doc.DocumentNode.SelectSingleNode("//div[contains(@class, 'toon-nav')]");
                if (toonNav == null)
                {
                    return(null);
                }

                string detailCode = null;
                foreach (HtmlNode node in toonNav.SelectNodes(".//a[@href]").ToArray())
                {
                    var href = node.GetAttributeValue("href", "");
                    if (string.IsNullOrWhiteSpace(href))
                    {
                        continue;
                    }

                    var code = DaruUriParser.Detail.GetCode(new Uri(this.Uri, href));
                    if (string.IsNullOrWhiteSpace(code))
                    {
                        continue;
                    }

                    detailCode = code;
                    break;
                }

                var detailEntry = ArchiveManager.GetDetail(detailCode);

                if (detailEntry == null)
                {
                    var detailUri = DaruUriParser.Detail.GetUri(detailCode);

                    DetailPage.DetailInfomation detailInfo = null;

                    var detailResult = Utility.Retry((retries2) =>
                    {
                        using (var req = new HttpRequestMessage(HttpMethod.Get, detailUri))
                            using (var res = this.CallRequest(hc, req))
                            {
                                if (this.WaitFromHttpStatusCode(retries2, res.StatusCode))
                                {
                                    return(false);
                                }

                                var htmlDetail = res.Content.ReadAsStringAsync().Exec();
                                if (string.IsNullOrWhiteSpace(html))
                                {
                                    return(false);
                                }

                                detailInfo = DetailPage.GetDetailInfomation(hc, detailUri, htmlDetail);
                                return(detailInfo != null);
                            }
                    });

                    if (!detailResult)
                    {
                        return(null);
                    }

                    ArchiveManager.UpdateDetail(detailCode, detailInfo.Title, detailInfo.MangaList.Select(e => e.MangaCode).ToArray());

                    detailEntry = ArchiveManager.GetDetail(detailCode);

                    if (detailEntry == null)
                    {
                        return(null);
                    }
                }

                this.Title = detailEntry.Title;
            }
            #endregion

            #region Detail.Title + xx화
            {
                var titleNode = doc.DocumentNode.SelectSingleNode(".//div[contains(@class, 'toon-title')]");
                if (titleNode == null)
                {
                    return(null);
                }

                foreach (var titleNodeChild in titleNode.ChildNodes.ToArray())
                {
                    if (titleNodeChild.NodeType == HtmlNodeType.Element)
                    {
                        titleNodeChild.Remove();
                    }
                }

                var title = Utility.ReplaceHtmlTagAndRemoveTab(titleNode.InnerText ?? string.Empty);
                if (string.IsNullOrWhiteSpace(title))
                {
                    return(null);
                }

                if (string.IsNullOrWhiteSpace(title))
                {
                    return(null);
                }
                this.TitleWithNo = title;
            }
            #endregion

            #region 이미지 정보 가져오는 부분
            {
                var imgList = Regex.Matches(Regex.Match(doc.DocumentNode.InnerHtml, "var img_list = [^;]+").Groups[0].Value, "\"([^\"]+)\"")
                              .Cast <Match>()
                              .Select(e => e.Groups[1].Value.Replace("\\", ""))
                              .Select(e => new Uri(this.Uri, e))
                              .ToArray();
                var imgList1 = Regex.Matches(Regex.Match(html, "var img_list1 = [^;]+").Groups[0].Value, "\"([^\"]+)\"")
                               .Cast <Match>()
                               .Select(e => e.Groups[1].Value.Replace("\\", ""))
                               .Select(e => new Uri(this.Uri, e))
                               .ToArray();

                for (var i = 0; i < imgList.Length; i++)
                {
                    var imageInfo = new ImageInfomation()
                    {
                        Index = i + 1,
                    };

                    if (i < imgList1.Length)
                    {
                        imageInfo.ImageUri = new Uri[]
                        {
                            new Uri(imgList[i].ToString().Replace("//img.", "//s3.")),
                            imgList[i],
                            imgList1[i],
                        }.Distinct().ToArray();
                    }
                    else
                    {
                        imageInfo.ImageUri = new Uri[]
                        {
                            new Uri(imgList[i].ToString().Replace("//img.", "//s3.")),
                            imgList[i],
                        }.Distinct().ToArray();
                    }

                    mangaInfo.Images.Add(imageInfo);
                }
            }
            #endregion

            this.m_decryptor = new ImageDecryptor(html, mangaInfo.NewUri);

            return(mangaInfo);
        }