Add partial search implementation and fix bugs

This commit is contained in:
ahjephson
2024-06-23 10:37:25 +01:00
parent 0f21d454ae
commit e9e41950f7
47 changed files with 1266 additions and 200 deletions

View File

@@ -1,4 +1,5 @@
using Lantean.QBitTorrentClient.Models;
using System.Collections.Generic;
using System.Net;
using System.Net.Http.Json;
using System.Text.Json;
@@ -947,7 +948,153 @@ namespace Lantean.QBitTorrentClient
#region Search
// not implementing Search right now
public async Task<int> StartSearch(string pattern, IEnumerable<string> plugins, string category = "all")
{
var content = new FormUrlEncodedBuilder()
.Add("pattern", pattern)
.AddPipeSeparated("plugins", plugins)
.Add("category", category)
.ToFormUrlEncodedContent();
var response = await _httpClient.PostAsync("search/start", content);
response.EnsureSuccessStatusCode();
var obj = await GetJson<Dictionary<string, JsonElement>>(response.Content);
return obj["id"].GetInt32();
}
public async Task StopSearch(int id)
{
var content = new FormUrlEncodedBuilder()
.Add("id", id)
.ToFormUrlEncodedContent();
var response = await _httpClient.PostAsync("search/stop", content);
response.EnsureSuccessStatusCode();
}
public async Task<SearchStatus?> GetSearchStatus(int id)
{
var query = new QueryBuilder();
query.Add("id", id);
var response = await _httpClient.GetAsync($"search/status{query}");
if (response.StatusCode == HttpStatusCode.NotFound)
{
return null;
}
response.EnsureSuccessStatusCode();
return (await GetJsonList<SearchStatus>(response.Content)).FirstOrDefault();
}
public async Task<IReadOnlyList<SearchStatus>> GetSearchesStatus()
{
var response = await _httpClient.GetAsync($"search/status");
response.EnsureSuccessStatusCode();
return await GetJsonList<SearchStatus>(response.Content);
}
public async Task<SearchResults> GetSearchResults(int id, int? limit = null, int? offset = null)
{
var query = new QueryBuilder();
query.Add("id", id);
if (limit is not null)
{
query.Add("limit", limit.Value);
}
if (offset is not null)
{
query.Add("offset", offset.Value);
}
var response = await _httpClient.GetAsync($"search/results{query}");
response.EnsureSuccessStatusCode();
return await GetJson<SearchResults>(response.Content);
}
public async Task DeleteSearch(int id)
{
var content = new FormUrlEncodedBuilder()
.Add("id", id)
.ToFormUrlEncodedContent();
var response = await _httpClient.PostAsync("search/delete", content);
response.EnsureSuccessStatusCode();
}
public async Task<IReadOnlyList<SearchPlugin>> GetSearchPlugins()
{
var response = await _httpClient.GetAsync($"search/plugins");
response.EnsureSuccessStatusCode();
return await GetJsonList<SearchPlugin>(response.Content);
}
public async Task InstallSearchPlugins(params string[] sources)
{
var content = new FormUrlEncodedBuilder()
.AddPipeSeparated("sources", sources)
.ToFormUrlEncodedContent();
var response = await _httpClient.PostAsync("search/installPlugin", content);
response.EnsureSuccessStatusCode();
}
public async Task UninstallSearchPlugins(params string[] names)
{
var content = new FormUrlEncodedBuilder()
.AddPipeSeparated("names", names)
.ToFormUrlEncodedContent();
var response = await _httpClient.PostAsync("search/uninstallPlugin", content);
response.EnsureSuccessStatusCode();
}
public async Task EnableSearchPlugins(params string[] names)
{
var content = new FormUrlEncodedBuilder()
.AddPipeSeparated("names", names)
.Add("enabble", true)
.ToFormUrlEncodedContent();
var response = await _httpClient.PostAsync("search/enablePlugin", content);
response.EnsureSuccessStatusCode();
}
public async Task DisableSearchPlugins(params string[] names)
{
var content = new FormUrlEncodedBuilder()
.AddPipeSeparated("names", names)
.Add("enabble", false)
.ToFormUrlEncodedContent();
var response = await _httpClient.PostAsync("search/enablePlugin", content);
response.EnsureSuccessStatusCode();
}
public async Task UpdateSearchPlugins()
{
var response = await _httpClient.PostAsync("search/updatePlugins", null);
response.EnsureSuccessStatusCode();
}
#endregion Search

View File

@@ -178,7 +178,29 @@ namespace Lantean.QBitTorrentClient
#region Search
// not implementing Search right now
Task<int> StartSearch(string pattern, IEnumerable<string> plugins, string category = "all");
Task StopSearch(int id);
Task<SearchStatus?> GetSearchStatus(int id);
Task<IReadOnlyList<SearchStatus>> GetSearchesStatus();
Task<SearchResults> GetSearchResults(int id, int? limit = null, int? offset = null);
Task DeleteSearch(int id);
Task<IReadOnlyList<SearchPlugin>> GetSearchPlugins();
Task InstallSearchPlugins(params string[] sources);
Task UninstallSearchPlugins(params string[] names);
Task EnableSearchPlugins(params string[] names);
Task DisableSearchPlugins(params string[] names);
Task UpdateSearchPlugins();
#endregion Search
}

