private void bLoad_Click(object sender, EventArgs e)
        {
            string article_source = GetWebClient().DownloadString(new Uri(tbAddress.Text));

            pages       = ExHentaiParser.GetPagesUri(article_source);
            article     = ExHentaiParser.GetArticleData(article_source);
            lTitle.Text = article.Title;
            if (article.artist != null)
            {
                lArtist.Text = string.Join(", ", article.artist);
            }
            if (article.male != null)
            {
                tbTags.Text += "male: " + string.Join(", ", article.male) + "\r\n";
            }
            if (article.female != null)
            {
                tbTags.Text += "female: " + string.Join(", ", article.female) + "\r\n";
            }
            if (article.misc != null)
            {
                tbTags.Text += "misc: " + string.Join(", ", article.misc) + "\r\n";
            }
            ServicePointManager.DefaultConnectionLimit = 128;
            Task.Run(() => download_image(article.Thumbnail));

            bDownload_Click();
        }
예제 #2
0
        /// <summary>
        /// 아티클 정보를 다운로드하고 정보를 출력합니다.
        /// </summary>
        /// <param name="args"></param>
        static void ProcessArticle(string[] args)
        {
            string         html_source = NetCommon.DownloadExHentaiString(args[0]);
            EHentaiArticle article     = ExHentaiParser.ParseArticleData(html_source);

            Console.Instance.WriteLine(article);
        }
예제 #3
0
        /// <summary>
        /// 페이지 주소 정보를 출력합니다.
        /// </summary>
        /// <param name="args"></param>
        static void ProcessPaging(string[] args)
        {
            //string url = "https://exhentai.org/?inline_set=dm_l&page=" + args[0];
            //string url2 = "https://exhentai.org/?page=1&f_doujinshi=on&f_manga=on&f_artistcg=on&f_gamecg=on&f_search=language%3Akorean&f_apply=Apply+Filter&inline_set=dm_l";

            var result = new List <EHentaiResultArticle>();

            for (int i = 0; i < 20; i++)
            {
                try
                {
                    var url  = $"https://exhentai.org/?page={i}&f_doujinshi=on&f_manga=on&f_artistcg=on&f_gamecg=on&f_search=language%3Akorean&f_apply=Apply+Filter&inline_set=dm_l";
                    var url2 = $"https://exhentai.org/?page={i}&f_doujinshi=on&f_manga=on&f_artistcg=on&f_gamecg=on&advsearch=1&f_search=language%3Akorean&f_srdd=2&f_sname=on&f_stags=on&f_sdesc=on&f_sh=on&f_apply=Apply+Filter";
                    //           https://exhentai.org/?page=1&f_doujinshi=on&f_manga=on&f_artistcg=on&f_gamecg=on&advsearch=1&f_srdd=2&f_sname=on&f_stags=on&f_sh=on&f_apply=Apply+Filter
                    var html = NetCommon.DownloadExHentaiString(url2);
                    result.AddRange(ExHentaiParser.ParseResultPageListView(html));
                    Monitor.Instance.Push($"[Paging] {i+1}/1457");
                }
                catch (Exception e)
                {
                    Console.Instance.WriteErrorLine($"[Error] {i} {e.Message}");
                }
                Thread.Sleep(500);
            }

            string json = JsonConvert.SerializeObject(result, Formatting.Indented);

            using (var fs = new StreamWriter(new FileStream("exh.json", FileMode.Create, FileAccess.Write)))
            {
                fs.Write(json);
            }
        }
예제 #4
0
 public static void ProcessEXHentai(HArticleModel commander, bool unstable = false)
 {
     Task.Run(() =>
     {
         if (unstable)
         {
             MainWindow.Instance.Fade_MiddlePopup(true, $"불안정한 작업 진행중...[{unstable_request}개]");
         }
         var pages               = ExHentaiParser.GetPagesUri(NetCommon.DownloadExHentaiString(commander.URL));
         var pages_html          = EmiliaJobEXH.Instance.AddJob(pages.ToList(), x => { }).Select(x => ExHentaiParser.GetImagesUri(x));
         List <string> pages_all = new List <string>();
         pages_html.ToList().ForEach(x => pages_all.AddRange(x));
         var imagelink      = EmiliaJobEXH.Instance.AddJob(pages_all, x => { }).Select(x => ExHentaiParser.GetImagesAddress(x));
         List <string> tags = new List <string>();
         if (commander.male != null)
         {
             tags.AddRange(commander.male.Select(x => "male:" + x.Replace(' ', '_')));
         }
         if (commander.female != null)
         {
             tags.AddRange(commander.female.Select(x => "female:" + x.Replace(' ', '_')));
         }
         if (commander.misc != null)
         {
             tags.AddRange(commander.misc.Select(x => x.Replace(' ', '_')));
         }
         HitomiArticle article = new HitomiArticle
         {
             Magic      = commander.Magic,
             Title      = commander.Title,
             Artists    = commander.artist,
             Groups     = commander.group,
             Series     = commander.parody,
             Tags       = tags.ToArray(),
             Language   = commander.language != null ? commander.language[0] : "",
             Characters = commander.character
         };
         string dir         = HitomiCommon.MakeDownloadDirectory(article);
         article.ImagesLink = imagelink.ToList();
         Directory.CreateDirectory(dir);
         var se    = Koromo_Copy.Interface.SemaphoreExtends.MakeDefault();
         se.Cookie = "igneous=30e0c0a66;ipb_member_id=2742770;ipb_pass_hash=6042be35e994fed920ee7dd11180b65f;";
         DownloadSpace.Instance.RequestDownload(article.Title,
                                                imagelink.ToArray(),
                                                imagelink.Select(y => Path.Combine(dir, y.Split('/').Last())).ToArray(),
                                                se, dir, article);
         if (unstable)
         {
             Interlocked.Decrement(ref unstable_request);
         }
         if (unstable && unstable_request != 0)
         {
             MainWindow.Instance.Fade_MiddlePopup(true, $"불안정한 작업 진행중...[{unstable_request}개]");
         }
         else
         {
             MainWindow.Instance.FadeOut_MiddlePopup($"{imagelink.Count()}개 이미지 다운로드 시작...");
         }
     });
 }
예제 #5
0
        public void SyncExHentai()
        {
            eHentaiResultArticles = new List <EHentaiResultArticle>();

            for (int i = 0; i < 9999999; i++)
            {
                try
                {
                    var url = $"https://exhentai.org/?page={i}&f_doujinshi=on&f_manga=on&f_artistcg=on&f_gamecg=on&&f_cats=0&f_sname=on&f_stags=on&f_sh=on&advsearch=1&f_srdd=2&f_sname=on&f_stags=on&f_sdesc=on&f_sh=on";
                    var wc  = new WebClient();
                    wc.Encoding = Encoding.UTF8;
                    wc.Headers.Add(HttpRequestHeader.Accept, "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");
                    wc.Headers.Add(HttpRequestHeader.UserAgent, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36");
                    wc.Headers.Add(HttpRequestHeader.Cookie, "igneous=30e0c0a66;ipb_member_id=2742770;ipb_pass_hash=6042be35e994fed920ee7dd11180b65f;sl=dm_2");
                    var html = wc.DownloadString(url);

                    try
                    {
                        var exh = ExHentaiParser.ParseResultPageExtendedListView(html);
                        eHentaiResultArticles.AddRange(exh);
                        if (exh.Count != 25)
                        {
                            Logs.Instance.PushWarning("[Miss] " + url);
                        }
                        if (i > exhentaiLookupPage && exh.Min(x => x.URL.Split('/')[4].ToInt()) < latestId)
                        {
                            break;
                        }
                        Logs.Instance.Push("Parse exh page - " + i);
                    }
                    catch (Exception e)
                    {
                        Logs.Instance.PushError("[Fail] " + url);
                    }
                }
                catch (Exception e)
                {
                    Logs.Instance.PushError($"{i} {e.Message}");
                }
                Thread.Sleep(100);

                if (i % 1000 == 999)
                {
                    Thread.Sleep(60000);
                }
            }

            foreach (var z in eHentaiResultArticles)
            {
                var nn = z.URL.Split('/')[4].ToInt();

                if (!newedDataEH.Contains(nn))
                {
                    newedDataEH.Add(nn);
                }
            }
        }
예제 #6
0
        static void ProcessExtract()
        {
            var xxx = JsonConvert.DeserializeObject <List <EHentaiResultArticle> >(File.ReadAllText("ex-hentai-archive.json"));

            const string archive = @"E:\2019\e-archive";
            var          ix      = new FileIndexor();

            Task.Run(async() => await ix.ListingDirectoryAsync(archive)).Wait();

            var htmls = new List <string>();

            ix.Enumerate((string path, List <FileInfo> files) =>
            {
                files.ForEach(x => htmls.Add(x.FullName));
            });

            var result = new List <EHentaiResultArticle>();

            using (var progressBar = new Console.ConsoleProgressBar())
            {
                int x = 0;
                foreach (var html in htmls)
                {
                    var content = File.ReadAllText(html);
                    try
                    {
                        var exh = ExHentaiParser.ParseResultPageExtendedListView(content);
                        //Console.Instance.WriteLine("[GET] " + exh.Count + " Articles! - " + html);
                        result.AddRange(exh);
                        if (exh.Count != 25)
                        {
                            Console.Instance.WriteLine("[Miss] " + html);
                        }
                    }
                    catch (Exception e)
                    {
                        Console.Instance.WriteLine("[Fail] " + html);
                    }
                    x++;
                    progressBar.SetProgress(x / (float)htmls.Count * 100);
                }
            }


            JsonSerializer serializer = new JsonSerializer();

            serializer.Converters.Add(new JavaScriptDateTimeConverter());
            serializer.NullValueHandling = NullValueHandling.Ignore;

            Monitor.Instance.Push("Write file: ex-hentai-archive.json");
            using (StreamWriter sw = new StreamWriter(Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), "ex-hentai-archive.json")))
                using (JsonWriter writer = new JsonTextWriter(sw))
                {
                    serializer.Serialize(writer, result);
                }
        }
        private void wc_page_cb(object sender, DownloadStringCompletedEventArgs e)
        {
            var images = ExHentaiParser.GetImagesUri(e.Result);

            foreach (string image_uri in images)
            {
                WebClient wc = GetWebClient();
                wc.DownloadStringCompleted += wc_image_cb;
                wc.DownloadStringAsync(new Uri(image_uri), e.UserState);
                System.Threading.Thread.Sleep(500);
            }
        }
