Skip to content

Commit

Permalink
Optimizes caching in GUI functions
Browse files Browse the repository at this point in the history
Fixes crashes that occur when due to System.Text.JSON migration on DeckLog
  • Loading branch information
ronelm2000 committed Oct 8, 2024
1 parent 9f10301 commit 52b09ce
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 58 deletions.
48 changes: 31 additions & 17 deletions Montage.Weiss.Tools.GUI/ViewModels/Dialogs/ImportDeckViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ public partial class ImportDeckViewModel : ViewModelBase
[ObservableProperty]
private bool _isVisible;

[ObservableProperty]
private bool _isCommandEnabled;

[ObservableProperty]
private Func<MainWindowViewModel?> _parent;

Expand All @@ -27,6 +30,7 @@ public ImportDeckViewModel()
{
Parent = () => null;
IsVisible = Design.IsDesignMode;
IsCommandEnabled = true;
DeckUrl = string.Empty;
}

Expand All @@ -37,30 +41,40 @@ internal async Task ImportDeck()
if (parentModel.Container is not IContainer container)
return;

var progressReporter = new ProgressReporter(Log, message => parentModel.Status = message);
IsCommandEnabled = false;

try
{
var progressReporter = new ProgressReporter(Log, message => parentModel.Status = message);
var command = new ExportVerb { Source = DeckUrl, NonInteractive = true, NoWarning = true };
var deck = await command.Parse(container, progressReporter);

var command = new ExportVerb { Source = DeckUrl, NonInteractive = true, NoWarning = true };
var deck = await command.Parse(container, progressReporter);
parentModel.DeckName = deck.Name;
parentModel.DeckRemarks = deck.Remarks;

parentModel.DeckName = deck.Name;
parentModel.DeckRemarks = deck.Remarks;
var cacheList = deck.Ratios.Keys.Where(c => c.GetCachedImagePath() is null && c.EnglishSetType != EnglishSetType.Custom).ToAsyncEnumerable();
await new CacheVerb { }.Cache(container, progressReporter, cacheList);

var cacheList = deck.Ratios.Keys.Where(c => c.GetCachedImagePath() is null && c.EnglishSetType != EnglishSetType.Custom)
.DistinctBy(c => c.ReleaseID)
.Select(c => new CacheVerb { Language = (c.Language == CardLanguage.English ? "en" : "jp"), ReleaseIDorFullSerialID = c.ReleaseID })
.ToList();
parentModel.DeckRatioList.Clear();

foreach (var cacheCommand in cacheList)
await cacheCommand.Run(container, progressReporter);
foreach (var ratio in deck.Ratios)
parentModel.DeckRatioList.Add(new CardRatioViewModel(ratio.Key, ratio.Value));

parentModel.DeckRatioList.Clear();
parentModel.SortDeck();
parentModel.UpdateDeckStats();

foreach (var ratio in deck.Ratios)
parentModel.DeckRatioList.Add(new CardRatioViewModel(ratio.Key, ratio.Value));
parentModel.Status = $"Done Importing: {DeckUrl}";

parentModel.SortDeck();
parentModel.UpdateDeckStats();
}
catch (Exception ex)
{
Log.Error("Error occurred", ex);
parentModel.Status = ex.Message;
} finally
{

IsVisible = false;
IsVisible = false;
IsCommandEnabled = true;
}
}
}
26 changes: 5 additions & 21 deletions Montage.Weiss.Tools.GUI/ViewModels/MainWindowViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -226,11 +226,9 @@ private async Task<string> UpdateDatabaseView(string searchText, CancellationTok
.Distinct(c => c.Serial)
.Take(300)
.ToListAsync(token);
var cacheList = searchCardList.Where(c => c.GetCachedImagePath() is null && c.EnglishSetType != EnglishSetType.Custom)
.DistinctBy(c => c.ReleaseID)
.Select(c => new CacheVerb { Language = (c.Language == CardLanguage.English ? "en" : "jp"), ReleaseIDorFullSerialID = c.ReleaseID })
.ToList();
await Task.WhenAll(cacheList.Select(v => v.Run(Container, progressReporter)));

var cacheList = searchCardList.Where(c => c.GetCachedImagePath() is null && c.EnglishSetType != EnglishSetType.Custom).ToAsyncEnumerable();
await new CacheVerb { }.Cache(Container, progressReporter, cacheList, token);

if (token.IsCancellationRequested)
return searchText;
Expand Down Expand Up @@ -379,11 +377,8 @@ private async Task LoadDatabase(ProgressReporter progressReporter)

using var db = Container!.GetInstance<CardDatabaseContext>();
var initialCardList = db.WeissSchwarzCards.Take(100).ToList();
var cacheList = initialCardList.Where(c => c.GetCachedImagePath() is null && c.EnglishSetType != EnglishSetType.Custom)
.DistinctBy(c => c.ReleaseID)
.Select(c => new CacheVerb { Language = (c.Language == CardLanguage.English ? "en" : "jp"), ReleaseIDorFullSerialID = c.ReleaseID })
.ToList();
await Task.WhenAll(cacheList.Select(v => v.Run(Container, progressReporter)));
var cacheList = initialCardList.Where(c => c.GetCachedImagePath() is null && c.EnglishSetType != EnglishSetType.Custom).ToAsyncEnumerable();
await new CacheVerb { }.Cache(Container, progressReporter, cacheList);

foreach (var card in initialCardList)
{
Expand Down Expand Up @@ -414,17 +409,6 @@ await Dispatcher.UIThread.InvokeAsync(() =>
{
ImportSetDC.IsVisible = true;
});
// ImportSetVM = new ImportSetViewModel { Parent = this };
/*
var progressReporter = new ProgressReporter(log, message => Status = message);
await new ParseVerb
{
URI = "https://www.encoredecks.com/?page=1&set=608869f81e41dfffbd963099"
}.Run(Container!, progressReporter);
await LoadDatabase(progressReporter);
*/
}

internal async Task ImportDeck()
Expand Down
1 change: 1 addition & 0 deletions Montage.Weiss.Tools.GUI/Views/ImportDeckDialog.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center"
Click="ParseButton_Click"
IsEnabled="{Binding IsCommandEnabled}"
Grid.Column="2"
>
Parse
Expand Down
36 changes: 21 additions & 15 deletions MontageWeissTools/CLI/CacheVerb.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using CommandLine;
using Fluent.IO;
using Flurl;
using Flurl.Http;
using Lamar;
using Microsoft.EntityFrameworkCore;
Expand Down Expand Up @@ -34,27 +35,13 @@ public async Task Run(IContainer ioc, IProgress<CommandProgressReport> progress,
progress.Report(report);

var language = InterpretLanguage(Language);
Func<Flurl.Url, CookieSession> _cookieSession = (url) => ioc.GetInstance<GlobalCookieJar>()[url.Root];

using (var db = ioc.GetInstance<CardDatabaseContext>())
{
await db.Database.MigrateAsync(cancellationToken);
var list = GenerateQuery(db, language);

await foreach (var card in list.WithCancellation(cancellationToken))
{
report = report with
{
MessageType = MessageType.InProgress,
ReportMessage = new Card.API.Entities.Impls.MultiLanguageString
{
EN = $"Caching [${card.Serial}]..."
},
Percentage = 50
};
progress.Report(report);
await AddCachedImageAsync(card, _cookieSession, cancellationToken);
}
await Cache(ioc, progress, list, cancellationToken);

Log.Information("Done.");
Log.Information("PS: Please refrain from executing this command continuously as this may cause your IP address to get tagged as a DDoS bot.");
Expand All @@ -66,6 +53,25 @@ public async Task Run(IContainer ioc, IProgress<CommandProgressReport> progress,
progress.Report(report);
}

public async Task Cache(IContainer container, IProgress<CommandProgressReport> progress, IAsyncEnumerable<WeissSchwarzCard> list, CancellationToken cancellationToken = default)
{
Func<Flurl.Url, CookieSession> _cookieSession = (url) => container.GetInstance<GlobalCookieJar>()[url.Root];
await foreach (var card in list.WithCancellation(cancellationToken))
{
var report = new CommandProgressReport
{
MessageType = MessageType.InProgress,
ReportMessage = new Card.API.Entities.Impls.MultiLanguageString
{
EN = $"Caching [{card.Serial}]..."
},
Percentage = 50
};
progress.Report(report);
await AddCachedImageAsync(card, _cookieSession, cancellationToken);
}
}

private IAsyncEnumerable<WeissSchwarzCard> GenerateQuery(CardDatabaseContext db, CardLanguage? language)
{
if (language == null)
Expand Down
27 changes: 22 additions & 5 deletions MontageWeissTools/Impls/Parsers/Deck/DeckLogParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,11 @@ public async Task<WeissSchwarzDeck> Parse(string sourceUrlOrFile, IProgress<Deck
var response = await $"{settings.DeckViewURL}{deckID}" //
.WithReferrer(sourceUrlOrFile) //
.PostJsonAsync(null, cancellationToken: cancellationToken);
var json = JsonSerializer.Deserialize<DeckLogDeck>(await response.GetStringAsync())!;
var options = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
};
var json = JsonSerializer.Deserialize<DeckLogDeck>(await response.GetStringAsync(), options)!;
var newDeck = new WeissSchwarzDeck();
var missingSerials = new List<string>();
newDeck.Name = json.Title.ToString() ?? throw new DeckParsingException("Cannot parse the deck name.");
Expand Down Expand Up @@ -101,11 +105,11 @@ public async Task<WeissSchwarzDeck> Parse(string sourceUrlOrFile, IProgress<Deck
Log.Information("Parsing all missing sets from EncoreDecks. (Some sets may still be untranslated tho!)");
var deckLogSetList = await "https://www.encoredecks.com/api/serieslist"
.WithRESTHeaders()
.GetJsonAsync<List<dynamic>>(cancellationToken: cancellationToken);
.GetJsonAsync<List<EncoreDecksEntry>>(cancellationToken: cancellationToken);

await deckLogSetList
.Where(set => missingSets.Contains($"{set.side}{set.release}"))
.Select(set => (string)set._id)
.Where(set => missingSets.Contains($"{set.Side}{set.Release}"))
.Select(set => set.Id)
.ToAsyncEnumerable()
.ForEachAwaitWithCancellationAsync((set, ct) => _parse(set, aggregator, ct), cancellationToken);
}
Expand Down Expand Up @@ -186,7 +190,7 @@ internal void ReportParsedDeckData(WeissSchwarzDeck newDeck)
internal void ReportMissingSets(List<string> missingSets)
{
this.missingSets = missingSets;
report = report with { Percentage = 10, ReportMessage = new MultiLanguageString { EN = $"Found Missing Sets; Parsing using EncoreDecks: [{missingSets.ConcatAsString(",")}" } };
report = report with { Percentage = 10, ReportMessage = new MultiLanguageString { EN = $"Found Missing Sets; Parsing using EncoreDecks: [{missingSets.ConcatAsString(",")}]" } };
progress.Report(report);
}

Expand Down Expand Up @@ -221,7 +225,20 @@ private record DeckLogDeck

private record DeckLogCardRatio
{
[JsonPropertyName("card_number")]
public required string CardNumber { get; init; }

[JsonPropertyName("num")]
public required int Num { get; init; }
}

private record EncoreDecksEntry
{
[JsonPropertyName("side")]
public required string Side { get; init; }
[JsonPropertyName("release")]
public required string Release { get; init; }
[JsonPropertyName("_id")]
public required string Id { get; init; }
}
}

0 comments on commit 52b09ce

Please sign in to comment.