Esempio n. 1
0
 public DownloadListenerContext(ComicDownloadRequest request, ComicChapter chapter, ComicPage page, CancellationToken token)
 {
     Request = request;
     Chapter = chapter;
     Page    = page;
     Token   = token;
 }
Esempio n. 2
0
        protected override async Task <ComicPage[]> GetPagesAsync(ComicChapter chapter)
        {
            ComicPage[] res = null;
            if (UseStore)
            {
                res = await GetAsAsync <ComicPage[]>(chapter.TargetUrl);
            }
            if (res is null)
            {
                var remoteFetch = AppEngine.GetService <RemoteEngine>();
                if (remoteFetch != null && EnableRemote)
                {
                    res = await RemoteFetchPagesAsync(remoteFetch, chapter.TargetUrl);

                    if (res is null)
                    {
                        res = await base.GetPagesAsync(chapter);
                    }
                }
                else
                {
                    res = await base.GetPagesAsync(chapter);
                }
            }
            return(res);
        }
Esempio n. 3
0
 public DownloadExceptionListenerContext(ComicDownloadRequest request, ComicChapter chapter,
                                         ComicPage page, CancellationToken token,
                                         Exception exception)
     : base(request, chapter, page, token)
 {
     Exception = exception;
 }
Esempio n. 4
0
        protected override async Task <ComicPage[]> GetPagesAsync(ComicChapter chapter)
        {
            if (Entity is null)
            {
                return(null);
            }
            var entity = await rootFetcher.FetchChapterAsync(Entity.ComicUrl, chapter.TargetUrl);

            return(entity?.Pages);
        }
Esempio n. 5
0
        public async Task <IActionResult> Content(Guid chapterId)
        {
            if (await _chapterManager.GetById(chapterId) is var chapter && chapter == null)
            {
                return(NotFound());
            }

            if (await _titlesManager.GetById(chapter.TitleId) is var title && title == null)
            {
                return(NotFound());
            }

            if (!title.Visible || !chapter.Visible)
            {
                return(NotFound());
            }

            object result = chapter switch
            {
                ComicChapter comicChapter => new
                {
                    chapter.Id,
                    chapter.Volume,
                    chapter.Number,
                    chapter.Name,
                    chapter.ReleaseDate,
                    chapter.TitleId,
                    Pages = (await _pagesManager.GetAll(comicChapter)).Select(page => (ComicPage)page).OrderBy(page => page.Number).Select(page => new
                    {
                        page.Id,
                        page.Number,
                        pageUrl = $"/content/{comicChapter.TitleId}/{comicChapter.Id}/{page.Id}{(page.Animated ? ".gif" : ".png")}"
                    }).ToArray()
                },
                NovelChapter novelChapter => new
                {
                    chapter.Id,
                    chapter.Volume,
                    chapter.Number,
                    chapter.Name,
                    chapter.ReleaseDate,
                    chapter.TitleId,
                    novelChapter.Content,
                    Pages = (await _pagesManager.GetAll(novelChapter)).Select(page => new
                    {
                        page.Id,
                        pageUrl = $"/content/{novelChapter.TitleId}/{novelChapter.Id}/{page.Id}{(page.Animated ? ".gif" : ".png")}"
                    }).ToArray()
                },
                _ => throw new ArgumentException($"{chapter.GetType().Name} is not a supported type.")
            };

            return(Json(result));
        }
Esempio n. 6
0
 public ComicDownloadContext(ComicEntity entity,
                             ComicChapter chapter,
                             ComicPage page,
                             Stream sourceStream,
                             CancellationToken token)
 {
     Token        = token;
     Entity       = entity;
     Chapter      = chapter;
     Page         = page;
     SourceStream = sourceStream;
 }
Esempio n. 7
0
        public void GivenValueInit_PropertyValueMustEqualGiven()
        {
            var chapter = new ComicChapter();
            var page    = new ComicPage();
            var req     = new DownloadItemRequest(chapter, page);

            Assert.AreEqual(chapter, req.Chapter);
            Assert.AreEqual(page, req.Page);
            req = new DownloadItemRequest(page);
            Assert.IsNull(req.Chapter);
            Assert.AreEqual(page, req.Page);
        }
