mirror of
https://github.com/lantean-code/qbtmud.git
synced 2025-10-23 04:52:22 +00:00
Add new v5 properties to AddTorrent
This commit is contained in:
@@ -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>
|
||||||
|
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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
|
||||||
|
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -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; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
15
Lantean.QBitTorrentClient/Models/DownloadPathOption.cs
Normal file
15
Lantean.QBitTorrentClient/Models/DownloadPathOption.cs
Normal 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; }
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user