public async Task Run(IContainer ioc, IProgress <CommandProgressReport> progress, CancellationToken cancellationToken = default) { if (NoWarning) { NonInteractive = true; } var aggregator = new CommandProgressAggregator(progress); var cardDBProgress = aggregator.GetProgress <DatabaseUpdateReport>(); var deckParserProgress = aggregator.GetProgress <DeckParserProgressReport>(); Progress = aggregator.GetProgress <DeckExportProgressReport>(); await ioc.UpdateCardDatabase(cardDBProgress, cancellationToken); Log.Information("Running..."); var parser = await ioc.GetAllInstances <IDeckParser <WeissSchwarzDeck, WeissSchwarzCard> >() .ToAsyncEnumerable() .WhereAwait(async parser => await parser.IsCompatible(Source)) .OrderByDescending(parser => parser.Priority) .FirstAsync(cancellationToken); var deck = await parser.Parse(Source, deckParserProgress, cancellationToken); var inspectionOptions = new InspectionOptions() { IsNonInteractive = this.NonInteractive, NoWarning = this.NoWarning }; var exporter = ioc.GetAllInstances <IDeckExporter <WeissSchwarzDeck, WeissSchwarzCard> >() .Where(exporter => exporter.Alias.Contains(Exporter)) .First(); var inspectors = ioc.GetAllInstances <IExportedDeckInspector <WeissSchwarzDeck, WeissSchwarzCard> >() .Where(i => !(i is IFilter <IDeckExporter <WeissSchwarzDeck, WeissSchwarzCard> > filter) || filter.IsIncluded(exporter)); if (exporter is IFilter <IExportedDeckInspector <WeissSchwarzDeck, WeissSchwarzCard> > filter) { inspectors = inspectors.Where(filter.IsIncluded); } deck = await inspectors.OrderByDescending(inspector => inspector.Priority) .ToAsyncEnumerable() .AggregateAwaitAsync(deck, async(d, inspector) => await inspector.Inspect(d, inspectionOptions)); if (deck != WeissSchwarzDeck.Empty) { await exporter.Export(deck, this); } }
public async Task Run(IContainer container, IProgress <CommandProgressReport> progress, CancellationToken ct = default) { var Log = Serilog.Log.ForContext <ParseVerb>(); var parser = await container.GetAllInstances <ICardSetParser <WeissSchwarzCard> >() .ToAsyncEnumerable() .WhereAwait(async parser => await parser.IsCompatible(this)) .FirstAsync(); var redirector = new CommandProgressAggregator(progress); var cardList = await parser.Parse(URI, redirector, ct).ToListAsync(ct); var cards = cardList.Distinct(WeissSchwarzCard.SerialComparer).ToAsyncEnumerable(); var postProcessors = await container.GetAllInstances <ICardPostProcessor <WeissSchwarzCard> >() .ToAsyncEnumerable() .WhereAwait(async processor => await processor.IsCompatible(cardList)) .Where(processor => (parser is IFilter <ICardPostProcessor <WeissSchwarzCard> > filter) ? filter.IsIncluded(processor) : true) .WhereAwait(async processor => (processor is ISkippable <IParseInfo> skippable) ? await skippable.IsIncluded(this) : true) .WhereAwait(async processor => (processor is ISkippable <ICardSetParser <WeissSchwarzCard> > skippable) ? await skippable.IsIncluded(parser) : true) .OrderByDescending(processor => processor.Priority) .ToArrayAsync(ct) ; redirector.PostProcessorCount = postProcessors.Length; cards = postProcessors.Aggregate(cards, (pp, cs) => cs.Process(pp, redirector, ct)); await container.UpdateCardDatabase(redirector, ct); using (var db = container.GetInstance <CardDatabaseContext>()) { await foreach (var card in cards) { card.VersionTimestamp = Program.AppVersion; var dups = db.WeissSchwarzCards.AsQueryable <WeissSchwarzCard>().Where(c => c.Serial == card.Serial).ToArray(); if (dups.Length > 0) { db.WeissSchwarzCards.RemoveRange(dups); // delete all the dups, based on serial. } db.Add(card); Log.Information("Added to DB: {serial}", card.Serial); } progress.Report(new CommandProgressReport { ReportMessage = new MultiLanguageString { EN = "Saving all changes..." }, Percentage = 75 }); await db.SaveChangesAsync(); } Log.Information("Successfully parsed: {uri}", URI); progress.Report(new CommandProgressReport { ReportMessage = new MultiLanguageString { EN = $"Successfully parsed: {URI}" }, Percentage = 100 }); }