コード例 #1
0
ファイル: PageDownloaderJob.cs プロジェクト: NHxD/NHxD
        private static void DownloadPagesBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker    backgroundWorker = sender as BackgroundWorker;
            DownloadPagesRunArg runArg           = e.Argument as DownloadPagesRunArg;
            Metadata            metadata         = runArg.SearchResultCache.Find(runArg.Id);

            if (metadata == null)
            {
                string metadataFilePath;

                if (runArg.PathFormatter.IsEnabled)
                {
                    metadataFilePath = runArg.PathFormatter.GetMetadata(runArg.Id);
                }
                else
                {
                    // NOTE: must be an absolute path for the webbrowser to display the images correctly.
                    metadataFilePath = string.Format(CultureInfo.InvariantCulture, "{0}{1}{2}", runArg.PathFormatter.GetCacheDirectory(), runArg.Id, ".json");
                }

                metadata = JsonUtility.LoadFromFile <Metadata>(metadataFilePath);

                if (metadata == null)
                {
                    // TODO? redownload it instead of aborting?

                    e.Result = runArg.Id;
                    //e.Cancel = true;
                    return;
                }
            }

            int maxCount = (runArg.PageIndices != null && runArg.PageIndices.Length > 0) ?
                           runArg.PageIndices.Count() : metadata.Images.Pages.Count;
            int loadCount = 0;

            int[] cachedPageIndices = runArg.CacheFileSystem.GetCachedPageIndices(metadata.Id);
            int   cacheCount        = cachedPageIndices.Length;

            for (int i = 0; i < metadata.Images.Pages.Count; ++i)
            {
                if (backgroundWorker.CancellationPending)
                {
                    PageDownloadCompletedArg cancelledArg = new PageDownloadCompletedArg(loadCount, maxCount, cacheCount, metadata);

                    e.Result = cancelledArg;
                    //e.Cancel = true;
                    return;
                }

                string error = "";
                string pageCachedFilePath;
                if (runArg.PathFormatter.IsEnabled)
                {
                    pageCachedFilePath = runArg.PathFormatter.GetPage(metadata, i);
                }
                else
                {
                    string paddedIndex = (i + 1).ToString(CultureInfo.InvariantCulture).PadLeft(global::NHxD.Frontend.Winforms.PathFormatter.GetBaseCount(metadata.Images.Pages.Count), '0');

                    pageCachedFilePath = string.Format(CultureInfo.InvariantCulture, "{0}{1}/{2}{3}",
                                                       runArg.PathFormatter.GetCacheDirectory(), metadata.Id, paddedIndex, metadata.Images.Pages[i].GetFileExtension()).Replace('\\', '/');
                }

                bool shouldFilter = (runArg.PageIndices != null && runArg.PageIndices.Length > 0) ?
                                    ShouldFilterPage(metadata, i, runArg.PageIndices)
                                        : false;

                if (shouldFilter)
                {
                    pageCachedFilePath = "";
                    error = "SKIP";
                }
                else
                {
                    ++loadCount;

                    if (!File.Exists(pageCachedFilePath))
                    {
                        try
                        {
                            var mediaServerId = -1;

                            {
                                var url = $"https://nhentai.net/g/{metadata.Id}/{i + 1}/";

                                Program.Logger.LogLine($"Downloading gallery webpage {url}...");

                                using (var response = Task.Run(() => runArg.HttpClient?.GetAsync(url, HttpCompletionOption.ResponseHeadersRead)).GetAwaiter().GetResult())
                                {
                                    if (!response.IsSuccessStatusCode)
                                    {
                                        Program.Logger.ErrorLine($"{response.ReasonPhrase} ({response.StatusCode})");
                                        response.EnsureSuccessStatusCode();
                                    }
                                    else
                                    {
                                        var html = Task.Run(() => response.Content.ReadAsStringAsync()).GetAwaiter().GetResult();
                                        var mediaServerIdRegExp = new Regex(@"media_server:\s*(\d+),");
                                        var mediaServerIdMatch  = mediaServerIdRegExp.Match(html);

                                        if (!mediaServerIdMatch.Success)
                                        {
                                            throw new Exception("Could not find media server id.");
                                        }
                                        else
                                        {
                                            mediaServerId = int.Parse(mediaServerIdMatch.Groups[1].Value);
                                        }
                                    }
                                }
                            }

                            string uri = string.Format(CultureInfo.InvariantCulture, "https://i{3}.nhentai.net/galleries/{0}/{1}{2}", metadata.MediaId, i + 1, metadata.Images.Pages[i].GetFileExtension(), mediaServerId);

                            Program.Logger.LogLine($"Downloading gallery page {uri}...");

                            using (HttpResponseMessage response = Task.Run(() => runArg.HttpClient?.GetAsync(uri, HttpCompletionOption.ResponseHeadersRead)).GetAwaiter().GetResult())
                            {
                                if (!response.IsSuccessStatusCode)
                                {
                                    Program.Logger.ErrorLine($"{response.ReasonPhrase} ({response.StatusCode})");
                                    response.EnsureSuccessStatusCode();
                                }
                                else
                                {
                                    byte[] imageData = Task.Run(() => response.Content.ReadAsByteArrayAsync()).GetAwaiter().GetResult();

                                    // TODO: the issue is that I have designed things to be immutable so metadatas can't change.
                                    // but even if I do change the metadata and replace it in the searchResult,
                                    // it won't affect other cached searchResults with the same metadata. (because searchresults embed metadatas directly instead of storing indices to them)
                                    // so I might be able to save the changes to the metadata (file), one searchResult, but not everything (without greatly impacting performances)

                                    /*
                                     * //if (runArg.FixFileExtension)
                                     * {
                                     *      ImageType pageImageType = metadata.Images.Pages[i].Type;
                                     *      ImageType? realPageImageType = null;
                                     *
                                     *      if (imageData.Length >= 8
                                     *              && imageData.Match(0, 8, PngFileSignature))
                                     *      {
                                     *              realPageImageType = ImageType.Png;
                                     *      }
                                     *      else if (imageData.Length >= 8
                                     *              && imageData.Match(0, 2, JfifStartOfImageSegmentHeader)
                                     *              && imageData.Match(2, 2, JfifStartOfImageSegmentHeader)
                                     *              && imageData.Match(6, 5, JfifApp0SegmentSegmentIdentifier))
                                     *      {
                                     *              realPageImageType = ImageType.Jpeg;
                                     *      }
                                     *      else if (imageData.Length >= 8
                                     *              && imageData.Match(0, 8, GifFileSignature))
                                     *      {
                                     *              realPageImageType = ImageType.Gif;
                                     *      }
                                     *      else
                                     *      {
                                     *              // unknown format.
                                     *      }
                                     *
                                     *      if (pageImageType != realPageImageType)
                                     *      {
                                     *
                                     *      }
                                     * }
                                     */
                                    Directory.CreateDirectory(Path.GetDirectoryName(pageCachedFilePath));
                                    File.WriteAllBytes(pageCachedFilePath, imageData);

                                    ++cacheCount;
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            //pageCachedFilePath = "";
                            error = ex.Message;

                            Program.Logger.ErrorLine(ex.ToString());
                        }
                    }
                }

                PageDownloadProgressArg progressArg = new PageDownloadProgressArg(loadCount, maxCount, cacheCount, i, metadata, pageCachedFilePath, 0, 0, error);

                backgroundWorker.ReportProgress((int)(loadCount / (float)maxCount * 100), progressArg);
            }

            PageDownloadCompletedArg completedArg = new PageDownloadCompletedArg(loadCount, maxCount, cacheCount, metadata);

            e.Result = completedArg;
        }
コード例 #2
0
ファイル: PageDownloaderJob.cs プロジェクト: NHxD/NHxD
        private void DownloadPagesBackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            PageDownloadProgressArg arg = e.UserState as PageDownloadProgressArg;

            OnPageDownloadReportProgress(new PageDownloadReportProgressEventArgs(arg.LoadCount, arg.LoadTotal, arg.CacheCount, arg.PageIndex, arg.Metadata, arg.PageCachedFilePath, arg.DownloadedBytes, arg.DownloadSize, arg.Error));
        }