예제 #8
0
        static void ProcessSaveExhentaiPage(string[] args)
        {
            int startsId = int.Parse(args[0]);

            var db     = new SQLiteConnection("data.db");
            var target = db.Query <HitomiColumnModel>("SELECT Id, EHash FROM HitomiColumnModel WHERE EHash IS NOT NULL AND Language='korean'");

            target.Sort((x, y) => x.Id.CompareTo(y.Id));

            var rcount = 0;

            for (var i = 0; i < target.Count; i++)
            {
                if (target[i].Id < startsId)
                {
                    continue;
                }

                Logs.Instance.Push($"[Exhentai-Page] {target[i].Id} / {target[i].EHash}");

                var url = $"https://exhentai.org/g/{target[i].Id}/{target[i].EHash}";

                try
                {
                    var wc = new WebClient();
                    wc.Encoding = Encoding.UTF8;
                    wc.Headers.Add(HttpRequestHeader.Accept, "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");
                    wc.Headers.Add(HttpRequestHeader.UserAgent, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36");
                    wc.Headers.Add(HttpRequestHeader.Cookie, "igneous=30e0c0a66;ipb_member_id=2742770;ipb_pass_hash=6042be35e994fed920ee7dd11180b65f;sl=dm_2");
                    var html = wc.DownloadString(url);

                    //File.WriteAllText($"ex/{target[i].Id}.html", html);
                    var comment = ExHentaiParser.ParseArticleData(html).comment;
                    if (comment != null && comment.Length > 0)
                    {
                        File.WriteAllText($"ex/{target[i].Id}.json", Logs.SerializeObject(comment));
                    }
                }
                catch (Exception e)
                {
                    Logs.Instance.PushError("[Fail] " + url + "\r\n" + Logs.SerializeObject(e));
                }

                Thread.Sleep(100);

                if (rcount % 1000 == 999)
                {
                    Thread.Sleep(60000);
                }

                rcount++;
            }
        }
예제 #9
0
        static void ProcessExtract4()
        {
            const string archive = @"C:\Tools\koromo-copy\Koromo Copy UX\bin\Debug\exhentai-page";
            var          htmls   = new List <string>();

            foreach (var file in Directory.GetFiles(archive))
            {
                htmls.Add(File.ReadAllText(file));
            }

            var result = new List <EHentaiResultArticle>();

            using (var progressBar = new Console.ConsoleProgressBar())
            {
                int x = 0;
                foreach (var html in htmls)
                {
                    var content = html;
                    try
                    {
                        var exh = ExHentaiParser.ParseResultPageExtendedListView(content);
                        //Console.Instance.WriteLine("[GET] " + exh.Count + " Articles! - " + html);
                        result.AddRange(exh);
                        if (exh.Count != 25)
                        {
                            Console.Instance.WriteLine("[Miss] " + html);
                        }
                    }
                    catch (Exception e)
                    {
                        Console.Instance.WriteLine("[Fail] " + html);
                    }
                    x++;
                    progressBar.SetProgress(x / (float)htmls.Count * 100);
                }
            }


            JsonSerializer serializer = new JsonSerializer();

            serializer.Converters.Add(new JavaScriptDateTimeConverter());
            serializer.NullValueHandling = NullValueHandling.Ignore;

            Monitor.Instance.Push("Write file: ex-hentai-archive.json");
            using (StreamWriter sw = new StreamWriter(Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), "ex-hentai-archive2.json")))
                using (JsonWriter writer = new JsonTextWriter(sw))
                {
                    serializer.Serialize(writer, result);
                }
        }
예제 #10
0
        static void ProcessExtract2()
        {
            const string target = @"e-parse-fail.txt";
            var          lines  = File.ReadAllLines(target);

            var result = new List <EHentaiResultArticle>();

            using (var progressBar = new Console.ConsoleProgressBar())
            {
                int x = 0;
                foreach (var line in lines)
                {
                    var fn      = line.Replace("[Fail] ", "");
                    var content = File.ReadAllText(fn);

                    try
                    {
                        var exh = ExHentaiParser.ParseResultPageMinimalListView(content);
                        Console.Instance.WriteLine("[GET] " + exh.Count + " Articles! - " + fn);
                        result.AddRange(exh);
                    }
                    catch (Exception e)
                    {
                        Console.Instance.WriteLine("[Fail] " + fn);
                    }

                    x++;
                    progressBar.SetProgress(x / (float)lines.Length * 100);
                }
            }

            JsonSerializer serializer = new JsonSerializer();

            serializer.Converters.Add(new JavaScriptDateTimeConverter());
            serializer.NullValueHandling = NullValueHandling.Ignore;

            Monitor.Instance.Push("Write file: ex-hentai-archive2.json");
            using (StreamWriter sw = new StreamWriter(Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), "ex-hentai-archive2.json")))
                using (JsonWriter writer = new JsonTextWriter(sw))
                {
                    serializer.Serialize(writer, result);
                }
        }
        private void CommentWindow_Loaded(object sender, RoutedEventArgs e)
        {
            var html    = NetCommon.DownloadExHentaiString(url);
            var article = ExHentaiParser.ParseArticleData(html);

            foreach (var comment in article.comment)
            {
                Domain.CommentViewModel cvm = new Domain.CommentViewModel
                {
                    Author  = comment.Item2.Trim(),
                    Date    = comment.Item1.ToString(),
                    Content = Regex.Replace(comment.Item3, @"<a\b[^>]+>([^<]*(?:(?!</a)<[^<]*)*)</a>", "$1")
                };

                Comments.Children.Add(new CommentElements {
                    DataContext = cvm
                });
            }
        }
예제 #12
0
        private void frmComment_Load(object sender, EventArgs e)
        {
            WebClient wc = new WebClient();

            wc.Encoding = Encoding.UTF8;
            wc.Headers.Add(HttpRequestHeader.Cookie, "igneous=30e0c0a66;ipb_member_id=2742770;ipb_pass_hash=6042be35e994fed920ee7dd11180b65f;");
            ExHentaiArticle article = ExHentaiParser.GetArticleData(wc.DownloadString(url));

            label1.Text = $"댓글 : {article.comment.Length} 개";

            int ccc = 0;

            article.comment.ToList().ForEach(x => {
                richTextBox1.AppendText($"{x.Item2} - {x.Item1.ToString()}\r\n{x.Item3.Trim()}\r\n\r\n");
                richTextBox1.Select(ccc, x.Item2.Length);
                richTextBox1.SelectionFont = new Font(richTextBox1.Font.FontFamily, 11.0F, FontStyle.Bold);
                richTextBox1.Select(ccc + x.Item2.Length + 3, x.Item1.ToString().Length);
                richTextBox1.SelectionFont = new Font(richTextBox1.Font.FontFamily, 11.0F);
                ccc = richTextBox1.Text.Length;
            });
        }
