Add new v5 properties to AddTorrent

This commit is contained in:
ahjephson
2025-10-22 14:05:13 +01:00
parent e64a13c7c9
commit b8412bb232
6 changed files with 562 additions and 41 deletions

View File

@@ -1,33 +1,50 @@
<MudGrid> @using Lantean.QBitTorrentClient.Models
<MudGrid>
<MudItem xs="12"> <MudItem xs="12">
<MudSwitch Label="Additional Options" @bind-Value="Expanded" LabelPlacement="Placement.End" /> <MudSwitch Label="Additional Options" @bind-Value="Expanded" LabelPlacement="Placement.End" />
</MudItem> </MudItem>
</MudGrid> </MudGrid>
<MudCollapse Expanded="Expanded"> <MudCollapse Expanded="Expanded">
<MudGrid> <MudGrid Class="mt-2">
<MudItem xs="12"> <MudItem xs="12">
<MudSelect Label="Torrent Management Mode" @bind-Value="TorrentManagementMode" Variant="Variant.Outlined"> <MudSelect T="bool" Label="Torrent management mode" Value="@TorrentManagementMode" ValueChanged="@SetTorrentManagementMode" Variant="Variant.Outlined">
<MudSelectItem Value="false">Manual</MudSelectItem> <MudSelectItem Value="@false">Manual</MudSelectItem>
<MudSelectItem Value="true">Automatic</MudSelectItem> <MudSelectItem Value="@true">Automatic</MudSelectItem>
</MudSelect> </MudSelect>
</MudItem> </MudItem>
<MudItem xs="12" sm="6">
<MudTextField T="string" Label="Save files to location" Value="@SavePath" ValueChanged="@SavePathChanged" Variant="Variant.Outlined" Disabled="@TorrentManagementMode" />
</MudItem>
<MudItem xs="12" sm="6">
<FieldSwitch Label="Use incomplete save path" Value="@UseDownloadPath" ValueChanged="@SetUseDownloadPath" Disabled="@TorrentManagementMode" />
</MudItem>
<MudItem xs="12"> <MudItem xs="12">
<MudTextField Label="Save files to location" @bind-Value="SavePath" Variant="Variant.Outlined"></MudTextField> <MudTextField T="string" Label="Incomplete save path" Value="@DownloadPath" ValueChanged="@DownloadPathChanged" Variant="Variant.Outlined" Disabled="@DownloadPathDisabled" />
</MudItem> </MudItem>
@if (ShowCookieOption) @if (ShowCookieOption)
{ {
<MudItem xs="12"> <MudItem xs="12">
<MudTextField Label="Cookie" @bind-Value="Cookie" Variant="Variant.Outlined"></MudTextField> <MudTextField Label="Cookie" @bind-Value="Cookie" Variant="Variant.Outlined" />
</MudItem> </MudItem>
} }
<MudItem xs="12"> <MudItem xs="12">
<MudTextField Label="Rename" @bind-Value="RenameTorrent" Variant="Variant.Outlined"></MudTextField> <MudTextField Label="Rename" @bind-Value="RenameTorrent" Variant="Variant.Outlined" />
</MudItem> </MudItem>
<MudItem xs="12"> <MudItem xs="12">
<MudSelect Label="Category" @bind-Value="Category" Variant="Variant.Outlined"> <MudSelect T="string" Label="Category" Value="@Category" ValueChanged="@CategoryChanged" Variant="Variant.Outlined" Clearable="true">
@foreach (var category in Categories) <MudSelectItem Value="@string.Empty">None</MudSelectItem>
@foreach (var category in CategoryOptions)
{ {
<MudSelectItem Value="category">@category</MudSelectItem> <MudSelectItem Value="@category.Name">@category.Name</MudSelectItem>
}
</MudSelect>
</MudItem>
<MudItem xs="12">
<MudSelect T="string" Label="Tags" Variant="Variant.Outlined" MultiSelection="true" SelectedValues="@SelectedTags" SelectedValuesChanged="@SelectedTagsChanged" Disabled="@(AvailableTags.Count == 0)">
@foreach (var tag in AvailableTags)
{
<MudSelectItem Value="@tag">@tag</MudSelectItem>
} }
</MudSelect> </MudSelect>
</MudItem> </MudItem>
@@ -38,7 +55,7 @@
<FieldSwitch Label="Add to top of queue" @bind-Value="AddToTopOfQueue" /> <FieldSwitch Label="Add to top of queue" @bind-Value="AddToTopOfQueue" />
</MudItem> </MudItem>
<MudItem xs="12"> <MudItem xs="12">
<MudSelect Label="Stop condition" @bind-Value="StopCondition" Variant="Variant.Outlined"> <MudSelect T="string" Label="Stop condition" Value="@StopCondition" ValueChanged="@StopConditionChanged" Variant="Variant.Outlined">
<MudSelectItem Value="@("None")">None</MudSelectItem> <MudSelectItem Value="@("None")">None</MudSelectItem>
<MudSelectItem Value="@("MetadataReceived")">Metadata received</MudSelectItem> <MudSelectItem Value="@("MetadataReceived")">Metadata received</MudSelectItem>
<MudSelectItem Value="@("FilesChecked")">Files checked</MudSelectItem> <MudSelectItem Value="@("FilesChecked")">Files checked</MudSelectItem>
@@ -47,22 +64,58 @@
<MudItem xs="12"> <MudItem xs="12">
<FieldSwitch Label="Skip hash check" @bind-Value="SkipHashCheck" /> <FieldSwitch Label="Skip hash check" @bind-Value="SkipHashCheck" />
</MudItem> </MudItem>
<MudSelect Label="Content layout" @bind-Value="ContentLayout" Variant="Variant.Outlined">
<MudSelectItem Value="@("Original")">Original</MudSelectItem>
<MudSelectItem Value="@("Subfolder")">Create subfolder</MudSelectItem>
<MudSelectItem Value="@("NoSubfolder")">Don't create subfolder'</MudSelectItem>
</MudSelect>
<MudItem xs="12"> <MudItem xs="12">
<FieldSwitch Label="Download in sequentual order" @bind-Value="DownloadInSequentialOrder" /> <MudSelect T="string" Label="Content layout" Value="@ContentLayout" ValueChanged="@ContentLayoutChanged" Variant="Variant.Outlined">
<MudSelectItem Value="@("Original")">Original</MudSelectItem>
<MudSelectItem Value="@("Subfolder")">Create subfolder</MudSelectItem>
<MudSelectItem Value="@("NoSubfolder")">Don't create subfolder</MudSelectItem>
</MudSelect>
</MudItem>
<MudItem xs="12">
<FieldSwitch Label="Download in sequential order" @bind-Value="DownloadInSequentialOrder" />
</MudItem> </MudItem>
<MudItem xs="12"> <MudItem xs="12">
<FieldSwitch Label="Download first and last pieces first" @bind-Value="DownloadFirstAndLastPiecesFirst" /> <FieldSwitch Label="Download first and last pieces first" @bind-Value="DownloadFirstAndLastPiecesFirst" />
</MudItem> </MudItem>
<MudItem xs="12"> <MudItem xs="12" sm="6">
<MudNumericField Label="Limit download rate" @bind-Value="DownloadLimit" Variant="Variant.Outlined" Min="0" /> <MudNumericField Label="Limit download rate" @bind-Value="DownloadLimit" Variant="Variant.Outlined" Min="0" />
</MudItem> </MudItem>
<MudItem xs="12"> <MudItem xs="12" sm="6">
<MudNumericField Label="Limit upload rate" @bind-Value="UploadLimit" Variant="Variant.Outlined" Min="0" /> <MudNumericField Label="Limit upload rate" @bind-Value="UploadLimit" Variant="Variant.Outlined" Min="0" />
</MudItem> </MudItem>
<MudItem xs="12">
<MudSelect T="ShareLimitMode" Label="Share limit preset" Value="@SelectedShareLimitMode" ValueChanged="@ShareLimitModeChanged" Variant="Variant.Outlined">
<MudSelectItem Value="@ShareLimitMode.Global">Use global share limit</MudSelectItem>
<MudSelectItem Value="@ShareLimitMode.NoLimit">Set no share limit</MudSelectItem>
<MudSelectItem Value="@ShareLimitMode.Custom">Set custom share limit</MudSelectItem>
</MudSelect>
</MudItem>
<MudItem xs="12" sm="4">
<FieldSwitch Label="Ratio" Value="@RatioLimitEnabled" ValueChanged="@RatioLimitEnabledChanged" Disabled="@(!IsCustomShareLimit)" />
</MudItem>
<MudItem xs="12" sm="8">
<MudNumericField T="float" Label="Ratio limit" Value="@RatioLimit" ValueChanged="@RatioLimitChanged" Disabled="@(!RatioLimitEnabled || !IsCustomShareLimit)" Min="0" Step="0.1f" Format="F2" Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="12" sm="4">
<FieldSwitch Label="Total minutes" Value="@SeedingTimeLimitEnabled" ValueChanged="@SeedingTimeLimitEnabledChanged" Disabled="@(!IsCustomShareLimit)" />
</MudItem>
<MudItem xs="12" sm="8">
<MudNumericField T="int" Label="Total minutes" Value="@SeedingTimeLimit" ValueChanged="@SeedingTimeLimitChanged" Disabled="@(!SeedingTimeLimitEnabled || !IsCustomShareLimit)" Min="1" Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="12" sm="4">
<FieldSwitch Label="Inactive minutes" Value="@InactiveSeedingTimeLimitEnabled" ValueChanged="@InactiveSeedingTimeLimitEnabledChanged" Disabled="@(!IsCustomShareLimit)" />
</MudItem>
<MudItem xs="12" sm="8">
<MudNumericField T="int" Label="Inactive minutes" Value="@InactiveSeedingTimeLimit" ValueChanged="@InactiveSeedingTimeLimitChanged" Disabled="@(!InactiveSeedingTimeLimitEnabled || !IsCustomShareLimit)" Min="1" Variant="Variant.Outlined" />
</MudItem>
<MudItem xs="12">
<MudSelect T="ShareLimitAction" Label="Action when limit is reached" Value="@SelectedShareLimitAction" ValueChanged="@ShareLimitActionChanged" Disabled="@(!IsCustomShareLimit)" Variant="Variant.Outlined">
<MudSelectItem Value="@ShareLimitAction.Default">Default</MudSelectItem>
<MudSelectItem Value="@ShareLimitAction.Stop">Stop torrent</MudSelectItem>
<MudSelectItem Value="@ShareLimitAction.Remove">Remove torrent</MudSelectItem>
<MudSelectItem Value="@ShareLimitAction.RemoveWithContent">Remove torrent and data</MudSelectItem>
<MudSelectItem Value="@ShareLimitAction.EnableSuperSeeding">Enable super seeding</MudSelectItem>
</MudSelect>
</MudItem>
</MudGrid> </MudGrid>
</MudCollapse> </MudCollapse>