Esempio n. 8
0
        public async Task <ComicEntity> GetChaptersAsync(string targetUrl)
        {
            var str = string.Empty;

            using (var sr = new StreamReader(await GetStreamAsync(targetUrl)))
            {
                str = sr.ReadToEnd();
            }
            var html = new HtmlDocument();

            html.LoadHtml(str);

            var block      = html.DocumentNode.SelectNodes("//ul[@id='detail-list-select-1']/li/a");
            var hideBlock  = html.DocumentNode.SelectNodes("//ul[@id='detail-list-select-1']/ul[@class='chapteritem']/li/a");
            var titleBlock = html.DocumentNode.SelectSingleNode("//div[@class='banner_detail_form']/div[@class='info']/p[@class='title']")?.ChildNodes[0].InnerText;

            if (titleBlock == null)
            {
                titleBlock = targetUrl.Split(targetUrlSplit, StringSplitOptions.RemoveEmptyEntries)
                             .Last();
            }
            var descBlock = html.DocumentNode.SelectSingleNode("//div[@class='banner_detail_form']/div[@class='info']/p[@class='content']");
            var imgBlock  = html.DocumentNode.SelectSingleNode("//div[@class='banner_detail_form']/div[@class='cover']/img");
            var caps      = new List <ComicChapter>();
            IEnumerable <HtmlNode> blocks = block;

            if (hideBlock != null)
            {
                blocks = blocks.Concat(hideBlock);
            }
            foreach (var item in blocks)
            {
                var url  = item.Attributes["href"];
                var text = item.ChildNodes[0].InnerText;
                var cap  = new ComicChapter
                {
                    TargetUrl = GetBaseAddress() + url?.Value,
                    Title     = text?.Trim()
                };
                caps.Add(cap);
            }
            caps.Reverse();
            return(new ComicEntity
            {
                Chapters = caps.ToArray(),
                Descript = descBlock?.InnerText,
                ComicUrl = targetUrl,
                ImageUrl = imgBlock?.Attributes["src"]?.Value,
                Name = titleBlock?.Trim()
            });
        }
Esempio n. 9
0
        public async Task <ComicEntity> GetChaptersAsync(string targetUrl)
        {
            var mc   = new Uri(targetUrl).Segments.Last();
            var part = mc.Remove(0, 2);

            using (var mem = GetStream())
            {
                var arg = $"{{\"comic_id\":{part}}}";
                WrtieStream(mem, arg);
                var stream = await GetStreamAsync(detailUri, "POST", mem);

                string str = null;
                using (var sr = new StreamReader(stream))
                {
                    str = sr.ReadToEnd();
                }
                using (var jobj = JsonVisitor.FromString(str))
                {
                    var data   = jobj["data"];
                    var entity = new ComicEntity
                    {
                        Name     = data["title"].ToString(),
                        Descript = data["evaluate"].ToString(),
                        ComicUrl = targetUrl,
                        ImageUrl = data["vertical_cover"].ToString()
                    };
                    var ep     = data["ep_list"].ToEnumerable();
                    var len    = ep.Count();
                    var chapts = new List <ComicChapter>(ep.Count());
                    foreach (var item in ep)
                    {
                        var title = item["title"].ToString();
                        if (string.IsNullOrWhiteSpace(title))
                        {
                            title = entity.Name + "-" + (len - chapts.Count);
                        }
                        var id  = item["id"].ToString();
                        var url = "https://manga.bilibili.com/" + mc + "/mc" + id;
                        var chp = new ComicChapter
                        {
                            TargetUrl = url,
                            Title     = title
                        };
                        chapts.Add(chp);
                    }
                    chapts.Reverse();
                    entity.Chapters = chapts.ToArray();
                    return(entity);
                }
            }
        }