예제 #13
0
        /// <summary>
        /// 각종 기능을 테스트합니다.
        /// </summary>
        /// <param name="args"></param>
        static void ProcessTest(string[] args)
        {
            switch (args[0].ToInt32())
            {
            //
            //  Save and beautify metadatas
            //
            case 0:
            {
                var hiddendata = JsonConvert.DeserializeObject <List <HitomiArticle> >(File.ReadAllText(Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), "hiddendata.json")));
                Func <HitomiArticle, NHitomiArticle> r2n = (ha) =>
                {
                    return(new NHitomiArticle
                        {
                            Artists = ha.Artists,
                            Characters = ha.Characters,
                            Groups = ha.Groups,
                            Language = ha.Language,
                            Tags = ha.Tags,
                            Type = ha.Type,
                            DateTime = ha.DateTime,
                            Thumbnail = ha.Thumbnail,
                            Magic = ha.Magic,
                            Title = ha.Title
                        });
                };

                var jj   = hiddendata.Select(x => r2n(x));
                var json = JsonConvert.SerializeObject(jj, Formatting.Indented);
                using (var fs = new StreamWriter(new FileStream("hiddendata_beautify.json", FileMode.Create, FileAccess.Write)))
                {
                    fs.Write(json);
                }

                var json2 = JsonConvert.SerializeObject(jj, Formatting.None);
                using (var fs = new StreamWriter(new FileStream("hiddendata_nonbeautify.json", FileMode.Create, FileAccess.Write)))
                {
                    var bytes = json2.Zip();
                    fs.BaseStream.Write(json2.Zip(), 0, bytes.Length);
                }
            }
            break;

            //
            //  Load metadatas
            //
            case 1:
            {
                var bytes = File.ReadAllBytes("hiddendata_nonbeautify.json");
                var json  = JsonConvert.DeserializeObject <List <NHitomiArticle> >(bytes.Unzip());
                Console.Instance.Write($"{json.Count}");
            }
            break;

            case 2:
            {
                var str = File.ReadAllText("hiddendata.json");
                File.WriteAllBytes("hiddendata.compress", str.Zip());
            }
            break;

            case 3:
            {
                var str = File.ReadAllText("metadata.json");
                File.WriteAllBytes("metadata.compress", str.Zip());
            }
            break;

            case 4:
            {
                var str = JsonConvert.DeserializeObject <List <HitomiArticle> >(File.ReadAllText("hiddendata.json"));
                using (var fs = new StreamWriter(new FileStream("hiddendata.json", FileMode.Create, FileAccess.Write)))
                {
                    fs.Write(JsonConvert.SerializeObject(str, Formatting.None));
                }
            }
            break;

            case 5:
            {
                var bytes = File.ReadAllBytes("metadata.compress");
                File.WriteAllText("metadata.json", bytes.Unzip());
            }
            break;

            case 6:
            {
                var bytes = File.ReadAllBytes("hiddendata.compress");
                File.WriteAllText("hiddendata.json", bytes.Unzip());
            }
            break;

            case 7:
            {
                HitomiExplore.exploreNullSpace().ForEach(x => Console.Instance.WriteLine($"{x.Item1} {x.Item2} {x.Item3}"));
            }
            break;

            case 8:
            {
                // Update index-metadata.json
                HitomiData.Instance.LoadMetadataJson();
                HitomiData.Instance.LoadHiddendataJson();
                HitomiIndex.MakeIndex();
                var str = File.ReadAllBytes("index-metadata.json");
                File.WriteAllBytes("index-metadata.compress", str.ZipByte());
            }
            break;

            case 9:
            {
                //var hidden = JsonConvert.DeserializeObject<List<HitomiArticle>>(File.ReadAllText(Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), "hiddendata.json")));
                //var gall = JsonConvert.DeserializeObject<List<HitomiArticle>>(File.ReadAllText(Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), "galleries.json")));


                //for (int i = 0; i < gall.Count; i++)
                //    for (int j = 0; j < hidden.Count; j++)
                //        if (gall[i].Magic == hidden[j].Magic)
                //        {
                //            hidden[j].Groups = gall[i].Groups;
                //            hidden[j].Characters = gall[i].Characters;
                //        }

                //JsonSerializer serializer = new JsonSerializer();
                //serializer.Converters.Add(new Newtonsoft.Json.Converters.JavaScriptDateTimeConverter());
                //serializer.NullValueHandling = NullValueHandling.Ignore;

                //using (StreamWriter sw = new StreamWriter(Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), "hiddendata2.json")))
                //using (JsonWriter writer = new JsonTextWriter(sw))
                //{
                //    serializer.Serialize(writer, hidden);
                //}

                var x = new HitomiIndexDataModel();
                x.index    = HitomiIndex.Instance.index;
                x.metadata = HitomiIndex.Instance.metadata_collection;
                JsonSerializer serializer = new JsonSerializer();
                serializer.Converters.Add(new Newtonsoft.Json.Converters.JavaScriptDateTimeConverter());
                serializer.NullValueHandling = NullValueHandling.Ignore;

                Monitor.Instance.Push("Write file: metadata-index.json");
                using (StreamWriter sw = new StreamWriter(Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), "metadata-index.json")))
                    using (JsonWriter writer = new JsonTextWriter(sw))
                    {
                        serializer.Serialize(writer, x);
                    }

                HitomiData.Instance.LoadMetadataJson();
                HitomiData.Instance.LoadHiddendataJson();
                Monitor.Instance.Push("Write file: metadata-noptimized.json");
                using (StreamWriter sw = new StreamWriter(Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), "metadametadata-noptimizedta.json")))
                    using (JsonWriter writer = new JsonTextWriter(sw))
                    {
                        serializer.Serialize(writer, HitomiData.Instance.metadata_collection);
                    }
            }
            break;

            case 10:

            {
                foreach (var x in HitomiIndex.Instance.tagdata_collection.artist)
                {
                    Console.Instance.Write(x.Tag + ", ");
                }
            }

            break;

            case 11:
            {
                HitomiData.Instance.LoadMetadataJson();
                HitomiData.Instance.LoadHiddendataJson();
                HitomiData.Instance.RebuildTagData();
            }
            break;

            case 12:
            {
                // Update HitomiTitle
                for (int i = 0; i < 50; i++)
                {
                    try
                    {
                        var url3 = $"https://exhentai.org/?page={i}&f_doujinshi=on&f_manga=on&f_artistcg=on&f_gamecg=on&&f_cats=0&f_sname=on&f_stags=on&f_sh=on&advsearch=1&f_srdd=2&f_sname=on&f_stags=on&f_sdesc=on&f_sh=on";
                        var html = NetCommon.DownloadExHentaiString(url3);
                        File.WriteAllText($"exhentai-page/exhentai-{i}.html", html);
                        Monitor.Instance.Push($"[Paging] {i + 1}/1457");
                    }
                    catch (Exception e)
                    {
                        Console.Instance.WriteErrorLine($"[Error] {i} {e.Message}");
                    }
                    Thread.Sleep(100);
                }
                {
                    const string archive = @"C:\Dev\koromo-copy\Koromo Copy UX\bin\Debug\exhentai-page";
                    var          htmls   = new List <string>();

                    foreach (var file in Directory.GetFiles(archive))
                    {
                        htmls.Add(File.ReadAllText(file));
                    }

                    var result = new List <EHentaiResultArticle>();

                    using (var progressBar = new Console.ConsoleProgressBar())
                    {
                        int x = 0;
                        foreach (var html in htmls)
                        {
                            var content = html;
                            try
                            {
                                var exh = ExHentaiParser.ParseResultPageExtendedListView(content);
                                //Console.Instance.WriteLine("[GET] " + exh.Count + " Articles! - " + html);
                                result.AddRange(exh);
                                if (exh.Count != 25)
                                {
                                    Console.Instance.WriteLine("[Miss] " + html);
                                }
                            }
                            catch (Exception e)
                            {
                                Console.Instance.WriteLine("[Fail] " + html);
                            }
                            x++;
                            progressBar.SetProgress(x / (float)htmls.Count * 100);
                        }
                    }

                    JsonSerializer serializer = new JsonSerializer();
                    serializer.Converters.Add(new JavaScriptDateTimeConverter());
                    serializer.NullValueHandling = NullValueHandling.Ignore;

                    Monitor.Instance.Push("Write file: ex-hentai-archive.json");
                    using (StreamWriter sw = new StreamWriter(Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), "ex-hentai-archive2.json")))
                        using (JsonWriter writer = new JsonTextWriter(sw))
                        {
                            serializer.Serialize(writer, result);
                        }
                }
                {
                    var xxx = JsonConvert.DeserializeObject <List <EHentaiResultArticle> >(File.ReadAllText("ex-hentai-archive.json"));
                    var zzz = JsonConvert.DeserializeObject <List <EHentaiResultArticle> >(File.ReadAllText("ex-hentai-archive2.json"));

                    var exists = new HashSet <int>();
                    xxx.ForEach(x => exists.Add(x.URL.Split('/')[4].ToInt32()));

                    foreach (var z in zzz)
                    {
                        var nn = z.URL.Split('/')[4].ToInt32();

                        if (exists.Contains(nn))
                        {
                            Console.Instance.WriteLine("[Duplicate] " + nn);
                        }
                        else
                        {
                            xxx.Add(z);
                        }
                    }

                    JsonSerializer serializer = new JsonSerializer();
                    serializer.Converters.Add(new JavaScriptDateTimeConverter());
                    serializer.NullValueHandling = NullValueHandling.Ignore;

                    Monitor.Instance.Push("Write file: ex-hentai-archive3.json");
                    using (StreamWriter sw = new StreamWriter(Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), "ex-hentai-archive3.json")))
                        using (JsonWriter writer = new JsonTextWriter(sw))
                        {
                            serializer.Serialize(writer, xxx);
                        }
                }

                HitomiTitle.MakeTitle();
            }
            break;

            case 13:
                // Fill type
            {
                var md = JsonConvert.DeserializeObject <List <HitomiArticle> >(File.ReadAllText("hiddendata.json"));

                var xxx = JsonConvert.DeserializeObject <List <EHentaiResultArticle> >(File.ReadAllText("ex-hentai-archive.json"));
                //var md = JsonConvert.DeserializeObject<List<HitomiMetadata>>(File.ReadAllText("metadata.json"));

                var types = new Dictionary <string, string>();

                foreach (var xx in xxx)
                {
                    try
                    {
                        types.Add(xx.URL.Split('/')[4], xx.Type.ToLower());
                    }
                    catch (Exception e)
                    {
                        //Console.Instance.WriteLine("[??] " + xx.URL);
                    }
                }

                //for (int i = 0; i < md.Count; i++)
                //{
                //    if (md[i].Type  == null || md[i].Type.Trim() == "")
                //    {
                //        if (types.ContainsKey(md[i].ID.ToString()))
                //        {
                //            var x = md[i];
                //            x.Type = types[md[i].ID.ToString()];
                //            md[i] = x;
                //        }
                //        else
                //        {
                //            Console.Instance.WriteLine("[Fail] " + md[i].ID.ToString());
                //        }
                //    }
                //}

                for (int i = 0; i < md.Count; i++)
                {
                    if (md[i].Type == null || md[i].Type.Trim() == "")
                    {
                        if (types.ContainsKey(md[i].Magic.ToString()))
                        {
                            var x = md[i];
                            x.Type = types[md[i].Magic.ToString()];
                            md[i]  = x;
                        }
                        else
                        {
                            Console.Instance.WriteLine("[Fail] " + md[i].Magic.ToString());
                        }
                    }
                }

                JsonSerializer serializer = new JsonSerializer();
                serializer.Converters.Add(new JavaScriptDateTimeConverter());
                serializer.NullValueHandling = NullValueHandling.Ignore;

                Monitor.Instance.Push("Write file: metadata.json");
                using (StreamWriter sw = new StreamWriter(Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), "hiddendata2.json")))
                    using (JsonWriter writer = new JsonTextWriter(sw))
                    {
                        serializer.Serialize(writer, md);
                    }
            }
            break;
            }
        }