View File

@@ -378,5 +378,65 @@ namespace Lantean.QBitTorrentClient
{
return _apiClient.ToggleSequentialDownload(all, hashes);
}
public Task<int> StartSearch(string pattern, IEnumerable<string> plugins, string category = "all")
{
return _apiClient.StartSearch(pattern, plugins, category);
}
public Task StopSearch(int id)
{
return _apiClient.StopSearch(id);
}
public Task<SearchStatus?> GetSearchStatus(int id)
{
return _apiClient.GetSearchStatus(id);
}
public Task<IReadOnlyList<SearchStatus>> GetSearchesStatus()
{
return _apiClient.GetSearchesStatus();
}
public Task<SearchResults> GetSearchResults(int id, int? limit = null, int? offset = null)
{
return _apiClient.GetSearchResults(id, limit, offset);
}
public Task DeleteSearch(int id)
{
return _apiClient.DeleteSearch(id);
}
public Task<IReadOnlyList<SearchPlugin>> GetSearchPlugins()
{
return _apiClient.GetSearchPlugins();
}
public Task InstallSearchPlugins(params string[] sources)
{
return _apiClient.InstallSearchPlugins(sources);
}
public Task UninstallSearchPlugins(params string[] names)
{
return _apiClient.UninstallSearchPlugins(names);
}
public Task EnableSearchPlugins(params string[] names)
{
return _apiClient.EnableSearchPlugins(names);
}
public Task DisableSearchPlugins(params string[] names)
{
return _apiClient.DisableSearchPlugins(names);
}
public Task UpdateSearchPlugins()
{
return _apiClient.UpdateSearchPlugins();
}
}
}

View File

@@ -0,0 +1,20 @@
using System.Text.Json.Serialization;
namespace Lantean.QBitTorrentClient.Models
{
public record SearchCategory
{
[JsonConstructor]
public SearchCategory(string id, string name)
{
Id = id;
Name = name;
}
[JsonPropertyName("id")]
public string Id { get; set; }
[JsonPropertyName("name")]
public string Name { get; set; }
}
}

View File

@@ -0,0 +1,42 @@
using System.Text.Json.Serialization;
namespace Lantean.QBitTorrentClient.Models
{
public record SearchPlugin
{
[JsonConstructor]
public SearchPlugin(
bool enabled,
string fullName,
string name,
IReadOnlyList<SearchCategory> supportedCategories,
string url,
string version)
{
Enabled = enabled;
FullName = fullName;
Name = name;
SupportedCategories = supportedCategories;
Url = url;
Version = version;
}
[JsonPropertyName("enabled")]
public bool Enabled { get; set; }
[JsonPropertyName("fullName")]
public string FullName { get; set; }
[JsonPropertyName("name")]
public string Name { get; set; }
[JsonPropertyName("supportedCategories")]
public IReadOnlyList<SearchCategory> SupportedCategories { get; set; }
[JsonPropertyName("url")]
public string Url { get; set; }
[JsonPropertyName("version")]
public string Version { get; set; }
}
}

View File

@@ -0,0 +1,47 @@
using System.Text.Json.Serialization;
namespace Lantean.QBitTorrentClient.Models
{
public record SearchResult
{
[JsonConstructor]
public SearchResult(
string descriptionLink,
string fileName,
long fileSize,
string fileUrl,
int leechers,
int seeders,
string siteUrl)
{
DescriptionLink = descriptionLink;
FileName = fileName;
FileSize = fileSize;
FileUrl = fileUrl;
Leechers = leechers;
Seeders = seeders;
SiteUrl = siteUrl;
}
[JsonPropertyName("descrLink")]
public string DescriptionLink { get; set; }
[JsonPropertyName("fileName")]
public string FileName { get; set; }
[JsonPropertyName("fileSize")]
public long FileSize { get; set; }
[JsonPropertyName("fileUrl")]
public string FileUrl { get; set; }
[JsonPropertyName("nbLeechers")]
public int Leechers { get; set; }
[JsonPropertyName("nbSeeders")]
public int Seeders { get; set; }
[JsonPropertyName("siteUrl")]
public string SiteUrl { get; set; }
}
}

View File

@@ -0,0 +1,24 @@
using System.Text.Json.Serialization;
namespace Lantean.QBitTorrentClient.Models
{
public record SearchResults
{
[JsonConstructor]
public SearchResults(IReadOnlyList<SearchResult> results, string status, int total)
{
Results = results;
Status = status;
Total = total;
}
[JsonPropertyName("results")]
public IReadOnlyList<SearchResult> Results { get; }
[JsonPropertyName("status")]
public string Status { get; }
[JsonPropertyName("total")]
public int Total { get; }
}
}

View File

@@ -0,0 +1,24 @@
using System.Text.Json.Serialization;
namespace Lantean.QBitTorrentClient.Models
{
public record SearchStatus
{
[JsonConstructor]
public SearchStatus(int id, string status, int total)
{
Id = id;
Status = status;
Total = total;
}
[JsonPropertyName("id")]
public int Id { get; }
[JsonPropertyName("status")]
public string Status { get; }
[JsonPropertyName("total")]
public int Total { get; }
}
}