private async Task <List <MangaObject> > SearchMangaObjectAsync(String SearchTerm, CancellationToken ct, IProgress <Int32> progress) { List <MangaObject> SearchResults = new List <MangaObject>(); if (!Equals(progress, null)) { progress.Report(5); } Boolean firstResponse = true; IEnumerable <Task <ExtensionContentResult> > ExtensionContentTasksQuery = from Extension in ValidExtensions(CORE.Extensions, CORE.UserConfiguration.EnabledExtensions) select LoadExtensionSearchContent(Extension, SearchTerm); List <Task <ExtensionContentResult> > ExtensionContentTasks = ExtensionContentTasksQuery.ToList(); Int32 OriginalExtensionContentTasksCount = ExtensionContentTasks.Count; if (!Equals(progress, null)) { progress.Report(10); } while (ExtensionContentTasks.Count > 0) { // Load Content via Async and process as they complete. ct.ThrowIfCancellationRequested(); Task <ExtensionContentResult> completedTask = await Task.WhenAny(ExtensionContentTasks); ExtensionContentTasks.Remove(completedTask); ct.ThrowIfCancellationRequested(); ExtensionContentResult LoadedExtensionContentResult = await completedTask; if (!Equals(LoadedExtensionContentResult, null)) { String Content = LoadedExtensionContentResult.Content; if (LoadedExtensionContentResult.Extension is ISiteExtension) { // Extension was a ISiteExtension ISiteExtension SiteExtension = LoadedExtensionContentResult.Extension as ISiteExtension; List <SearchResultObject> SearchResultObjects = SiteExtension.ParseSearch(Content); foreach (SearchResultObject SearchResultObject in SearchResultObjects) { MangaObject MangaObject = SearchResultObject.ConvertToMangaObject(), ExistingMangaObject = SearchResults.FirstOrDefault(_MangaObject => { // Locate an Existing MangaObject List <String> ExistingMangaObjectNames = new List <String>(_MangaObject.AlternateNames), MangaObjectNames = new List <String>(MangaObject.AlternateNames); ExistingMangaObjectNames.Insert(0, _MangaObject.Name); MangaObjectNames.Insert(0, MangaObject.Name); ExistingMangaObjectNames = ExistingMangaObjectNames.Select(_ExistingMangaObjectName => SafeAlphaNumeric.Replace(_ExistingMangaObjectName.ToLower(), String.Empty)).ToList(); MangaObjectNames = MangaObjectNames.Select(_MangaObjectNames => SafeAlphaNumeric.Replace(_MangaObjectNames.ToLower(), String.Empty)).ToList(); return(ExistingMangaObjectNames.Intersect(MangaObjectNames).Any()); }); if (Equals(ExistingMangaObject, null)) { SearchResults.Add(MangaObject); } else { ExistingMangaObject.Merge(MangaObject); } } } else if (LoadedExtensionContentResult.Extension is IDatabaseExtension) { // Extension was a IDatabaseExtension IDatabaseExtension DatabaseExtension = LoadedExtensionContentResult.Extension as IDatabaseExtension; List <DatabaseObject> DatabaseObjects = DatabaseExtension.ParseSearch(Content); foreach (DatabaseObject DatabaseObject in DatabaseObjects) { MangaObject ExistingMangaObject = SearchResults.FirstOrDefault(_MangaObject => { // Locate an Existing MangaObject List <String> ExistingMangaObjectNames = new List <String>(_MangaObject.AlternateNames), DatabaseObjectNames = new List <String>(DatabaseObject.AlternateNames); ExistingMangaObjectNames.Insert(0, _MangaObject.Name); DatabaseObjectNames.Insert(0, DatabaseObject.Name); ExistingMangaObjectNames = ExistingMangaObjectNames.Select(_ExistingMangaObjectName => SafeAlphaNumeric.Replace(_ExistingMangaObjectName.ToLower(), String.Empty)).ToList(); DatabaseObjectNames = DatabaseObjectNames.Select(_DatabaseObjectNames => SafeAlphaNumeric.Replace(_DatabaseObjectNames.ToLower(), String.Empty)).ToList(); Int32 IntersectCount = ExistingMangaObjectNames.Intersect(DatabaseObjectNames).Count(), ExistingHalfCount = (Int32)Math.Ceiling((Double)ExistingMangaObjectNames.Count / 2); return(IntersectCount >= ExistingHalfCount); }); if (Equals(ExistingMangaObject, null)) { MangaObject databaseMangaObject = new MangaObject(); databaseMangaObject.AttachDatabase(DatabaseObject, true, true); SearchResults.Add(databaseMangaObject); } else { if (Equals(ExistingMangaObject.DatabaseLocations.FindIndex(_DatabaseLocation => Equals( _DatabaseLocation.ExtensionName, DatabaseExtension.ExtensionDescriptionAttribute.Name)), -1)) { ExistingMangaObject.AttachDatabase(DatabaseObject, preferDatabaseDescription: true); } } } } } firstResponse = Equals(SearchResults.Count, 0); Int32 ExtensionContentTasksProgress = (Int32)Math.Round(((Double)(OriginalExtensionContentTasksCount - ExtensionContentTasks.Count) / (Double)OriginalExtensionContentTasksCount) * 70); if (!Equals(progress, null)) { progress.Report(10 + ExtensionContentTasksProgress); } } if (!Equals(progress, null)) { progress.Report(85); } ct.ThrowIfCancellationRequested(); // Remove Database only results Int32 RemoveCount = SearchResults.RemoveAll(_ => Equals(_.Locations.Count, 0)); if (!Equals(progress, null)) { progress.Report(100); } ct.ThrowIfCancellationRequested(); return(SearchResults); }
public static void Merge(this MangaObject mangaObject, params MangaObject[] list) { mangaObject.Merge(list.AsEnumerable()); }
private async Task <MangaObject> LoadMangaObjectAsync(MangaObject MangaObject, CancellationToken ct, IProgress <Int32> progress) { try { await TaskConcurrencySemaphore.WaitAsync(ct); ct.ThrowIfCancellationRequested(); if (!Equals(progress, null)) { progress.Report(5); } IEnumerable <Task <ExtensionContentResult> > ExtensionContentTasksQuery = from Extension in ValidExtensions(CORE.Extensions, CORE.UserConfiguration.EnabledExtensions) select LoadExtensionMangaContent(Extension, MangaObject); List <Task <ExtensionContentResult> > ExtensionContentTasks = ExtensionContentTasksQuery.ToList(); Int32 OriginalExtensionContentTasksCount = ExtensionContentTasks.Count; Boolean preferDatabaseDescription = true; if (!Equals(progress, null)) { progress.Report(10); } while (ExtensionContentTasks.Count > 0) { // Load Content via Async and process as they complete. ct.ThrowIfCancellationRequested(); Task <ExtensionContentResult> completedTask = await Task.WhenAny(ExtensionContentTasks); ExtensionContentTasks.Remove(completedTask); ct.ThrowIfCancellationRequested(); ExtensionContentResult LoadedExtensionContentResult = await completedTask; if (!Equals(LoadedExtensionContentResult, null)) { String Content = LoadedExtensionContentResult.Content; try { if (LoadedExtensionContentResult.Extension is ISiteExtension) { MangaObject DownloadedMangaObject = (LoadedExtensionContentResult.Extension as ISiteExtension).ParseMangaObject(Content); if (!Equals(DownloadedMangaObject, null)) { MangaObject.Merge(DownloadedMangaObject); } } else if (LoadedExtensionContentResult.Extension is IDatabaseExtension) { DatabaseObject DownloadedDatabaseObject = (LoadedExtensionContentResult.Extension as IDatabaseExtension).ParseDatabaseObject(Content); if (!Equals(DownloadedDatabaseObject, null)) { MangaObject.AttachDatabase(DownloadedDatabaseObject, preferDatabaseDescription: preferDatabaseDescription); preferDatabaseDescription = false; // Only prefer the first database } } } catch (Exception ex) { String Name = LoadedExtensionContentResult.Extension.ExtensionDescriptionAttribute.Name, Language = LoadedExtensionContentResult.Extension.ExtensionDescriptionAttribute.Language; if (!Equals(CORE.Logger, null)) { CORE.Logger.Warn(String.Format("Unable to parse from {0}-{1} for {2}.", Name, Language, MangaObject.Name), ex); } } } Int32 ExtensionContentTasksProgress = (Int32)Math.Round(((Double)(OriginalExtensionContentTasksCount - ExtensionContentTasks.Count) / (Double)OriginalExtensionContentTasksCount) * 80); if (!Equals(progress, null)) { progress.Report(10 + ExtensionContentTasksProgress); } } ct.ThrowIfCancellationRequested(); if (!Equals(progress, null)) { progress.Report(100); } return(MangaObject); } finally { TaskConcurrencySemaphore.Release(); } }