From c3724921f36d292f30b6a1771f0663b4971a1fea Mon Sep 17 00:00:00 2001 From: Mateusz Skoczek Date: Sun, 3 Mar 2024 16:23:45 +0100 Subject: [PATCH] hardcoded search error messages changed to string resources --- .../Strings/en-US/SearchResources.resw | 141 ++++++++++++++++++ .../Home/HomeViewModel.cs | 4 +- .../StringResourcesService.cs | 3 + .../MediaSearchException.cs | 18 ++- .../SourceSearchService.cs | 7 +- .../TwitchSearchService.cs | 37 ++++- .../VDownload.Sources/SearchService.cs | 13 +- 7 files changed, 202 insertions(+), 21 deletions(-) create mode 100644 VDownload.Core/VDownload.Core.Strings/Strings/en-US/SearchResources.resw diff --git a/VDownload.Core/VDownload.Core.Strings/Strings/en-US/SearchResources.resw b/VDownload.Core/VDownload.Core.Strings/Strings/en-US/SearchResources.resw new file mode 100644 index 0000000..a9da29a --- /dev/null +++ b/VDownload.Core/VDownload.Core.Strings/Strings/en-US/SearchResources.resw @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Playlist is empty + + + Invalid url. Url cannot be empty. + + + Invalid url. Url does not match any of supported source. + + + Invalid url. Twitch channel not found. + + + Twitch authentication error. Not authenticated to Twitch. + + + Twitch authentication error. Authentication token is invalid. + + + Invalid url. Url does not match any of supported source's media types. + + \ No newline at end of file diff --git a/VDownload.Core/VDownload.Core.ViewModels/Home/HomeViewModel.cs b/VDownload.Core/VDownload.Core.ViewModels/Home/HomeViewModel.cs index c6b8fcc..48fae5a 100644 --- a/VDownload.Core/VDownload.Core.ViewModels/Home/HomeViewModel.cs +++ b/VDownload.Core/VDownload.Core.ViewModels/Home/HomeViewModel.cs @@ -200,7 +200,7 @@ namespace VDownload.Core.ViewModels.Home catch (MediaSearchException ex) { OptionBarLoading = false; - OptionBarMessage = ex.Message; + OptionBarMessage = _stringResourcesService.SearchResources.Get(ex.StringCode); OptionBarSearchNotPending = true; return; } @@ -229,7 +229,7 @@ namespace VDownload.Core.ViewModels.Home catch (MediaSearchException ex) { OptionBarLoading = false; - OptionBarMessage = ex.Message; + OptionBarMessage = _stringResourcesService.SearchResources.Get(ex.StringCode); OptionBarSearchNotPending = true; return; } diff --git a/VDownload.Services/VDownload.Services.UI/VDownload.Services.UI.StringResources/StringResourcesService.cs b/VDownload.Services/VDownload.Services.UI/VDownload.Services.UI.StringResources/StringResourcesService.cs index 062e9ce..5fe0549 100644 --- a/VDownload.Services/VDownload.Services.UI/VDownload.Services.UI.StringResources/StringResourcesService.cs +++ b/VDownload.Services/VDownload.Services.UI/VDownload.Services.UI.StringResources/StringResourcesService.cs @@ -12,6 +12,7 @@ namespace VDownload.Services.UI.StringResources StringResources HomeDownloadsViewResources { get; } StringResources AuthenticationViewResources { get; } StringResources NotificationsResources { get; } + StringResources SearchResources { get; } } @@ -35,6 +36,7 @@ namespace VDownload.Services.UI.StringResources public StringResources HomeDownloadsViewResources { get; protected set; } public StringResources AuthenticationViewResources { get; protected set; } public StringResources NotificationsResources { get; protected set; } + public StringResources SearchResources { get; protected set; } #endregion @@ -53,6 +55,7 @@ namespace VDownload.Services.UI.StringResources HomeDownloadsViewResources = BuildResource("HomeDownloadsViewResources"); AuthenticationViewResources = BuildResource("AuthenticationViewResources"); NotificationsResources = BuildResource("NotificationsResources"); + SearchResources = BuildResource("SearchResources"); } #endregion diff --git a/VDownload.Sources/VDownload.Sources.Common/MediaSearchException.cs b/VDownload.Sources/VDownload.Sources.Common/MediaSearchException.cs index 48e41a9..8db706c 100644 --- a/VDownload.Sources/VDownload.Sources.Common/MediaSearchException.cs +++ b/VDownload.Sources/VDownload.Sources.Common/MediaSearchException.cs @@ -8,13 +8,21 @@ namespace VDownload.Sources.Common { public class MediaSearchException : Exception { + #region PROPERTIES + + public string StringCode { get; protected set; } + + #endregion + + + #region CONSTRUCTORS - public MediaSearchException() : base() { } - - public MediaSearchException(string message) : base(message) { } - - public MediaSearchException(string message, Exception inner) : base(message, inner) { } + public MediaSearchException(string stringCode) : this(stringCode, stringCode) { } + public MediaSearchException(string stringCode, string message) : base(message) + { + StringCode = stringCode; + } #endregion } diff --git a/VDownload.Sources/VDownload.Sources.Common/SourceSearchService.cs b/VDownload.Sources/VDownload.Sources.Common/SourceSearchService.cs index 2d0362b..cc56a0c 100644 --- a/VDownload.Sources/VDownload.Sources.Common/SourceSearchService.cs +++ b/VDownload.Sources/VDownload.Sources.Common/SourceSearchService.cs @@ -32,7 +32,7 @@ namespace VDownload.Sources.Common return video; } } - throw new MediaSearchException("Invalid url"); // TODO : Change to string resource + throw CreateExceptionUnknownMediaType(); } public async Task SearchPlaylist(string url, int maxVideoCount) @@ -47,7 +47,7 @@ namespace VDownload.Sources.Common return video; } } - throw new MediaSearchException("Invalid url"); // TODO : Change to string resource + throw CreateExceptionUnknownMediaType(); } #endregion @@ -60,6 +60,9 @@ namespace VDownload.Sources.Common protected abstract IEnumerable GetPlaylistRegexes(); + protected MediaSearchException CreateExceptionUnknownMediaType() => new MediaSearchException("UnknownMediaType"); + protected MediaSearchException CreateExceptionEmptyPlaylist() => new MediaSearchException("EmptyPlaylist"); + #endregion } } diff --git a/VDownload.Sources/VDownload.Sources.Twitch/VDownload.Sources.Twitch/TwitchSearchService.cs b/VDownload.Sources/VDownload.Sources.Twitch/VDownload.Sources.Twitch/TwitchSearchService.cs index c523181..8d40d3a 100644 --- a/VDownload.Sources/VDownload.Sources.Twitch/VDownload.Sources.Twitch/TwitchSearchService.cs +++ b/VDownload.Sources/VDownload.Sources.Twitch/VDownload.Sources.Twitch/TwitchSearchService.cs @@ -110,8 +110,22 @@ namespace VDownload.Sources.Twitch protected async Task GetChannel(string id, int count) { byte[] token = await GetToken(); - GetUsersResponse info = await _apiService.HelixGetUser(id, token); - Api.Helix.GetUsers.Response.Data userResponse = info.Data[0]; + + Api.Helix.GetUsers.Response.Data userResponse; + try + { + GetUsersResponse info = await _apiService.HelixGetUser(id, token); + if (info.Data.Count <= 0) + { + throw CreateExceptionChannelNotFound(); + } + userResponse = info.Data[0]; + } + catch (InvalidOperationException ex) + { + // TODO: Add logging + throw; + } TwitchChannel channel = new TwitchChannel { @@ -130,6 +144,12 @@ namespace VDownload.Sources.Twitch { videos = count > 100 ? 100 : count; GetVideosResponse videosResponse = await _apiService.HelixGetUserVideos(channel.Id, token, videos, cursor); + + if (!tasks.Any() && !videosResponse.Data.Any()) + { + throw CreateExceptionEmptyPlaylist(); + } + videosList = videosResponse.Data; cursor = videosResponse.Pagination.Cursor; tasks.AddRange(videosList.Select(ParseVod)); @@ -271,19 +291,20 @@ namespace VDownload.Sources.Twitch protected async Task GetToken() { - byte[]? token = await _twitchAuthenticationService.GetToken(); - if (token is null) - { - throw new MediaSearchException("Not authenticated to Twitch"); // TODO : Change to string resource - } + byte[]? token = await _twitchAuthenticationService.GetToken() ?? throw CreateExceptionNotAuthenticated(); + TwitchValidationResult validation = await _twitchAuthenticationService.ValidateToken(token); if (!validation.Success) { - throw new MediaSearchException("Twitch authentication error"); // TODO : Change to string resource + throw CreateExceptionTokenValidationUnsuccessful(); } return token; } + protected MediaSearchException CreateExceptionNotAuthenticated() => new MediaSearchException("TwitchNotAuthenticated"); + protected MediaSearchException CreateExceptionTokenValidationUnsuccessful() => new MediaSearchException("TwitchTokenValidationUnsuccessful"); + protected MediaSearchException CreateExceptionChannelNotFound() => new MediaSearchException("TwitchChannelNotFound"); + #endregion } } diff --git a/VDownload.Sources/VDownload.Sources/SearchService.cs b/VDownload.Sources/VDownload.Sources/SearchService.cs index 984281f..e96165f 100644 --- a/VDownload.Sources/VDownload.Sources/SearchService.cs +++ b/VDownload.Sources/VDownload.Sources/SearchService.cs @@ -58,7 +58,8 @@ namespace VDownload.Sources return await mapping.Service.SearchVideo(url); } } - throw new MediaSearchException("Source is not supported"); // TODO : Change to string resource + + throw CreateExceptionSourceNotSupported(); } public async Task SearchPlaylist(string url, int maxVideoCount) @@ -72,7 +73,8 @@ namespace VDownload.Sources return await mapping.Service.SearchPlaylist(url, maxVideoCount); } } - throw new MediaSearchException("Source is not supported"); // TODO : Change to string resource + + throw CreateExceptionSourceNotSupported(); } #endregion @@ -81,14 +83,17 @@ namespace VDownload.Sources #region PRIVATE METHODS - private void BaseUrlCheck(string url) + protected void BaseUrlCheck(string url) { if (string.IsNullOrWhiteSpace(url)) { - throw new MediaSearchException("Url cannot be empty"); // TODO : Change to string resource + throw CreateExceptionEmptyUrl(); } } + protected MediaSearchException CreateExceptionSourceNotSupported() => new MediaSearchException("SourceNotSupported"); + protected MediaSearchException CreateExceptionEmptyUrl() => new MediaSearchException("EmptyUrl"); + #endregion } }