FIx issue with duplicate paused/stopped status lists when handling v4/5 differences

This commit is contained in:
ahjephson
2025-04-22 14:03:33 +01:00
parent 3215fa3936
commit 4578dcc11f
9 changed files with 84 additions and 55 deletions

View File

@@ -10,18 +10,14 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="FluentAssertions" Version="7.1.0" AllowedVersions="[5.0.0,7.*.*)" /> <PackageReference Include="FluentAssertions" Version="7.2.0" AllowedVersions="[5.0.0,7.*.*)" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="9.0.1" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.13.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="9.0.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageReference Include="MudBlazor" Version="8.2.0" />
<PackageReference Include="System.Text.RegularExpressions" Version="4.3.1" /> <PackageReference Include="System.Text.RegularExpressions" Version="4.3.1" />
<PackageReference Include="xunit" Version="2.9.3" /> <PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.0.1"> <PackageReference Include="xunit.runner.visualstudio" Version="3.0.2">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
<PackageReference Include="System.Net.Http" Version="4.3.4" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -12,10 +12,7 @@ namespace Lantean.QBTMud.Components
{ {
public partial class TorrentActions : IAsyncDisposable public partial class TorrentActions : IAsyncDisposable
{ {
private const int _defaultVersion = 5;
private bool _disposedValue; private bool _disposedValue;
private int? _version;
private List<UIAction>? _actions; private List<UIAction>? _actions;
@@ -74,30 +71,7 @@ namespace Lantean.QBTMud.Components
protected bool OverlayVisible { get; set; } protected bool OverlayVisible { get; set; }
protected int MajorVersion protected int MajorVersion => VersionHelper.GetMajorVersion(Version);
{
get
{
if (_version is not null)
{
return _version.Value;
}
if (string.IsNullOrEmpty(Version))
{
return _defaultVersion;
}
if (!System.Version.TryParse(Version.Replace("v", ""), out var version))
{
return _defaultVersion;
}
_version = version.Major;
return _version.Value;
}
}
protected override void OnInitialized() protected override void OnInitialized()
{ {

View File

@@ -0,0 +1,34 @@

namespace Lantean.QBTMud.Helpers
{
internal static class VersionHelper
{
private static int? _version;
private const int _defaultVersion = 5;
public static int DefaultVersion => _defaultVersion;
public static int GetMajorVersion(string? version)
{
if (_version is not null)
{
return _version.Value;
}
if (string.IsNullOrEmpty(version))
{
return _defaultVersion;
}
if (!Version.TryParse(version?.Replace("v", ""), out var theVersion))
{
return _defaultVersion;
}
_version = theVersion.Major;
return _version.Value;
}
}
}

View File

@@ -12,13 +12,13 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Blazored.LocalStorage" Version="4.5.0" /> <PackageReference Include="Blazored.LocalStorage" Version="4.5.0" />
<PackageReference Include="ByteSize" Version="2.1.2" /> <PackageReference Include="ByteSize" Version="2.1.2" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="9.0.1" /> <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="9.0.4" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="9.0.1" PrivateAssets="all" /> <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="9.0.4" PrivateAssets="all" />
<PackageReference Include="Microsoft.Extensions.Http" Version="9.0.1" /> <PackageReference Include="Microsoft.Extensions.Http" Version="9.0.4" />
<PackageReference Include="MudBlazor" Version="8.2.0" /> <PackageReference Include="MudBlazor" Version="8.5.1" />
<PackageReference Include="MudBlazor.ThemeManager" Version="3.0.0" /> <PackageReference Include="MudBlazor.ThemeManager" Version="3.0.0" />
<!-- added to fix vuln in dependency --> <!-- added to fix vuln in dependency -->
<PackageReference Include="System.Text.Json" Version="9.0.1" /> <PackageReference Include="System.Text.Json" Version="9.0.4" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -83,7 +83,7 @@ namespace Lantean.QBTMud.Layout
Preferences = await ApiClient.GetApplicationPreferences(); Preferences = await ApiClient.GetApplicationPreferences();
Version = await ApiClient.GetApplicationVersion(); Version = await ApiClient.GetApplicationVersion();
var data = await ApiClient.GetMainData(_requestId); var data = await ApiClient.GetMainData(_requestId);
MainData = DataManager.CreateMainData(data); MainData = DataManager.CreateMainData(data, Version);
_requestId = data.ResponseId; _requestId = data.ResponseId;
_refreshInterval = MainData.ServerState.RefreshInterval; _refreshInterval = MainData.ServerState.RefreshInterval;
@@ -128,7 +128,7 @@ namespace Lantean.QBTMud.Layout
if (MainData is null || data.FullUpdate) if (MainData is null || data.FullUpdate)
{ {
MainData = DataManager.CreateMainData(data); MainData = DataManager.CreateMainData(data, Version);
} }
else else
{ {

View File

@@ -11,7 +11,8 @@
Dictionary<string, HashSet<string>> tagState, Dictionary<string, HashSet<string>> tagState,
Dictionary<string, HashSet<string>> categoriesState, Dictionary<string, HashSet<string>> categoriesState,
Dictionary<string, HashSet<string>> statusState, Dictionary<string, HashSet<string>> statusState,
Dictionary<string, HashSet<string>> trackersState) Dictionary<string, HashSet<string>> trackersState,
int majorVersion)
{ {
Torrents = torrents.ToDictionary(); Torrents = torrents.ToDictionary();
Tags = tags.ToHashSet(); Tags = tags.ToHashSet();
@@ -22,6 +23,7 @@
CategoriesState = categoriesState; CategoriesState = categoriesState;
StatusState = statusState; StatusState = statusState;
TrackersState = trackersState; TrackersState = trackersState;
MajorVersion = majorVersion;
} }
public Dictionary<string, Torrent> Torrents { get; } public Dictionary<string, Torrent> Torrents { get; }
@@ -36,5 +38,6 @@
public Dictionary<string, HashSet<string>> TrackersState { get; } public Dictionary<string, HashSet<string>> TrackersState { get; }
public string? SelectedTorrentHash { get; set; } public string? SelectedTorrentHash { get; set; }
public bool LostConnection { get; set; } public bool LostConnection { get; set; }
public int MajorVersion { get; }
} }
} }

View File

@@ -8,6 +8,7 @@
Completed, Completed,
Resumed, Resumed,
Paused, Paused,
Stopped,
Active, Active,
Inactive, Inactive,
Stalled, Stalled,
@@ -15,6 +16,6 @@
StalledDownloading, StalledDownloading,
Checking, Checking,
Errored, Errored,
Stopped
} }
} }