Esempio n. 10
0
        public void GivenValue_PropertyValueMustEqualGiven()
        {
            var saver = new NullComicSaver();
            var req   = new DownloadItemRequest[0];
            var prov  = new NullSourceProvider();
            var eq    = new ComicDownloadRequest(saver, null, null, req, prov);
            var chp   = new ComicChapter();
            var page  = new ComicPage();
            var ctx   = new DownloadListenerContext(eq, chp, page, default);

            Assert.AreEqual(eq, ctx.Request);
            Assert.AreEqual(chp, ctx.Chapter);
            Assert.AreEqual(page, ctx.Page);
            Assert.AreEqual(CancellationToken.None, ctx.Token);
        }
Esempio n. 11
0
        public async Task <IActionResult> ChapterJson(Guid chapterId)
        {
            if (await _chapterManager.GetById(chapterId) is var chapter && chapter == null)
            {
                return(Json(new
                {
                    success = false,
                    messages = new[] { ValidationMessages.ChapterNotFound }
                }));
            }

            var title = await _titlesManager.GetById(chapter.TitleId);

            if (!_signInManager.IsSignedIn(User) && (!title !.Visible || !chapter.Visible))
            {
                return(Json(new
                {
                    success = false,
                    messages = new[] { ValidationMessages.ContentNotAvailable }
                }));
            }

            object result = chapter switch
            {
                ComicChapter comicChapter => new
                {
                    success = true,
                    Pages   = (await _pagesManager.GetAll(comicChapter)).Select(page => (ComicPage)page).OrderBy(page => page.Number).Select(page => new
                    {
                        number  = page.Number,
                        address = $"/content/{comicChapter.TitleId}/{comicChapter.Id}/{page.Id}{(page.Animated ? ".gif" : ".png")}"
                    }).ToArray()
                },
                NovelChapter novelChapter => new
                {
                    success = true,
                    content = novelChapter.Content.AddImgLazyLoading("/assets/placeholder_page.png")
                },
                _ => new
                {
                    success = false
                }
            };

            return(Json(result));
        }
Esempio n. 12
0
        public async Task <ComicEntity> GetChaptersAsync(string targetUrl)
        {
            var str = string.Empty;

            using (var sr = new StreamReader(await CreateRequest(targetUrl)))
            {
                str = await sr.ReadToEndAsync();
            }
            var html = new HtmlDocument();

            html.LoadHtml(str);
            var title = html.DocumentNode.SelectSingleNode("//div[@class='TopicList']/div/div[@class='right fl']/h3")?.InnerText;

            if (title == null)
            {
                title = targetUrl.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries).LastOrDefault();
            }
            var desc  = html.DocumentNode.SelectSingleNode("//div[@class='comicIntro']/div[@class='details']/div/p");
            var nodes = html.DocumentNode.SelectNodes("//div[@class='TopicItem cls']");
            var img   = html.DocumentNode.SelectSingleNode("//div[@class='TopicItem cls']/div[@class='left fl']/img[@class='imgCover']");
            var caps  = new List <ComicChapter>();

            foreach (var item in nodes)
            {
                var a    = item.SelectSingleNode("div[@class='cover fl']/a");
                var href = a.Attributes["href"];
                var imgs = a.SelectNodes("img")[1];
                var dt   = imgs.Attributes["alt"];
                var chap = new ComicChapter
                {
                    TargetUrl = "https://www.kuaikanmanhua.com/" + href.Value,
                    Title     = dt.Value
                };
                caps.Add(chap);
            }
            caps.Reverse();
            return(new ComicEntity
            {
                Chapters = caps.ToArray(),
                Name = title,
                Descript = desc?.InnerText,
                ComicUrl = targetUrl,
                ImageUrl = img?.Attributes["src"]?.Value
            });
        }
