diff --git a/Lantean.QBTMud/Components/Dialogs/RenameFilesDialog.razor b/Lantean.QBTMud/Components/Dialogs/RenameFilesDialog.razor
index 0de18b2..7dafb6d 100644
--- a/Lantean.QBTMud/Components/Dialogs/RenameFilesDialog.razor
+++ b/Lantean.QBTMud/Components/Dialogs/RenameFilesDialog.razor
@@ -1,7 +1,53 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Filename + Extension
+ Filename
+ Extension
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Replace
+ Replace all
+
+
+
+
+
Close
- Rename
+ @(ReplaceAll ? "Replace all" : "Replace")
diff --git a/Lantean.QBTMud/Components/Dialogs/RenameFilesDialog.razor.cs b/Lantean.QBTMud/Components/Dialogs/RenameFilesDialog.razor.cs
index 3eab22f..9ab5b8d 100644
--- a/Lantean.QBTMud/Components/Dialogs/RenameFilesDialog.razor.cs
+++ b/Lantean.QBTMud/Components/Dialogs/RenameFilesDialog.razor.cs
@@ -6,6 +6,7 @@ using Lantean.QBTMud.Services;
using Microsoft.AspNetCore.Components;
using MudBlazor;
using System.Collections.ObjectModel;
+using static MudBlazor.Colors;
namespace Lantean.QBTMud.Components.Dialogs
{
@@ -51,6 +52,11 @@ namespace Lantean.QBTMud.Components.Dialogs
private ReadOnlyCollection GetFiles()
{
+ if (!FileList.Any())
+ {
+ return new ReadOnlyCollection([]);
+ }
+
var maxLevel = FileList.Max(f => f.Level);
// this is a flat file structure
if (maxLevel == 0)
@@ -321,65 +327,107 @@ namespace Lantean.QBTMud.Components.Dialogs
protected bool UseRegex { get; set; }
- protected void UseRegexChanged(bool value)
+ protected async Task UseRegexChanged(bool value)
{
UseRegex = value;
+
+ await UpdatePreferences(p => p.UseRegex = value);
}
protected bool MatchAllOccurrences { get; set; }
- protected void MatchAllOccurrencesChanged(bool value)
+ protected async Task MatchAllOccurrencesChanged(bool value)
{
MatchAllOccurrences = value;
+
+ await UpdatePreferences(p => p.MatchAllOccurrences = value);
}
protected bool CaseSensitive { get; set; }
- protected void CaseSensitiveChanged(bool value)
+ protected async Task CaseSensitiveChanged(bool value)
{
CaseSensitive = value;
+
+ await UpdatePreferences(p => p.CaseSensitive = value);
}
protected string Replacement { get; set; } = "";
- protected void ReplacementChanged(string value)
+ protected async Task ReplacementChanged(string value)
{
Replacement = value;
+
+ await UpdatePreferences(p => p.Replace = value);
}
protected AppliesTo AppliesToValue { get; set; } = AppliesTo.FilenameExtension;
- protected void AppliesToChanged(AppliesTo value)
+ protected async Task AppliesToChanged(AppliesTo value)
{
AppliesToValue = value;
+
+ await UpdatePreferences(p => p.AppliesTo = value);
}
protected bool IncludeFiles { get; set; } = true;
- protected void IncludeFilesChanged(bool value)
+ protected async Task IncludeFilesChanged(bool value)
{
IncludeFiles = value;
+
+ await UpdatePreferences(p => p.IncludeFiles = value);
}
protected bool IncludeFolders { get; set; }
- protected void IncludeFoldersChanged(bool value)
+ protected async Task IncludeFoldersChanged(bool value)
{
IncludeFolders = value;
+
+ await UpdatePreferences(p => p.IncludeFolders = value);
}
protected int FileEnumerationStart { get; set; }
- protected void FileEnumerationStartChanged(int value)
+ protected async Task FileEnumerationStartChanged(int value)
{
FileEnumerationStart = value;
+
+ await UpdatePreferences(p => p.FileEnumerationStart = value);
}
protected bool ReplaceAll { get; set; }
- protected void ReplaceAllChanged(bool value)
+ protected async Task ReplaceAllChanged(bool value)
{
ReplaceAll = value;
+
+ await UpdatePreferences(p => p.ReplaceAll = value);
+ }
+
+ protected bool RememberMultiRenameSettings { get; set; }
+
+ protected async Task RememberMultiRenameSettingsChanged(bool value)
+ {
+ RememberMultiRenameSettings = value;
+
+ await UpdatePreferences(p => p.RememberPreferences = value);
+ }
+
+ private async Task UpdatePreferences(Action updateAction)
+ {
+ var preferences = await LocalStorage.GetItemAsync(_preferencesStorageKey) ?? new();
+ updateAction(preferences);
+ if (preferences.RememberPreferences)
+ {
+ await LocalStorage.SetItemAsync(_preferencesStorageKey, preferences);
+ }
+ else
+ {
+ await LocalStorage.RemoveItemAsync(_preferencesStorageKey);
+ }
+
}
protected override async Task OnInitializedAsync()
@@ -414,8 +462,43 @@ namespace Lantean.QBTMud.Components.Dialogs
MudDialog.Cancel();
}
- protected void Submit()
+ protected async Task Submit()
{
+ if (Hash is null)
+ {
+ MudDialog.Close();
+
+ return;
+ }
+
+ var renamedFiles = FileNameMatcher.GetRenamedFiles(
+ SelectedItems,
+ Search,
+ UseRegex,
+ Replacement,
+ MatchAllOccurrences,
+ CaseSensitive,
+ AppliesToValue,
+ IncludeFiles,
+ IncludeFolders,
+ ReplaceAll,
+ FileEnumerationStart);
+
+ foreach (var (_, renamedFile) in renamedFiles)
+ {
+ var oldPath = renamedFile.Path + renamedFile.OriginalName;
+ var newPath = renamedFile.Path + renamedFile.NewName;
+ if (renamedFile.IsFolder)
+ {
+
+ await ApiClient.RenameFolder(Hash, oldPath, newPath);
+ }
+ else
+ {
+ await ApiClient.RenameFile(Hash, oldPath, newPath);
+ }
+ }
+
MudDialog.Close();
}
diff --git a/Lantean.QBTMud/Components/FiltersNav.razor.cs b/Lantean.QBTMud/Components/FiltersNav.razor.cs
index 4256982..090edc4 100644
--- a/Lantean.QBTMud/Components/FiltersNav.razor.cs
+++ b/Lantean.QBTMud/Components/FiltersNav.razor.cs
@@ -1,7 +1,6 @@
using Blazored.LocalStorage;
using Lantean.QBitTorrentClient;
using Lantean.QBTMud.Components.UI;
-using Lantean.QBTMud.EventHandlers;
using Lantean.QBTMud.Helpers;
using Lantean.QBTMud.Models;
using Microsoft.AspNetCore.Components;
diff --git a/Lantean.QBTMud/Components/TorrentActions.razor.cs b/Lantean.QBTMud/Components/TorrentActions.razor.cs
index 8aa64df..b989730 100644
--- a/Lantean.QBTMud/Components/TorrentActions.razor.cs
+++ b/Lantean.QBTMud/Components/TorrentActions.razor.cs
@@ -109,7 +109,7 @@ namespace Lantean.QBTMud.Components
new("delete", "Remove", Icons.Material.Filled.Delete, Color.Error, CreateCallback(Remove), separatorBefore: true),
new("setLocation", "Set location", Icons.Material.Filled.MyLocation, Color.Info, CreateCallback(SetLocation), separatorBefore: true),
new("rename", "Rename", Icons.Material.Filled.DriveFileRenameOutline, Color.Info, CreateCallback(Rename)),
- new("renameFiles", "Rename files", Icons.Material.Filled.DriveFileRenameOutline, Color.Warning, CreateCallback(Rename)),
+ new("renameFiles", "Rename files", Icons.Material.Filled.DriveFileRenameOutline, Color.Warning, CreateCallback(RenameFiles)),
new("category", "Category", Icons.Material.Filled.List, Color.Info, CreateCallback(ShowCategories)),
new("tags", "Tags", Icons.Material.Filled.Label, Color.Info, CreateCallback(ShowTags)),
new("autoTorrentManagement", "Automatic Torrent Management", Icons.Material.Filled.Check, Color.Info, CreateCallback(ToggleAutoTMM)),
@@ -174,14 +174,30 @@ namespace Lantean.QBTMud.Components
protected async Task Pause()
{
- await ApiClient.PauseTorrents(Hashes);
- Snackbar.Add("Torrent paused.");
+ if (MajorVersion < 5)
+ {
+ await ApiClient.PauseTorrents(Hashes);
+ Snackbar.Add("Torrent paused.");
+ }
+ else
+ {
+ await ApiClient.StopTorrents(Hashes);
+ Snackbar.Add("Torrent stopped.");
+ }
}
protected async Task Resume()
{
- await ApiClient.ResumeTorrents(Hashes);
- Snackbar.Add("Torrent resumed.");
+ if (MajorVersion < 5)
+ {
+ await ApiClient.ResumeTorrents(Hashes);
+ Snackbar.Add("Torrent resumed.");
+ }
+ else
+ {
+ await ApiClient.StartTorrents(Hashes);
+ Snackbar.Add("Torrent started.");
+ }
}
protected async Task ForceStart()
@@ -298,7 +314,7 @@ namespace Lantean.QBTMud.Components
protected async Task MoveToTop()
{
- await ApiClient.MaximalTorrentPriority(null, Hashes.ToArray());
+ await ApiClient.MaxTorrentPriority(null, Hashes.ToArray());
}
protected async Task MoveUp()
@@ -313,7 +329,7 @@ namespace Lantean.QBTMud.Components
protected async Task MoveToBottom()
{
- await ApiClient.MinimalTorrentPriority(null, Hashes.ToArray());
+ await ApiClient.MinTorrentPriority(null, Hashes.ToArray());
}
protected async Task Copy(string value)
@@ -557,18 +573,18 @@ namespace Lantean.QBTMud.Components
if (MajorVersion >= 5)
{
- if (actionStates.ContainsKey("start"))
+ if (actionStates.TryGetValue("start", out ActionState? startActionState))
{
- actionStates["start"].TextOverride = "Start";
+ startActionState.TextOverride = "Start";
}
else
{
actionStates["start"] = new ActionState { TextOverride = "Start" };
}
- if (actionStates.ContainsKey("pause"))
+ if (actionStates.TryGetValue("pause", out ActionState? stopActionState))
{
- actionStates["pause"].TextOverride = "Stop";
+ stopActionState.TextOverride = "Stop";
}
else
{
diff --git a/Lantean.QBTMud/Components/UI/ContextMenu.razor.cs b/Lantean.QBTMud/Components/UI/ContextMenu.razor.cs
index 57d49d9..981a12f 100644
--- a/Lantean.QBTMud/Components/UI/ContextMenu.razor.cs
+++ b/Lantean.QBTMud/Components/UI/ContextMenu.razor.cs
@@ -1,5 +1,4 @@
-using Lantean.QBTMud.EventHandlers;
-using Lantean.QBTMud.Interop;
+using Lantean.QBTMud.Interop;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.JSInterop;
diff --git a/Lantean.QBTMud/Components/UI/CustomNavLink.razor.cs b/Lantean.QBTMud/Components/UI/CustomNavLink.razor.cs
index f2ff61a..23e3bf1 100644
--- a/Lantean.QBTMud/Components/UI/CustomNavLink.razor.cs
+++ b/Lantean.QBTMud/Components/UI/CustomNavLink.razor.cs
@@ -1,5 +1,4 @@
-using Lantean.QBTMud.EventHandlers;
-using Microsoft.AspNetCore.Components;
+using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
using MudBlazor;
using MudBlazor.Utilities;
diff --git a/Lantean.QBTMud/Components/UI/DynamicTable.razor.cs b/Lantean.QBTMud/Components/UI/DynamicTable.razor.cs
index 696e604..a8707d2 100644
--- a/Lantean.QBTMud/Components/UI/DynamicTable.razor.cs
+++ b/Lantean.QBTMud/Components/UI/DynamicTable.razor.cs
@@ -1,5 +1,4 @@
using Blazored.LocalStorage;
-using Lantean.QBTMud.EventHandlers;
using Lantean.QBTMud.Helpers;
using Lantean.QBTMud.Models;
using Microsoft.AspNetCore.Components;
diff --git a/Lantean.QBTMud/Components/UI/TableDataLongPressEventArgs.cs b/Lantean.QBTMud/Components/UI/TableDataLongPressEventArgs.cs
index 94601a0..d0fe205 100644
--- a/Lantean.QBTMud/Components/UI/TableDataLongPressEventArgs.cs
+++ b/Lantean.QBTMud/Components/UI/TableDataLongPressEventArgs.cs
@@ -1,5 +1,4 @@
-using Lantean.QBTMud.EventHandlers;
-using MudBlazor;
+using MudBlazor;
namespace Lantean.QBTMud.Components.UI
{
diff --git a/Lantean.QBTMud/Components/UI/TdExtended.razor.cs b/Lantean.QBTMud/Components/UI/TdExtended.razor.cs
index 7d958f6..cffe7c9 100644
--- a/Lantean.QBTMud/Components/UI/TdExtended.razor.cs
+++ b/Lantean.QBTMud/Components/UI/TdExtended.razor.cs
@@ -1,5 +1,4 @@
-using Lantean.QBTMud.EventHandlers;
-using Microsoft.AspNetCore.Components;
+using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
using MudBlazor;
diff --git a/Lantean.QBTMud/EventHandlers/EventHandlers.cs b/Lantean.QBTMud/EventHandlers/EventHandlers.cs
index cdfad75..65c7e77 100644
--- a/Lantean.QBTMud/EventHandlers/EventHandlers.cs
+++ b/Lantean.QBTMud/EventHandlers/EventHandlers.cs
@@ -1,6 +1,6 @@
using Microsoft.AspNetCore.Components;
-namespace Lantean.QBTMud.EventHandlers
+namespace Lantean.QBTMud
{
[EventHandler("onlongpress", typeof(LongPressEventArgs), enableStopPropagation: true, enablePreventDefault: true)]
public static class EventHandlers
diff --git a/Lantean.QBTMud/EventHandlers/LongPressEventArgs.cs b/Lantean.QBTMud/EventHandlers/LongPressEventArgs.cs
index 74c50fe..e5ae58f 100644
--- a/Lantean.QBTMud/EventHandlers/LongPressEventArgs.cs
+++ b/Lantean.QBTMud/EventHandlers/LongPressEventArgs.cs
@@ -1,4 +1,4 @@
-namespace Lantean.QBTMud.EventHandlers
+namespace Lantean.QBTMud
{
public class LongPressEventArgs : EventArgs
{
diff --git a/Lantean.QBTMud/Helpers/DialogHelper.cs b/Lantean.QBTMud/Helpers/DialogHelper.cs
index cb517b7..154b411 100644
--- a/Lantean.QBTMud/Helpers/DialogHelper.cs
+++ b/Lantean.QBTMud/Helpers/DialogHelper.cs
@@ -53,24 +53,10 @@ namespace Lantean.QBTMud.Helpers
files.Add(file.Name, stream);
}
- await apiClient.AddTorrent(
- urls: null,
- files,
- options.SavePath,
- options.Cookie,
- options.Category,
- tags: null,
- options.SkipHashCheck,
- !options.StartTorrent,
- options.ContentLayout,
- options.RenameTorrent,
- options.UploadLimit,
- options.DownloadLimit,
- ratioLimit: null,
- seedingTimeLimit: null,
- options.TorrentManagementMode,
- options.DownloadInSequentialOrder,
- options.DownloadFirstAndLastPiecesFirst);
+ var addTorrentParams = CreateAddTorrentParams(options);
+ addTorrentParams.Torrents = files;
+
+ await apiClient.AddTorrent(addTorrentParams);
foreach (var stream in streams)
{
@@ -78,6 +64,46 @@ namespace Lantean.QBTMud.Helpers
}
}
+ private static QBitTorrentClient.Models.AddTorrentParams CreateAddTorrentParams(TorrentOptions options)
+ {
+ var addTorrentParams = new QBitTorrentClient.Models.AddTorrentParams();
+ addTorrentParams.AddToTopOfQueue = options.AddToTopOfQueue;
+ addTorrentParams.AutoTorrentManagement = options.TorrentManagementMode;
+ addTorrentParams.Category = options.Category;
+ if (!string.IsNullOrEmpty(options.ContentLayout))
+ {
+ addTorrentParams.ContentLayout = Enum.Parse(options.ContentLayout);
+ }
+ if (string.IsNullOrEmpty(options.Cookie))
+ {
+ addTorrentParams.Cookie = options.Cookie;
+ }
+ addTorrentParams.DownloadLimit = options.DownloadLimit;
+ addTorrentParams.DownloadPath = options.DownloadPath;
+ addTorrentParams.FirstLastPiecePriority = options.DownloadFirstAndLastPiecesFirst;
+ addTorrentParams.InactiveSeedingTimeLimit = options.InactiveSeedingTimeLimit;
+ addTorrentParams.Paused = !options.StartTorrent;
+ addTorrentParams.RatioLimit = options.RatioLimit;
+ addTorrentParams.RenameTorrent = options.RenameTorrent;
+ addTorrentParams.SavePath = options.SavePath;
+ addTorrentParams.SeedingTimeLimit = options.SeedingTimeLimit;
+ addTorrentParams.SequentialDownload = options.DownloadInSequentialOrder;
+ if (!string.IsNullOrEmpty(options.ShareLimitAction))
+ {
+ addTorrentParams.ShareLimitAction = Enum.Parse(options.ShareLimitAction);
+ }
+ addTorrentParams.SkipChecking = options.SkipHashCheck;
+ if (!string.IsNullOrEmpty(options.StopCondition))
+ {
+ addTorrentParams.StopCondition = Enum.Parse(options.StopCondition);
+ }
+ addTorrentParams.Stopped = !options.StartTorrent;
+ addTorrentParams.Tags = options.Tags;
+ addTorrentParams.UploadLimit = options.UploadLimit;
+ addTorrentParams.UseDownloadPath = options.UseDownloadPath;
+ return addTorrentParams;
+ }
+
public static async Task InvokeAddTorrentLinkDialog(this IDialogService dialogService, IApiClient apiClient, string? url = null)
{
var parameters = new DialogParameters
@@ -94,24 +120,10 @@ namespace Lantean.QBTMud.Helpers
var options = (AddTorrentLinkOptions)dialogResult.Data;
- await apiClient.AddTorrent(
- urls: options.Urls,
- torrents: null,
- options.SavePath,
- options.Cookie,
- options.Category,
- tags: null,
- options.SkipHashCheck,
- !options.StartTorrent,
- options.ContentLayout,
- options.RenameTorrent,
- options.UploadLimit,
- options.DownloadLimit,
- ratioLimit: null,
- seedingTimeLimit: null,
- options.TorrentManagementMode,
- options.DownloadInSequentialOrder,
- options.DownloadFirstAndLastPiecesFirst);
+ var addTorrentParams = CreateAddTorrentParams(options);
+ addTorrentParams.Urls = options.Urls;
+
+ await apiClient.AddTorrent(addTorrentParams);
}
public static async Task InvokeDeleteTorrentDialog(this IDialogService dialogService, IApiClient apiClient, params string[] hashes)
@@ -192,7 +204,7 @@ namespace Lantean.QBTMud.Helpers
{
var parameters = new DialogParameters
{
- //{ nameof(RenameFilesDialog.Hash), hash }
+ { nameof(RenameFilesDialog.Hash), hash }
};
await dialogService.ShowAsync("Rename Files", parameters, FullScreenDialogOptions);
diff --git a/Lantean.QBTMud/Lantean.QBTMud.csproj b/Lantean.QBTMud/Lantean.QBTMud.csproj
index 7eb8098..7fbdf42 100644
--- a/Lantean.QBTMud/Lantean.QBTMud.csproj
+++ b/Lantean.QBTMud/Lantean.QBTMud.csproj
@@ -15,7 +15,7 @@
-
+
diff --git a/Lantean.QBTMud/Models/TorrentOptions.cs b/Lantean.QBTMud/Models/TorrentOptions.cs
index aadbb56..32d8483 100644
--- a/Lantean.QBTMud/Models/TorrentOptions.cs
+++ b/Lantean.QBTMud/Models/TorrentOptions.cs
@@ -1,4 +1,6 @@
-namespace Lantean.QBTMud.Models
+using Lantean.QBitTorrentClient.Models;
+
+namespace Lantean.QBTMud.Models
{
public record TorrentOptions
{
@@ -61,5 +63,12 @@
public long DownloadLimit { get; }
public long UploadLimit { get; }
+ public string? DownloadPath { get; internal set; }
+ public int? InactiveSeedingTimeLimit { get; internal set; }
+ public float? RatioLimit { get; internal set; }
+ public int? SeedingTimeLimit { get; internal set; }
+ public string? ShareLimitAction { get; internal set; }
+ public bool? UseDownloadPath { get; internal set; }
+ public IEnumerable? Tags { get; internal set; }
}
}
\ No newline at end of file
diff --git a/Lantean.QBTMud/Pages/Login.razor.cs b/Lantean.QBTMud/Pages/Login.razor.cs
index f238708..d986dc4 100644
--- a/Lantean.QBTMud/Pages/Login.razor.cs
+++ b/Lantean.QBTMud/Pages/Login.razor.cs
@@ -49,7 +49,7 @@ namespace Lantean.QBTMud.Pages
protected override Task OnInitializedAsync()
{
- return DoLogin("admin", "AQnwFmBzV");
+ return DoLogin("admin", "eBGJzbjkJ");
}
#endif
diff --git a/Lantean.QBTMud/wwwroot/Lantean.QBTMudBlade.lib.module.js b/Lantean.QBTMud/wwwroot/Lantean.QBTMud.lib.module.js
similarity index 100%
rename from Lantean.QBTMud/wwwroot/Lantean.QBTMudBlade.lib.module.js
rename to Lantean.QBTMud/wwwroot/Lantean.QBTMud.lib.module.js
diff --git a/Lantean.QBitTorrentClient/ApiClient.cs b/Lantean.QBitTorrentClient/ApiClient.cs
index c149691..03c3864 100644
--- a/Lantean.QBitTorrentClient/ApiClient.cs
+++ b/Lantean.QBitTorrentClient/ApiClient.cs
@@ -305,7 +305,7 @@ namespace Lantean.QBitTorrentClient
#region Torrent management
- public async Task> GetTorrentList(string? filter = null, string? category = null, string? tag = null, string? sort = null, bool? reverse = null, int? limit = null, int? offset = null, params string[] hashes)
+ public async Task> GetTorrentList(string? filter = null, string? category = null, string? tag = null, string? sort = null, bool? reverse = null, int? limit = null, int? offset = null, bool? isPrivate = null, params string[] hashes)
{
var query = new QueryBuilder();
if (filter is not null)
@@ -340,6 +340,10 @@ namespace Lantean.QBitTorrentClient
{
query.Add("hashes", string.Join('|', hashes));
}
+ if (isPrivate is not null)
+ {
+ query.Add("private", isPrivate.Value ? "true" : "false");
+ }
var response = await _httpClient.GetAsync("torrents/info", query);
@@ -486,79 +490,110 @@ namespace Lantean.QBitTorrentClient
await ThrowIfNotSuccessfulStatusCode(response);
}
- public async Task AddTorrent(IEnumerable? urls = null, Dictionary? torrents = null, string? savePath = null, string? cookie = null, string? category = null, IEnumerable? tags = null, bool? skipChecking = null, bool? paused = null, string? contentLayout = null, string? renameTorrent = null, long? uploadLimit = null, long? downloadLimit = null, float? ratioLimit = null, int? seedingTimeLimit = null, bool? autoTorrentManagement = null, bool? sequentialDownload = null, bool? firstLastPiecePriority = null)
+ public async Task AddTorrent(AddTorrentParams addTorrentParams)
{
var content = new MultipartFormDataContent();
- if (urls is not null)
+ if (addTorrentParams.Urls is not null)
{
- content.AddString("urls", string.Join('\n', urls));
+ content.AddString("urls", string.Join('\n', addTorrentParams.Urls));
}
- if (torrents is not null)
+ if (addTorrentParams.Torrents is not null)
{
- foreach (var (name, stream) in torrents)
+ foreach (var (name, stream) in addTorrentParams.Torrents)
{
content.Add(new StreamContent(stream), "torrents", name);
}
}
- if (savePath is not null)
+ if (addTorrentParams.SkipChecking is not null)
{
- content.AddString("savepath", savePath);
+ content.AddString("skip_checking", addTorrentParams.SkipChecking.Value);
}
- if (cookie is not null)
+ if (addTorrentParams.SequentialDownload is not null)
{
- content.AddString("cookie", cookie);
+ content.AddString("sequentialDownload", addTorrentParams.SequentialDownload.Value);
}
- if (category is not null)
+ if (addTorrentParams.FirstLastPiecePriority is not null)
{
- content.AddString("category", category);
+ content.AddString("firstLastPiecePrio", addTorrentParams.FirstLastPiecePriority.Value);
}
- if (tags is not null)
+ if (addTorrentParams.AddToTopOfQueue is not null)
{
- content.AddString("tags", string.Join(',', tags));
+ content.AddString("addToTopOfQueue", addTorrentParams.AddToTopOfQueue.Value);
}
- if (skipChecking is not null)
+ // v4
+ if (addTorrentParams.Paused is not null)
{
- content.AddString("skip_checking", skipChecking.Value);
+ content.AddString("paused", addTorrentParams.Paused.Value);
}
- if (paused is not null)
+ // v5
+ if (addTorrentParams.Stopped is not null)
{
- content.AddString("paused", paused.Value);
+ content.AddString("stopped", addTorrentParams.Stopped.Value);
}
- if (contentLayout is not null)
+ if (addTorrentParams.SavePath is not null)
{
- content.AddString("contentLayout", contentLayout);
+ content.AddString("savepath", addTorrentParams.SavePath);
}
- if (renameTorrent is not null)
+ if (addTorrentParams.DownloadPath is not null)
{
- content.AddString("rename", renameTorrent);
+ content.AddString("downloadPath", addTorrentParams.DownloadPath);
}
- if (uploadLimit is not null)
+ if (addTorrentParams.UseDownloadPath is not null)
{
- content.AddString("upLimit", uploadLimit.Value);
+ content.AddString("useDownloadPath", addTorrentParams.UseDownloadPath.Value);
}
- if (downloadLimit is not null)
+ if (addTorrentParams.Category is not null)
{
- content.AddString("dlLimit", downloadLimit.Value);
+ content.AddString("category", addTorrentParams.Category);
}
- if (ratioLimit is not null)
+ if (addTorrentParams.Tags is not null)
{
- content.AddString("ratioLimit", ratioLimit.Value);
+ content.AddString("tags", string.Join(',', addTorrentParams.Tags));
}
- if (seedingTimeLimit is not null)
+ if (addTorrentParams.RenameTorrent is not null)
{
- content.AddString("seedingTimeLimit", seedingTimeLimit.Value);
+ content.AddString("rename", addTorrentParams.RenameTorrent);
}
- if (autoTorrentManagement is not null)
+ if (addTorrentParams.UploadLimit is not null)
{
- content.AddString("autoTMM", autoTorrentManagement.Value);
+ content.AddString("upLimit", addTorrentParams.UploadLimit.Value);
}
- if (sequentialDownload is not null)
+ if (addTorrentParams.DownloadLimit is not null)
{
- content.AddString("sequentialDownload", sequentialDownload.Value);
+ content.AddString("dlLimit", addTorrentParams.DownloadLimit.Value);
}
- if (firstLastPiecePriority is not null)
+ if (addTorrentParams.RatioLimit is not null)
{
- content.AddString("firstLastPiecePrio", firstLastPiecePriority.Value);
+ content.AddString("ratioLimit", addTorrentParams.RatioLimit.Value);
+ }
+ if (addTorrentParams.SeedingTimeLimit is not null)
+ {
+ content.AddString("seedingTimeLimit", addTorrentParams.SeedingTimeLimit.Value);
+ }
+ if (addTorrentParams.InactiveSeedingTimeLimit is not null)
+ {
+ content.AddString("inactiveSeedingTimeLimit", addTorrentParams.InactiveSeedingTimeLimit.Value);
+ }
+ if (addTorrentParams.ShareLimitAction is not null)
+ {
+ content.AddString("shareLimitAction", addTorrentParams.ShareLimitAction.Value);
+ }
+ if (addTorrentParams.AutoTorrentManagement is not null)
+ {
+ content.AddString("autoTMM", addTorrentParams.AutoTorrentManagement.Value);
+ }
+ if (addTorrentParams.StopCondition is not null)
+ {
+ content.AddString("stopCondition", addTorrentParams.StopCondition.Value);
+ }
+ if (addTorrentParams.ContentLayout is not null)
+ {
+ content.AddString("contentLayout", addTorrentParams.ContentLayout.Value);
+ }
+
+ if (addTorrentParams.Cookie is not null)
+ {
+ content.AddString("cookie", addTorrentParams.Cookie);
}
var response = await _httpClient.PostAsync("torrents/add", content);
@@ -606,7 +641,7 @@ namespace Lantean.QBitTorrentClient
public async Task AddPeers(IEnumerable hashes, IEnumerable peers)
{
var content = new FormUrlEncodedBuilder()
- .AddPipeSeparated("hash", hashes)
+ .AddPipeSeparated("hashes", hashes)
.AddPipeSeparated("urls", peers)
.ToFormUrlEncodedContent();
@@ -618,7 +653,7 @@ namespace Lantean.QBitTorrentClient
public async Task IncreaseTorrentPriority(bool? all = null, params string[] hashes)
{
var content = new FormUrlEncodedBuilder()
- .AddAllOrPipeSeparated("hash", all, hashes)
+ .AddAllOrPipeSeparated("hashes", all, hashes)
.ToFormUrlEncodedContent();
var response = await _httpClient.PostAsync("torrents/increasePrio", content);
@@ -629,7 +664,7 @@ namespace Lantean.QBitTorrentClient
public async Task DecreaseTorrentPriority(bool? all = null, params string[] hashes)
{
var content = new FormUrlEncodedBuilder()
- .AddAllOrPipeSeparated("hash", all, hashes)
+ .AddAllOrPipeSeparated("hashes", all, hashes)
.ToFormUrlEncodedContent();
var response = await _httpClient.PostAsync("torrents/decreasePrio", content);
@@ -637,10 +672,10 @@ namespace Lantean.QBitTorrentClient
await ThrowIfNotSuccessfulStatusCode(response);
}
- public async Task MaximalTorrentPriority(bool? all = null, params string[] hashes)
+ public async Task MaxTorrentPriority(bool? all = null, params string[] hashes)
{
var content = new FormUrlEncodedBuilder()
- .AddAllOrPipeSeparated("hash", all, hashes)
+ .AddAllOrPipeSeparated("hashes", all, hashes)
.ToFormUrlEncodedContent();
var response = await _httpClient.PostAsync("torrents/topPrio", content);
@@ -648,10 +683,10 @@ namespace Lantean.QBitTorrentClient
await ThrowIfNotSuccessfulStatusCode(response);
}
- public async Task MinimalTorrentPriority(bool? all = null, params string[] hashes)
+ public async Task MinTorrentPriority(bool? all = null, params string[] hashes)
{
var content = new FormUrlEncodedBuilder()
- .AddAllOrPipeSeparated("hash", all, hashes)
+ .AddAllOrPipeSeparated("hashes", all, hashes)
.ToFormUrlEncodedContent();
var response = await _httpClient.PostAsync("torrents/bottomPrio", content);
diff --git a/Lantean.QBitTorrentClient/IApiClient.cs b/Lantean.QBitTorrentClient/IApiClient.cs
index c21e4e0..7916055 100644
--- a/Lantean.QBitTorrentClient/IApiClient.cs
+++ b/Lantean.QBitTorrentClient/IApiClient.cs
@@ -74,7 +74,7 @@ namespace Lantean.QBitTorrentClient
#region Torrent management
- Task> GetTorrentList(string? filter = null, string? category = null, string? tag = null, string? sort = null, bool? reverse = null, int? limit = null, int? offset = null, params string[] hashes);
+ Task> GetTorrentList(string? filter = null, string? category = null, string? tag = null, string? sort = null, bool? reverse = null, int? limit = null, int? offset = null, bool? isPrivate = null, params string[] hashes);
Task GetTorrentProperties(string hash);
@@ -102,7 +102,7 @@ namespace Lantean.QBitTorrentClient
Task ReannounceTorrents(bool? all = null, params string[] hashes);
- Task AddTorrent(IEnumerable? urls = null, Dictionary? torrents = null, string? savePath = null, string? cookie = null, string? category = null, IEnumerable? tags = null, bool? skipChecking = null, bool? paused = null, string? contentLayout = null, string? renameTorrent = null, long? uploadLimit = null, long? downloadLimit = null, float? ratioLimit = null, int? seedingTimeLimit = null, bool? autoTorrentManagement = null, bool? sequentialDownload = null, bool? firstLastPiecePriority = null);
+ Task AddTorrent(AddTorrentParams addTorrentParams);
Task AddTrackersToTorrent(string hash, IEnumerable urls);
@@ -116,9 +116,9 @@ namespace Lantean.QBitTorrentClient
Task DecreaseTorrentPriority(bool? all = null, params string[] hashes);
- Task MaximalTorrentPriority(bool? all = null, params string[] hashes);
+ Task MaxTorrentPriority(bool? all = null, params string[] hashes);
- Task MinimalTorrentPriority(bool? all = null, params string[] hashes);
+ Task MinTorrentPriority(bool? all = null, params string[] hashes);
Task SetFilePriority(string hash, IEnumerable id, Priority priority);
diff --git a/Lantean.QBitTorrentClient/Models/AddTorrentParams.cs b/Lantean.QBitTorrentClient/Models/AddTorrentParams.cs
new file mode 100644
index 0000000..577d586
--- /dev/null
+++ b/Lantean.QBitTorrentClient/Models/AddTorrentParams.cs
@@ -0,0 +1,54 @@
+namespace Lantean.QBitTorrentClient.Models
+{
+ public record AddTorrentParams
+ {
+ public IEnumerable? Urls { get; set; }
+
+ public bool? SkipChecking { get; set; }
+
+ public bool? SequentialDownload { get; set; }
+
+ public bool? FirstLastPiecePriority { get; set; }
+
+ public bool? AddToTopOfQueue { get; set; }
+
+ // v4
+ public bool? Paused { get; set; }
+ // v5
+ public bool? Stopped { get; set; }
+
+ public string? SavePath { get; set; }
+
+ public string? DownloadPath { get; set; }
+
+ public bool? UseDownloadPath { get; set; }
+
+ public string? Category { get; set; }
+
+ public IEnumerable? Tags { get; set; }
+
+ public string? RenameTorrent { get; set; }
+
+ public long? UploadLimit { get; set; }
+
+ public long? DownloadLimit { get; set; }
+
+ public float? RatioLimit { get; set; }
+
+ public int? SeedingTimeLimit { get; set; }
+
+ public int? InactiveSeedingTimeLimit { get; set; }
+
+ public ShareLimitAction? ShareLimitAction { get; set; }
+
+ public bool? AutoTorrentManagement { get; set; }
+
+ public StopCondition? StopCondition { get; set; }
+
+ public TorrentContentLayout? ContentLayout { get; set; }
+
+ public string? Cookie { get; set; }
+
+ public Dictionary? Torrents { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/Lantean.QBitTorrentClient/Models/ShareLimitAction.cs b/Lantean.QBitTorrentClient/Models/ShareLimitAction.cs
new file mode 100644
index 0000000..0c7c9fb
--- /dev/null
+++ b/Lantean.QBitTorrentClient/Models/ShareLimitAction.cs
@@ -0,0 +1,12 @@
+namespace Lantean.QBitTorrentClient.Models
+{
+ public enum ShareLimitAction
+ {
+ Default = -1, // special value
+
+ Stop = 0,
+ Remove = 1,
+ RemoveWithContent = 3,
+ EnableSuperSeeding = 2
+ }
+}
\ No newline at end of file
diff --git a/Lantean.QBitTorrentClient/Models/StopCondition.cs b/Lantean.QBitTorrentClient/Models/StopCondition.cs
new file mode 100644
index 0000000..112fb51
--- /dev/null
+++ b/Lantean.QBitTorrentClient/Models/StopCondition.cs
@@ -0,0 +1,9 @@
+namespace Lantean.QBitTorrentClient.Models
+{
+ public enum StopCondition
+ {
+ None = 0,
+ MetadataReceived = 1,
+ FilesChecked = 2
+ }
+}
\ No newline at end of file
diff --git a/Lantean.QBitTorrentClient/Models/TorrentContentLayout.cs b/Lantean.QBitTorrentClient/Models/TorrentContentLayout.cs
new file mode 100644
index 0000000..aacae72
--- /dev/null
+++ b/Lantean.QBitTorrentClient/Models/TorrentContentLayout.cs
@@ -0,0 +1,9 @@
+namespace Lantean.QBitTorrentClient.Models
+{
+ public enum TorrentContentLayout
+ {
+ Original,
+ Subfolder,
+ NoSubfolder
+ }
+}
\ No newline at end of file
diff --git a/Lantean.QBitTorrentClient/MultipartFormDataContentExtensions.cs b/Lantean.QBitTorrentClient/MultipartFormDataContentExtensions.cs
index 71eee18..23faec8 100644
--- a/Lantean.QBitTorrentClient/MultipartFormDataContentExtensions.cs
+++ b/Lantean.QBitTorrentClient/MultipartFormDataContentExtensions.cs
@@ -27,6 +27,11 @@
content.AddString(name, value.ToString());
}
+ public static void AddString(this MultipartFormDataContent content, string name, Enum value)
+ {
+ content.AddString(name, value.ToString());
+ }
+
public static void AddString(this MultipartFormDataContent content, string name, DateTimeOffset value, bool useSeconds = true)
{
content.AddString(name, useSeconds ? value.ToUnixTimeSeconds() : value.ToUnixTimeMilliseconds());