View File

@@ -5,7 +5,7 @@ namespace Lantean.QBTMud.Services
{ {
public class DataManager : IDataManager public class DataManager : IDataManager
{ {
private static readonly Status[] _statuses = Enum.GetValues<Status>(); private static Status[]? _statusArray = null;
public PeerList CreatePeerList(QBitTorrentClient.Models.TorrentPeers torrentPeers) public PeerList CreatePeerList(QBitTorrentClient.Models.TorrentPeers torrentPeers)
{ {
@@ -25,8 +25,9 @@ namespace Lantean.QBTMud.Services
return peerList; return peerList;
} }
public MainData CreateMainData(QBitTorrentClient.Models.MainData mainData) public MainData CreateMainData(QBitTorrentClient.Models.MainData mainData, string version)
{ {
var majorVersion = VersionHelper.GetMajorVersion(version);
var torrents = new Dictionary<string, Torrent>(mainData.Torrents?.Count ?? 0); var torrents = new Dictionary<string, Torrent>(mainData.Torrents?.Count ?? 0);
if (mainData.Torrents is not null) if (mainData.Torrents is not null)
{ {
@@ -87,8 +88,9 @@ namespace Lantean.QBTMud.Services
categoriesState.Add(category, torrents.Values.Where(t => FilterHelper.FilterCategory(t, category, serverState.UseSubcategories)).ToHashesHashSet()); categoriesState.Add(category, torrents.Values.Where(t => FilterHelper.FilterCategory(t, category, serverState.UseSubcategories)).ToHashesHashSet());
} }
var statusState = new Dictionary<string, HashSet<string>>(_statuses.Length + 2); var statuses = GetStatuses(majorVersion).ToArray();
foreach (var status in _statuses) var statusState = new Dictionary<string, HashSet<string>>(statuses.Length + 2);
foreach (var status in statuses)
{ {
statusState.Add(status.ToString(), torrents.Values.Where(t => FilterHelper.FilterStatus(t, status)).ToHashesHashSet()); statusState.Add(status.ToString(), torrents.Values.Where(t => FilterHelper.FilterStatus(t, status)).ToHashesHashSet());
} }
@@ -101,7 +103,7 @@ namespace Lantean.QBTMud.Services
trackersState.Add(tracker, torrents.Values.Where(t => FilterHelper.FilterTracker(t, tracker)).ToHashesHashSet()); trackersState.Add(tracker, torrents.Values.Where(t => FilterHelper.FilterTracker(t, tracker)).ToHashesHashSet());
} }
var torrentList = new MainData(torrents, tags, categories, trackers, serverState, tagState, categoriesState, statusState, trackersState); var torrentList = new MainData(torrents, tags, categories, trackers, serverState, tagState, categoriesState, statusState, trackersState, majorVersion);
return torrentList; return torrentList;
} }
@@ -206,7 +208,7 @@ namespace Lantean.QBTMud.Services
{ {
foreach (var (url, hashes) in mainData.Trackers) foreach (var (url, hashes) in mainData.Trackers)
{ {
if (!torrentList.Trackers.TryGetValue(url, out var existingHashes)) if (!torrentList.Trackers.TryGetValue(url, out _))
{ {
torrentList.Trackers.Add(url, hashes); torrentList.Trackers.Add(url, hashes);
} }
@@ -225,7 +227,7 @@ namespace Lantean.QBTMud.Services
{ {
var newTorrent = CreateTorrent(hash, torrent); var newTorrent = CreateTorrent(hash, torrent);
torrentList.Torrents.Add(hash, newTorrent); torrentList.Torrents.Add(hash, newTorrent);
AddTorrentToStates(torrentList, hash); AddTorrentToStates(torrentList, hash, torrentList.MajorVersion);
} }
else else
{ {
@@ -241,7 +243,7 @@ namespace Lantean.QBTMud.Services
} }
} }
private static void AddTorrentToStates(MainData torrentList, string hash) private static void AddTorrentToStates(MainData torrentList, string hash, int version)
{ {
var torrent = torrentList.Torrents[hash]; var torrent = torrentList.Torrents[hash];
@@ -271,7 +273,7 @@ namespace Lantean.QBTMud.Services
value.AddIfTrue(hash, FilterHelper.FilterCategory(torrent, category, torrentList.ServerState.UseSubcategories)); value.AddIfTrue(hash, FilterHelper.FilterCategory(torrent, category, torrentList.ServerState.UseSubcategories));
} }
foreach (var status in _statuses) foreach (var status in GetStatuses(version))
{ {
torrentList.StatusState[status.ToString()].AddIfTrue(hash, FilterHelper.FilterStatus(torrent, status)); torrentList.StatusState[status.ToString()].AddIfTrue(hash, FilterHelper.FilterStatus(torrent, status));
} }
@@ -289,6 +291,25 @@ namespace Lantean.QBTMud.Services
} }
} }
private static Status[] GetStatuses(int version)
{
if (_statusArray is not null)
{
return _statusArray;
}
if (version == 5)
{
_statusArray = Enum.GetValues<Status>().Where(s => s != Status.Paused).ToArray();
}
else
{
_statusArray = Enum.GetValues<Status>().Where(s => s != Status.Stopped).ToArray();
}
return _statusArray;
}
private static void UpdateTorrentStates(MainData torrentList, string hash) private static void UpdateTorrentStates(MainData torrentList, string hash)
{ {
var torrent = torrentList.Torrents[hash]; var torrent = torrentList.Torrents[hash];
@@ -317,7 +338,7 @@ namespace Lantean.QBTMud.Services
value.AddIfTrueOrRemove(hash, FilterHelper.FilterCategory(torrent, category, torrentList.ServerState.UseSubcategories)); value.AddIfTrueOrRemove(hash, FilterHelper.FilterCategory(torrent, category, torrentList.ServerState.UseSubcategories));
} }
foreach (var status in _statuses) foreach (var status in GetStatuses(torrentList.MajorVersion))
{ {
torrentList.StatusState[status.ToString()].AddIfTrueOrRemove(hash, FilterHelper.FilterStatus(torrent, status)); torrentList.StatusState[status.ToString()].AddIfTrueOrRemove(hash, FilterHelper.FilterStatus(torrent, status));
} }
@@ -361,7 +382,7 @@ namespace Lantean.QBTMud.Services
categoryState.RemoveIfTrue(hash, FilterHelper.FilterCategory(torrent, category, torrentList.ServerState.UseSubcategories)); categoryState.RemoveIfTrue(hash, FilterHelper.FilterCategory(torrent, category, torrentList.ServerState.UseSubcategories));
} }
foreach (var status in _statuses) foreach (var status in GetStatuses(torrentList.MajorVersion))
{ {
if (!torrentList.StatusState.TryGetValue(status.ToString(), out var statusState)) if (!torrentList.StatusState.TryGetValue(status.ToString(), out var statusState))
{ {

View File

@@ -4,7 +4,7 @@ namespace Lantean.QBTMud.Services
{ {
public interface IDataManager public interface IDataManager
{ {
MainData CreateMainData(QBitTorrentClient.Models.MainData mainData); MainData CreateMainData(QBitTorrentClient.Models.MainData mainData, string version);
Torrent CreateTorrent(string hash, QBitTorrentClient.Models.Torrent torrent); Torrent CreateTorrent(string hash, QBitTorrentClient.Models.Torrent torrent);