예제 #14
0
        static void ProcessStart()
        {
            Console.Clear();
            Console.Title = "hsync";

            Console.WriteLine($"hsync - DB Synchronization Manager");
            Console.WriteLine($"Copyright (C) 2020. project violet-server.");
            Console.WriteLine($"Version: {Version.Text} (Build: {Internals.GetBuildDate().ToLongDateString()})");
            Console.WriteLine("");

            if (!File.Exists("hiddendata.json"))
            {
                Logs.Instance.Push("Welcome to hsync!\r\n\tDownload the necessary data before running the program!");
                download_data("https://github.com/project-violet/database/releases/download/rd2020.06.07/hiddendata.json", "hiddendata.json");
            }
            if (!File.Exists("metadata.json"))
            {
                download_data("https://github.com/project-violet/database/releases/download/rd2020.06.07/metadata.json", "metadata.json");
            }
            if (!File.Exists("ex-hentai-archive.json"))
            {
                download_data("https://github.com/project-violet/database/releases/download/rd2020.06.07/ex-hentai-archive.json", "ex-hentai-archive.json");
            }

            HitomiData.Instance.Load();

            var latest = HitomiData.Instance.metadata_collection.First().ID;

//#if true
            // Sync Hitomi
            {
                var range  = 2000;
                var exists = new HashSet <int>();
                foreach (var metadata in HitomiData.Instance.metadata_collection)
                {
                    exists.Add(metadata.ID);
                }

                var gburls = Enumerable.Range(latest - range, range * 2).Where(x => !exists.Contains(x)).Select(x => $"https://ltn.hitomi.la/galleryblock/{x}.html").ToList();
                var dcnt   = 0;
                var ecnt   = 0;
                Console.Write("Running galleryblock tester... ");
                List <string> htmls;
                using (var pb = new ProgressBar())
                {
                    htmls = NetTools.DownloadStrings(gburls, "",
                                                     () => {
                        pb.Report(gburls.Count, Interlocked.Increment(ref dcnt), ecnt);
                    },
                                                     () => {
                        pb.Report(gburls.Count, dcnt, Interlocked.Increment(ref ecnt));
                    });
                }
                Console.WriteLine("Complete");

                var gurls = new List <string>(gburls.Count);
                for (int i = 0; i < gburls.Count; i++)
                {
                    if (htmls[i] == null)
                    {
                        continue;
                    }
                    var aa = HitomiParser.ParseGalleryBlock(htmls[i]);
                    if (aa.Magic.Contains("-"))
                    {
                        gurls.Add("https://hitomi.la/" + aa.Magic);
                    }
                    else
                    {
                        gurls.Add("https://hitomi.la/galleries/" + i + ".html");
                    }
                }

                dcnt = 0;
                ecnt = 0;
                Console.Write("Running gallery tester... ");
                List <string> htmls2 = null;
                if (gurls.Count != 0)
                {
                    using (var pb = new ProgressBar())
                    {
                        htmls2 = NetTools.DownloadStrings(gurls, "",
                                                          () => {
                            pb.Report(gburls.Count, Interlocked.Increment(ref dcnt), ecnt);
                        },
                                                          () => {
                            pb.Report(gburls.Count, dcnt, Interlocked.Increment(ref ecnt));
                        });
                    }
                }
                Console.WriteLine("Complete");

                Console.Write("Check redirect gallery html... ");
                var last_change = true;
                while (last_change)
                {
                    last_change = false;
                    for (int i = 0; i < htmls2.Count; i++)
                    {
                        if (htmls2[i] == null)
                        {
                            continue;
                        }
                        var node  = htmls2[i].ToHtmlNode();
                        var title = node.SelectSingleNode("//title");
                        if (title != null && title.InnerText == "Redirect")
                        {
                            htmls2[i]   = NetTools.DownloadString(node.SelectSingleNode("//a").GetAttributeValue("href", ""));
                            last_change = true;
                        }
                    }
                }
                Console.WriteLine("Complete");

                var result = new List <HitomiArticle>();
                for (int i = 0, j = 0; i < gburls.Count; i++)
                {
                    if (htmls[i] == null)
                    {
                        continue;
                    }
                    var aa = HitomiParser.ParseGalleryBlock(htmls[i]);
                    if (htmls2[j] != null)
                    {
                        var ab = HitomiParser.ParseGallery(htmls2[j]);
                        aa.Groups     = ab.Groups;
                        aa.Characters = ab.Characters;
                    }
                    result.Add(aa);
                    j++;
                }

                Console.Write("Save to hiddendata.json... ");
                HitomiData.Instance.SaveWithNewData(result);
                Console.WriteLine("Complete");

//#if true
//                Console.Write("Save to index-metadata.json... ");
//                HitomiIndex.MakeIndex();
//                Console.WriteLine("Complete");
//#endif
            }

//#if false
            // Sync EH
            {
                var result = new List <EHentaiResultArticle>();

                for (int i = 0; i < 9999999; i++)
                {
                    try
                    {
                        //var task = NetTask.MakeDefault($"https://exhentai.org/?page={i}&f_doujinshi=on&f_manga=on&f_artistcg=on&f_gamecg=on&&f_cats=0&f_sname=on&f_stags=on&f_sh=on&advsearch=1&f_srdd=2&f_sname=on&f_stags=on&f_sdesc=on&f_sh=on");
                        //task.Cookie = "igneous=30e0c0a66;ipb_member_id=2742770;ipb_pass_hash=6042be35e994fed920ee7dd11180b65f;sl=dm_2";
                        //var html = NetTools.DownloadString(task);
                        var url = $"https://exhentai.org/?page={i}&f_doujinshi=on&f_manga=on&f_artistcg=on&f_gamecg=on&&f_cats=0&f_sname=on&f_stags=on&f_sh=on&advsearch=1&f_srdd=2&f_sname=on&f_stags=on&f_sdesc=on&f_sh=on";
                        var wc  = new WebClient();
                        wc.Encoding = Encoding.UTF8;
                        wc.Headers.Add(HttpRequestHeader.Accept, "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");
                        wc.Headers.Add(HttpRequestHeader.UserAgent, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36");
                        wc.Headers.Add(HttpRequestHeader.Cookie, "igneous=30e0c0a66;ipb_member_id=2742770;ipb_pass_hash=6042be35e994fed920ee7dd11180b65f;sl=dm_2");
                        var html = wc.DownloadString(url);

                        try
                        {
                            var exh = ExHentaiParser.ParseResultPageExtendedListView(html);
                            result.AddRange(exh);
                            if (exh.Count != 25)
                            {
                                Logs.Instance.PushWarning("[Miss] " + url);
                            }
                            if (i > 500 && exh.Min(x => x.URL.Split('/')[4].ToInt()) < latest)
                            {
                                break;
                            }
                            Logs.Instance.Push("Parse exh page - " + i);
                        }
                        catch (Exception e)
                        {
                            Logs.Instance.PushError("[Fail] " + url);
                        }
                    }
                    catch (Exception e)
                    {
                        Logs.Instance.PushError($"{i} {e.Message}");
                    }
                    Thread.Sleep(100);

                    if (i % 1000 == 999)
                    {
                        Thread.Sleep(60000);
                    }
                }

                var xxx = JsonConvert.DeserializeObject <List <EHentaiResultArticle> >(File.ReadAllText("ex-hentai-archive.json"));
                File.Move("ex-hentai-archive.json", $"ex-hentai-archive-{DateTime.Now.Ticks}.json");

                var exists = new HashSet <int>();
                xxx.ForEach(x => exists.Add(x.URL.Split('/')[4].ToInt()));

                foreach (var z in result)
                {
                    var nn = z.URL.Split('/')[4].ToInt();

                    if (!exists.Contains(nn))
                    {
                        xxx.Add(z);
                    }
                }

                JsonSerializer serializer = new JsonSerializer();
                serializer.Converters.Add(new JavaScriptDateTimeConverter());
                serializer.NullValueHandling = NullValueHandling.Ignore;

                Logs.Instance.Push("Write file: ex-hentai-archive.json");
                using (StreamWriter sw = new StreamWriter("ex-hentai-archive.json"))
                    using (JsonWriter writer = new JsonTextWriter(sw))
                    {
                        serializer.Serialize(writer, xxx);
                    }
            }
//#endif
//#endif

//#if false
            // Make DataBase
            {
                HitomiData.Instance.metadata_collection.Clear();
                HitomiData.Instance.Load();
                var xxx = JsonConvert.DeserializeObject <List <EHentaiResultArticle> >(File.ReadAllText("ex-hentai-archive.json"));

                Console.Write("Make database... ");
                var dict = new Dictionary <string, int>();

                for (int i = 0; i < xxx.Count; i++)
                {
                    if (!dict.ContainsKey(xxx[i].URL.Split('/')[4]))
                    {
                        dict.Add(xxx[i].URL.Split('/')[4], i);
                    }
                }

                {
                    var db   = new SQLiteConnection("hitomidata.db");
                    var info = db.GetTableInfo(typeof(HitomiColumnModel).Name);
                    if (!info.Any())
                    {
                        db.CreateTable <HitomiColumnModel>();
                    }
                    db.InsertAll(HitomiData.Instance.metadata_collection.Select(md =>
                    {
                        var dd = new HitomiColumnModel
                        {
                            Id         = md.ID,
                            Artists    = (md.Artists != null && md.Artists.Length > 0 && md.Artists[0] != "" ? "|" + string.Join("|", md.Artists) + "|" : "N/A|"),
                            Characters = (md.Characters != null && md.Characters.Length > 0 && md.Characters[0] != "" ? "|" + string.Join("|", md.Characters) + "|" : null),
                            Groups     = (md.Groups != null && md.Groups.Length > 0 && md.Groups[0] != "" ? "|" + string.Join("|", md.Groups) + "|" : null),
                            Series     = (md.Parodies != null && md.Parodies.Length > 0 && md.Parodies[0] != "" ? "|" + string.Join("|", md.Parodies) + "|" : null),
                            Title      = md.Name,
                            Tags       = (md.Tags != null && md.Tags.Length > 0 && md.Tags[0] != "" ? "|" + string.Join("|", md.Tags) + "|" : null),
                            Type       = md.Type,
                            Language   = md.Language,
                        };

                        if (dict.ContainsKey(md.ID.ToString()))
                        {
                            var ii       = xxx[dict[md.ID.ToString()]];
                            dd.Uploader  = ii.Uploader;
                            dd.Published = DateTime.Parse(ii.Published);
                            dd.EHash     = ii.URL.Split('/')[5];
                            dd.Files     = ii.Files.Split(' ')[0].ToInt();
                            if (ii.Title.StartsWith("("))
                            {
                                dd.Class = ii.Title.Split("(")[1].Split(")")[0];
                            }
                        }

                        return(dd);
                    }));
                    db.Close();
                }

                Console.WriteLine("Complete-All");

                {
                    var db   = new SQLiteConnection("hitomidata-korean.db");
                    var info = db.GetTableInfo(typeof(HitomiColumnModel).Name);
                    if (!info.Any())
                    {
                        db.CreateTable <HitomiColumnModel>();
                    }
                    db.InsertAll(HitomiData.Instance.metadata_collection.Where(md => md.Language == null || md.Language == "" || md.Language == "korean").Select(md =>
                    {
                        var dd = new HitomiColumnModel
                        {
                            Id         = md.ID,
                            Artists    = (md.Artists != null && md.Artists.Length > 0 && md.Artists[0] != "" ? "|" + string.Join("|", md.Artists) + "|" : "N/A|"),
                            Characters = (md.Characters != null && md.Characters.Length > 0 && md.Characters[0] != "" ? "|" + string.Join("|", md.Characters) + "|" : null),
                            Groups     = (md.Groups != null && md.Groups.Length > 0 && md.Groups[0] != "" ? "|" + string.Join("|", md.Groups) + "|" : null),
                            Series     = (md.Parodies != null && md.Parodies.Length > 0 && md.Parodies[0] != "" ? "|" + string.Join("|", md.Parodies) + "|" : null),
                            Title      = md.Name,
                            Tags       = (md.Tags != null && md.Tags.Length > 0 && md.Tags[0] != "" ? "|" + string.Join("|", md.Tags) + "|" : null),
                            Type       = md.Type,
                            Language   = md.Language,
                        };

                        if (dict.ContainsKey(md.ID.ToString()))
                        {
                            var ii       = xxx[dict[md.ID.ToString()]];
                            dd.Uploader  = ii.Uploader;
                            dd.Published = DateTime.Parse(ii.Published);
                            dd.EHash     = ii.URL.Split('/')[5];
                            dd.Files     = ii.Files.Split(' ')[0].ToInt();
                            if (ii.Title.StartsWith("("))
                            {
                                dd.Class = ii.Title.Split("(")[1].Split(")")[0];
                            }
                        }

                        return(dd);
                    }));
                    db.Close();
                }

                Console.WriteLine("Complete-Korean");

                {
                    var db   = new SQLiteConnection("hitomidata-japanese.db");
                    var info = db.GetTableInfo(typeof(HitomiColumnModel).Name);
                    if (!info.Any())
                    {
                        db.CreateTable <HitomiColumnModel>();
                    }
                    db.InsertAll(HitomiData.Instance.metadata_collection.Where(md => md.Language == null || md.Language == "" || md.Language == "japanese").Select(md =>
                    {
                        var dd = new HitomiColumnModel
                        {
                            Id         = md.ID,
                            Artists    = (md.Artists != null && md.Artists.Length > 0 && md.Artists[0] != "" ? "|" + string.Join("|", md.Artists) + "|" : "N/A|"),
                            Characters = (md.Characters != null && md.Characters.Length > 0 && md.Characters[0] != "" ? "|" + string.Join("|", md.Characters) + "|" : null),
                            Groups     = (md.Groups != null && md.Groups.Length > 0 && md.Groups[0] != "" ? "|" + string.Join("|", md.Groups) + "|" : null),
                            Series     = (md.Parodies != null && md.Parodies.Length > 0 && md.Parodies[0] != "" ? "|" + string.Join("|", md.Parodies) + "|" : null),
                            Title      = md.Name,
                            Tags       = (md.Tags != null && md.Tags.Length > 0 && md.Tags[0] != "" ? "|" + string.Join("|", md.Tags) + "|" : null),
                            Type       = md.Type,
                            Language   = md.Language,
                        };

                        if (dict.ContainsKey(md.ID.ToString()))
                        {
                            var ii       = xxx[dict[md.ID.ToString()]];
                            dd.Uploader  = ii.Uploader;
                            dd.Published = DateTime.Parse(ii.Published);
                            dd.EHash     = ii.URL.Split('/')[5];
                            dd.Files     = ii.Files.Split(' ')[0].ToInt();
                            if (ii.Title.StartsWith("("))
                            {
                                dd.Class = ii.Title.Split("(")[1].Split(")")[0];
                            }
                        }

                        return(dd);
                    }));
                    db.Close();
                }

                Console.WriteLine("Complete-Japanese");

                {
                    var db   = new SQLiteConnection("hitomidata-english.db");
                    var info = db.GetTableInfo(typeof(HitomiColumnModel).Name);
                    if (!info.Any())
                    {
                        db.CreateTable <HitomiColumnModel>();
                    }
                    db.InsertAll(HitomiData.Instance.metadata_collection.Where(md => md.Language == null || md.Language == "" || md.Language == "english").Select(md =>
                    {
                        var dd = new HitomiColumnModel
                        {
                            Id         = md.ID,
                            Artists    = (md.Artists != null && md.Artists.Length > 0 && md.Artists[0] != "" ? "|" + string.Join("|", md.Artists) + "|" : "N/A|"),
                            Characters = (md.Characters != null && md.Characters.Length > 0 && md.Characters[0] != "" ? "|" + string.Join("|", md.Characters) + "|" : null),
                            Groups     = (md.Groups != null && md.Groups.Length > 0 && md.Groups[0] != "" ? "|" + string.Join("|", md.Groups) + "|" : null),
                            Series     = (md.Parodies != null && md.Parodies.Length > 0 && md.Parodies[0] != "" ? "|" + string.Join("|", md.Parodies) + "|" : null),
                            Title      = md.Name,
                            Tags       = (md.Tags != null && md.Tags.Length > 0 && md.Tags[0] != "" ? "|" + string.Join("|", md.Tags) + "|" : null),
                            Type       = md.Type,
                            Language   = md.Language,
                        };

                        if (dict.ContainsKey(md.ID.ToString()))
                        {
                            var ii       = xxx[dict[md.ID.ToString()]];
                            dd.Uploader  = ii.Uploader;
                            dd.Published = DateTime.Parse(ii.Published);
                            dd.EHash     = ii.URL.Split('/')[5];
                            dd.Files     = ii.Files.Split(' ')[0].ToInt();
                            if (ii.Title.StartsWith("("))
                            {
                                dd.Class = ii.Title.Split("(")[1].Split(")")[0];
                            }
                        }

                        return(dd);
                    }));
                    db.Close();
                }

                Console.WriteLine("Complete-English");

                {
                    var db   = new SQLiteConnection("hitomidata-chinese.db");
                    var info = db.GetTableInfo(typeof(HitomiColumnModel).Name);
                    if (!info.Any())
                    {
                        db.CreateTable <HitomiColumnModel>();
                    }
                    db.InsertAll(HitomiData.Instance.metadata_collection.Where(md => md.Language == null || md.Language == "" || md.Language == "chinese").Select(md =>
                    {
                        var dd = new HitomiColumnModel
                        {
                            Id         = md.ID,
                            Artists    = (md.Artists != null && md.Artists.Length > 0 && md.Artists[0] != "" ? "|" + string.Join("|", md.Artists) + "|" : "N/A|"),
                            Characters = (md.Characters != null && md.Characters.Length > 0 && md.Characters[0] != "" ? "|" + string.Join("|", md.Characters) + "|" : null),
                            Groups     = (md.Groups != null && md.Groups.Length > 0 && md.Groups[0] != "" ? "|" + string.Join("|", md.Groups) + "|" : null),
                            Series     = (md.Parodies != null && md.Parodies.Length > 0 && md.Parodies[0] != "" ? "|" + string.Join("|", md.Parodies) + "|" : null),
                            Title      = md.Name,
                            Tags       = (md.Tags != null && md.Tags.Length > 0 && md.Tags[0] != "" ? "|" + string.Join("|", md.Tags) + "|" : null),
                            Type       = md.Type,
                            Language   = md.Language,
                        };

                        if (dict.ContainsKey(md.ID.ToString()))
                        {
                            var ii       = xxx[dict[md.ID.ToString()]];
                            dd.Uploader  = ii.Uploader;
                            dd.Published = DateTime.Parse(ii.Published);
                            dd.EHash     = ii.URL.Split('/')[5];
                            dd.Files     = ii.Files.Split(' ')[0].ToInt();
                            if (ii.Title.StartsWith("("))
                            {
                                dd.Class = ii.Title.Split("(")[1].Split(")")[0];
                            }
                        }

                        return(dd);
                    }));
                    db.Close();
                }

                Console.WriteLine("Complete-Chinese");
            }
//#endif
        }
예제 #15
0
        /// <summary>
        /// E Hentai Magic Number를 이용해 작품 정보를 가져옵니다.
        /// </summary>
        /// <param name="magic_number"></param>
        /// <returns></returns>
        public static HArticleModel?GetArticleData(int magic_number)
        {
            string magic = magic_number.ToString();

            Monitor.Instance.Push($"[HCommander] [1] {magic}");

            //
            // 1. 히토미 데이터로 찾기
            //
            var search_hitomi = HitomiLegalize.GetMetadataFromMagic(magic);

            if (search_hitomi.HasValue)
            {
                // 히토미 데이터가 존재한다면 데이터의 유효 여부를 판단한다.
                try
                {
                    var url     = $"https://hitomi.la/galleries/{magic}.html";
                    var request = WebRequest.Create(url);
                    using (var response = request.GetResponse())
                    {
                        using (var responseStream = response.GetResponseStream())
                        {
                            // 최종 승인
                            return(ConvertTo(search_hitomi.Value, url, magic));
                        }
                    }
                }
                catch
                {
                }
            }

            Monitor.Instance.Push($"[HCommander] [2] {magic}");

            //
            // 2. Hiyobi를 이용해 탐색한다
            //
            if (search_hitomi.HasValue && search_hitomi.Value.Language == "korean")
            {
                try
                {
                    var html    = NetCommon.DownloadString(HiyobiCommon.GetInfoAddress(magic));
                    var article = HiyobiParser.ParseGalleryConents(html);
                    return(ConvertTo(article, HiyobiCommon.GetInfoAddress(magic), magic));
                }
                catch
                {
                }
            }

            Monitor.Instance.Push($"[HCommander] [3] {magic}");

            //
            // 9.3/4 샰쮘뽣?뛤3쇼뵀?gVA덲탭k융뷠킢쪳1SPS?XF퍵8C샜쁬
            //
            var f = ExHentaiData.data.AsParallel().Where(x => (x >> 40) == magic_number).ToList();

            if (f.Count > 0)
            {
                try
                {
                    //var url = $"https://e-hentai.org/g/{magic}/{f[0] ^ 1L * magic_number << 40:x}/";
                    //var html2 = NetCommon.DownloadExHentaiString(url);
                    //var article = EHentaiParser.ParseArticleData(html2);
                    //return ConvertTo(article, url, magic);
                    throw new Exception();
                }
                catch
                {
                    var url     = $"https://exhentai.org/g/{magic}/{f[0] ^ 1L * magic_number << 40:x}/";
                    var html2   = NetCommon.DownloadExHentaiString(url);
                    var article = ExHentaiParser.ParseArticleData(html2);
                    return(ConvertTo(article, url, magic));
                }
            }

            //
            // 3. GalleryBlock을 이용해 제목을 가져온다.
            //
            string title = "";

            try
            {
                var html    = NetCommon.DownloadString($"{HitomiCommon.HitomiGalleryBlock}{magic}.html");
                var article = HitomiParser.ParseGalleryBlock(html);
                title = article.Title;
            }
            catch
            {
                Monitor.Instance.Push($"[HCommander] [0] {magic}");
                return(null);
            }

            //
            // 4. 'Show Expunged Galleries' 옵션을 이용해 Ex-Hentai에서 검색한 후 정보를 가져온다.
            //
            try
            {
                var html = NetCommon.DownloadExHentaiString($"https://exhentai.org/?f_doujinshi=1&f_manga=1&f_artistcg=1&f_gamecg=1&f_western=1&f_non-h=1&f_imageset=1&f_cosplay=1&f_asianporn=1&f_misc=1&f_search={title}&page=0&f_apply=Apply+Filter&advsearch=1&f_sname=on&f_stags=on&f_sh=on&f_srdd=2");

                if (html.Contains($"/{magic}/"))
                {
                    var url     = Regex.Match(html, $"(https://exhentai.org/g/{magic}/\\w+/)").Value;
                    var html2   = NetCommon.DownloadExHentaiString(url);
                    var article = ExHentaiParser.ParseArticleData(html2);
                    return(ConvertTo(article, url, magic));
                }
            }
            catch
            { }

            Monitor.Instance.Push($"[HCommander] [0] {magic}");
            return(null);
        }
예제 #16
0
        private void textBox2_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                e.Handled          = true;
                e.SuppressKeyPress = true;

                textBox2.Text = textBox2.Text.Trim();

                PushString("dc-koromo@hitomi-copy$ " + textBox2.Text);
                string[] split = textBox2.Text.Trim().Split(' ');
                string   cmd   = split[0];

                if (cmd == "enum" || cmd == "enumi" || cmd == "enumx")
                {
                    if (textBox2.Text.Trim().Split(' ').Length == 1)
                    {
                        foreach (var f in Application.OpenForms)
                        {
                            PushString(f.GetType().Name);
                        }
                    }
                    else
                    {
                        try
                        {
                            string frm_name = textBox2.Text.Trim().Split(' ')[1];
                            if (cmd == "enum")
                            {
                                enum_recursion(Application.OpenForms[frm_name], textBox2.Text.Trim().Split(' '), 2, BindingFlags.Instance | BindingFlags.Public);
                            }
                            else if (cmd == "enumi")
                            {
                                enum_recursion(Application.OpenForms[frm_name], textBox2.Text.Trim().Split(' '), 2, default_bf);
                            }
                            else if (cmd == "enumx")
                            {
                                enum_recursion(Application.OpenForms[frm_name], textBox2.Text.Trim().Split(' '), 2);
                            }
                        }
                        catch (Exception ex)
                        {
                            PushString(ex.Message);
                        }
                    }
                }
                else if (cmd == "get")
                {
                    if (split.Length >= 3)
                    {
                        string frm = split[1];
                        string var = split[2];

                        try
                        {
                            PushString(LogEssential.SerializeObject(get_recursion(Application.OpenForms[frm], split, 2)));
                        }
                        catch (Exception ex)
                        {
                            PushString(ex.Message);
                        }
                    }
                    else if (split.Length >= 2 && split[1] == "hitomi_analysis")
                    {
                        PushString(string.Join("\r\n", HitomiAnalysis.Instance.Rank.Select(p => $"{p.Item1} ({p.Item2})")));
                        PushString($"Artist Counts : {HitomiAnalysis.Instance.Rank.Count}");
                    }
                    else
                    {
                        PushString("using 'get (Form) (Variable1) [Variable2] ...'");
                    }
                }
                else if (cmd == "set")
                {
                    if (split.Length >= 4)
                    {
                        string frm = split[1];
                        string var = split[2];
                        string val = split[3];

                        try
                        {
                            set_recurion(Application.OpenForms[frm], split, 2);
                        }
                        catch (Exception ex)
                        {
                            PushString(ex.Message);
                        }
                    }
                    else
                    {
                        PushString("using 'set (Form) (Variable1) [Variable2] ... [Value]'");
                    }
                }
                else if (cmd == "ra")
                {
                    if (split.Length > 1)
                    {
                        if (split[1] == "ulist")
                        {
                            PushString("User History");
                            HitomiAnalysisArtist user;
                            user = new HitomiAnalysisArtist(HitomiLog.Instance.GetEnumerator());
                            foreach (var pair in user.GetDictionary())
                            {
                                PushString($"{pair.Key} ({pair.Value})");
                            }
                        }
                        else if (split[1] == "list")
                        {
                            PushString("User Custom History");
                            if (HitomiAnalysis.Instance.CustomAnalysis != null)
                            {
                                HitomiAnalysis.Instance.CustomAnalysis.Sort((a, b) => a.Item2.CompareTo(b.Item2));
                                PushString(string.Join("\r\n", HitomiAnalysis.Instance.CustomAnalysis.Select(x => $"{x.Item1} ({x.Item2})")));
                            }
                        }
                        else if (split[1] == "clear")
                        {
                            HitomiAnalysis.Instance.CustomAnalysis.Clear();
                        }
                        else if (split[1] == "update")
                        {
                            HitomiAnalysis.Instance.Update();
                            (Application.OpenForms[0] as frmMain).UpdateNewStatistics();
                        }
                        else if (split[1] == "on")
                        {
                            HitomiAnalysis.Instance.UserDefined = true;
                        }
                        else if (split[1] == "off")
                        {
                            HitomiAnalysis.Instance.UserDefined = false;
                        }
                        else if (split[1] == "mion")
                        {
                            HitomiAnalysis.Instance.MustInclude = true;
                        }
                        else if (split[1] == "mioff")
                        {
                            HitomiAnalysis.Instance.MustInclude = false;
                        }
                        else if (split[1] == "rank")
                        {
                            PushString(string.Join("\r\n", HitomiAnalysis.Instance.Rank.ToArray().Reverse().Select(p => $"{p.Item1} ({p.Item2})")));
                            PushString($"Artist Counts : {HitomiAnalysis.Instance.Rank.Count}");
                        }
                        else if (split[1] == "add")
                        {
                            if (split.Length >= 3)
                            {
                                string artist = Regex.Replace(split[2], "_", " ");

                                bool found = false;
                                found = HitomiData.Instance.tagdata_collection.artist.Any(x => x.Tag == artist);

                                if (!found)
                                {
                                    PushString($"'{artist}' is not found.");
                                    string similar = "";
                                    int    diff    = int.MaxValue;
                                    HitomiData.Instance.tagdata_collection.artist.ForEach(x => { int diff_t = StringAlgorithms.get_diff(artist, x.Tag); if (diff_t < diff)
                                                                                                 {
                                                                                                     diff = diff_t; similar = x.Tag;
                                                                                                 }
                                                                                          });
                                    PushString($"Are you looking for '{similar}'?");
                                    return;
                                }

                                (Application.OpenForms[0] as frmMain).AddRecommendArtist(artist);
                            }
                            else
                            {
                                PushString("using 'ra add (artist)'");
                            }
                        }
                        else if (split[1] == "+")
                        {
                            if (split.Length >= 4)
                            {
                                try
                                {
                                    string tag = Regex.Replace(split[2], "_", " ");
                                    int    val = Convert.ToInt32(split[3]);

                                    bool found = false;
                                    found = HitomiData.Instance.tagdata_collection.female.Any(x => x.Tag == tag);
                                    if (found == false)
                                    {
                                        found = HitomiData.Instance.tagdata_collection.male.Any(x => x.Tag == tag);
                                    }
                                    if (found == false)
                                    {
                                        found = HitomiData.Instance.tagdata_collection.tag.Any(x => x.Tag == tag);
                                    }

                                    if (!found)
                                    {
                                        PushString($"'{tag}' is not found.");
                                        string similar = "";
                                        int    diff    = int.MaxValue;
                                        HitomiData.Instance.tagdata_collection.female.ForEach(x => { int diff_t = StringAlgorithms.get_diff(tag, x.Tag); if (diff_t < diff)
                                                                                                     {
                                                                                                         diff = diff_t; similar = x.Tag;
                                                                                                     }
                                                                                              });
                                        HitomiData.Instance.tagdata_collection.male.ForEach(x => { int diff_t = StringAlgorithms.get_diff(tag, x.Tag); if (diff_t < diff)
                                                                                                   {
                                                                                                       diff = diff_t; similar = x.Tag;
                                                                                                   }
                                                                                            });
                                        HitomiData.Instance.tagdata_collection.tag.ForEach(x => { int diff_t = StringAlgorithms.get_diff(tag, x.Tag); if (diff_t < diff)
                                                                                                  {
                                                                                                      diff = diff_t; similar = x.Tag;
                                                                                                  }
                                                                                           });
                                        PushString($"Are you looking for '{similar}'?");
                                        return;
                                    }

                                    if (HitomiAnalysis.Instance.CustomAnalysis.Any(x => x.Item1 == tag))
                                    {
                                        for (int i = 0; i < HitomiAnalysis.Instance.CustomAnalysis.Count; i++)
                                        {
                                            if (HitomiAnalysis.Instance.CustomAnalysis[i].Item1 == tag)
                                            {
                                                HitomiAnalysis.Instance.CustomAnalysis[i] = new Tuple <string, int>(tag, val);
                                            }
                                        }
                                    }
                                    else
                                    {
                                        HitomiAnalysis.Instance.CustomAnalysis.Add(new Tuple <string, int>(tag, val));
                                    }
                                }
                                catch (Exception ex)
                                {
                                    PushString(ex.Message);
                                }
                            }
                            else if (split.Length == 3)
                            {
                                string tag = Regex.Replace(split[2], "_", " ");
                                List <Tuple <string, int, int> > diff = new List <Tuple <string, int, int> >();
                                HitomiData.Instance.tagdata_collection.female.ForEach(x => diff.Add(new Tuple <string, int, int>(x.Tag, StringAlgorithms.get_diff(tag, x.Tag), x.Count)));
                                HitomiData.Instance.tagdata_collection.male.ForEach(x => diff.Add(new Tuple <string, int, int>(x.Tag, StringAlgorithms.get_diff(tag, x.Tag), x.Count)));
                                HitomiData.Instance.tagdata_collection.tag.ForEach(x => diff.Add(new Tuple <string, int, int>(x.Tag, StringAlgorithms.get_diff(tag, x.Tag), x.Count)));
                                diff.Sort((a, b) => a.Item2.CompareTo(b.Item2));
                                for (int i = 5; i >= 0; i--)
                                {
                                    PushString($"{diff[i].Item1} [{diff[i].Item3}]");
                                }
                                return;
                            }
                            else
                            {
                                PushString("'+' command need 2 more parameters.");
                            }
                        }
                        else if (split[1] == "+a")
                        {
                            if (split.Length >= 3)
                            {
                                try
                                {
                                    string artist = Regex.Replace(split[2], "_", " ");

                                    bool found = false;
                                    found = HitomiData.Instance.tagdata_collection.artist.Any(x => x.Tag == artist);

                                    if (!found)
                                    {
                                        PushString($"'{artist}' is not found.");
                                        string similar = "";
                                        int    diff    = int.MaxValue;
                                        HitomiData.Instance.tagdata_collection.artist.ForEach(x => { int diff_t = StringAlgorithms.get_diff(artist, x.Tag); if (diff_t < diff)
                                                                                                     {
                                                                                                         diff = diff_t; similar = x.Tag;
                                                                                                     }
                                                                                              });
                                        PushString($"Are you looking for '{similar}'?");
                                        return;
                                    }

                                    foreach (var data in HitomiData.Instance.metadata_collection)
                                    {
                                        if (!HitomiSetting.Instance.GetModel().RecommendLanguageALL)
                                        {
                                            string lang = data.Language;
                                            if (data.Language == null)
                                            {
                                                lang = "N/A";
                                            }
                                            if (HitomiSetting.Instance.GetModel().Language != "ALL" &&
                                                HitomiSetting.Instance.GetModel().Language != lang)
                                            {
                                                continue;
                                            }
                                        }
                                        if (data.Artists != null && data.Tags != null && data.Artists.Contains(artist))
                                        {
                                            foreach (var tag in data.Tags)
                                            {
                                                if (HitomiAnalysis.Instance.CustomAnalysis.Any(x => x.Item1 == tag))
                                                {
                                                    for (int i = 0; i < HitomiAnalysis.Instance.CustomAnalysis.Count; i++)
                                                    {
                                                        if (HitomiAnalysis.Instance.CustomAnalysis[i].Item1 == tag)
                                                        {
                                                            HitomiAnalysis.Instance.CustomAnalysis[i] = new Tuple <string, int>(tag, HitomiAnalysis.Instance.CustomAnalysis[i].Item2 + 1);
                                                        }
                                                    }
                                                }
                                                else
                                                {
                                                    HitomiAnalysis.Instance.CustomAnalysis.Add(new Tuple <string, int>(tag, 1));
                                                }
                                            }
                                        }
                                    }
                                }
                                catch (Exception ex)
                                {
                                    PushString(ex.Message);
                                }
                            }
                            else
                            {
                                PushString("'+a' command need 1 more parameters.");
                            }
                        }
                        else if (split[1] == "-")
                        {
                            if (split.Length >= 3)
                            {
                                string tag = Regex.Replace(split[2], "_", " ");
                                for (int i = 0; i < HitomiAnalysis.Instance.CustomAnalysis.Count; i++)
                                {
                                    if (HitomiAnalysis.Instance.CustomAnalysis[i].Item1 == tag)
                                    {
                                        HitomiAnalysis.Instance.CustomAnalysis.RemoveAt(i--);
                                    }
                                }
                            }
                        }
                        else
                        {
                            PushString($"'{split[1]}' is not a valid command option.");
                        }
                    }
                    else
                    {
                        PushString("using 'ra (option) [tag] [count] ...'");
                        PushString("  (option): ulist, list, clear, update, on, off, mion, mioff, rank, add, +, +a");
                    }
                }
                else if (cmd == "install")
                {
                    if (split.Length > 1)
                    {
                        if (split[1] == "driver")
                        {
                            try
                            {
                                const string driver_url = "https://github.com/dc-koromo/hitomi-downloader-2/releases/download/driver/driver.exe";
                                PushString($"Please wait ...");
                                string temp = Path.GetTempFileName();

                                using (var wc = new System.Net.WebClient())
                                    wc.DownloadFile(driver_url,
                                                    Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "driver.exe"));

                                PushString("Complete!");
                            }
                            catch (Exception ex)
                            {
                                PushString(ex.Message);
                            }
                        }
                        else
                        {
                            PushString($"'{split[1]}' is not a valid command option.");
                        }
                    }
                    else
                    {
                        PushString("using 'install [option]'");
                        PushString("  (install): driver");
                    }
                }
                else if (cmd == "hi")
                {
                    // Hitomi
                    if (split.Length > 1)
                    {
                    }
                }
                else if (cmd == "exh")
                {
                    // ExHentai
                    if (split.Length > 1)
                    {
                        if (split[1] == "info")
                        {
                            if (split.Length > 2)
                            {
                                try
                                {
                                    string          article_source = frmMain.GetEXHWebClient().DownloadString(new Uri(split[2]));
                                    ExHentaiArticle article        = ExHentaiParser.GetArticleData(article_source);
                                    LogEssential.Instance.PushLog(article);
                                }
                                catch (Exception ex)
                                {
                                    PushString(ex.Message);
                                }
                            }
                            else
                            {
                                PushString("'info' command need 1 more parameter, url.");
                            }
                        }
                        else if (split[1] == "comment")
                        {
                            if (split.Length > 2)
                            {
                                try
                                {
                                    string          article_source = frmMain.GetEXHWebClient().DownloadString(new Uri(split[2]));
                                    ExHentaiArticle article        = ExHentaiParser.GetArticleData(article_source);
                                    foreach (var tuple in article.comment)
                                    {
                                        PushString($"{tuple.Item2} - {tuple.Item1.ToString()}");
                                        PushString(tuple.Item3);
                                    }
                                }
                                catch (Exception ex)
                                {
                                    PushString(ex.Message);
                                }
                            }
                            else
                            {
                                PushString("'comment' command need 1 more parameter, url.");
                            }
                        }
                        else
                        {
                            PushString($"'{split[1]}' command not found.");
                        }
                    }
                    else
                    {
                        PushString("using 'exh [option] [var1] [var2] ...'");
                        PushString("  (option): info, comment");
                    }
                }
                else if (cmd == "help")
                {
                    PushString("Realtime Variable Update System");
                    PushString("Copyright (C) 2018. Hitomi Parser Developers");
                    PushString("");
                    PushString("enum [Form] [Variable1] [Variable2] ... : Enumerate form or class members.");
                    PushString("enumi [Form] [Variable1] [Variable2] ... : Enumerate form or class members with private members.");
                    PushString("enumx [Form] [Variable1] [Variable2] ... : Enumerate all class members without static.");
                    PushString("get (Form|hitomi_analysis) (Variable1) [Variable2] ... : Get value.");
                    PushString("set (Form) (Variable1) [Variable2] ... [Value] : Set value.");
                    PushString("fucs : Frequently Used Command Snippet");
                    PushString("ra (option) [var1] [var2] ... : Recommend artists tools.");
                    PushString("install (option) : Download external procedure.");
                    PushString("exh [option] [var1] [var2] ... : Ex-hentai tools");
                }
                else if (cmd == "fucs")
                {
                    PushString("get frmMain latest_load_count");
                    PushString("   - get Recommend scroll status");
                    PushString("set frmMain latest_load_count 100");
                    PushString("   - set Recommend scroll status to 100");
                }
                else
                {
                    PushString("Command not found. Try 'help' command.");
                }

                cmd_stack.Insert(0, textBox2.Text + " ");
                textBox2.Text = "";
                stack_pointer = 0;
            }
            else if (e.KeyCode == Keys.Up)
            {
                if (textBox2.Text == "")
                {
                    stack_pointer = 0;
                }
                if (stack_pointer >= cmd_stack.Count)
                {
                    stack_pointer = cmd_stack.Count - 1;
                }
                if (stack_pointer >= 0)
                {
                    textBox2.Text = cmd_stack[stack_pointer];
                    Application.DoEvents();
                    textBox2.Focus();
                    textBox2.SelectionStart  = Math.Max(0, textBox2.Text.Length * 10);
                    textBox2.SelectionLength = 0;
                    textBox2.Focus();
                }
                stack_pointer++;
            }
            else if (e.KeyCode == Keys.Down)
            {
                textBox2.SelectionStart  = Math.Max(0, textBox2.Text.Length - 1);
                textBox2.SelectionLength = 0;
            }
        }
