Exemple #1
0
        public override (List <NetTask>, ExtractedInfo) Extract(string url, IExtractorOption option = null)
        {
            var match = ValidUrl.Match(url).Groups;

            if (option == null)
            {
                option = RecommendOption(url);
            }

            if (option.Type == ExtractorType.Images)
            {
                var id = match["id"].Value;

                // Handle Redirect
                var string3 = NetTools.DownloadString(url);
RETRY_DOWNLOAD1:
                if (string.IsNullOrEmpty(string3))
                {
                    return(null, null);
                }
                if (string3.ToHtmlNode().SelectSingleNode("//title").InnerText == "Redirect")
                {
                    id      = string3.ToHtmlNode().SelectSingleNode("//a").GetAttributeValue("href", "").Split('/', '-').Last().Split('.')[0];
                    string3 = NetTools.DownloadString(string3.ToHtmlNode().SelectSingleNode("//a").GetAttributeValue("href", ""));
                    goto RETRY_DOWNLOAD1;
                }

                var sinfo    = new ExtractedInfo.WorksComic();
                var imgs_url = $"https://ltn.hitomi.la/galleries/{id}.js";
                option.PageReadCallback?.Invoke($"https://ltn.hitomi.la/galleryblock/{id}.html");
                option.PageReadCallback?.Invoke(url);
                option.PageReadCallback?.Invoke(imgs_url);
                var urls = new List <string> {
                    $"https://ltn.hitomi.la/galleryblock/{id}.html",
                    imgs_url
                };

                var strings = NetTools.DownloadStrings(urls);

                if (string.IsNullOrEmpty(strings[0]) || string.IsNullOrEmpty(strings[1]))
                {
                    return(null, null);
                }

                var data1 = ParseGalleryBlock(strings[0]);
                var imgs  = strings[1];

                var string2 = NetTools.DownloadString($"https://hitomi.la{data1.Magic}");
                if (string.IsNullOrEmpty(string2))
                {
                    return(null, null);
                }
                var data2 = ParseGallery(string2);

                option.SimpleInfoCallback?.Invoke($"[{id}] {data1.Title}");

                // download.js
                var number_of_frontends = 3;
                var subdomain           = Convert.ToChar(97 + (Convert.ToInt32(id.Last()) % number_of_frontends));
                if (id.Last() == '0')
                {
                    subdomain = 'a';
                }

                var arr      = JToken.Parse(imgs.Substring(imgs.IndexOf('=') + 1))["files"];
                var img_urls = new List <string>();
                foreach (var obj in (JArray)arr)
                {
                    var hash = obj.Value <string>("hash");
                    if (obj.Value <int>("haswebp") == 0 || hash == null)
                    {
                        //img_urls.Add($"https://{subdomain}a.hitomi.la/galleries/{id}/{obj.Value<string>("name")}");
                        var postfix = hash.Substring(hash.Length - 3);
                        img_urls.Add($"https://{subdomain}a.hitomi.la/images/{postfix[2]}/{postfix[0]}{postfix[1]}/{hash}.{obj.Value<string>("name").Split('.').Last()}");
                    }
                    else if (hash == "")
                    {
                        img_urls.Add($"https://{subdomain}a.hitomi.la/webp/{obj.Value<string>("name")}.webp");
                    }
                    else if (hash.Length < 3)
                    {
                        img_urls.Add($"https://{subdomain}a.hitomi.la/webp/{hash}.webp");
                    }
                    else
                    {
                        var postfix = hash.Substring(hash.Length - 3);
                        img_urls.Add($"https://{subdomain}a.hitomi.la/webp/{postfix[2]}/{postfix[0]}{postfix[1]}/{hash}.webp");
                    }
                }

                var result   = new List <NetTask>();
                var ordering = 1;
                foreach (var img in img_urls)
                {
                    var filename = Path.GetFileNameWithoutExtension(img.Split('/').Last());
                    if (!(option as HitomiExtractorOption).RealFilename)
                    {
                        filename = ordering++.ToString("000");
                    }

                    var task = NetTask.MakeDefault(img);
                    task.SaveFile = true;
                    task.Filename = img.Split('/').Last();
                    task.Format   = new ExtractorFileNameFormat
                    {
                        Title      = data1.Title,
                        Id         = id,
                        Language   = data1.Language,
                        UploadDate = data1.Posted,
                        FilenameWithoutExtension = filename,
                        Extension = Path.GetExtension(img.Split('/').Last()).Replace(".", "")
                    };

                    if (data1.artist != null)
                    {
                        task.Format.Artist = data1.artist[0];
                    }
                    else
                    {
                        task.Format.Artist = "NA";
                    }

                    if (data1.parody != null)
                    {
                        task.Format.Series = data1.parody[0];
                    }
                    else
                    {
                        task.Format.Series = "NA";
                    }

                    if (data2.group != null)
                    {
                        task.Format.Group = data2.group[0];
                    }
                    else
                    {
                        task.Format.Group = "NA";
                    }

                    if (data2.character != null)
                    {
                        task.Format.Character = data2.character[0];
                    }
                    else
                    {
                        task.Format.Character = "NA";
                    }

                    if (task.Format.Artist == "NA" && task.Format.Group != "NA")
                    {
                        task.Format.Artist = task.Format.Group;
                    }

                    result.Add(task);
                }

                option.ThumbnailCallback?.Invoke(result[0]);

                sinfo.Thumbnail   = result[0];
                sinfo.URL         = url;
                sinfo.Title       = data1.Title;
                sinfo.Author      = data1.artist?.ToArray();
                sinfo.AuthorGroup = data2.group?.ToArray();
                sinfo.ShortInfo   = $"[{id}] {data1.Title}";
                sinfo.Tags        = data1.Tags?.ToArray();
                sinfo.Characters  = data2.character?.ToArray();
                sinfo.Language    = data1.Language;
                sinfo.Parodies    = data1.parody?.ToArray();

                result.ForEach(task => task.Format.Extractor = GetType().Name.Replace("Extractor", ""));
                return(result, new ExtractedInfo {
                    Info = sinfo, Type = ExtractedInfo.ExtractedType.WorksComic
                });
            }

            return(null, null);
        }
        public override (List <NetTask>, ExtractedInfo) Extract(string url, IExtractorOption option = null)
        {
            var match = ValidUrl.Match(url).Groups;

            if (option == null)
            {
                option = RecommendOption(url);
            }

            if (option.Type == ExtractorType.Images)
            {
                var sinfo    = new ExtractedInfo.WorksComic();
                var imgs_url = $"https://ltn.hitomi.la/galleries/{match["id"].Value}.js";
                option.PageReadCallback?.Invoke($"https://ltn.hitomi.la/galleryblock/{match["id"]}.html");
                option.PageReadCallback?.Invoke(url);
                option.PageReadCallback?.Invoke(imgs_url);
                var urls = new List <string> {
                    $"https://ltn.hitomi.la/galleryblock/{match["id"]}.html",
                    url,
                    imgs_url
                };

                var strings = NetTools.DownloadStrings(urls);

                if (string.IsNullOrEmpty(strings[0]) || string.IsNullOrEmpty(strings[1]) || string.IsNullOrEmpty(strings[2]))
                {
                    return(null, null);
                }

                var data1 = ParseGalleryBlock(strings[0]);
                var data2 = ParseGallery(strings[1]);
                var imgs  = strings[2];

                option.SimpleInfoCallback?.Invoke($"[{data1.Magic}] {data1.Title}");

                // download.js
                var number_of_frontends = 3;
                var subdomain           = Convert.ToChar(97 + (Convert.ToInt32(match["id"].Value.Last()) % number_of_frontends));
                if (match["id"].Value.Last() == '0')
                {
                    subdomain = 'a';
                }

                var arr      = JArray.Parse(imgs.Substring(imgs.IndexOf('[')));
                var img_urls = new List <string>();
                foreach (var obj in arr)
                {
                    if (obj.Value <int>("haswebp") == 0)
                    {
                        img_urls.Add($"https://{subdomain}a.hitomi.la/galleries/{match["id"].Value}/{obj.Value<string>("name")}");
                    }
                    else
                    {
                        img_urls.Add($"https://{subdomain}a.hitomi.la/webp/{match["id"].Value}/{obj.Value<string>("name")}.webp");
                    }
                }

                var result = new List <NetTask>();
                foreach (var img in img_urls)
                {
                    var task = NetTask.MakeDefault(img);
                    task.SaveFile = true;
                    task.Filename = img.Split('/').Last();
                    task.Format   = new ExtractorFileNameFormat
                    {
                        Title      = data1.Title,
                        Id         = data1.Magic,
                        Language   = data1.Language,
                        UploadDate = data1.Posted,
                        FilenameWithoutExtension = Path.GetFileNameWithoutExtension(img.Split('/').Last()),
                        Extension = Path.GetExtension(img.Split('/').Last()).Replace(".", "")
                    };

                    if (data1.artist != null)
                    {
                        task.Format.Artist = data1.artist[0];
                    }
                    else
                    {
                        task.Format.Artist = "N/A";
                    }

                    if (data1.parody != null)
                    {
                        task.Format.Series = data1.parody[0];
                    }
                    else
                    {
                        task.Format.Series = "N/A";
                    }

                    if (data2.group != null)
                    {
                        task.Format.Group = data2.group[0];
                    }
                    else
                    {
                        task.Format.Group = "N/A";
                    }

                    if (data2.character != null)
                    {
                        task.Format.Character = data2.character[0];
                    }
                    else
                    {
                        task.Format.Character = "N/A";
                    }

                    if (task.Format.Artist == "N/A" && task.Format.Group != "N/A")
                    {
                        task.Format.Artist = task.Format.Group;
                    }

                    result.Add(task);
                }

                option.ThumbnailCallback?.Invoke(result[0]);

                sinfo.Thumbnail   = result[0];
                sinfo.URL         = url;
                sinfo.Title       = data1.Title;
                sinfo.Author      = data1.artist?.ToArray();
                sinfo.AuthorGroup = data2.group?.ToArray();
                sinfo.ShortInfo   = $"[{data1.Magic}] {data1.Title}";
                sinfo.Tags        = data1.Tags?.ToArray();
                sinfo.Characters  = data2.character?.ToArray();
                sinfo.Language    = data1.Language;
                sinfo.Parodies    = data1.parody?.ToArray();

                result.ForEach(task => task.Format.Extractor = GetType().Name.Replace("Extractor", ""));
                return(result, new ExtractedInfo {
                    Info = sinfo, Type = ExtractedInfo.ExtractedType.WorksComic
                });
            }

            return(null, null);
        }