Skip to content

Commit

Permalink
1.27.5583
Browse files Browse the repository at this point in the history
* Улучшена поддержка сайта Acomics:
  + Добавлена поддержка глав и томов
  + Добавлена упаковка глав и томов, если они имеются у конкретного комикса
* Общие доработки по процессу скачивания.
  • Loading branch information
MonkAlex committed Apr 15, 2015
1 parent 8e408e6 commit f38e8f7
Show file tree
Hide file tree
Showing 24 changed files with 895 additions and 422 deletions.
6 changes: 3 additions & 3 deletions MangaReader/Account/Grouple.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public static void Login()
{"j_password", SettingLogin.Password},
{"remember_me", "checked"}
};
lock (ClientLock)
using (TimedLock.Lock(ClientLock))
{
try
{
Expand All @@ -101,7 +101,7 @@ public static void Logout()
{
IsLogined = false;
_bookmarsk = null;
lock (ClientLock)
using (TimedLock.Lock(ClientLock))
{
Page.GetPage(LogoutUri, Client);
}
Expand All @@ -115,7 +115,7 @@ public static List<Readmanga> LoadBookmarks()
{
var bookmarks = new List<Readmanga>();
var document = new HtmlDocument();
lock (ClientLock)
using (TimedLock.Lock(ClientLock))
{
document.LoadHtml(Page.GetPage(BookmarksUri, Client));
}
Expand Down
107 changes: 18 additions & 89 deletions MangaReader/Manga/Acomic/Acomics.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using MangaReader.Services;

namespace MangaReader.Manga.Acomic
Expand All @@ -15,39 +14,18 @@ public class Acomics : Mangas

public new static Guid Type { get { return Guid.Parse("F090B9A2-1400-4F5E-B298-18CD35341C34"); } }

/// <summary>
/// Статус загрузки.
/// </summary>
public override bool IsDownloaded
{
get { return downloadedChapters != null && downloadedChapters.Any() && downloadedChapters.All(c => c.IsDownloaded); }
}

/// <summary>
/// Процент загрузки манги.
/// </summary>
public override double Downloaded
{
get { return (downloadedChapters != null && downloadedChapters.Any()) ? (downloadedChapters.Count(ch => ch.IsDownloaded) / (double)downloadedChapters.Count) * 100.0 : 0; }
set { }
}

public override List<Compression.CompressionMode> AllowedCompressionModes
{
get { return base.AllowedCompressionModes.Where(m => Equals(m, Compression.CompressionMode.Manga)).ToList(); }
get
{
return base.AllowedCompressionModes
.Where(m => this.HasVolumes && Equals(m, Compression.CompressionMode.Volume) ||
this.HasChapters && Equals(m, Compression.CompressionMode.Chapter) ||
Equals(m, Compression.CompressionMode.Manga))
.ToList();
}
}

/// <summary>
/// Загружаемый список глав.
/// </summary>
private List<Chapter> downloadedChapters;

/// <summary>
/// Закешированный список глав.
/// </summary>
private List<Chapter> allChapters;


#endregion

#region Методы
Expand All @@ -63,69 +41,19 @@ public override void Refresh()
else if (newName != this.ServerName)
this.ServerName = newName;


this.allChapters = Getter.GetMangaChapters(this.Uri);
Getter.UpdateContentType(this);
OnPropertyChanged("IsCompleted");
}

/// <summary>
/// Скачать все главы.
/// </summary>
public override void Download(string mangaFolder = null, string volumePrefix = null, string chapterPrefix = null)
protected override void UpdateContent()
{
if (!this.NeedUpdate)
return;

this.Refresh();

if (mangaFolder == null)
mangaFolder = this.Folder;

if (this.allChapters == null)
Getter.GetMangaChapters(this.Uri);

this.downloadedChapters = this.allChapters;
if (Settings.Update)
{
this.downloadedChapters = this.downloadedChapters
.Where(ch => this.Histories.All(m => m.Uri != ch.Uri))
.ToList();
}

if (!this.downloadedChapters.Any())
return;

Log.Add("Download start " + this.Name);
this.Pages.Clear();
this.Chapters.Clear();
this.Volumes.Clear();

// Формируем путь к главе вида Папка_манги\Том_001\Глава_0001
try
{
Parallel.ForEach(this.downloadedChapters,
ch =>
{
ch.Download(mangaFolder);
this.AddHistory(ch.Uri);
this.OnPropertyChanged("Downloaded");
OnDownloadProgressChanged(this);
});
this.Save();
Log.Add("Download end " + this.Name);
}

catch (AggregateException ae)
{
foreach (var ex in ae.InnerExceptions)
Log.Exception(ex);
}
catch (Exception ex)
{
Log.Exception(ex);
}
}
Getter.UpdateContent(this);

public override string ToString()
{
return this.Name;
base.UpdateContent();
}

#endregion
Expand All @@ -140,10 +68,11 @@ public Acomics(Uri url)
: this()
{
this.Uri = url;
this.ServerName = Getter.GetMangaName(url);
this.Refresh();
}

public Acomics() : base()
public Acomics()
: base()
{
this.CompressionMode = Compression.CompressionMode.Manga;
}
Expand Down
83 changes: 10 additions & 73 deletions MangaReader/Manga/Acomic/Chapter.cs
Original file line number Diff line number Diff line change
@@ -1,98 +1,35 @@
using System;
using System.Globalization;
using System.IO;
using System.Text.RegularExpressions;
using MangaReader.Services;

namespace MangaReader.Manga.Acomic
{
/// <summary>
/// Глава.
/// </summary>
public class Chapter
public class Chapter : MangaReader.Manga.Chapter
{
#region Свойства

/// <summary>
/// Количество перезапусков загрузки.
/// </summary>
private int restartCounter;

/// <summary>
/// Хранилище ссылок на изображения.
/// </summary>
public Uri ImageLink;

/// <summary>
/// Название главы.
/// </summary>
public string Name;

/// <summary>
/// Ссылка на главу.
/// </summary>
public Uri Uri;

/// <summary>
/// Номер главы.
/// </summary>
public int Number;

public bool IsDownloaded = false;

#endregion

#region Методы
#region Конструктор

/// <summary>
/// Скачать главу.
/// Глава манги.
/// </summary>
/// <param name="chapterFolder">Папка для файлов.</param>
public void Download(string chapterFolder)
/// <param name="uri">Ссылка на главу.</param>
/// <param name="desc">Описание главы.</param>
public Chapter(Uri uri, string desc)
: this(uri)
{
this.IsDownloaded = false;

if (restartCounter > 3)
throw new Exception(string.Format("Load failed after {0} counts.", restartCounter));

try
{
chapterFolder = Page.MakeValidPath(chapterFolder);
if (!Directory.Exists(chapterFolder))
Directory.CreateDirectory(chapterFolder);

var file = Page.DownloadFile(this.ImageLink);
if (!file.Exist)
throw new Exception("Restart chapter download, downloaded file is corrupted, link = " + this.ImageLink);

var fileName = Number.ToString(CultureInfo.InvariantCulture).PadLeft(4, '0') + "." + file.Extension;
File.WriteAllBytes(string.Concat(chapterFolder, Path.DirectorySeparatorChar, fileName), file.Body);
this.IsDownloaded = true;
}
catch (Exception ex)
{
Log.Exception(ex, this.Uri.OriginalString, this.Name);
++restartCounter;
Download(chapterFolder);
}
this.Name = desc;
}

#endregion

#region Конструктор

/// <summary>
/// Глава манги.
/// </summary>
/// <param name="uri">Ссылка на главу.</param>
/// <param name="desc">Описание главы.</param>
/// <param name="link">Ссылка на изображение.</param>
public Chapter(Uri uri, string desc, Uri link)
public Chapter(Uri uri)
: base(uri)
{
this.Uri = uri;
this.Name = desc;
this.ImageLink = link;
this.restartCounter = 0;
this.Number = Convert.ToInt32(Regex.Match(uri.OriginalString, @"/[-]?[0-9]+", RegexOptions.RightToLeft).Value.Remove(0, 1));
}

Expand Down
83 changes: 80 additions & 3 deletions MangaReader/Manga/Acomic/Getter.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
Expand Down Expand Up @@ -44,12 +45,88 @@ public static string GetMangaName(Uri uri)
return WebUtility.HtmlDecode(name);
}

public static void UpdateContentType(Acomics manga)
{
try
{
var document = new HtmlDocument();
document.LoadHtml(Page.GetPage(new Uri(manga.Uri.OriginalString + @"/content"), Getter.GetAdultClient(manga.Uri)));
manga.HasVolumes = document.DocumentNode.SelectNodes("//h2[@class=\"serial-chapters-head\"]") != null;
manga.HasChapters = document.DocumentNode.SelectNodes("//div[@class=\"chapters\"]//li") != null;
}
catch (Exception){}
}

/// <summary>
/// Получить содержание манги - тома и главы.
/// </summary>
/// <param name="manga">Манга.</param>
public static void UpdateContent(Acomics manga)
{
var volumes = new List<Volume>();
var chapters = new List<Chapter>();
var pages = new List<MangaPage>();
try
{
var document = new HtmlDocument();
document.LoadHtml(Page.GetPage(new Uri(manga.Uri.OriginalString + @"/content"), Getter.GetAdultClient(manga.Uri)));

var volumeNodes = document.DocumentNode.SelectNodes("//h2[@class=\"serial-chapters-head\"]");
if (volumeNodes != null)
for (int i = 0; i < volumeNodes.Count; i++)
{
var desc = volumeNodes[i].InnerText;
var newVolume = new Volume(desc, volumes.Count + 1);
var subVolumeNodes = volumeNodes[i].ParentNode.ChildNodes[i * 2 + 1].ChildNodes;
AddChapters(subVolumeNodes, newVolume.Chapters);
volumes.Add(newVolume);
}

if (volumeNodes == null || !volumes.Any())
{
var chapterNodes = document.DocumentNode.SelectNodes("//div[@class=\"chapters\"]//li");
AddChapters(chapterNodes, chapters);
}

var allPages = GetMangaPages(manga.Uri);
var innerChapters = chapters.Count == 0 ? volumes.SelectMany(v => v.Chapters).Cast<Chapter>().ToList() : chapters;
for (int i = 0; i < innerChapters.Count; i++)
{
var current = innerChapters[i].Number;
var next = i + 1 != innerChapters.Count ? innerChapters[i + 1].Number : int.MaxValue;
innerChapters[i].Pages.AddRange(allPages.Where(p => current <= p.Number && p.Number < next));
innerChapters[i].Number = i + 1;
}
pages.AddRange(allPages.Except(innerChapters.SelectMany(c => c.Pages).Cast<MangaPage>()));
}
catch (NullReferenceException ex) { Log.Exception(ex); }

manga.HasVolumes = volumes.Any();
manga.HasChapters = volumes.Any() || chapters.Any();
manga.Volumes.AddRange(volumes);
manga.Chapters.AddRange(chapters);
manga.Pages.AddRange(pages);
}

private static void AddChapters(HtmlNodeCollection collection, IList chapters)
{
if (collection == null)
return;

foreach (var chapter in collection)
{
var desc = chapter.InnerText;
var link = new Uri(chapter.ChildNodes[0].ChildNodes[0].Attributes[0].Value);
chapters.Add(new Chapter(link, desc));
}
}

/// <summary>
/// Получить главы манги.
/// Получить страницы манги.
/// </summary>
/// <param name="uri">Ссылка на мангу.</param>
/// <returns>Словарь (ссылка, описание).</returns>
public static List<Chapter> GetMangaChapters(Uri uri)
private static List<MangaPage> GetMangaPages(Uri uri)
{
var links = new List<Uri> { };
var description = new List<string> { };
Expand Down Expand Up @@ -82,7 +159,7 @@ public static List<Chapter> GetMangaChapters(Uri uri)
catch (NullReferenceException ex) { Log.Exception(ex, "Ошибка получения списка глав.", uri.ToString()); }
catch (ArgumentNullException ex) { Log.Exception(ex, "Главы не найдены.", uri.ToString()); }

return links.Select((t, i) => new Chapter(t, description[i], images[i])).ToList();
return links.Select((t, i) => new MangaPage(t, images[i]) { Name = description[i] }).ToList();
}
}
}
Loading

0 comments on commit f38e8f7

Please sign in to comment.