View File

@@ -1,4 +1,10 @@
using Lantean.QBitTorrentClient; using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Lantean.QBitTorrentClient;
using Lantean.QBitTorrentClient.Models;
using Lantean.QBTMud.Models; using Lantean.QBTMud.Models;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
@@ -6,6 +12,15 @@ namespace Lantean.QBTMud.Components.Dialogs
{ {
public partial class AddTorrentOptions public partial class AddTorrentOptions
{ {
private readonly List<CategoryOption> _categoryOptions = new();
private readonly Dictionary<string, CategoryOption> _categoryLookup = new(StringComparer.Ordinal);
private string _manualSavePath = string.Empty;
private bool _manualUseDownloadPath;
private string _manualDownloadPath = string.Empty;
private string _defaultSavePath = string.Empty;
private string _defaultDownloadPath = string.Empty;
private bool _defaultDownloadPathEnabled;
[Inject] [Inject]
protected IApiClient ApiClient { get; set; } = default!; protected IApiClient ApiClient { get; set; } = default!;
@@ -16,15 +31,25 @@ namespace Lantean.QBTMud.Components.Dialogs
protected bool TorrentManagementMode { get; set; } protected bool TorrentManagementMode { get; set; }
protected string SavePath { get; set; } = default!; protected string SavePath { get; set; } = string.Empty;
protected string DownloadPath { get; set; } = string.Empty;
protected bool UseDownloadPath { get; set; }
protected bool DownloadPathDisabled => TorrentManagementMode || !UseDownloadPath;
protected string? Cookie { get; set; } protected string? Cookie { get; set; }
protected string? RenameTorrent { get; set; } protected string? RenameTorrent { get; set; }
protected IEnumerable<string> Categories { get; set; } = []; protected IReadOnlyList<CategoryOption> CategoryOptions => _categoryOptions;
protected string? Category { get; set; } protected string? Category { get; set; } = string.Empty;
protected List<string> AvailableTags { get; private set; } = [];
protected HashSet<string> SelectedTags { get; private set; } = new(StringComparer.Ordinal);
protected bool StartTorrent { get; set; } = true; protected bool StartTorrent { get; set; } = true;
@@ -32,41 +57,264 @@ namespace Lantean.QBTMud.Components.Dialogs
protected string StopCondition { get; set; } = "None"; protected string StopCondition { get; set; } = "None";
protected bool SkipHashCheck { get; set; } = false; protected bool SkipHashCheck { get; set; }
protected string ContentLayout { get; set; } = "Original"; protected string ContentLayout { get; set; } = "Original";
protected bool DownloadInSequentialOrder { get; set; } = false; protected bool DownloadInSequentialOrder { get; set; }
protected bool DownloadFirstAndLastPiecesFirst { get; set; } = false; protected bool DownloadFirstAndLastPiecesFirst { get; set; }
protected long DownloadLimit { get; set; } protected long DownloadLimit { get; set; }
protected long UploadLimit { get; set; } protected long UploadLimit { get; set; }
protected ShareLimitMode SelectedShareLimitMode { get; set; } = ShareLimitMode.Global;
protected bool RatioLimitEnabled { get; set; }
protected float RatioLimit { get; set; } = 1.0f;
protected bool SeedingTimeLimitEnabled { get; set; }
protected int SeedingTimeLimit { get; set; } = 1440;
protected bool InactiveSeedingTimeLimitEnabled { get; set; }
protected int InactiveSeedingTimeLimit { get; set; } = 1440;
protected ShareLimitAction SelectedShareLimitAction { get; set; } = ShareLimitAction.Default;
protected bool IsCustomShareLimit => SelectedShareLimitMode == ShareLimitMode.Custom;
protected override async Task OnInitializedAsync() protected override async Task OnInitializedAsync()
{ {
var categories = await ApiClient.GetAllCategories(); var categories = await ApiClient.GetAllCategories();
Categories = categories.Select(c => c.Key).ToList(); foreach (var (name, value) in categories.OrderBy(kvp => kvp.Key, StringComparer.OrdinalIgnoreCase))
{
var option = new CategoryOption(name, value.SavePath, value.DownloadPath);
_categoryOptions.Add(option);
_categoryLookup[name] = option;
}
var tags = await ApiClient.GetAllTags();
AvailableTags = tags.OrderBy(t => t, StringComparer.OrdinalIgnoreCase).ToList();
var preferences = await ApiClient.GetApplicationPreferences(); var preferences = await ApiClient.GetApplicationPreferences();
TorrentManagementMode = preferences.AutoTmmEnabled; TorrentManagementMode = preferences.AutoTmmEnabled;
SavePath = preferences.SavePath;
_defaultSavePath = preferences.SavePath ?? string.Empty;
_manualSavePath = _defaultSavePath;
SavePath = _defaultSavePath;
_defaultDownloadPath = preferences.TempPath ?? string.Empty;
_defaultDownloadPathEnabled = preferences.TempPathEnabled;
_manualDownloadPath = _defaultDownloadPath;
_manualUseDownloadPath = preferences.TempPathEnabled;
UseDownloadPath = _manualUseDownloadPath;
DownloadPath = UseDownloadPath ? _manualDownloadPath : string.Empty;
StartTorrent = !preferences.AddStoppedEnabled; StartTorrent = !preferences.AddStoppedEnabled;
AddToTopOfQueue = preferences.AddToTopOfQueue; AddToTopOfQueue = preferences.AddToTopOfQueue;
StopCondition = preferences.TorrentStopCondition; StopCondition = preferences.TorrentStopCondition;
ContentLayout = preferences.TorrentContentLayout; ContentLayout = preferences.TorrentContentLayout;
RatioLimitEnabled = preferences.MaxRatioEnabled;
RatioLimit = preferences.MaxRatio;
SeedingTimeLimitEnabled = preferences.MaxSeedingTimeEnabled;
if (preferences.MaxSeedingTimeEnabled)
{
SeedingTimeLimit = preferences.MaxSeedingTime;
}
InactiveSeedingTimeLimitEnabled = preferences.MaxInactiveSeedingTimeEnabled;
if (preferences.MaxInactiveSeedingTimeEnabled)
{
InactiveSeedingTimeLimit = preferences.MaxInactiveSeedingTime;
}
SelectedShareLimitAction = MapShareLimitAction(preferences.MaxRatioAct);
if (TorrentManagementMode)
{
ApplyAutomaticPaths();
}
}
protected Task SetTorrentManagementMode(bool value)
{
if (TorrentManagementMode == value)
{
return Task.CompletedTask;
}
TorrentManagementMode = value;
if (TorrentManagementMode)
{
ApplyAutomaticPaths();
}
else
{
RestoreManualPaths();
}
return Task.CompletedTask;
}
protected Task SavePathChanged(string value)
{
SavePath = value;
if (!TorrentManagementMode)
{
_manualSavePath = value;
}
return Task.CompletedTask;
}
protected Task SetUseDownloadPath(bool value)
{
if (TorrentManagementMode)
{
return Task.CompletedTask;
}
_manualUseDownloadPath = value;
UseDownloadPath = value;
if (value)
{
if (string.IsNullOrWhiteSpace(_manualDownloadPath))
{
_manualDownloadPath = string.IsNullOrWhiteSpace(_defaultDownloadPath) ? string.Empty : _defaultDownloadPath;
}
DownloadPath = _manualDownloadPath;
}
else
{
_manualDownloadPath = DownloadPath;
DownloadPath = string.Empty;
}
return Task.CompletedTask;
}
protected Task DownloadPathChanged(string value)
{
DownloadPath = value;
if (!TorrentManagementMode && UseDownloadPath)
{
_manualDownloadPath = value;
}
return Task.CompletedTask;
}
protected Task CategoryChanged(string? value)
{
Category = string.IsNullOrWhiteSpace(value) ? null : value;
if (TorrentManagementMode)
{
ApplyAutomaticPaths();
}
return Task.CompletedTask;
}
protected Task SelectedTagsChanged(IEnumerable<string> tags)
{
SelectedTags = tags is null
? new HashSet<string>(StringComparer.Ordinal)
: new HashSet<string>(tags, StringComparer.Ordinal);
return Task.CompletedTask;
}
protected Task StopConditionChanged(string value)
{
StopCondition = value;
return Task.CompletedTask;
}
protected Task ContentLayoutChanged(string value)
{
ContentLayout = value;
return Task.CompletedTask;
}
protected Task ShareLimitModeChanged(ShareLimitMode mode)
{
SelectedShareLimitMode = mode;
if (mode != ShareLimitMode.Custom)
{
RatioLimitEnabled = false;
SeedingTimeLimitEnabled = false;
InactiveSeedingTimeLimitEnabled = false;
SelectedShareLimitAction = ShareLimitAction.Default;
}
return Task.CompletedTask;
}
protected Task RatioLimitEnabledChanged(bool value)
{
RatioLimitEnabled = value;
return Task.CompletedTask;
}
protected Task RatioLimitChanged(float value)
{
RatioLimit = value;
return Task.CompletedTask;
}
protected Task SeedingTimeLimitEnabledChanged(bool value)
{
SeedingTimeLimitEnabled = value;
return Task.CompletedTask;
}
protected Task SeedingTimeLimitChanged(int value)
{
SeedingTimeLimit = value;
return Task.CompletedTask;
}
protected Task InactiveSeedingTimeLimitEnabledChanged(bool value)
{
InactiveSeedingTimeLimitEnabled = value;
return Task.CompletedTask;
}
protected Task InactiveSeedingTimeLimitChanged(int value)
{
InactiveSeedingTimeLimit = value;
return Task.CompletedTask;
}
protected Task ShareLimitActionChanged(ShareLimitAction value)
{
SelectedShareLimitAction = value;
return Task.CompletedTask;
} }
public TorrentOptions GetTorrentOptions() public TorrentOptions GetTorrentOptions()
{ {
return new TorrentOptions( var options = new TorrentOptions(
TorrentManagementMode, TorrentManagementMode,
SavePath, _manualSavePath,
Cookie, Cookie,
RenameTorrent, RenameTorrent,
Category, string.IsNullOrWhiteSpace(Category) ? null : Category,
StartTorrent, StartTorrent,
AddToTopOfQueue, AddToTopOfQueue,
StopCondition, StopCondition,
@@ -76,6 +324,152 @@ namespace Lantean.QBTMud.Components.Dialogs
DownloadFirstAndLastPiecesFirst, DownloadFirstAndLastPiecesFirst,
DownloadLimit, DownloadLimit,
UploadLimit); UploadLimit);
options.UseDownloadPath = TorrentManagementMode ? null : UseDownloadPath;
options.DownloadPath = (!TorrentManagementMode && UseDownloadPath) ? DownloadPath : null;
options.Tags = SelectedTags.Count > 0 ? SelectedTags.ToArray() : null;
switch (SelectedShareLimitMode)
{
case ShareLimitMode.Global:
options.RatioLimit = Limits.GlobalLimit;
options.SeedingTimeLimit = Limits.GlobalLimit;
options.InactiveSeedingTimeLimit = Limits.GlobalLimit;
options.ShareLimitAction = ShareLimitAction.Default.ToString();
break;
case ShareLimitMode.NoLimit:
options.RatioLimit = Limits.NoLimit;
options.SeedingTimeLimit = Limits.NoLimit;
options.InactiveSeedingTimeLimit = Limits.NoLimit;
options.ShareLimitAction = ShareLimitAction.Default.ToString();
break;
case ShareLimitMode.Custom:
options.RatioLimit = RatioLimitEnabled ? RatioLimit : Limits.NoLimit;
options.SeedingTimeLimit = SeedingTimeLimitEnabled ? SeedingTimeLimit : Limits.NoLimit;
options.InactiveSeedingTimeLimit = InactiveSeedingTimeLimitEnabled ? InactiveSeedingTimeLimit : Limits.NoLimit;
options.ShareLimitAction = SelectedShareLimitAction.ToString();
break;
}
return options;
} }
private void ApplyAutomaticPaths()
{
SavePath = ResolveAutomaticSavePath();
var (enabled, path) = ResolveAutomaticDownloadPath();
UseDownloadPath = enabled;
DownloadPath = enabled ? path ?? string.Empty : string.Empty;
}
private void RestoreManualPaths()
{
SavePath = _manualSavePath;
UseDownloadPath = _manualUseDownloadPath;
DownloadPath = _manualUseDownloadPath ? _manualDownloadPath : string.Empty;
}
private string ResolveAutomaticSavePath()
{
var category = GetSelectedCategory();
if (category is null)
{
return _defaultSavePath;
}
if (!string.IsNullOrWhiteSpace(category.SavePath))
{
return category.SavePath!;
}
if (!string.IsNullOrWhiteSpace(_defaultSavePath) && !string.IsNullOrWhiteSpace(category.Name))
{
return Path.Combine(_defaultSavePath, category.Name);
}
return _defaultSavePath;
}
private (bool Enabled, string? Path) ResolveAutomaticDownloadPath()
{
var category = GetSelectedCategory();
if (category is null)
{
if (!_defaultDownloadPathEnabled)
{
return (false, string.Empty);
}
return (true, _defaultDownloadPath);
}
if (category.DownloadPath is null)
{
if (!_defaultDownloadPathEnabled)
{
return (false, string.Empty);
}
return (true, ComposeDefaultDownloadPath(category.Name));
}
if (!category.DownloadPath.Enabled)
{
return (false, string.Empty);
}
if (!string.IsNullOrWhiteSpace(category.DownloadPath.Path))
{
return (true, category.DownloadPath.Path);
}
return (true, ComposeDefaultDownloadPath(category.Name));
}
private string ComposeDefaultDownloadPath(string categoryName)
{
if (string.IsNullOrWhiteSpace(_defaultDownloadPath))
{
return string.Empty;
}
if (string.IsNullOrWhiteSpace(categoryName))
{
return _defaultDownloadPath;
}
return Path.Combine(_defaultDownloadPath, categoryName);
}
private CategoryOption? GetSelectedCategory()
{
if (string.IsNullOrWhiteSpace(Category))
{
return null;
}
return _categoryLookup.TryGetValue(Category, out var option) ? option : null;
}
private static ShareLimitAction MapShareLimitAction(int preferenceValue)
{
return preferenceValue switch
{
0 => ShareLimitAction.Stop,
1 => ShareLimitAction.Remove,
2 => ShareLimitAction.RemoveWithContent,
3 => ShareLimitAction.EnableSuperSeeding,
_ => ShareLimitAction.Default
};
}
protected enum ShareLimitMode
{
Global,
NoLimit,
Custom
}
protected sealed record CategoryOption(string Name, string? SavePath, DownloadPathOption? DownloadPath);
} }
} }

