From 0e894bfa192be74dd909feaa9d9148aef908308d Mon Sep 17 00:00:00 2001 From: Drombeys Date: Sat, 27 Apr 2024 15:23:17 +0300 Subject: [PATCH] Implement caching of web resources and news --- .../Manager/InitializerManager.cs | 61 +++++++++++++++---- .../SourceGenerationContext.cs | 2 + .../Storage/FileNameStorage.cs | 7 ++- .../Storage/PathStorage.cs | 2 + 4 files changed, 56 insertions(+), 16 deletions(-) diff --git a/src/ImeSense.Launchers.Belarus.Core/Manager/InitializerManager.cs b/src/ImeSense.Launchers.Belarus.Core/Manager/InitializerManager.cs index 1ad38d6..d17485c 100644 --- a/src/ImeSense.Launchers.Belarus.Core/Manager/InitializerManager.cs +++ b/src/ImeSense.Launchers.Belarus.Core/Manager/InitializerManager.cs @@ -1,4 +1,3 @@ -using System; using System.Diagnostics; using ImeSense.Launchers.Belarus.Core.Helpers; @@ -34,6 +33,10 @@ public async Task InitializeAsync(ISplashScreenManager splashScreenManager) var stopwatch = new Stopwatch(); stopwatch.Start(); + if (!Directory.Exists(DirectoryStorage.LauncherCache)) { + Directory.CreateDirectory(DirectoryStorage.LauncherCache); + } + splashScreenManager.UpdateInformation(new InformationMessage( _localeManager.GetStringByKey("LocalizedStrings.Loading"), _localeManager.GetStringByKey("LocalizedStrings.AccessingRepository"))); @@ -62,12 +65,24 @@ public async Task InitializeAsync(ISplashScreenManager splashScreenManager) _launcherStorage.IsGameReleaseCurrent = await IsGameReleaseCurrentAsync(splashScreenManager.CancellationToken); _launcherStorage.IsUserAuthorized = File.Exists(PathStorage.LauncherSetting); - if (_launcherStorage.IsUserAuthorized) { - await Task.Factory.StartNew(() => LoadNewsAsync(locale, splashScreenManager.CancellationToken)); + if (_launcherStorage.IsGameReleaseCurrent) { + var contentNews = await LocaleLoadCacheAsync(PathStorage.NewsCache) ?? []; + if (contentNews.Any(x => x.Locale != null && x.Locale.Key.Equals(_userManager.UserSettings.Locale.Key))) { + _launcherStorage.NewsContents = new(contentNews); + } else { + await LoadRemoteContent(splashScreenManager, locale); + } + + var contentRes = await LocaleLoadCacheAsync(PathStorage.WebResourcesCache); + if (contentRes is not null && contentRes.Count != 0) { + _launcherStorage.WebResources = new(contentRes); + } else { + await Task.Factory.StartNew(() => RemoteLoadWebResourcesAsync(cancellationToken: splashScreenManager.CancellationToken)); + } } else { - await Task.Factory.StartNew(() => LoadNewsAsync(cancellationToken: splashScreenManager.CancellationToken)); + await LoadRemoteContent(splashScreenManager, locale); + await Task.Factory.StartNew(() => RemoteLoadWebResourcesAsync(cancellationToken: splashScreenManager.CancellationToken)); } - await Task.Factory.StartNew(() => LoadWebResourcesAsync(cancellationToken: splashScreenManager.CancellationToken)); } else { if (_launcherStorage.IsUserAuthorized) { _launcherStorage.NewsContents = new(LoadErrorNews(locale) ?? []); @@ -87,6 +102,30 @@ public async Task InitializeAsync(ISplashScreenManager splashScreenManager) } } + private async Task LoadRemoteContent(ISplashScreenManager splashScreenManager, Locale? locale) + { + if (_launcherStorage.IsUserAuthorized) { + await Task.Factory.StartNew(() => RemoteLoadNewsAsync(locale, splashScreenManager.CancellationToken), splashScreenManager.CancellationToken); + } else { + await Task.Factory.StartNew(() => RemoteLoadNewsAsync(cancellationToken: splashScreenManager.CancellationToken), splashScreenManager.CancellationToken); + } + } + + private async Task?> LocaleLoadCacheAsync(string cachePath, CancellationToken cancellationToken = default) + { + try { + if (!File.Exists(cachePath)) { + return null; + } + + return await FileDataHelper.LoadDataAsync>(cachePath, cancellationToken); + } catch (Exception ex) { + _logger.LogError("{Message}", ex.Message); + _logger.LogError("{StackTrace}", ex.StackTrace); + throw; + } + } + private List? LoadErrorNews(Locale? locale = null) { // News in all languages @@ -132,7 +171,6 @@ private async Task CheckGitHubConnectionAsync(CancellationToken cancellati } } - private async Task IsLauncherReleaseCurrentAsync(CancellationToken cancellationToken = default) { var tags = await _gitStorageApiService.GetTagsAsync(UriStorage.LauncherApiUri, cancellationToken); @@ -161,10 +199,6 @@ private async Task IsGameReleaseCurrentAsync(CancellationToken cancellatio { var gitStorageRelease = _launcherStorage.GitHubRelease; - if (!Directory.Exists(DirectoryStorage.LauncherCache)) { - Directory.CreateDirectory(DirectoryStorage.LauncherCache); - } - if (File.Exists(PathStorage.CurrentRelease)) { var releaseComparer = gitStorageRelease != null && await _releaseComparerService.IsComparerAsync(gitStorageRelease, cancellationToken); if (!releaseComparer) { @@ -195,13 +229,13 @@ public void InitializeLocale() _localeManager.SetLocale(userSettings.Locale.Key); } - private async Task LoadWebResourcesAsync(CancellationToken cancellationToken = default) + private async Task RemoteLoadWebResourcesAsync(CancellationToken cancellationToken = default) { try { var contents = await _gitStorageApiService .DownloadJsonAsync>(FileNameStorage.WebResources, UriStorage.BelarusApiUri, cancellationToken); - if (contents != null) { + await FileSystemHelper.WriteReleaseAsync(contents, Path.Combine(DirectoryStorage.LauncherCache, FileNameStorage.WebResources), cancellationToken); _launcherStorage.WebResources = new(contents); } } catch (Exception ex) { @@ -211,7 +245,7 @@ private async Task LoadWebResourcesAsync(CancellationToken cancellationToken = d } } - private async Task LoadNewsAsync(Locale? locale = null, CancellationToken cancellationToken = default) + private async Task RemoteLoadNewsAsync(Locale? locale = null, CancellationToken cancellationToken = default) { // News in all languages var allNews = new List(); @@ -233,6 +267,7 @@ private async Task LoadNewsAsync(Locale? locale = null, CancellationToken cancel _logger.LogError("{StackTrace}", ex.StackTrace); } + await FileSystemHelper.WriteReleaseAsync(allNews, Path.Combine(DirectoryStorage.LauncherCache, "News.json"), cancellationToken); _launcherStorage.NewsContents = new(allNews); } diff --git a/src/ImeSense.Launchers.Belarus.Core/SourceGenerationContext.cs b/src/ImeSense.Launchers.Belarus.Core/SourceGenerationContext.cs index 8b39f0a..5798907 100644 --- a/src/ImeSense.Launchers.Belarus.Core/SourceGenerationContext.cs +++ b/src/ImeSense.Launchers.Belarus.Core/SourceGenerationContext.cs @@ -16,11 +16,13 @@ namespace ImeSense.Launchers.Belarus.Core; [JsonSerializable(typeof(NewsContent))] [JsonSerializable(typeof(IEnumerable))] [JsonSerializable(typeof(IEnumerable))] +[JsonSerializable(typeof(List))] [JsonSerializable(typeof(Tag))] [JsonSerializable(typeof(IEnumerable))] [JsonSerializable(typeof(UserSettings))] [JsonSerializable(typeof(WebResource))] [JsonSerializable(typeof(WebResource[]))] +[JsonSerializable(typeof(List))] [JsonSerializable(typeof(IEnumerable))] public partial class SourceGenerationContext : JsonSerializerContext { diff --git a/src/ImeSense.Launchers.Belarus.Core/Storage/FileNameStorage.cs b/src/ImeSense.Launchers.Belarus.Core/Storage/FileNameStorage.cs index 640bf52..2fb89c5 100644 --- a/src/ImeSense.Launchers.Belarus.Core/Storage/FileNameStorage.cs +++ b/src/ImeSense.Launchers.Belarus.Core/Storage/FileNameStorage.cs @@ -12,9 +12,10 @@ public static class FileNameStorage public static string GameSetting => "user.ltx"; public static string LauncherSetting => "sblauncher.json"; public static string CurrentRelease => "CurrentRelease.json"; - - public static string LegacyHash => "hash.json"; - public static string LegacyNews => "news.json"; + public static string NewsContent => "News.json"; public static string NewsContentRus => "news_content_rus.json"; public static string NewsContentEng => "news_content_eng.json"; + + public static string LegacyHash => "hash.json"; + public static string LegacyNews => "news.json"; } diff --git a/src/ImeSense.Launchers.Belarus.Core/Storage/PathStorage.cs b/src/ImeSense.Launchers.Belarus.Core/Storage/PathStorage.cs index ae4e6b7..dcbefc8 100644 --- a/src/ImeSense.Launchers.Belarus.Core/Storage/PathStorage.cs +++ b/src/ImeSense.Launchers.Belarus.Core/Storage/PathStorage.cs @@ -5,4 +5,6 @@ public static class PathStorage public static string LauncherSetting => Path.Combine(DirectoryStorage.AppData, FileNameStorage.LauncherSetting); public static string CurrentRelease => Path.Combine(DirectoryStorage.LauncherCache, FileNameStorage.CurrentRelease); public static string GameUser => Path.Combine(DirectoryStorage.AppData, FileNameStorage.GameSetting); + public static string NewsCache => Path.Combine(DirectoryStorage.LauncherCache, FileNameStorage.NewsContent); + public static string WebResourcesCache => Path.Combine(DirectoryStorage.LauncherCache, FileNameStorage.WebResources); }