예제 #17
0
 private void wc_image_cb(object sender, DownloadStringCompletedEventArgs e)
 {
     ImageLinkCallback(ExHentaiParser.GetImagesAddress(e.Result), e.UserState as ExHentaiArticle);
 }
예제 #18
0
        public void SyncExHentai()
        {
            var result = new List <EHentaiResultArticle>();

            for (int i = 0; i < 9999999; i++)
            {
                try
                {
                    //var task = NetTask.MakeDefault($"https://exhentai.org/?page={i}&f_doujinshi=on&f_manga=on&f_artistcg=on&f_gamecg=on&&f_cats=0&f_sname=on&f_stags=on&f_sh=on&advsearch=1&f_srdd=2&f_sname=on&f_stags=on&f_sdesc=on&f_sh=on");
                    //task.Cookie = "igneous=30e0c0a66;ipb_member_id=2742770;ipb_pass_hash=6042be35e994fed920ee7dd11180b65f;sl=dm_2";
                    //var html = NetTools.DownloadString(task);
                    var url = $"https://exhentai.org/?page={i}&f_doujinshi=on&f_manga=on&f_artistcg=on&f_gamecg=on&&f_cats=0&f_sname=on&f_stags=on&f_sh=on&advsearch=1&f_srdd=2&f_sname=on&f_stags=on&f_sdesc=on&f_sh=on";
                    var wc  = new WebClient();
                    wc.Encoding = Encoding.UTF8;
                    wc.Headers.Add(HttpRequestHeader.Accept, "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");
                    wc.Headers.Add(HttpRequestHeader.UserAgent, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36");
                    wc.Headers.Add(HttpRequestHeader.Cookie, "igneous=30e0c0a66;ipb_member_id=2742770;ipb_pass_hash=6042be35e994fed920ee7dd11180b65f;sl=dm_2");
                    var html = wc.DownloadString(url);

                    try
                    {
                        var exh = ExHentaiParser.ParseResultPageExtendedListView(html);
                        result.AddRange(exh);
                        if (exh.Count != 25)
                        {
                            Logs.Instance.PushWarning("[Miss] " + url);
                        }
                        if (i > exhentaiLookupPage && exh.Min(x => x.URL.Split('/')[4].ToInt()) < latestId)
                        {
                            break;
                        }
                        Logs.Instance.Push("Parse exh page - " + i);
                    }
                    catch (Exception e)
                    {
                        Logs.Instance.PushError("[Fail] " + url);
                    }
                }
                catch (Exception e)
                {
                    Logs.Instance.PushError($"{i} {e.Message}");
                }
                Thread.Sleep(100);

                if (i % 1000 == 999)
                {
                    Thread.Sleep(60000);
                }
            }

            var xxx = JsonConvert.DeserializeObject <List <EHentaiResultArticle> >(File.ReadAllText("ex-hentai-archive.json"));

            File.Move("ex-hentai-archive.json", $"ex-hentai-archive-{DateTime.Now.Ticks}.json");

            var exists = new HashSet <int>();

            xxx.ForEach(x => exists.Add(x.URL.Split('/')[4].ToInt()));

            foreach (var z in result)
            {
                var nn = z.URL.Split('/')[4].ToInt();

                if (!exists.Contains(nn))
                {
                    newedDataEH.Add(nn);
                    xxx.Add(z);
                }
            }

            JsonSerializer serializer = new JsonSerializer();

            serializer.Converters.Add(new JavaScriptDateTimeConverter());
            serializer.NullValueHandling = NullValueHandling.Ignore;

            Logs.Instance.Push("Write file: ex-hentai-archive.json");
            using (StreamWriter sw = new StreamWriter("ex-hentai-archive.json"))
                using (JsonWriter writer = new JsonTextWriter(sw))
                {
                    serializer.Serialize(writer, xxx);
                }
        }