Esempio n. 13
0
        protected virtual async Task StorePageAsync(ComicEntity entity, ComicChapter chapter, ComicPage page)
        {
            KeepingAction?.Invoke(entity, chapter, page, null, KeepingActionTypes.BeginStorePage);
            OnBeginStorePage(chapter, page);
            try
            {
                var mode = WriteMode;
                if (mode == ComicStoreWriteModes.NotExists)
                {
                    var ok = await storeService.ExistsAsync(page.TargetUrl);

                    if (ok)
                    {
                        KeepingAction?.Invoke(entity, chapter, page, null, KeepingActionTypes.EndStorePage);
                        OnEndStorePage(chapter, page, false);
                        return;
                    }
                }
                var path = page.TargetUrl;
                if (HasImageFolderName)
                {
                    path = string.Concat(ImageFolderName, "/", page.TargetUrl);
                }
                var stream = await fetchService.GetStreamAsync(page.TargetUrl);

                if (stream is null)
                {
                    stream = await Provider.GetImageStreamAsync(page.TargetUrl);

                    if (fetchService != storeService)
                    {
                        await fetchService.SaveAsync(path, stream);
                    }
                }
                stream.Seek(0, SeekOrigin.Begin);
                await storeService.SaveAsync(path, stream);
            }
            catch (Exception ex)
            {
                KeepingAction?.Invoke(entity, chapter, page, ex, KeepingActionTypes.StorePageException);
                OnStorePageException(chapter, page, ex);
            }
            KeepingAction?.Invoke(entity, chapter, page, null, KeepingActionTypes.EndStorePage);
            OnEndStorePage(chapter, page, true);
        }
Esempio n. 14
0
        public async Task <ComicEntity> GetChaptersAsync(string targetUrl)
        {
            var str = string.Empty;

            using (var sr = new StreamReader(await GetStreamAsync(targetUrl)))
            {
                str = sr.ReadToEnd();
            }
            var html = new HtmlDocument();

            html.LoadHtml(str);
            var img   = html.DocumentNode.SelectSingleNode("//div[@class='banner_detail_form']/div[@class='cover']/img");
            var title = html.DocumentNode.SelectSingleNode("//div[@class='banner_detail_form']/div[@class='info']/p[@class='title']");
            var desc  = html.DocumentNode.SelectSingleNode("//p[@id='a_closes']");

            var chpsBox = html.DocumentNode.SelectNodes("//div[@id='chapterlistload']/ul/li/a");
            var chps    = new List <ComicChapter>();

            foreach (var item in chpsBox)
            {
                var name = item.InnerText.Trim();
                var addr = item.Attributes["href"].Value;
                var chp  = new ComicChapter
                {
                    Title     = name,
                    TargetUrl = "http://www.bikabika.com" + addr
                };
                chps.Add(chp);
            }
            var entity = new ComicEntity
            {
                ComicUrl = targetUrl,
                Descript = desc?.InnerText,
                ImageUrl = img?.Attributes["src"].Value,
                Name     = title?.InnerText,
                Chapters = chps.ToArray()
            };

            return(entity);
        }
Esempio n. 15
0
        public async Task <ComicEntity> GetChaptersAsync(string targetUrl)
        {
            var str = string.Empty;

            using (var sr = new StreamReader(await GetStreamAsync(targetUrl)))
            {
                str = sr.ReadToEnd();
            }
            var html = new HtmlDocument();

            html.LoadHtml(str);

            var imgBox     = html.DocumentNode.SelectSingleNode("//div[@class='works-intro clearfix']/div[@class='works-cover ui-left']/a/img");
            var targetList = html.DocumentNode.SelectNodes("//div[@id='chapter']/div[@class='works-chapter-list-wr ui-left']/ol/li/p/span/a");
            var baseQuery  = "//div[@class='works-intro-text']/";
            var nameBox    = html.DocumentNode.SelectSingleNode(baseQuery + "div[@class='works-intro-head clearfix']/h2[@class='works-intro-title ui-left']");
            var descBox    = html.DocumentNode.SelectSingleNode("//p[@class='works-intro-short ui-text-gray9']");
            var imgLink    = imgBox?.Attributes["src"]?.Value;
            var chapters   = new List <ComicChapter>();

            foreach (var item in targetList)
            {
                var name = item.InnerText?.Trim();
                var link = "https://ac.qq.com" + item.Attributes["href"].Value;
                var ch   = new ComicChapter {
                    TargetUrl = link, Title = name
                };
                chapters.Add(ch);
            }
            return(new ComicEntity
            {
                Name = nameBox?.InnerText,
                Descript = descBox?.InnerText?.Trim(),
                ComicUrl = targetUrl,
                ImageUrl = imgLink,
                Chapters = chapters.ToArray()
            });
        }
