Exemple #1
0
        public MangaObject ParseMangaObject(string Content)
        {
            HtmlDocument MangaObjectDocument = new HtmlDocument();

            MangaObjectDocument.LoadHtml(Content);

            HtmlNode MangaNode = MangaObjectDocument.DocumentNode.SelectSingleNode(".//section[contains(@class, 'manga')]");
            String   Name      = HtmlEntity.DeEntitize(MangaNode.SelectSingleNode(".//div/div[1]/h1/a").InnerText);

            Name = Name.Substring(0, Name.LastIndexOf(' '));
            HtmlNode      AlternateNamesNode = MangaNode.SelectSingleNode(".//div/table/tr/td[2]/table/tr[4]/td");
            List <String> AlternateNames     = (from AltName in HtmlEntity.DeEntitize(AlternateNamesNode.InnerText).Split(';')
                                                select AltName.Trim()).ToList();
            List <String> Authors = (from Node in MangaNode.SelectNodes(".//div/table/tr/td[2]/table/tr[5]/td/a")
                                     select HtmlEntity.DeEntitize(Node.InnerText)).ToList();
            List <String> Artists = (from Node in MangaNode.SelectNodes(".//div/table/tr/td[2]/table/tr[6]/td/a")
                                     select HtmlEntity.DeEntitize(Node.InnerText)).ToList();
            List <String> Genres = (from Node in MangaNode.SelectNodes(".//div/table/tr/td[2]/table/tr[7]/td/a")
                                    select HtmlEntity.DeEntitize(Node.InnerText)).ToList();

            // Detect type
            MangaObjectType MangaType = MangaObjectType.Unknown;
            String          mType     = MangaNode.SelectSingleNode(".//div/table/tr/td[2]/table/tr[8]/td").InnerText.ToLower();

            if (mType.Contains("japanese manga"))
            {
                MangaType = MangaObjectType.Manga;
            }
            else if (mType.Contains("korean manhwa"))
            {
                MangaType = MangaObjectType.Manhwa;
            }

            // Get description
            String Description = HtmlEntity.DeEntitize(MangaNode.SelectSingleNode(".//div/p").InnerText);

            // Chapters
            List <ChapterObject> Chapters = new List <ChapterObject>();

            foreach (HtmlNode ChapterVersionNode in MangaNode.SelectNodes(".//*[@id='list']/div[starts-with(@id, 'stream_')]"))
            {
                foreach (HtmlNode VolumeNode in ChapterVersionNode.SelectNodes(".//div[contains(@class, 'volume')]"))
                {
                    UInt32   Volume         = 0;
                    HtmlNode VolumeNameNode = VolumeNode.SelectSingleNode(".//h4");
                    if (!Equals(VolumeNameNode, null))
                    {
                        String[] idParts = VolumeNameNode.GetAttributeValue("id", "v-1-").Split('-');
                        UInt32.TryParse(idParts[2], out Volume);
                    }

                    foreach (HtmlNode ChapterNode in ChapterVersionNode.SelectNodes(".//div/ul/li"))
                    {
                        HtmlNode InfoNode = ChapterNode.SelectSingleNode(".//a");
                        String   ChapterName = HtmlEntity.DeEntitize(InfoNode.InnerText),
                                 Url = InfoNode.GetAttributeValue("href", null);
                        UInt32 Chapter = 0, SubChapter = 0;

                        Match match = Regex.Match(ChapterName, @"(vol\.(?<Volume>\d+)\s)?ch\.(?<Chapter>\d+)(\.(?<SubChapter>\d+))?");
                        if (match.Success)
                        {
                            if (match.Groups["Volume"].Success)
                            {
                                UInt32.TryParse(match.Groups["Volume"].Value, out Volume);
                            }
                            if (match.Groups["Chapter"].Success)
                            {
                                UInt32.TryParse(match.Groups["Chapter"].Value, out Chapter);
                            }
                            if (match.Groups["SubChapter"].Success)
                            {
                                UInt32.TryParse(match.Groups["SubChapter"].Value, out SubChapter);
                            }
                        }

                        if (Equals(Url, null))
                        {
                            continue;
                        }
                        Url = String.Format("{0}{1}", ExtensionDescriptionAttribute.RootUrl, Url);

                        ChapterObject NewChapterObject = new ChapterObject()
                        {
                            Name       = ChapterName,
                            Volume     = Volume,
                            Chapter    = Chapter,
                            SubChapter = SubChapter,
                            Locations  =
                            {
                                new LocationObject()
                                {
                                    Enabled           = true,
                                    ExtensionName     = ExtensionDescriptionAttribute.Name,
                                    ExtensionLanguage = ExtensionDescriptionAttribute.Language,
                                    Url = Url
                                }
                            }
                        };
                        ChapterObject ExistingChapterObject = Chapters.FirstOrDefault(o =>
                        {
                            if (!Int32.Equals(o.Chapter, NewChapterObject.Chapter))
                            {
                                return(false);
                            }
                            if (!Int32.Equals(o.SubChapter, NewChapterObject.SubChapter))
                            {
                                return(false);
                            }
                            return(true);
                        });
                        if (Equals(ExistingChapterObject, null))
                        {
                            Chapters.Add(NewChapterObject);
                        }
                        else
                        {
                            ExistingChapterObject.Merge(NewChapterObject);
                        }
                    }
                }
            }
            Chapters = Chapters.OrderBy(c => c.Chapter).ThenBy(c => c.SubChapter).ThenBy(c => c.Volume).ToList();

            return(new MangaObject()
            {
                Name = Name,
                AlternateNames = AlternateNames,
                Description = Description,
                Authors = Authors,
                Artists = Artists,
                Genres = Genres,
                MangaType = MangaType,
                Chapters = Chapters
            });
        }