View File

@@ -1,4 +1,3 @@
using System.Linq;
using Lantean.QBitTorrentClient; using Lantean.QBitTorrentClient;
using ShareLimitAction = Lantean.QBitTorrentClient.Models.ShareLimitAction; using ShareLimitAction = Lantean.QBitTorrentClient.Models.ShareLimitAction;
using Lantean.QBTMud.Components.Dialogs; using Lantean.QBTMud.Components.Dialogs;
@@ -77,12 +76,18 @@ namespace Lantean.QBTMud.Helpers
addTorrentParams.ContentLayout = Enum.Parse<QBitTorrentClient.Models.TorrentContentLayout>(options.ContentLayout); addTorrentParams.ContentLayout = Enum.Parse<QBitTorrentClient.Models.TorrentContentLayout>(options.ContentLayout);
} }
addTorrentParams.DownloadLimit = options.DownloadLimit; addTorrentParams.DownloadLimit = options.DownloadLimit;
addTorrentParams.DownloadPath = options.DownloadPath; if (!string.IsNullOrWhiteSpace(options.DownloadPath))
{
addTorrentParams.DownloadPath = options.DownloadPath;
}
addTorrentParams.FirstLastPiecePriority = options.DownloadFirstAndLastPiecesFirst; addTorrentParams.FirstLastPiecePriority = options.DownloadFirstAndLastPiecesFirst;
addTorrentParams.InactiveSeedingTimeLimit = options.InactiveSeedingTimeLimit; addTorrentParams.InactiveSeedingTimeLimit = options.InactiveSeedingTimeLimit;
addTorrentParams.RatioLimit = options.RatioLimit; addTorrentParams.RatioLimit = options.RatioLimit;
addTorrentParams.RenameTorrent = options.RenameTorrent; addTorrentParams.RenameTorrent = options.RenameTorrent;
addTorrentParams.SavePath = options.SavePath; if (!options.TorrentManagementMode)
{
addTorrentParams.SavePath = options.SavePath;
}
addTorrentParams.SeedingTimeLimit = options.SeedingTimeLimit; addTorrentParams.SeedingTimeLimit = options.SeedingTimeLimit;
addTorrentParams.SequentialDownload = options.DownloadInSequentialOrder; addTorrentParams.SequentialDownload = options.DownloadInSequentialOrder;
if (!string.IsNullOrEmpty(options.ShareLimitAction)) if (!string.IsNullOrEmpty(options.ShareLimitAction))
@@ -97,7 +102,10 @@ namespace Lantean.QBTMud.Helpers
addTorrentParams.Stopped = !options.StartTorrent; addTorrentParams.Stopped = !options.StartTorrent;
addTorrentParams.Tags = options.Tags; addTorrentParams.Tags = options.Tags;
addTorrentParams.UploadLimit = options.UploadLimit; addTorrentParams.UploadLimit = options.UploadLimit;
addTorrentParams.UseDownloadPath = options.UseDownloadPath; if (options.UseDownloadPath.HasValue)
{
addTorrentParams.UseDownloadPath = options.UseDownloadPath;
}
return addTorrentParams; return addTorrentParams;
} }
@@ -259,7 +267,7 @@ namespace Lantean.QBTMud.Helpers
ShareLimitAction = t.ShareLimitAction, ShareLimitAction = t.ShareLimitAction,
}).ToList(); }).ToList();
var referenceValue = shareRatioValues.First(); var referenceValue = shareRatioValues[0];
var torrentsHaveSameShareRatio = shareRatioValues.Distinct().Count() == 1; var torrentsHaveSameShareRatio = shareRatioValues.Distinct().Count() == 1;
var parameters = new DialogParameters var parameters = new DialogParameters