Esempio n. 16
0
 public async Task <ComicEntity> GetChaptersAsync(string targetUrl)
 {
     using (var stream = await GetStreamAsync(targetUrl))
     {
         var str = string.Empty;
         using (var sr = new StreamReader(stream))
         {
             str = sr.ReadToEnd();
         }
         var html = new HtmlDocument();
         html.LoadHtml(str);
         var img  = html.DocumentNode.SelectSingleNode("//div[@class='inner']/div[@class='ctdbLeft ']/a/img");
         var desc = html.DocumentNode.SelectSingleNode("//p[@id='worksDesc']");
         var list = html.DocumentNode.SelectNodes("//div[@class='comic-content-list']/ul/li/a");
         var chps = new List <ComicChapter>();
         foreach (var item in list)
         {
             var url  = item.Attributes["href"].Value;
             var name = item.Attributes["title"].Value;
             var chp  = new ComicChapter
             {
                 TargetUrl = "https://www.qimiaomh.com" + url,
                 Title     = name
             };
             chps.Add(chp);
         }
         var entity = new ComicEntity
         {
             Name     = img.Attributes["alt"].Value,
             Chapters = chps.ToArray(),
             ComicUrl = targetUrl,
             Descript = desc?.InnerText,
             ImageUrl = img.Attributes["src"].Value
         };
         return(entity);
     }
 }
Esempio n. 17
0
 public DownloadSaveListenerContext(ComicDownloadRequest request, ComicChapter chapter, ComicPage page, CancellationToken token,
                                    Stream targetStream)
     : base(request, chapter, page, token)
 {
     baseStream = targetStream;
 }
Esempio n. 18
0
        private async Task DownloadPageAsync(ComicDownloadRequest request, ComicChapter chapter, ComicPage page, CancellationToken token)
        {
            var listener = request.Listener;
            DownloadListenerContext listenerContext = null;

            if (listener != null)
            {
                listenerContext = new DownloadListenerContext(request, chapter, page, token);
                await listener.ReadyFetchAsync(listenerContext);
            }
            if (listener != null && token.IsCancellationRequested)
            {
                await listener.CanceledAsync(listenerContext);

                return;
            }
            var ctx = new ComicDownloadContext(request.Entity, chapter, page, null, token);

            if (!request.Saver.NeedToSave(ctx))
            {
                if (listener != null)
                {
                    await listener.NotNeedToSaveAsync(listenerContext);
                }
                return;
            }
            try
            {
                if (listener != null)
                {
                    await listener.BeginFetchPageAsync(listenerContext);
                }
                using (var stream = await request.Provider.GetImageStreamAsync(page.TargetUrl))
                    using (var destStream = streamManager.GetStream())
                    {
                        DownloadSaveListenerContext saveCtx = null;
                        if (listener != null)
                        {
                            saveCtx = new DownloadSaveListenerContext(request, chapter, page, token, destStream);
                            await listener.ReadySaveAsync(saveCtx);
                        }
                        await stream.CopyToAsync(destStream);

                        destStream.Seek(0, SeekOrigin.Begin);
                        ctx = new ComicDownloadContext(request.Entity, chapter, page, destStream, token);
                        await request.Saver.SaveAsync(ctx);

                        if (listener != null)
                        {
                            await listener.EndFetchPageAsync(saveCtx);
                        }
                    }
            }
            catch (Exception ex)
            {
                if (listener != null)
                {
                    var errCtx = new DownloadExceptionListenerContext(request, chapter, page, token, ex);
                    await listener.FetchPageExceptionAsync(errCtx);
                }
            }
            if (listener != null)
            {
                await listener.ComplatedSaveAsync(listenerContext);
            }
        }
