diff --git a/JL.Core/Anki/AnkiConfig.cs b/JL.Core/Anki/AnkiConfig.cs index d7c8fc22..60d12036 100644 --- a/JL.Core/Anki/AnkiConfig.cs +++ b/JL.Core/Anki/AnkiConfig.cs @@ -1,3 +1,4 @@ +using System.Collections.Immutable; using System.Text.Json; using System.Text.Json.Serialization; using JL.Core.Utilities; @@ -12,11 +13,11 @@ public sealed class AnkiConfig [JsonPropertyName("fields")] public Dictionary Fields { get; } - [JsonPropertyName("tags")] public string[] Tags { get; } + [JsonPropertyName("tags")] public ImmutableArray Tags { get; } [JsonIgnore] private static Dictionary? s_ankiConfigDict; - public AnkiConfig(string deckName, string modelName, Dictionary fields, string[] tags) + public AnkiConfig(string deckName, string modelName, Dictionary fields, ImmutableArray tags) { DeckName = deckName; ModelName = modelName; diff --git a/JL.Core/Anki/AnkiConnect.cs b/JL.Core/Anki/AnkiConnect.cs index 88eb3152..de91854f 100644 --- a/JL.Core/Anki/AnkiConnect.cs +++ b/JL.Core/Anki/AnkiConnect.cs @@ -52,9 +52,8 @@ public static async Task Sync() using StringContent payload = new(JsonSerializer.Serialize(req, Utils.s_defaultJso)); Utils.Logger.Information("Sending: {Payload}", await payload.ReadAsStringAsync().ConfigureAwait(false)); - HttpResponseMessage postResponse = await Networking.Client - .PostAsync(CoreConfig.AnkiConnectUri, payload) - .ConfigureAwait(false); + using HttpResponseMessage postResponse = await Networking.Client + .PostAsync(CoreConfig.AnkiConnectUri, payload).ConfigureAwait(false); if (postResponse.IsSuccessStatusCode) { diff --git a/JL.Core/Anki/Note.cs b/JL.Core/Anki/Note.cs index 3a975a8d..2c751103 100644 --- a/JL.Core/Anki/Note.cs +++ b/JL.Core/Anki/Note.cs @@ -1,3 +1,4 @@ +using System.Collections.Immutable; using System.Text.Json.Serialization; namespace JL.Core.Anki; @@ -12,7 +13,7 @@ internal sealed class Note [JsonPropertyName("options")] public Dictionary Options { get; } - [JsonPropertyName("tags")] public string[] Tags { get; } + [JsonPropertyName("tags")] public ImmutableArray Tags { get; } [JsonPropertyName("audio")] public Dictionary? Audio { get; } @@ -25,7 +26,7 @@ public Note( string modelName, Dictionary fields, Dictionary options, - string[] tags, + ImmutableArray tags, Dictionary? audio, Dictionary? video, Dictionary? picture diff --git a/JL.Core/Audio/AudioUtils.cs b/JL.Core/Audio/AudioUtils.cs index 8134f2d2..c8b3c91d 100644 --- a/JL.Core/Audio/AudioUtils.cs +++ b/JL.Core/Audio/AudioUtils.cs @@ -32,7 +32,7 @@ public static class AudioUtils { try { - HttpResponseMessage response = await Networking.Client.GetAsync(url).ConfigureAwait(false); + using HttpResponseMessage response = await Networking.Client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false); if (response.IsSuccessStatusCode) { @@ -64,7 +64,7 @@ public static class AudioUtils { try { - HttpResponseMessage response = await Networking.Client.GetAsync(url).ConfigureAwait(false); + using HttpResponseMessage response = await Networking.Client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false); if (response.IsSuccessStatusCode) { diff --git a/JL.Core/Dicts/EDICT/ResourceUpdater.cs b/JL.Core/Dicts/EDICT/ResourceUpdater.cs index d5032b3a..1217e3d5 100644 --- a/JL.Core/Dicts/EDICT/ResourceUpdater.cs +++ b/JL.Core/Dicts/EDICT/ResourceUpdater.cs @@ -35,7 +35,7 @@ internal static async Task UpdateResource(string resourcePath, Uri resourc "Info"); } - HttpResponseMessage response = await Networking.Client.SendAsync(request).ConfigureAwait(false); + using HttpResponseMessage response = await Networking.Client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false); if (response.IsSuccessStatusCode) { Stream responseStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false); diff --git a/JL.Core/Dicts/IDictRecord.cs b/JL.Core/Dicts/IDictRecord.cs index 21dab1de..fa086cbc 100644 --- a/JL.Core/Dicts/IDictRecord.cs +++ b/JL.Core/Dicts/IDictRecord.cs @@ -1,5 +1,7 @@ namespace JL.Core.Dicts; +#pragma warning disable CA1040 public interface IDictRecord { } +#pragma warning restore CA1040 diff --git a/JL.Core/Network/Networking.cs b/JL.Core/Network/Networking.cs index 68aa0077..717e591b 100644 --- a/JL.Core/Network/Networking.cs +++ b/JL.Core/Network/Networking.cs @@ -6,7 +6,7 @@ namespace JL.Core.Network; public static class Networking { - public static readonly HttpClient Client = new(new HttpClientHandler { UseProxy = false }) { Timeout = TimeSpan.FromMinutes(10) }; + public static readonly HttpClient Client = new(new HttpClientHandler { UseProxy = false, CheckCertificateRevocationList = true }); internal const string Jpod101NoAudioMd5Hash = "7E-2C-2F-95-4E-F6-05-13-73-BA-91-6F-00-01-68-DC"; private static readonly Uri s_gitHubApiUrlForLatestJLRelease = new("https://api.github.com/repos/rampaa/JL/releases/latest"); @@ -17,7 +17,7 @@ public static async Task CheckForJLUpdates(bool isAutoCheck) using HttpRequestMessage gitHubApiRequest = new(HttpMethod.Get, s_gitHubApiUrlForLatestJLRelease); gitHubApiRequest.Headers.Add("User-Agent", "JL"); - HttpResponseMessage gitHubApiResponse = await Client.SendAsync(gitHubApiRequest).ConfigureAwait(false); + using HttpResponseMessage gitHubApiResponse = await Client.SendAsync(gitHubApiRequest, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false); if (gitHubApiResponse.IsSuccessStatusCode) { diff --git a/JL.Windows/GUI/PreferencesWindow.xaml.cs b/JL.Windows/GUI/PreferencesWindow.xaml.cs index 320daaf5..1a92ed1e 100644 --- a/JL.Windows/GUI/PreferencesWindow.xaml.cs +++ b/JL.Windows/GUI/PreferencesWindow.xaml.cs @@ -1,3 +1,4 @@ +using System.Collections.Immutable; using System.Globalization; using System.Text; using System.Windows; @@ -305,9 +306,9 @@ private static void CreateFieldElements(Dictionary fields, IEnu } string rawTags = tagsTextBox.Text; - string[] tags = string.IsNullOrEmpty(rawTags) - ? Array.Empty() - : rawTags.Split(',').Select(static s => s.Trim()).ToArray(); + ImmutableArray tags = string.IsNullOrEmpty(rawTags) + ? ImmutableArray.Empty + : rawTags.Split(',').Select(static s => s.Trim()).ToImmutableArray(); return new AnkiConfig(deckName, modelName, dict, tags); } diff --git a/JL.Windows/Utilities/WindowsUtils.cs b/JL.Windows/Utilities/WindowsUtils.cs index d71afddc..04596201 100644 --- a/JL.Windows/Utilities/WindowsUtils.cs +++ b/JL.Windows/Utilities/WindowsUtils.cs @@ -30,6 +30,7 @@ namespace JL.Windows.Utilities; internal static class WindowsUtils { + private static readonly Random s_random = new(); private static DateTime s_lastAudioPlayTime = new(); public static WaveOut? AudioPlayer { get; private set; } @@ -264,23 +265,22 @@ public static void SearchWithBrowser(string? selectedText) public static async Task UpdateJL(Uri latestReleaseUrl) { - using HttpRequestMessage downloadRequest = new(HttpMethod.Get, latestReleaseUrl); - HttpResponseMessage downloadResponse = await Networking.Client.SendAsync(downloadRequest).ConfigureAwait(false); + using HttpResponseMessage downloadResponse = await Networking.Client.GetAsync(latestReleaseUrl, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false); if (downloadResponse.IsSuccessStatusCode) { - Stream downloadResponseStream = await downloadResponse.Content.ReadAsStreamAsync().ConfigureAwait(false); - await using (downloadResponseStream.ConfigureAwait(false)) - { - string tmpDirectory = Path.Join(Utils.ApplicationPath, "tmp"); + string tmpDirectory = Path.Join(Utils.ApplicationPath, "tmp"); - if (Directory.Exists(tmpDirectory)) - { - Directory.Delete(tmpDirectory, true); - } + if (Directory.Exists(tmpDirectory)) + { + Directory.Delete(tmpDirectory, true); + } - _ = Directory.CreateDirectory(tmpDirectory); + _ = Directory.CreateDirectory(tmpDirectory); + Stream downloadResponseStream = await downloadResponse.Content.ReadAsStreamAsync().ConfigureAwait(false); + await using (downloadResponseStream.ConfigureAwait(false)) + { using ZipArchive archive = new(downloadResponseStream); archive.ExtractToDirectory(tmpDirectory); } @@ -352,7 +352,6 @@ public static void PlayAudio(byte[] audio, string audioFormat, float volume) }); } -#pragma warning disable CA5394 public static async Task Motivate() { DateTime currentTime = DateTime.Now; @@ -366,8 +365,6 @@ public static async Task Motivate() try { - Random rand = new(); - string[] filePaths = Directory.GetFiles(Path.Join(Utils.ResourcesPath, "Motivation")); int numFiles = filePaths.Length; @@ -378,7 +375,10 @@ public static async Task Motivate() return; } - string randomFilePath = filePaths[rand.Next(numFiles)]; +#pragma warning disable CA5394 + string randomFilePath = filePaths[s_random.Next(numFiles)]; +#pragma warning restore CA5394 + byte[] audioData = await File.ReadAllBytesAsync(randomFilePath).ConfigureAwait(false); PlayAudio(audioData, "mp3", 1); Stats.IncrementStat(StatType.Imoutos); @@ -389,7 +389,6 @@ public static async Task Motivate() Utils.Frontend.Alert(AlertLevel.Error, "Error motivating"); } } -#pragma warning restore CA5394 public static Brush? BrushFromHex(string hexColorString) {