Merge pull request #986 from asylumexp/fix/torbox-database-error

[TorBox] fix: remove usage of GetHashInfoAsync
This commit is contained in:
Roger Far 2026-05-30 08:55:56 -06:00 committed by GitHub
commit a9013e0c2a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 52 additions and 25 deletions

View file

@ -22,7 +22,7 @@
<PackageReference Include="TestableIO.System.IO.Abstractions" Version="22.1.1" /> <PackageReference Include="TestableIO.System.IO.Abstractions" Version="22.1.1" />
<PackageReference Include="TestableIO.System.IO.Abstractions.TestingHelpers" Version="22.1.1" /> <PackageReference Include="TestableIO.System.IO.Abstractions.TestingHelpers" Version="22.1.1" />
<PackageReference Include="TestableIO.System.IO.Abstractions.Wrappers" Version="22.1.1" /> <PackageReference Include="TestableIO.System.IO.Abstractions.Wrappers" Version="22.1.1" />
<PackageReference Include="TorBox.NET" Version="2.0.0" /> <PackageReference Include="TorBox.NET" Version="2.1.0" />
<PackageReference Include="xunit" Version="2.9.3" /> <PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.5"> <PackageReference Include="xunit.runner.visualstudio" Version="3.1.5">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>

View file

@ -46,6 +46,7 @@ public class TorBoxDebridClientTest
{ {
new() new()
{ {
Id = 12345,
Hash = "hash1", Hash = "hash1",
Name = "torrent1", Name = "torrent1",
Size = 1000, Size = 1000,
@ -78,7 +79,7 @@ public class TorBoxDebridClientTest
// Assert // Assert
Assert.Equal(2, result.Count); Assert.Equal(2, result.Count);
var torrentResult = result.FirstOrDefault(r => r.Id == "hash1"); var torrentResult = result.FirstOrDefault(r => r.Id == "12345");
Assert.NotNull(torrentResult); Assert.NotNull(torrentResult);
Assert.Equal(DownloadType.Torrent, torrentResult.Type); Assert.Equal(DownloadType.Torrent, torrentResult.Type);
@ -200,12 +201,12 @@ public class TorBoxDebridClientTest
} }
[Fact] [Fact]
public async Task Delete_CallsTorrentsControl_WhenTypeIsTorrent() public async Task Delete_CallsTorrentsControlById_WhenTypeIsTorrent()
{ {
// Arrange // Arrange
var torrent = new Torrent var torrent = new Torrent
{ {
RdId = "torrent-id", RdId = "12345",
Type = DownloadType.Torrent Type = DownloadType.Torrent
}; };
@ -220,7 +221,7 @@ public class TorBoxDebridClientTest
await clientMock.Object.Delete(torrent); await clientMock.Object.Delete(torrent);
// Assert // Assert
torrentsApiMock.Verify(m => m.ControlAsync("torrent-id", "delete", It.IsAny<CancellationToken>()), Times.Once); torrentsApiMock.Verify(m => m.ControlByIdAsync(12345, "delete", It.IsAny<CancellationToken>()), Times.Once);
} }
[Fact] [Fact]
@ -375,6 +376,7 @@ public class TorBoxDebridClientTest
var torrent = new Torrent var torrent = new Torrent
{ {
Hash = "test-hash", Hash = "test-hash",
RdId = "12345",
RdFiles = JsonConvert.SerializeObject(files) RdFiles = JsonConvert.SerializeObject(files)
}; };
@ -385,12 +387,6 @@ public class TorBoxDebridClientTest
torBoxClientMock.Setup(m => m.Torrents).Returns(torrentsApiMock.Object); torBoxClientMock.Setup(m => m.Torrents).Returns(torrentsApiMock.Object);
clientMock.Protected().Setup<ITorBoxNetClient>("GetClient", ItExpr.IsAny<String>()).Returns(torBoxClientMock.Object); clientMock.Protected().Setup<ITorBoxNetClient>("GetClient", ItExpr.IsAny<String>()).Returns(torBoxClientMock.Object);
torrentsApiMock.Setup(m => m.GetHashInfoAsync("test-hash", true, 1000, It.IsAny<CancellationToken>()))
.ReturnsAsync(new TorrentInfoResult
{
Id = 12345
});
_fileFilterMock.Setup(m => m.IsDownloadable(torrent, It.IsAny<String>(), It.IsAny<Int64>())).Returns(true); _fileFilterMock.Setup(m => m.IsDownloadable(torrent, It.IsAny<String>(), It.IsAny<Int64>())).Returns(true);
_settings.Current.Provider.PreferZippedDownloads = false; _settings.Current.Provider.PreferZippedDownloads = false;
@ -422,6 +418,7 @@ public class TorBoxDebridClientTest
var torrent = new Torrent var torrent = new Torrent
{ {
Hash = "test-hash", Hash = "test-hash",
RdId = "12345",
RdName = "TestTorrent", RdName = "TestTorrent",
RdFiles = JsonConvert.SerializeObject(files), RdFiles = JsonConvert.SerializeObject(files),
DownloadClient = DownloadClient.Aria2c DownloadClient = DownloadClient.Aria2c
@ -436,12 +433,6 @@ public class TorBoxDebridClientTest
torBoxClientMock.Setup(m => m.Torrents).Returns(torrentsApiMock.Object); torBoxClientMock.Setup(m => m.Torrents).Returns(torrentsApiMock.Object);
clientMock.Protected().Setup<ITorBoxNetClient>("GetClient", ItExpr.IsAny<String>()).Returns(torBoxClientMock.Object); clientMock.Protected().Setup<ITorBoxNetClient>("GetClient", ItExpr.IsAny<String>()).Returns(torBoxClientMock.Object);
torrentsApiMock.Setup(m => m.GetHashInfoAsync("test-hash", true, 1000, It.IsAny<CancellationToken>()))
.ReturnsAsync(new TorrentInfoResult
{
Id = 12345
});
_fileFilterMock.Setup(m => m.IsDownloadable(torrent, It.IsAny<String>(), It.IsAny<Int64>())).Returns(true); _fileFilterMock.Setup(m => m.IsDownloadable(torrent, It.IsAny<String>(), It.IsAny<Int64>())).Returns(true);
// Act // Act

View file

@ -26,7 +26,7 @@
<PackageReference Include="Synology.Api.Client" Version="[0.3.93]" /> <PackageReference Include="Synology.Api.Client" Version="[0.3.93]" />
<PackageReference Include="TestableIO.System.IO.Abstractions" Version="22.1.1" /> <PackageReference Include="TestableIO.System.IO.Abstractions" Version="22.1.1" />
<PackageReference Include="TestableIO.System.IO.Abstractions.Wrappers" Version="22.1.1" /> <PackageReference Include="TestableIO.System.IO.Abstractions.Wrappers" Version="22.1.1" />
<PackageReference Include="TorBox.NET" Version="2.0.0" /> <PackageReference Include="TorBox.NET" Version="2.1.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View file

@ -81,7 +81,7 @@ public class TorBoxDebridClient(
allowZip: Settings.Get.Provider.PreferZippedDownloads, allowZip: Settings.Get.Provider.PreferZippedDownloads,
as_queued: asQueued); as_queued: asQueued);
return result.Data!.Hash!; return result.Data?.TorrentId?.ToString() ?? throw new InvalidOperationException("TorBox API did not return torrent ID.");
}); });
} }
@ -97,7 +97,7 @@ public class TorBoxDebridClient(
allowZip: Settings.Get.Provider.PreferZippedDownloads, allowZip: Settings.Get.Provider.PreferZippedDownloads,
as_queued: asQueued); as_queued: asQueued);
return result.Data!.Hash!; return result.Data?.TorrentId?.ToString() ?? throw new InvalidOperationException("TorBox API did not return torrent ID");
}); });
} }
@ -171,7 +171,7 @@ public class TorBoxDebridClient(
} }
else else
{ {
await GetClient().Torrents.ControlAsync(torrent.RdId, "delete"); await GetClient().Torrents.ControlByIdAsync(Int32.Parse(torrent.RdId), "delete");
} }
}); });
} }
@ -331,8 +331,12 @@ public class TorBoxDebridClient(
} }
else else
{ {
var torrentId = await HandleErrors(() => GetClient().Torrents.GetHashInfoAsync(torrent.Hash, true)); if (torrent.RdId == null)
id = torrentId?.Id; {
return null;
}
id = Int32.Parse(torrent.RdId);
} }
if (id == null) if (id == null)
@ -456,7 +460,7 @@ public class TorBoxDebridClient(
{ {
return new() return new()
{ {
Id = torrent.Hash, Id = torrent.Id.ToString(),
Filename = torrent.Name, Filename = torrent.Name,
OriginalFilename = torrent.Name, OriginalFilename = torrent.Name,
Hash = torrent.Hash, Hash = torrent.Hash,
@ -611,7 +615,7 @@ public class TorBoxDebridClient(
} }
else else
{ {
var result = await GetClient().Torrents.GetHashInfoAsync(id, true); var result = await GetClient().Torrents.GetIdInfoAsync(Int32.Parse(id), true);
if (result != null) if (result != null)
{ {

View file

@ -664,6 +664,38 @@ public class Torrents(
{ {
torrentsByRdId.TryGetValue(rdTorrent.Id, out var torrent); torrentsByRdId.TryGetValue(rdTorrent.Id, out var torrent);
// TorBox migration from storing torrent hash in RdId to torrent ids.
if (torrent == null
&& Settings.Get.Provider.Provider == Provider.TorBox
&& rdTorrent.Type == DownloadType.Torrent
&& !String.IsNullOrWhiteSpace(rdTorrent.Hash)
&& !String.IsNullOrWhiteSpace(rdTorrent.Id))
{
torrent = torrents.FirstOrDefault(localTorrent => localTorrent is { Type: DownloadType.Torrent, ClientKind: null or Provider.TorBox }
&& !String.IsNullOrWhiteSpace(localTorrent.Hash)
&& !String.IsNullOrWhiteSpace(localTorrent.RdId)
&& localTorrent.RdId.Equals(localTorrent.Hash, StringComparison.OrdinalIgnoreCase)
&& localTorrent.Hash.Equals(rdTorrent.Hash, StringComparison.OrdinalIgnoreCase));
if (torrent != null)
{
if (!String.IsNullOrWhiteSpace(torrent.RdId))
{
torrentsByRdId.Remove(torrent.RdId);
}
await torrentData.UpdateRdId(torrent, rdTorrent.Id);
torrent.RdId = rdTorrent.Id;
torrent.ClientKind = Provider.TorBox;
torrentsByRdId[rdTorrent.Id] = torrent;
logger.LogInformation("Migrated TorBox torrent RdId from hash to torrent id for {TorrentName} ({Hash}) -> {RdId}",
torrent.RdName ?? rdTorrent.Filename,
rdTorrent.Hash,
rdTorrent.Id);
}
}
// Auto import torrents only torrents that have their files selected // Auto import torrents only torrents that have their files selected
if (torrent == null && settings.Current.Provider.AutoImport) if (torrent == null && settings.Current.Provider.AutoImport)
{ {