public override IEnumerable <IManga> Search(string name) { var hosts = ConfigStorage.Plugins .Where(p => p.GetParser().GetType() == typeof(Parser)) .Select(p => p.GetSettings().MainUri); var client = new CookieClient(); foreach (var host in hosts) { var searchHost = new Uri(host, "?do=search&subaction=search&story=" + WebUtility.UrlEncode(name)); var page = Page.GetPage(searchHost, client); if (!page.HasContent) { continue; } var document = new HtmlDocument(); document.LoadHtml(page.Content); var mangas = document.DocumentNode.SelectNodes("//div[@class='content_row']"); if (mangas == null) { continue; } foreach (var manga in mangas) { var image = manga.SelectSingleNode(".//div[@class='manga_images']//img"); var imageUri = image?.Attributes.Single(a => a.Name == "src").Value; var mangaNode = manga.SelectSingleNode(".//h2//a"); var mangaUri = mangaNode.Attributes.Single(a => a.Name == "href").Value; var mangaName = mangaNode.InnerText; // Это не манга, идем дальше. if (!mangaUri.Contains("/manga/")) { continue; } var result = Mangas.Create(new Uri(mangaUri)); result.Name = WebUtility.HtmlDecode(mangaName); if (imageUri != null) { result.Cover = client.DownloadData(new Uri(host, imageUri)); } yield return(result); } } }
public static async Task <Acomics.Acomics> CreateAcomics() { using (var context = Repository.GetEntityContext()) { var manga = await Mangas.Create(AcomicsUri).ConfigureAwait(false) as Acomics.Acomics; manga.Status = "example status"; manga.NeedUpdate = false; manga.Name = "Acomics from example" + Guid.NewGuid(); await context.Save(manga).ConfigureAwait(false); return(manga); } }
/// <summary> /// Создать мангу. /// </summary> /// <returns></returns> public static async Task <Grouple.Readmanga> CreateReadmanga() { using (var context = Repository.GetEntityContext()) { var manga = await Mangas.Create(ReadmangaUri).ConfigureAwait(false) as Grouple.Readmanga; manga.Status = "example status"; manga.NeedUpdate = false; manga.Name = "readmanga from example" + Guid.NewGuid(); await context.Save(manga).ConfigureAwait(false); return(manga); } }
protected override async Task <List <IManga> > DownloadBookmarks() { var bookmarks = new List <IManga>(); var document = new HtmlDocument(); await this.DoLogin().ConfigureAwait(false); if (!IsLogined) { return(bookmarks); } var page = await Page.GetPageAsync(BookmarksUri, GetClient()).ConfigureAwait(false); document.LoadHtml(page.Content); var firstOrDefault = document.DocumentNode .SelectNodes("//div[@class=\"bookmarks-lists\"]"); var bookMarksNode = firstOrDefault?.FirstOrDefault(); if (bookMarksNode == null) { Log.AddFormat("Bookmarks from '{0}' not found.", this.MainUri); return(bookmarks); } var parser = new Parser(); using (var context = Repository.GetEntityContext("Loading bookmarks")) { var loadedBookmarks = Regex .Matches(bookMarksNode.OuterHtml, @"href='(.*?)'", RegexOptions.IgnoreCase) .OfType <Group>() .Select(g => g.Captures[0]) .OfType <Match>() .Select(m => new Uri(m.Groups[1].Value)); await Task.WhenAll(loadedBookmarks.Select(async b => { var manga = await Mangas.Create(b).ConfigureAwait(false); await parser.UpdateNameAndStatus(manga).ConfigureAwait(false); bookmarks.Add(manga); })).ConfigureAwait(false); } return(bookmarks); }
public override async Task Execute(object parameter) { if (isLoading) { return; } var model = parameter as MangaSearchViewModel; if (model == null) { return; } try { this.isLoading = true; this.OnCanExecuteChanged(); this.Name = "Loading..."; var manga = await Mangas.Create(model.Uri).ConfigureAwait(true); if (manga == null) { return; } await manga.Refresh().ConfigureAwait(true); if (await manga.IsValid().ConfigureAwait(true)) { var explorer = ExplorerViewModel.Instance; var searchTab = new MangaModel(manga); explorer.Tabs.Add(searchTab); explorer.SelectedTab = searchTab; var covers = await manga.Parser.GetPreviews(manga).ConfigureAwait(true); searchTab.Cover = covers.FirstOrDefault(); } } finally { this.isLoading = false; this.OnCanExecuteChanged(); this.Name = "Preview"; } }
//function to return new MangaModel object public static MangaModel toViewModel(Mangas mangamodel) { var result = new MangaModel() { Id = mangamodel.Id, Title = mangamodel.Title, Author = mangamodel.Author, Chapters = mangamodel.Chapters, Genre = mangamodel.Genre, Releasedate = mangamodel.Releasedate, Status = mangamodel.Status, Description = mangamodel.Description, Rating = mangamodel.Rating, fileName = mangamodel.MangaImagePath }; return(result); }
//function to return new Manga object public static Mangas toAggregate(MangaModel mangamodel) { var result = new Mangas() { Id = mangamodel.Id, Title = mangamodel.Title, Author = mangamodel.Author, Chapters = mangamodel.Chapters, Genre = mangamodel.Genre, Releasedate = mangamodel.Releasedate, Status = mangamodel.Status, Description = mangamodel.Description, Rating = mangamodel.Rating, MangaImagePath = mangamodel.fileName, }; return(result); }
protected override async Task <IManga> GetMangaFromNode(Uri host, ISiteHttpClient client, HtmlNode manga) { var image = manga.SelectSingleNode(".//div[@class='manga_images']//img"); var imageUri = image?.Attributes.Single(a => a.Name == "src").Value; var mangaNode = manga.SelectSingleNode(".//h2//a"); var mangaUri = mangaNode.Attributes.Single(a => a.Name == "href").Value; var mangaName = mangaNode.InnerText; var result = await Mangas.Create(new Uri(mangaUri)).ConfigureAwait(false); result.Name = WebUtility.HtmlDecode(mangaName); if (!string.IsNullOrWhiteSpace(imageUri)) { result.Cover = await client.GetData(new Uri(host, imageUri)).ConfigureAwait(false); } return(result); }
protected override async Task <IManga> GetMangaFromNode(Uri host, CookieClient client, HtmlNode manga) { var image = manga.SelectSingleNode(".//img"); var imageUri = image?.Attributes.Single(a => a.Name == "data-src").Value; var mangaNode = manga.SelectSingleNode(".//div[@class='img-overlay text-center']//a"); var mangaUri = mangaNode.Attributes.Single(a => a.Name == "href").Value; var mangaName = mangaNode.InnerText.Trim(); var result = await Mangas.Create(new Uri(host, mangaUri)).ConfigureAwait(false); result.Name = WebUtility.HtmlDecode(mangaName); if (!string.IsNullOrWhiteSpace(imageUri) && client != null) { result.Cover = await client.DownloadDataTaskAsync(new Uri(host, imageUri)).ConfigureAwait(false); } return(result); }
public override IEnumerable <IManga> Search(string name) { var hosts = ConfigStorage.Plugins .Where(p => p.GetParser().GetType() == typeof(Parser)) .Select(p => p.GetSettings().MainUri); var client = new CookieClient(); foreach (var host in hosts) { var searchHost = new Uri(host, "search?keyword=" + WebUtility.UrlEncode(name)); var page = Page.GetPage(searchHost, client); if (!page.HasContent) { continue; } var document = new HtmlDocument(); document.LoadHtml(page.Content); var mangas = document.DocumentNode.SelectNodes("//table[@class='catalog-elem list-loadable']"); if (mangas == null) { continue; } foreach (var manga in mangas) { var image = manga.SelectSingleNode(".//td[@class='catdata1']//a//img"); var imageUri = image?.Attributes.Single(a => a.Name == "src").Value; var mangaNode = manga.SelectSingleNode(".//div[@class='title']//a"); var mangaUri = mangaNode.Attributes.Single(a => a.Name == "href").Value; var mangaName = mangaNode.InnerText; var result = Mangas.Create(new Uri(host, mangaUri)); result.Name = WebUtility.HtmlDecode(mangaName); if (imageUri != null) { result.Cover = client.DownloadData(new Uri(host, imageUri)); } yield return(result); } } }
public async Task MintmangaBonus() { using (var context = Repository.GetEntityContext()) { var uri = new Uri(MangaInfos.Mintmanga.HarukaNaReceive.Uri); var toRemove = await context.Get <IManga>().Where(m => m.Uri == uri).ToListAsync().ConfigureAwait(false); foreach (var remove in toRemove) { await context.Delete(remove).ConfigureAwait(false); } var manga = await Mangas.CreateFromWeb(uri).ConfigureAwait(false); await manga.Parser.UpdateContent(manga).ConfigureAwait(false); var chapters = manga.Volumes.SelectMany(v => v.Container).OfType <Grouple.GroupleChapter>(); Assert.AreEqual(1, chapters.Count(c => c.VolumeNumber == 1 && c.Number == 0)); } }
private async Task ShowPreview() { if (Uri.TryCreate(ManualUri, UriKind.Absolute, out Uri parsedUri)) { using (Repository.GetEntityContext($"Show preview for manga from uri {parsedUri}")) { var manga = await Mangas.Create(parsedUri).ConfigureAwait(true); if (manga == null) { return; } var model = new MangaSearchViewModel(manga); model.Cover = (await manga.Parser.GetPreviews(manga).ConfigureAwait(true)).FirstOrDefault(); await model.PreviewFoundManga.Execute(model).ConfigureAwait(true); } } }
protected override async Task <List <IManga> > DownloadBookmarks(Guid mangaType) { var bookmarks = new List <IManga>(); var document = new HtmlDocument(); var isLogined = await this.DoLogin(mangaType).ConfigureAwait(false); if (!isLogined) { return(bookmarks); } var client = await GetClient().ConfigureAwait(false); var page = await client.GetPage(BookmarksUri).ConfigureAwait(false); document.LoadHtml(page.Content); var nodes = document.DocumentNode .SelectNodes("//div[@style=\"float:left;width:810px;margin-top:3px;\"]//a[not(contains(@style,'font-size:11px;'))]"); if (nodes == null) { Log.AddFormat("Bookmarks from '{0}' not found.", this.MainUri); return(bookmarks); } await Task.WhenAll(nodes.Select(async u => { #warning HACK for https in bookmarks var manga = await Mangas.Create(new Uri(MainUri, new Uri(u.Attributes[0].Value).PathAndQuery)).ConfigureAwait(false); if (manga == null) { return; } manga.ServerName = WebUtility.HtmlDecode(u.InnerText); bookmarks.Add(manga); })).ConfigureAwait(false); return(bookmarks); }
/// <summary> /// Добавить мангу. /// </summary> /// <param name="uri"></param> public bool Add(Uri uri) { using (var context = Repository.GetEntityContext()) { if (context.Get <IManga>().Any(m => m.Uri == uri)) { return(false); } } var newManga = Mangas.CreateFromWeb(uri); if (newManga == null || !newManga.IsValid()) { return(false); } OnLibraryChanged(new LibraryViewModelArgs(null, newManga, MangaOperation.Added, LibraryOperation.UpdateMangaChanged)); Log.Info(Strings.Library_Status_MangaAdded + newManga.Name); return(true); }
public async Task MangachanBonus() { using (var context = Repository.GetEntityContext()) { var login = await context.Get <MangachanLogin>().SingleAsync().ConfigureAwait(false); login.PasswordHash = "e84fce6c43aacd7f8452409a63083c18"; login.UserId = "282433"; login.IsLogined = true; await context.Save(login).ConfigureAwait(false); } var manga = await Mangas.CreateFromWeb(new Uri("https://manga-chan.me/manga/5335-the-breaker-new-waves.html")).ConfigureAwait(false); await manga.Parser.UpdateContent(manga).ConfigureAwait(false); var chapters = manga.Volumes.SelectMany(v => v.Container).ToList(); Assert.AreEqual(1, chapters.Count(c => c.Number == 170)); Assert.AreEqual(1, chapters.Count(c => c.Number == 170.1)); }
public async Task ValidateStatusAndDescription(MangaInfo mangaInfo) { IManga manga; using (var context = Repository.GetEntityContext("Description")) { if (mangaInfo.Uri == MangaInfos.Mangachan.EveScramble.Uri) { var login = await context.Get <MangachanLogin>().SingleAsync().ConfigureAwait(false); login.PasswordHash = "e84fce6c43aacd7f8452409a63083c18"; login.UserId = "282433"; login.IsLogined = true; await context.Save(login).ConfigureAwait(false); } var mangaUri = new Uri(mangaInfo.Uri); var existsManga = await context.Get <IManga>().FirstOrDefaultAsync(m => m.Uri == mangaUri).ConfigureAwait(false); if (existsManga != null) { await context.Delete(existsManga).ConfigureAwait(false); } manga = await Mangas.CreateFromWeb(mangaUri).ConfigureAwait(false); } Assert.AreEqual(mangaInfo.Description, manga.Description); if (Equals(mangaInfo.Status, manga.Status)) { Assert.Pass(); } else { var storedWords = GetWords(mangaInfo.Status); var downloaded = GetWords(manga.Status); var changes = storedWords.Except(downloaded).Count() + downloaded.Except(storedWords).Count(); // Status can contain regular changed info, try to compare Assert.LessOrEqual(changes, 2); } }
protected override async Task <List <IManga> > DownloadBookmarks() { var bookmarks = new List <IManga>(); var document = new HtmlDocument(); await this.DoLogin(); if (!IsLogined) { return(bookmarks); } var page = await Page.GetPageAsync(BookmarksUri, GetClient()); document.LoadHtml(page.Content); var nodes = document.DocumentNode .SelectNodes("//div[@style=\"float:left;width:810px;margin-top:3px;\"]//a[not(contains(@style,'font-size:11px;'))]"); if (nodes == null) { Log.AddFormat("Bookmarks from '{0}' not found.", this.MainUri); return(bookmarks); } var parser = new Parser(); var mangas = nodes .Select(u => { var manga = Mangas.Create(new Uri(u.Attributes[0].Value)); manga.ServerName = WebUtility.HtmlDecode(u.InnerText); return(manga); }) // .Where(m => !string.IsNullOrWhiteSpace(m.Name)) .ToList(); bookmarks.AddRange(mangas); return(bookmarks); }
protected override async Task <List <IManga> > DownloadBookmarks(Guid mangaType) { var bookmarks = new List <IManga>(); var document = new HtmlDocument(); var isLogined = await this.DoLogin(mangaType).ConfigureAwait(false); if (!isLogined) { return(bookmarks); } var cookieClient = await AcomicsPlugin.Instance.GetCookieClient(false).ConfigureAwait(false); var page = await cookieClient.GetPage(BookmarksUri).ConfigureAwait(false); document.LoadHtml(page.Content); var nodes = document.DocumentNode.SelectNodes("//table[@class=\"decor\"]//a"); if (nodes == null) { Log.AddFormat("Bookmarks from '{0}' not found.", this.MainUri); return(bookmarks); } foreach (var node in nodes) { var name = WebUtility.HtmlDecode(node.ChildNodes.Single().InnerText); var url = node.Attributes.Single().Value; var manga = await Mangas.Create(new Uri(this.MainUri, url)).ConfigureAwait(false); manga.Name = name; bookmarks.Add(manga); } return(bookmarks); }
public async Task DownloadAcomics() { var rm = Mangas.CreateFromWeb(new Uri(@"https://acomics.ru/~MGS-LDIOH")); var sw = new Stopwatch(); sw.Start(); rm.PropertyChanged += RmOnDownloadChanged; DirectoryHelpers.DeleteDirectory(rm.GetAbsoulteFolderPath()); await rm.Download(); sw.Stop(); Log.Add($"manga loaded {sw.Elapsed.TotalSeconds}, iscompleted = {rm.IsDownloaded}, lastpercent = {lastPercent}"); Assert.IsTrue(Directory.Exists(rm.GetAbsoulteFolderPath())); var files = Directory.GetFiles(rm.GetAbsoulteFolderPath(), "*", SearchOption.AllDirectories); Assert.AreEqual(6, files.Length); var fileInfos = files.Select(f => new FileInfo(f)).ToList(); Assert.AreEqual(8301123, fileInfos.Sum(f => f.Length)); Assert.AreEqual(1, fileInfos.GroupBy(f => f.Length).Max(g => g.Count())); Assert.IsTrue(rm.IsDownloaded); Assert.AreEqual(100, lastPercent); }
public async Task Download(MangaInfo mangaInfo) { IManga manga; var sw = new Stopwatch(); using (var context = Repository.GetEntityContext($"Test to download {mangaInfo.Uri}")) { foreach (var toDelete in context.Get <IManga>().Where(m => m.Uri.ToString() == mangaInfo.Uri)) { await context.Delete(toDelete).ConfigureAwait(false); DirectoryHelpers.DeleteDirectory(toDelete.GetAbsoluteFolderPath()); } manga = await Mangas.CreateFromWeb(new Uri(mangaInfo.Uri)).ConfigureAwait(false); DirectoryHelpers.DeleteDirectory(manga.GetAbsoluteFolderPath()); sw.Start(); await manga.Download().ConfigureAwait(false); } sw.Stop(); Log.Add($"manga loaded {sw.Elapsed.TotalSeconds}, iscompleted = {manga.IsDownloaded}, downloaded = {manga.Downloaded}%"); Assert.IsTrue(Directory.Exists(manga.GetAbsoluteFolderPath())); var files = Directory.GetFiles(manga.GetAbsoluteFolderPath(), "*", SearchOption.AllDirectories); Assert.AreEqual(mangaInfo.FilesInFolder, files.Length); var fileInfos = files.Select(f => new FileInfo(f)).ToList(); Assert.AreEqual(mangaInfo.FolderSize, fileInfos.Sum(f => f.Length), mangaInfo.FolderSize / 100.0); if (mangaInfo.AllFilesUnique) { Assert.AreEqual(1, fileInfos.GroupBy(f => f.Length).Max(g => g.Count())); } Assert.IsTrue(manga.IsDownloaded); Assert.AreEqual(100, manga.Downloaded); }
public async Task DownloadHentaichan() { CreateLogin(); var rm = Mangas.CreateFromWeb(new Uri(@"http://hentai-chan.me/manga/12850-twisted-intent-chast-1.html")); var sw = new Stopwatch(); sw.Start(); rm.PropertyChanged += RmOnDownloadChanged; DirectoryHelpers.DeleteDirectory(rm.GetAbsoulteFolderPath()); await rm.Download(); sw.Stop(); Log.Add($"manga loaded {sw.Elapsed.TotalSeconds}, iscompleted = {rm.IsDownloaded}, lastpercent = {lastPercent}"); Assert.IsTrue(Directory.Exists(rm.GetAbsoulteFolderPath())); var files = Directory.GetFiles(rm.GetAbsoulteFolderPath(), "*", SearchOption.AllDirectories); Assert.AreEqual(32, files.Length); var fileInfos = files.Select(f => new FileInfo(f)).ToList(); Assert.AreEqual(9984593, fileInfos.Sum(f => f.Length)); Assert.AreEqual(1, fileInfos.GroupBy(f => f.Length).Max(g => g.Count())); Assert.IsTrue(rm.IsDownloaded); Assert.AreEqual(100, lastPercent); }
protected override async Task <IManga> GetMangaFromNode(Uri host, CookieClient client, HtmlNode manga) { var image = manga.SelectSingleNode(".//div[@class='manga_images']//img"); var imageUri = image?.Attributes.Single(a => a.Name == "src").Value; var mangaNode = manga.SelectSingleNode(".//h2//a"); var mangaUri = mangaNode.Attributes.Single(a => a.Name == "href").Value; var mangaName = mangaNode.InnerText; // Это не манга, идем дальше. if (!mangaUri.Contains("/manga/")) { return(null); } var result = await Mangas.Create(new Uri(mangaUri)).ConfigureAwait(false); result.Name = WebUtility.HtmlDecode(mangaName); if (!string.IsNullOrWhiteSpace(imageUri)) { result.Cover = await client.DownloadDataTaskAsync(new Uri(host, imageUri)).ConfigureAwait(false); } return(result); }
private static async Task<IManga> GetManga(string url) { return await Mangas.CreateFromWeb(new Uri(url)).ConfigureAwait(false); }
public bool CanExecuteLoadMoreCommand(Manga item) { return(IsNotBusy && (!Mangas.Any() /*|| !Mangas[0].IsLoading*/)); }
protected override async Task <List <IManga> > DownloadBookmarks() { var bookmarks = new List <IManga>(); var document = new HtmlDocument(); await this.DoLogin().ConfigureAwait(false); if (!IsLogined) { return(bookmarks); } var pages = new List <Uri>() { BookmarksUri }; for (int i = 0; i < pages.Count; i++) { var page = await Page.GetPageAsync(pages[i], GetClient()).ConfigureAwait(false); document.LoadHtml(page.Content); if (i == 0) { var pageNodes = document.DocumentNode.SelectNodes("//div[@class=\"navigation\"]//a"); if (pageNodes != null) { foreach (var node in pageNodes) { pages.Add(new Uri(node.Attributes[0].Value)); } pages = pages.Distinct().ToList(); } } var nodes = document.DocumentNode.SelectNodes("//div[@class=\"manga_row1\"]"); if (nodes == null) { Log.AddFormat("Bookmarks from '{0}' not found.", this.MainUri); return(bookmarks); } var parser = new Parser(); var mangas = nodes .Select(n => n.OuterHtml) .SelectMany(h => Regex.Matches(h, "href=\"(.*?)\"", RegexOptions.IgnoreCase) .OfType <Group>() .Select(g => g.Captures[0]) .OfType <Match>() .Select(m => new Uri(m.Groups[1].Value))); await Task.WhenAll(mangas.Select(async m => { var manga = await Mangas.Create(m).ConfigureAwait(false); if (manga == null) { return; } await parser.UpdateNameAndStatus(manga).ConfigureAwait(false); if (!string.IsNullOrWhiteSpace(manga.Name)) { bookmarks.Add(manga); } })).ConfigureAwait(false); } return(bookmarks); }
private InfoManga nInfoM() { Mangas mg = new Mangas() { Titulo = "", Nome = "Nome: ", ANome = "Nome Alternativo: ", Ano = "Ano de Lançamento: ", Status = "Status: ", Autor = "Autor: ", Artista = "Artista: ", DirecaoLeitura = "Direção de Leitura: ", Generos = "Generos: " }; InfoManga im = new InfoManga(); im.Info = mg; return im; }
private Acomics.Acomics GetManga(string uri) { var manga = Mangas.CreateFromWeb(new Uri(uri)) as Acomics.Acomics; new Acomics.Parser().UpdateContent(manga); return manga; }
private Hentaichan.Hentaichan GetManga(string url) { var manga = Mangas.CreateFromWeb(new Uri(url)) as Hentaichan.Hentaichan; return(manga); }
private void AddManga() { #warning Отсюда нужен переход к превью. Mangas.CreateFromWeb(new Uri(ManualUri)); }
private static IManga GetManga(string url) { return(Mangas.CreateFromWeb(new Uri(url))); }