|
4 | 4 | using System.Collections.Generic;
|
5 | 5 | using System.IO;
|
6 | 6 | using System.Linq;
|
| 7 | +using System.Reactive.Linq; |
7 | 8 | using System.Threading;
|
8 | 9 | using System.Threading.Tasks;
|
9 | 10 | using System.Threading.Tasks.Dataflow;
|
@@ -132,112 +133,132 @@ private void SetSelectedSearchItem(OnlineBookViewModel vm)
|
132 | 133 | SelectedSearchBook = OnlineSearchBooks.SingleOrDefault(p => p.IsSelected)?.Book;
|
133 | 134 | }
|
134 | 135 |
|
135 |
| - private async Task<Book> GenerateBookEntryFromOnlineBookAsync(Services.Novel.Models.Book book = null) |
| 136 | + private IObservable<Book> GenerateBookEntryFromOnlineBook(Services.Novel.Models.Book book = null) |
136 | 137 | {
|
137 |
| - if (book == null) |
| 138 | + return Observable.StartAsync(async () => |
138 | 139 | {
|
139 |
| - book = SelectedSearchBook; |
140 |
| - } |
141 |
| - |
142 |
| - if (book != null) |
143 |
| - { |
144 |
| - Book entry = null; |
145 |
| - var dialog = ServiceLocator.Instance.GetService<ICustomDialog>(AppConstants.ProgressDialog); |
146 |
| - var cancelSource = new CancellationTokenSource(); |
147 |
| - dialog.InjectTask( |
148 |
| - Task.Run(async () => |
| 140 | + if (book == null) |
149 | 141 | {
|
150 |
| - EpubService.ClearCache(); |
151 |
| - DispatcherQueue.TryEnqueue(() => |
152 |
| - { |
153 |
| - dialog.InjectData(StringResources.GettingChapters); |
154 |
| - }); |
| 142 | + book = SelectedSearchBook; |
| 143 | + } |
155 | 144 |
|
156 |
| - var chapters = await _novelService.GetBookChaptersAsync(book.SourceId, book.Url, cancelSource); |
157 |
| - var chapterContents = new List<Tuple<int, string, string>>(); |
158 |
| - var progress = 0; |
159 |
| - var total = chapters.Count; |
160 |
| - var options = new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 12, BoundedCapacity = total }; |
161 |
| - options.CancellationToken = cancelSource.Token; |
162 |
| - var action = new ActionBlock<Services.Novel.Models.Chapter>( |
163 |
| - async chapter => |
| 145 | + if (book != null) |
| 146 | + { |
| 147 | + Book entry = null; |
| 148 | + var dialog = ServiceLocator.Instance.GetService<ICustomDialog>(AppConstants.ProgressDialog); |
| 149 | + var cancelSource = new CancellationTokenSource(); |
| 150 | + dialog.InjectTask( |
| 151 | + Task.Run(async () => |
164 | 152 | {
|
165 |
| - if (cancelSource.Token.IsCancellationRequested) |
166 |
| - { |
167 |
| - return; |
168 |
| - } |
169 |
| - |
170 |
| - var content = await _novelService.GetChapterContentAsync(book.SourceId, chapter, cancelSource); |
171 |
| - chapterContents.Add(new Tuple<int, string, string>(content.ChapterIndex, chapter.Title, content.Content)); |
172 |
| - progress++; |
| 153 | + EpubService.ClearCache(); |
173 | 154 | DispatcherQueue.TryEnqueue(() =>
|
174 | 155 | {
|
175 |
| - dialog.InjectData(new Tuple<int, int, string>(progress, total, string.Format(StringResources.ChapterDownloadingProgress, progress, total))); |
| 156 | + dialog.InjectData(StringResources.GettingChapters); |
176 | 157 | });
|
177 |
| - }, |
178 |
| - options); |
179 | 158 |
|
180 |
| - foreach (var chapter in chapters) |
181 |
| - { |
182 |
| - action.Post(chapter); |
183 |
| - } |
| 159 | + var chapters = await _novelService.GetBookChaptersAsync(book.SourceId, book.Url, cancelSource); |
| 160 | + var chapterContents = new List<Tuple<int, string, string>>(); |
| 161 | + var progress = 0; |
| 162 | + var total = chapters.Count; |
| 163 | + var options = new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 12, BoundedCapacity = total }; |
| 164 | + options.CancellationToken = cancelSource.Token; |
| 165 | + var action = new ActionBlock<Services.Novel.Models.Chapter>( |
| 166 | + async chapter => |
| 167 | + { |
| 168 | + if (cancelSource.Token.IsCancellationRequested) |
| 169 | + { |
| 170 | + return; |
| 171 | + } |
184 | 172 |
|
185 |
| - action.Complete(); |
186 |
| - await action.Completion; |
| 173 | + var content = await _novelService.GetChapterContentAsync(book.SourceId, chapter, cancelSource); |
| 174 | + chapterContents.Add(new Tuple<int, string, string>(content.ChapterIndex, chapter.Title, content.Content)); |
| 175 | + progress++; |
| 176 | + DispatcherQueue.TryEnqueue(() => |
| 177 | + { |
| 178 | + dialog.InjectData(new Tuple<int, int, string>(progress, total, string.Format(StringResources.ChapterDownloadingProgress, progress, total))); |
| 179 | + }); |
| 180 | + }, |
| 181 | + options); |
187 | 182 |
|
188 |
| - DispatcherQueue.TryEnqueue(() => |
189 |
| - { |
190 |
| - dialog.InjectData(StringResources.ConvertingAndMovingFile); |
191 |
| - }); |
192 |
| - var configure = new EpubServiceConfiguration() |
193 |
| - { |
194 |
| - Title = book.BookName, |
195 |
| - Author = book.Author, |
196 |
| - Language = "zh", |
197 |
| - OutputFileName = $"{book.BookName}.epub", |
198 |
| - OutputFolderPath = Path.Combine(_rootDirectory.FullName, VMConstants.Library.BooksFolder), |
199 |
| - }; |
| 183 | + foreach (var chapter in chapters) |
| 184 | + { |
| 185 | + action.Post(chapter); |
| 186 | + } |
200 | 187 |
|
201 |
| - configure = await EpubService.InitializeSplitedBookAsync(chapterContents, configure); |
202 |
| - var service = new EpubService(configure); |
203 |
| - await service.CreateAsync(); |
| 188 | + action.Complete(); |
| 189 | + await action.Completion; |
204 | 190 |
|
205 |
| - entry = GetBookEntryFromOnlineBook(book, Path.Combine(configure.OutputFolderPath, configure.OutputFileName)); |
206 |
| - }), |
207 |
| - cancelSource); |
| 191 | + DispatcherQueue.TryEnqueue(() => |
| 192 | + { |
| 193 | + dialog.InjectData(StringResources.ConvertingAndMovingFile); |
| 194 | + }); |
| 195 | + var configure = new EpubServiceConfiguration() |
| 196 | + { |
| 197 | + Title = book.BookName, |
| 198 | + Author = book.Author, |
| 199 | + Language = "zh", |
| 200 | + OutputFileName = $"{book.BookName}.epub", |
| 201 | + OutputFolderPath = Path.Combine(_rootDirectory.FullName, VMConstants.Library.BooksFolder), |
| 202 | + }; |
| 203 | + |
| 204 | + try |
| 205 | + { |
| 206 | + configure = await EpubService.InitializeSplitedBookAsync(chapterContents, configure); |
| 207 | + var service = new EpubService(configure); |
| 208 | + await service.CreateAsync(); |
| 209 | + } |
| 210 | + catch (Exception ex) |
| 211 | + { |
| 212 | + AppViewModel.Instance.ShowTip(ex.Message, InfoType.Error); |
| 213 | + } |
208 | 214 |
|
209 |
| - await dialog.ShowAsync(); |
210 |
| - EpubService.ClearGenerated(); |
| 215 | + entry = GetBookEntryFromOnlineBook(book, Path.Combine(configure.OutputFolderPath, configure.OutputFileName)); |
| 216 | + }), |
| 217 | + cancelSource); |
211 | 218 |
|
212 |
| - if (entry != null) |
213 |
| - { |
214 |
| - if (OriginalBook != null) |
| 219 | + await dialog.ShowAsync(); |
| 220 | + EpubService.ClearGenerated(); |
| 221 | + |
| 222 | + if (entry != null) |
215 | 223 | {
|
216 |
| - var sourceEntry = await LibraryContext.Books.FirstOrDefaultAsync(p => p.Id == OriginalBook.Id); |
217 |
| - if (sourceEntry != null) |
| 224 | + if (OriginalBook != null) |
218 | 225 | {
|
219 |
| - await UpdateBookEntryAsync(sourceEntry, entry); |
220 |
| - entry = sourceEntry; |
| 226 | + var sourceEntry = await LibraryContext.Books.FirstOrDefaultAsync(p => p.Id == OriginalBook.Id); |
| 227 | + if (sourceEntry != null) |
| 228 | + { |
| 229 | + await UpdateBookEntryAsync(sourceEntry, entry); |
| 230 | + entry = sourceEntry; |
| 231 | + } |
| 232 | + else |
| 233 | + { |
| 234 | + await InsertBookEntryAsync(entry); |
| 235 | + } |
| 236 | + |
| 237 | + OriginalBook = null; |
221 | 238 | }
|
222 | 239 | else
|
223 | 240 | {
|
224 | 241 | await InsertBookEntryAsync(entry);
|
225 | 242 | }
|
| 243 | + } |
226 | 244 |
|
227 |
| - OriginalBook = null; |
| 245 | + if (entry != null) |
| 246 | + { |
| 247 | + AppViewModel.Instance.ShowTip(StringResources.ExploreBookAdded, InfoType.Success); |
| 248 | + AppViewModel.Instance.RequestNavigateTo(AppViewModel.Instance.NavigationList.First(p => p.Type == NavigationItemType.Item)); |
228 | 249 | }
|
229 | 250 | else
|
230 | 251 | {
|
231 |
| - await InsertBookEntryAsync(entry); |
| 252 | + AppViewModel.Instance.ShowTip(StringResources.FailedToDownload, InfoType.Error); |
232 | 253 | }
|
233 |
| - } |
234 | 254 |
|
235 |
| - return entry; |
236 |
| - } |
237 |
| - else |
238 |
| - { |
239 |
| - throw new Exception(StringResources.NoSelectedOnlineBook); |
240 |
| - } |
| 255 | + return entry; |
| 256 | + } |
| 257 | + else |
| 258 | + { |
| 259 | + throw new Exception(StringResources.NoSelectedOnlineBook); |
| 260 | + } |
| 261 | + }); |
241 | 262 | }
|
242 | 263 |
|
243 | 264 | private async Task SyncBooksAsync()
|
|
0 commit comments