Esempio n. 19
0
 public ChapterWithPage(ComicChapter chapter, ComicPage[] pages)
 {
     Chapter = chapter;
     Pages   = pages;
 }
Esempio n. 20
0
 public DownloadItemRequest(ComicChapter chapter, ComicPage page)
 {
     Chapter = chapter;
     Page    = page;
 }
Esempio n. 21
0
 protected virtual void OnBeginStorePage(ComicChapter chapter, ComicPage page)
 {
 }
Esempio n. 22
0
        protected virtual async Task <ChapterWithPage> StoreChapterAsync(ComicEntity entity, ComicChapter chapter)
        {
            var pages = await Provider.GetPagesAsync(chapter.TargetUrl);

            if (pages != null)
            {
                foreach (var item in pages)
                {
                    if (tokenSource.IsCancellationRequested)
                    {
                        break;
                    }
                    await StorePageAsync(entity, chapter, item);
                }
            }
            return(new ChapterWithPage(chapter, pages));
        }
Esempio n. 23
0
 protected virtual void OnStoreChapterException(ComicEntity entity, ComicChapter chapter, Exception ex)
 {
 }
Esempio n. 24
0
 public void LoadChapter()
 {
     comicChapter = ComicChapter.LoadFromFile(inpPathfield.text);
 }
Esempio n. 25
0
 protected virtual void OnEndStorePage(ComicChapter chapter, ComicPage page, bool write)
 {
 }
Esempio n. 26
0
        public async Task <ComicEntity> GetChaptersAsync(string targetUrl)
        {
            targetUrl = GetTrueUrl(targetUrl);
            string str = null;

            using (var sr = new StreamReader(await CreateRequest(targetUrl)))
            {
                str = sr.ReadToEnd();
            }
            var doc = new HtmlDocument();

            doc.LoadHtml(str);
            var title = doc.DocumentNode.SelectSingleNode("//div[@class='comic_deCon']/h1/a")?.InnerText;

            if (title == null)
            {
                title = doc.DocumentNode.SelectSingleNode("//span[@class='anim_title_text']/a/h1")?.InnerText;
            }
            if (title == null)
            {
                title = targetUrl.Split('/').Last();
            }
            var desc = doc.DocumentNode.SelectSingleNode("//div[@clas='wrap_intro_l_comic']/div[@class='comic_deCon']/p[@class='comic_deCon_d']");
            var node = doc.DocumentNode.SelectNodes("//div[@class='cartoon_online_border']/ul/li/a");

            if (node == null)
            {
                node = doc.DocumentNode.SelectNodes("//ul[@class='list_con_li autoHeight']/li/a");
            }
            var img     = doc.DocumentNode.SelectSingleNode("//div[@class='wrap_intro_l_comic']/div[@class='comic_i']/div[@class='comic_i_img']/a/img");
            var chartps = new List <ComicChapter>();

            for (int i = node.Count - 1; i >= 0; i--)
            {
                var item = node[i];
                var name = item.InnerText;
                var url  = item.Attributes["href"]?.Value;
                if (url != null && !url.StartsWith("http://") &&
                    !url.StartsWith("https://"))
                {
                    url = "https://manhua.dmzj.com" + url;
                }
                var chap = new ComicChapter
                {
                    TargetUrl = url,
                    Title     = HttpUtility.UrlDecode(name)
                };
                chartps.Add(chap);
            }
            chartps.Reverse();
            var entity = new ComicEntity
            {
                Chapters = chartps.ToArray(),
                Descript = desc?.InnerText,
                ComicUrl = targetUrl,
                ImageUrl = img?.Attributes["src"]?.Value,
                Name     = title?.Trim()
            };

            return(entity);
        }
Esempio n. 27
0
 protected virtual void OnEndStoreChapter(ComicEntity entity, ComicChapter chapter)
 {
 }
Esempio n. 28
0
 protected virtual void OnStorePageException(ComicChapter chapter, ComicPage page, Exception ex)
 {
 }