Skip to content

Commit

Permalink
Async API
Browse files Browse the repository at this point in the history
  • Loading branch information
versfx committed Nov 14, 2016
1 parent f21b65e commit 37e5bca
Show file tree
Hide file tree
Showing 41 changed files with 794 additions and 380 deletions.
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

## Example
```csharp
// Opening a book
EpubBook epubBook = EpubReader.OpenBook("alice_in_wonderland.epub");
// Opens a book and reads all of its content into the memory
EpubBook epubBook = EpubReader.ReadBook("alice_in_wonderland.epub");


// COMMON PROPERTIES
Expand All @@ -18,7 +18,7 @@ string author = epubBook.Author;
// Book's authors (list of authors names)
List<string> authors = epubBook.AuthorList;

// Book's cover image (null if there are no cover)
// Book's cover image (null if there is no cover)
Image coverImage = epubBook.CoverImage;


Expand Down Expand Up @@ -57,7 +57,7 @@ EpubContentType contentType = firstImage.ContentType;
// MIME type (e.g. "image/jpeg", "image/png")
string mimeContentType = firstImage.ContentMimeType;

// Creating Image class instance from content
// Creating Image class instance from the content
using (MemoryStream imageStream = new MemoryStream(firstImage.Content))
{
Image image = Image.FromStream(imageStream);
Expand Down Expand Up @@ -120,11 +120,11 @@ foreach (EpubNavigationHeadMeta meta in navigation.Head)
## Download latest stable release
[Via NuGet package from nuget.org](https://www.nuget.org/packages/VersFx.Formats.Text.Epub)

[DLL file from GitHub (VersFx.Formats.Text.Epub.dll, 45.5 KB)](https://github.com/versfx/EpubReader/releases/download/v1.0.1/VersFx.Formats.Text.Epub.dll)
[DLL file from GitHub (VersFx.Formats.Text.Epub.dll, 71.5 KB)](https://github.com/versfx/EpubReader/releases/download/v1.0.2/VersFx.Formats.Text.Epub.dll)

## Demo app
[Download (EpubReaderDemo.zip, 400 KB)](https://github.com/versfx/EpubReader/releases/download/v1.0.1/EpubReaderDemo.zip)
[Download (EpubReaderDemo.zip, 413 KB)](https://github.com/versfx/EpubReader/releases/download/v1.0.2/EpubReaderDemo.zip)

This application demonstrates how can you open EPUB books and extract their content using this library.
This application demonstrates the opening EPUB books and extracting their content using this library.

HTML renderer used in this demo app may be a little bit slow for some books.
23 changes: 18 additions & 5 deletions Source/EpubReaderDemo/Controls/BookHtmlContent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@
using System.Collections.Generic;
using System.IO;
using System.IO.Packaging;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
Expand Down Expand Up @@ -39,8 +36,9 @@ public ChapterContentViewModel ChapterContent

protected override void OnImageLoad(HtmlImageLoadEventArgs e)
{
string imageFilePath = GetFullPath(ChapterContent.HtmlFilePath, e.Src);
byte[] imageContent;
if (ChapterContent.Images.TryGetValue(e.Src, out imageContent))
if (ChapterContent.Images.TryGetValue(imageFilePath, out imageContent))
{
using (MemoryStream imageStream = new MemoryStream(imageContent))
{
Expand All @@ -59,8 +57,9 @@ protected override void OnImageLoad(HtmlImageLoadEventArgs e)

protected override void OnStylesheetLoad(HtmlStylesheetLoadEventArgs e)
{
string styleSheetFilePath = GetFullPath(ChapterContent.HtmlFilePath, e.Src);
string styleSheetContent;
if (ChapterContent.StyleSheets.TryGetValue(e.Src, out styleSheetContent))
if (ChapterContent.StyleSheets.TryGetValue(styleSheetFilePath, out styleSheetContent))
e.SetStyleSheet = styleSheetContent;
base.OnStylesheetLoad(e);
}
Expand All @@ -75,6 +74,20 @@ private static void OnChapterContentChanged(DependencyObject dependencyObject, D
bookHtmlContent.Text = bookHtmlContent.ChapterContent.HtmlContent;
}

private string GetFullPath(string htmlFilePath, string relativePath)
{
if (relativePath.StartsWith("/"))
return relativePath.Length > 1 ? relativePath.Substring(1) : String.Empty;
string basePath = Path.GetDirectoryName(htmlFilePath);
while (relativePath.StartsWith("../"))
{
relativePath = relativePath.Length > 3 ? relativePath.Substring(3) : String.Empty;
basePath = Path.GetDirectoryName(basePath);
}
string fullPath = String.Concat(basePath.Replace('\\', '/'), '/', relativePath);
return fullPath.Length > 1 ? fullPath.Substring(1) : String.Empty;
}

private void RegisterFonts()
{
foreach (KeyValuePair<string, byte[]> fontFile in ChapterContent.Fonts)
Expand Down
2 changes: 2 additions & 0 deletions Source/EpubReaderDemo/EpubReaderDemo.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@
<Compile Include="Models\BookModel.cs" />
<Compile Include="Models\LibraryModel.cs" />
<Compile Include="Utils\BindingProxy.cs" />
<Compile Include="Utils\BooleanToInverseVisibilityConverter.cs" />
<Compile Include="Utils\BooleanToVisibilityConverter.cs" />
<Compile Include="Utils\Command.cs" />
<Compile Include="Utils\ExpressionUtils.cs" />
<Compile Include="Utils\IntToDoubleConverter.cs" />
Expand Down
11 changes: 4 additions & 7 deletions Source/EpubReaderDemo/Models/BookModel.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using EpubReaderDemo.Entities;
using EpubReaderDemo.ViewModels;
using VersFx.Formats.Text.Epub;
using VersFx.Formats.Text.Epub.Entities;

namespace EpubReaderDemo.Models
{
Expand All @@ -21,9 +18,9 @@ public BookModel()
settings = applicationContext.Settings;
}

public EpubBook OpenBook(int bookId)
public async Task<EpubBook> OpenBookAsync(int bookId)
{
EpubBook epubBook = EpubReader.OpenBook(settings.Books.First(book => book.Id == bookId).FilePath);
EpubBook epubBook = await EpubReader.ReadBookAsync(settings.Books.First(book => book.Id == bookId).FilePath);
return epubBook;
}

Expand All @@ -38,7 +35,7 @@ private List<ChapterViewModel> GetChapters(List<EpubChapter> epubChapters)
foreach (EpubChapter epubChapter in epubChapters)
{
List<ChapterViewModel> subChapters = GetChapters(epubChapter.SubChapters);
ChapterViewModel chapterViewModel = new ChapterViewModel(epubChapter.Title, subChapters, epubChapter.HtmlContent);
ChapterViewModel chapterViewModel = new ChapterViewModel(epubChapter.ContentFileName, epubChapter.Title, subChapters, epubChapter.HtmlContent);
result.Add(chapterViewModel);
}
return result;
Expand Down
11 changes: 6 additions & 5 deletions Source/EpubReaderDemo/Models/LibraryModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,20 +40,21 @@ public void AddBookToLibrary(string bookFilePath)
bookId = settings.Books.Max(bookItem => bookItem.Id) + 1;
else
bookId = 1;
EpubBook epubBook = EpubReader.OpenBook(bookFilePath);
if (epubBook.CoverImage != null)
EpubBookRef epubBookRef = EpubReader.OpenBook(bookFilePath);
Image coverImage = epubBookRef.ReadCover();
if (coverImage != null)
{
if (!Directory.Exists(Constants.COVER_IMAGES_FOLDER))
Directory.CreateDirectory(Constants.COVER_IMAGES_FOLDER);
using (Image resizedCoverImage = ResizeCover(epubBook.CoverImage))
using (Image resizedCoverImage = ResizeCover(coverImage))
resizedCoverImage.Save(GetBookCoverImageFilePath(bookId), ImageFormat.Png);
}
Book book = new Book
{
Id = bookId,
FilePath = bookFilePath,
Title = epubBook.Title,
HasCover = epubBook.CoverImage != null
Title = epubBookRef.Title,
HasCover = coverImage != null
};
settings.Books.Add(book);
applicationContext.SaveSettings();
Expand Down
4 changes: 2 additions & 2 deletions Source/EpubReaderDemo/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
[assembly: AssemblyTitle("EpubReaderDemo")]
[assembly: AssemblyDescription("Demo application for VersFx.Formats.Text.Epub library")]
[assembly: AssemblyCopyright("Unlicense <http://unlicense.org>")]
[assembly: AssemblyVersion("1.0.1.0")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyVersion("1.0.2.0")]
[assembly: AssemblyFileVersion("1.0.2.0")]
[assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)]
[assembly: ComVisible(false)]
5 changes: 4 additions & 1 deletion Source/EpubReaderDemo/Styles/Common.xaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:u="clr-namespace:EpubReaderDemo.Utils">
<u:BooleanToVisibilityConverter x:Key="booleanToVisibilityConverter" />
<u:BooleanToInverseVisibilityConverter x:Key="booleanToInverseVisibilityConverter" />
<Style x:Key="windowStyle" TargetType="Window">
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="Icon" Value="/Resources/Book_icon.ico" />
Expand Down
22 changes: 22 additions & 0 deletions Source/EpubReaderDemo/Utils/BooleanToInverseVisibilityConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;

namespace EpubReaderDemo.Utils
{
public class BooleanToInverseVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (!(value is bool))
return Visibility.Hidden;
return !(bool)value ? Visibility.Visible : (parameter != null ? Visibility.Collapsed : Visibility.Hidden);
}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return null;
}
}
}
22 changes: 22 additions & 0 deletions Source/EpubReaderDemo/Utils/BooleanToVisibilityConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;

namespace EpubReaderDemo.Utils
{
public class BooleanToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (!(value is bool))
return Visibility.Hidden;
return (bool)value ? Visibility.Visible : (parameter != null ? Visibility.Collapsed : Visibility.Hidden);
}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return null;
}
}
}
56 changes: 43 additions & 13 deletions Source/EpubReaderDemo/ViewModels/BookViewModel.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using EpubReaderDemo.Models;
Expand All @@ -14,8 +12,9 @@ namespace EpubReaderDemo.ViewModels
public class BookViewModel : ViewModel
{
private readonly BookModel bookModel;
private readonly EpubBook epubBook;

private bool isLoading;
private ObservableCollection<ChapterViewModel> contents;
private Dictionary<string, byte[]> images;
private Dictionary<string, string> styleSheets;
private Dictionary<string, byte[]> fonts;
Expand All @@ -26,19 +25,38 @@ public class BookViewModel : ViewModel
public BookViewModel(int bookId)
{
bookModel = new BookModel();
epubBook = bookModel.OpenBook(bookId);
Contents = new ObservableCollection<ChapterViewModel>(bookModel.GetChapters(epubBook));
images = epubBook.Content.Images.ToDictionary(imageFile => imageFile.Key, imageFile => imageFile.Value.Content);
styleSheets = epubBook.Content.Css.ToDictionary(cssFile => cssFile.Key, cssFile => cssFile.Value.Content);
fonts = epubBook.Content.Fonts.ToDictionary(fontFile => fontFile.Key, fontFile => fontFile.Value.Content);
isLoading = true;
selectChapterCommand = null;
selectedChapter = null;
selectedChapterContent = null;
if (Contents.Any())
SelectChapter(Contents.First());
bookModel.OpenBookAsync(bookId).ContinueWith(epubBook => BookOpened(epubBook), TaskScheduler.FromCurrentSynchronizationContext());
}

public ObservableCollection<ChapterViewModel> Contents { get; private set; }
public ObservableCollection<ChapterViewModel> Contents
{
get
{
return contents;
}
private set
{
contents = value;
OnPropertyChanged(() => Contents);
}
}

public bool IsLoading
{
get
{
return isLoading;
}
private set
{
isLoading = value;
OnPropertyChanged(() => IsLoading);
}
}

public ChapterContentViewModel SelectedChapterContent
{
Expand All @@ -63,14 +81,26 @@ public ICommand SelectChapterCommand
}
}

private void BookOpened(Task<EpubBook> task)
{
EpubBook epubBook = task.Result;
Contents = new ObservableCollection<ChapterViewModel>(bookModel.GetChapters(epubBook));
images = epubBook.Content.Images.ToDictionary(imageFile => imageFile.Key, imageFile => imageFile.Value.Content);
styleSheets = epubBook.Content.Css.ToDictionary(cssFile => cssFile.Key, cssFile => cssFile.Value.Content);
fonts = epubBook.Content.Fonts.ToDictionary(fontFile => fontFile.Key, fontFile => fontFile.Value.Content);
if (Contents.Any())
SelectChapter(Contents.First());
IsLoading = false;
}

private void SelectChapter(ChapterViewModel chapterViewModel)
{
if (selectedChapter != null)
selectedChapter.IsSelected = false;
selectedChapter = chapterViewModel;
selectedChapter.IsTreeItemExpanded = true;
selectedChapter.IsSelected = true;
SelectedChapterContent = new ChapterContentViewModel(selectedChapter.HtmlContent, images, styleSheets, fonts);
SelectedChapterContent = new ChapterContentViewModel(selectedChapter.FilePath, selectedChapter.HtmlContent, images, styleSheets, fonts);
}
}
}
10 changes: 4 additions & 6 deletions Source/EpubReaderDemo/ViewModels/ChapterContentViewModel.cs
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.Generic;

namespace EpubReaderDemo.ViewModels
{
public class ChapterContentViewModel : ViewModel
{
public ChapterContentViewModel(string htmlContent, Dictionary<string, byte[]> images, Dictionary<string, string> styleSheets, Dictionary<string, byte[]> fonts)
public ChapterContentViewModel(string htmlFilePath, string htmlContent, Dictionary<string, byte[]> images, Dictionary<string, string> styleSheets, Dictionary<string, byte[]> fonts)
{
HtmlFilePath = htmlFilePath;
HtmlContent = htmlContent;
Images = images;
StyleSheets = styleSheets;
Fonts = fonts;
}

public string HtmlFilePath { get; private set; }
public string HtmlContent { get; private set; }
public Dictionary<string, byte[]> Images { get; private set; }
public Dictionary<string, string> StyleSheets { get; private set; }
Expand Down
4 changes: 3 additions & 1 deletion Source/EpubReaderDemo/ViewModels/ChapterViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,17 @@ public class ChapterViewModel : ViewModel
private bool isTreeItemExpanded;
private bool isSelected;

public ChapterViewModel(string title, IEnumerable<ChapterViewModel> subChapters, string htmlContent)
public ChapterViewModel(string filePath, string title, IEnumerable<ChapterViewModel> subChapters, string htmlContent)
{
FilePath = filePath;
Title = title;
SubChapters = new ObservableCollection<ChapterViewModel>(subChapters);
HtmlContent = htmlContent;
isTreeItemExpanded = false;
isSelected = false;
}

public string FilePath { get; private set; }
public string Title { get; private set; }
public ObservableCollection<ChapterViewModel> SubChapters { get; private set; }
public string HtmlContent { get; private set; }
Expand Down
Loading

0 comments on commit 37e5bca

Please sign in to comment.