Exemple #2
0
        public MangaObject ParseMangaObject(String content)
        {
            HtmlDocument MangaObjectDocument = new HtmlDocument();

            MangaObjectDocument.LoadHtml(content);

            String MangaCoverPrime       = MangaObjectDocument.GetElementbyId("mangaimg").SelectSingleNode(".//img").Attributes["src"].Value;
            Regex  MangaCoverRegex       = new Regex(@"(\d+)\.jpg");
            Int32  MangaCoverInt         = Int32.Parse(MangaCoverRegex.Match(MangaCoverPrime).Groups[1].Value);
            List <LocationObject> Covers = new List <LocationObject>();

            for (Int32 mcI = 0; mcI <= MangaCoverInt; ++mcI)
            {
                Covers.Add(new LocationObject()
                {
                    Url               = MangaCoverRegex.Replace(MangaCoverPrime, String.Format("{0}.jpg", mcI)),
                    ExtensionName     = ExtensionDescriptionAttribute.Name,
                    ExtensionLanguage = ExtensionDescriptionAttribute.Language
                });
            }
            Covers.TrimExcess();

            HtmlNode MangaProperties = MangaObjectDocument.GetElementbyId("mangaproperties").SelectSingleNode(".//table"),
                     ChapterListing  = MangaObjectDocument.GetElementbyId("listing"),
                     MangaDesciption = MangaObjectDocument.GetElementbyId("readmangasum").SelectSingleNode(".//p");

            String MangaName                  = HtmlEntity.DeEntitize(MangaProperties.SelectSingleNode(".//tr[1]/td[2]/h2").InnerText),
                   ReadDirection              = MangaProperties.SelectSingleNode(".//tr[7]/td[2]").InnerText,
                   ReleaseYear                = Regex.Match(MangaProperties.SelectSingleNode(".//tr[3]/td[2]").InnerText, @"\d+").Value,
                   Release                    = String.Format("01/01/{0}", String.IsNullOrWhiteSpace(ReleaseYear) ? "0001" : ReleaseYear),
                   Desciption                 = MangaDesciption != null ? MangaDesciption.InnerText : String.Empty;
            MangaObjectType MangaType         = MangaObjectType.Unknown;
            FlowDirection   PageFlowDirection = FlowDirection.RightToLeft;

            switch (ReadDirection.ToLower())
            {
            default:
                MangaType         = MangaObjectType.Unknown;
                PageFlowDirection = FlowDirection.RightToLeft;
                break;

            case "right to left":
                MangaType         = MangaObjectType.Manga;
                PageFlowDirection = FlowDirection.RightToLeft;
                break;

            case "left to right":
                MangaType         = MangaObjectType.Manhwa;
                PageFlowDirection = FlowDirection.LeftToRight;
                break;
            }

            String[] AlternateNames = MangaProperties.SelectSingleNode(".//tr[2]/td[2]").InnerText.Split(new String[] { ", " }, StringSplitOptions.RemoveEmptyEntries),
            Authors = MangaProperties.SelectSingleNode(".//tr[5]/td[2]").InnerText.Split(new String[] { ", " }, StringSplitOptions.RemoveEmptyEntries),
            Artists = MangaProperties.SelectSingleNode(".//tr[6]/td[2]").InnerText.Split(new String[] { ", " }, StringSplitOptions.RemoveEmptyEntries),
            Genres  = (from HtmlNode GenreNode in MangaProperties.SelectSingleNode(".//tr[8]/td[2]").SelectNodes(".//span[contains(@class,'genretags')]") select HtmlEntity.DeEntitize(GenreNode.InnerText)).ToArray();

            ChapterObject[] Chapters = (from HtmlNode ChapterNode in ChapterListing.SelectNodes(".//tr[not(contains(@class,'table_head'))]")
                                        select new ChapterObject()
            {
                Name = HtmlEntity.DeEntitize(ChapterNode.SelectSingleNode(".//td[1]").LastChild.InnerText.Substring(3).Trim()),
                Chapter = UInt32.Parse(ChapterNode.SelectSingleNode(".//td[1]/a").InnerText.Substring(ChapterNode.SelectSingleNode(".//td[1]/a").InnerText.LastIndexOf(' ') + 1)),
                Locations =
                {
                    new LocationObject()
                    {
                        ExtensionName = ExtensionDescriptionAttribute.Name,
                        ExtensionLanguage = ExtensionDescriptionAttribute.Language,
                        Url = String.Format("{0}{1}", ExtensionDescriptionAttribute.RootUrl, ChapterNode.SelectSingleNode(".//td[1]/a").Attributes["href"].Value)
                    }
                },
                Released = DateTime.Parse(ChapterNode.SelectSingleNode(".//td[2]").InnerText)
            }).ToArray();

            return(new MangaObject()
            {
                Name = HtmlEntity.DeEntitize(MangaName),
                MangaType = MangaType,
                PageFlowDirection = PageFlowDirection,
                Description = HtmlEntity.DeEntitize(Desciption),
                AlternateNames = AlternateNames.ToList(),
                CoverLocations = Covers,
                Authors = (from Author in Authors select HtmlEntity.DeEntitize(Author)).ToList(),
                Artists = (from Artist in Artists select HtmlEntity.DeEntitize(Artist)).ToList(),
                Genres = Genres.ToList(),
                Released = DateTime.Parse(Release),
                Chapters = Chapters.ToList()
            });
        }