View File

@@ -0,0 +1,44 @@
using Lantean.QBitTorrentClient.Models;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace Lantean.QBitTorrentClient.Converters
{
public sealed class DownloadPathOptionJsonConverter : JsonConverter<DownloadPathOption>
{
public override DownloadPathOption? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return reader.TokenType switch
{
JsonTokenType.Null => null,
JsonTokenType.False => new DownloadPathOption(false, null),
JsonTokenType.True => new DownloadPathOption(true, null),
JsonTokenType.String => new DownloadPathOption(true, reader.GetString()),
_ => throw new JsonException($"Unexpected token {reader.TokenType} when parsing download_path.")
};
}
public override void Write(Utf8JsonWriter writer, DownloadPathOption? value, JsonSerializerOptions options)
{
if (value is null)
{
writer.WriteNullValue();
return;
}
if (!value.Enabled)
{
writer.WriteBooleanValue(false);
return;
}
if (string.IsNullOrWhiteSpace(value.Path))
{
writer.WriteBooleanValue(true);
return;
}
writer.WriteStringValue(value.Path);
}
}
}

View File

@@ -1,4 +1,5 @@
using System.Text.Json.Serialization; using Lantean.QBitTorrentClient.Converters;
using System.Text.Json.Serialization;
namespace Lantean.QBitTorrentClient.Models namespace Lantean.QBitTorrentClient.Models
{ {
@@ -7,10 +8,12 @@ namespace Lantean.QBitTorrentClient.Models
[JsonConstructor] [JsonConstructor]
public Category( public Category(
string name, string name,
string? savePath) string? savePath,
DownloadPathOption? downloadPath)
{ {
Name = name; Name = name;
SavePath = savePath; SavePath = savePath;
DownloadPath = downloadPath;
} }
[JsonPropertyName("name")] [JsonPropertyName("name")]
@@ -18,5 +21,9 @@ namespace Lantean.QBitTorrentClient.Models
[JsonPropertyName("savePath")] [JsonPropertyName("savePath")]
public string? SavePath { get; } public string? SavePath { get; }
[JsonPropertyName("download_path")]
[JsonConverter(typeof(DownloadPathOptionJsonConverter))]
public DownloadPathOption? DownloadPath { get; }
} }
} }

View File

@@ -0,0 +1,15 @@
namespace Lantean.QBitTorrentClient.Models
{
public record DownloadPathOption
{
public DownloadPathOption(bool enabled, string? path)
{
Enabled = enabled;
Path = path;
}
public bool Enabled { get; }
public string? Path { get; }
}
}