Exemple #3
0
        public MangaObject ParseMangaObject(string content)
        {
            HtmlDocument MangaObjectDocument = new HtmlDocument();

            MangaObjectDocument.LoadHtml(content);

            HtmlNode InformationNode = MangaObjectDocument.DocumentNode.SelectSingleNode("//div[contains(@class,'ipsBox')]/div");
            String   Cover           = InformationNode.SelectSingleNode(".//div[1]/img").Attributes["src"].Value;

            HtmlNode MangaProperties = InformationNode.SelectSingleNode(".//table[contains(@class,'ipb_table')]"),
                     ChapterListing  = MangaObjectDocument.DocumentNode.SelectSingleNode("//table[contains(@class,'chapters_list')]");

            String MangaName                  = HtmlEntity.DeEntitize(MangaObjectDocument.DocumentNode.SelectSingleNode("//h1[contains(@class,'ipsType_pagetitle')]").InnerText.Trim()),
                   MangaTypeProp              = HtmlEntity.DeEntitize(MangaProperties.SelectSingleNode(".//tr[5]/td[2]").InnerText),
                   Desciption                 = HtmlEntity.DeEntitize(MangaProperties.SelectSingleNode(".//tr[7]/td[2]").InnerText.Replace("<br>", "\n"));
            MangaObjectType MangaType         = MangaObjectType.Unknown;
            FlowDirection   PageFlowDirection = FlowDirection.RightToLeft;

            switch (MangaTypeProp.ToLower())
            {
            default:
                MangaType         = MangaObjectType.Unknown;
                PageFlowDirection = FlowDirection.RightToLeft;
                break;

            case "manga (japanese)":
                MangaType         = MangaObjectType.Manga;
                PageFlowDirection = FlowDirection.RightToLeft;
                break;

            case "manhwa (korean)":
                MangaType         = MangaObjectType.Manhwa;
                PageFlowDirection = FlowDirection.LeftToRight;
                break;

            case "manhua (chinese)":
                MangaType         = MangaObjectType.Manhua;
                PageFlowDirection = FlowDirection.LeftToRight;
                break;
            }

            HtmlNodeCollection AlternateNameNodes = MangaProperties.SelectSingleNode(".//tr[1]/td[2]").SelectNodes(".//span"),
                               GenreNodes         = MangaProperties.SelectSingleNode(".//tr[4]/td[2]").SelectNodes(".//a/span");

            String[] AlternateNames = { },
            Authors = { HtmlEntity.DeEntitize(MangaProperties.SelectSingleNode(".//tr[2]/td[2]/a").InnerText) },
            Artists = { HtmlEntity.DeEntitize(MangaProperties.SelectSingleNode(".//tr[3]/td[2]/a").InnerText) },
            Genres  = { };
            if (AlternateNameNodes != null && AlternateNameNodes.Count > 0)
            {
                AlternateNames = (from HtmlNode AltNameNode in AlternateNameNodes select HtmlEntity.DeEntitize(AltNameNode.InnerText.Trim())).ToArray();
            }
            if (GenreNodes != null && GenreNodes.Count > 0)
            {
                Genres = (from HtmlNode GenreNode in GenreNodes select HtmlEntity.DeEntitize(GenreNode.InnerText.Trim())).ToArray();
            }

            List <ChapterObject> Chapters     = new List <ChapterObject>();
            HtmlNodeCollection   ChapterNodes = ChapterListing.SelectNodes(String.Format(".//tr[contains(@class,'lang_{0} chapter_row')]", ExtensionDescriptionAttribute.Language));

            if (ChapterNodes != null && ChapterNodes.Count > 0)
            {
                foreach (HtmlNode ChapterNode in ChapterNodes)
                {
                    HtmlNode VolChapNameNode = ChapterNode.SelectSingleNode("td[1]/a");
                    Match    VolChapMatch = Regex.Match(VolChapNameNode.InnerText, @"(Vol\.(?<Volume>\d+)\s)?(Ch\.(?<Chapter>\d+))(\.(?<SubChapter>\d+))?");
                    String   ChapterName = VolChapNameNode.InnerText.Substring(VolChapMatch.Length + 2).Trim(),
                             ReleaseData = ReleaseData = ChapterNode.SelectSingleNode("td[5]").InnerText;
                    ChapterObject PrevChapter = Chapters.LastOrDefault();
                    UInt32        Volume = 0, Chapter = 0, SubChapter = 0;
                    if (VolChapMatch.Groups["Volume"].Success)
                    {
                        UInt32.TryParse(VolChapMatch.Groups["Volume"].Value, out Volume);
                    }
                    if (VolChapMatch.Groups["Chapter"].Success)
                    {
                        UInt32.TryParse(VolChapMatch.Groups["Chapter"].Value, out Chapter);
                    }
                    if (VolChapMatch.Groups["SubChapter"].Success)
                    {
                        UInt32.TryParse(VolChapMatch.Groups["SubChapter"].Value, out SubChapter);
                    }

                    DateTime Released = DateTime.Now;
                    if (ReleaseData.Contains("-"))
                    {
                        ReleaseData = ReleaseData.Split(new String[] { " - " }, StringSplitOptions.RemoveEmptyEntries)[0];
                        DateTime.TryParseExact(ReleaseData, "dd MMMM yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out Released);
                    }
                    else if (ReleaseData.EndsWith("ago"))
                    {
                        String[] ReleaseDataParts = ReleaseData.Split(new Char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                        Double   Offset           = 1;
                        if (!Double.TryParse(ReleaseDataParts[0], out Offset))
                        {
                            Offset = 1;
                        }
                        Offset *= -1;
                        switch (ReleaseDataParts[1].ToLower())
                        {
                        default:
                        case "seconds":
                            Released = Released.AddSeconds(Offset);
                            break;

                        case "minutes":
                            Released = Released.AddMinutes(Offset);
                            break;

                        case "hours":
                            Released = Released.AddHours(Offset);
                            break;

                        case "days":
                            Released = Released.AddDays(Offset);
                            break;

                        case "weeks":
                            Released = Released.AddDays(7 * Offset);
                            break;
                        }
                    }

                    String ChapterUrl  = VolChapNameNode.Attributes["href"].Value;
                    String ChapterHash = ChapterUrl.Split('#').Last().Split('_').First();
                    ChapterUrl = String.Format("https://bato.to/areader?id={0}&p=1&supress_webtoon=t", ChapterHash);
                    ChapterObject chapterObject = new ChapterObject()
                    {
                        Name       = HtmlEntity.DeEntitize(ChapterName),
                        Volume     = Volume,
                        Chapter    = Chapter,
                        SubChapter = SubChapter,
                        Released   = Released,
                        Locations  =
                        {
                            new LocationObject()
                            {
                                ExtensionName     = ExtensionDescriptionAttribute.Name,
                                ExtensionLanguage = ExtensionDescriptionAttribute.Language,
                                Url = ChapterUrl
                            }
                        }
                    };
                    if (!Chapters.Any(o => o.Chapter == chapterObject.Chapter && ((Int32)o.SubChapter - chapterObject.SubChapter).InRange(-4, 4)))
                    {
                        Chapters.Add(chapterObject);
                    }
                    else
                    {
                        Chapters.Find(o => o.Chapter == chapterObject.Chapter && ((Int32)o.SubChapter - chapterObject.SubChapter).InRange(-4, 4)).Merge(chapterObject);
                    }
                }
            }
            Chapters.Reverse();

            Double Rating = -1;

            try
            {
                HtmlNode RatingNode = MangaObjectDocument.DocumentNode.SelectSingleNode("//div[contains(@class,'rating')]");
                String   RatingText = new String(RatingNode.InnerText.Trim().Substring(1, 4).Where(IsValidRatingChar).ToArray());
                Double.TryParse(RatingText, out Rating);
            }
            catch { }

            return(new MangaObject()
            {
                Name = MangaName,
                MangaType = MangaType,
                PageFlowDirection = PageFlowDirection,
                Description = HtmlEntity.DeEntitize(Desciption),
                AlternateNames = AlternateNames.ToList(),
                CoverLocations = { new LocationObject()
                                   {
                                       Url = Cover,
                                       ExtensionName = ExtensionDescriptionAttribute.Name,
                                       ExtensionLanguage = ExtensionDescriptionAttribute.Language
                                   } },
                Authors = Authors.ToList(),
                Artists = Artists.ToList(),
                Genres = Genres.ToList(),
                Released = (Chapters.FirstOrDefault() ?? new ChapterObject()).Released,
                Chapters = Chapters,
                Rating = Rating
            });
        }