mirror of
https://github.com/Prowlarr/Prowlarr
synced 2026-05-08 21:14:30 +02:00
Fix Qui API compatibility: categories, response format, mappings, and equality
Qui's API returns categories as objects (not strings) and indexer responses as flat JSON (not nested under torznab_indexer). The API also never returns api_key in responses, which caused GetIndexerMappings to never match. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
df53c980d1
commit
9287eaede0
3 changed files with 34 additions and 22 deletions
|
|
@ -45,7 +45,6 @@ public override List<AppIndexerMap> GetIndexerMappings()
|
|||
if (indexer.Backend == "prowlarr" &&
|
||||
(indexer.BaseUrl?.TrimEnd('/').Equals(baseUrl, StringComparison.OrdinalIgnoreCase) == true ||
|
||||
indexer.BaseUrl?.StartsWith(baseUrl + "/", StringComparison.OrdinalIgnoreCase) == true) &&
|
||||
indexer.ApiKey == _configFileProvider.ApiKey &&
|
||||
int.TryParse(indexer.IndexerId, out var indexerId))
|
||||
{
|
||||
mappings.Add(new AppIndexerMap { IndexerId = indexerId, RemoteIndexerId = indexer.Id });
|
||||
|
|
@ -132,7 +131,11 @@ public override void UpdateIndexer(IndexerDefinition indexer, bool forceSync = f
|
|||
else
|
||||
{
|
||||
_quiProxy.RemoveIndexer(remoteIndexer.Id, Settings);
|
||||
_appIndexerMapService.Delete(indexerMapping.Id);
|
||||
|
||||
if (indexerMapping != null)
|
||||
{
|
||||
_appIndexerMapService.Delete(indexerMapping.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -204,7 +207,7 @@ private QuiIndexer BuildQuiIndexer(IndexerDefinition indexer, IndexerCapabilitie
|
|||
LimitMax = 200,
|
||||
IndexerId = indexer.Id.ToString(),
|
||||
Capabilities = capabilities,
|
||||
Categories = supportedCategories.Select(c => c.ToString()).ToList()
|
||||
Categories = supportedCategories.Select(c => new QuiCategory { CategoryId = c, CategoryName = NewznabStandardCategory.GetCatDesc(c) }).ToList()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,13 +5,22 @@
|
|||
|
||||
namespace NzbDrone.Core.Applications.Qui
|
||||
{
|
||||
public class QuiIndexerResponse
|
||||
public class QuiCategory
|
||||
{
|
||||
[JsonProperty("torznab_indexer")]
|
||||
public QuiIndexer TorznabIndexer { get; set; }
|
||||
[JsonProperty("indexer_id")]
|
||||
public int IndexerId { get; set; }
|
||||
|
||||
[JsonProperty("category_id")]
|
||||
public int CategoryId { get; set; }
|
||||
|
||||
[JsonProperty("category_name")]
|
||||
public string CategoryName { get; set; }
|
||||
|
||||
[JsonProperty("parent_category_id")]
|
||||
public int? ParentCategoryId { get; set; }
|
||||
}
|
||||
|
||||
public class QuiIndexer
|
||||
public class QuiIndexer : IEquatable<QuiIndexer>
|
||||
{
|
||||
[JsonProperty("id")]
|
||||
public int Id { get; set; }
|
||||
|
|
@ -50,7 +59,7 @@ public class QuiIndexer
|
|||
public List<string> Capabilities { get; set; }
|
||||
|
||||
[JsonProperty("categories")]
|
||||
public List<string> Categories { get; set; }
|
||||
public List<QuiCategory> Categories { get; set; }
|
||||
|
||||
public bool Equals(QuiIndexer other)
|
||||
{
|
||||
|
|
@ -59,8 +68,8 @@ public bool Equals(QuiIndexer other)
|
|||
return false;
|
||||
}
|
||||
|
||||
var thisCategories = (Categories ?? Enumerable.Empty<string>()).OrderBy(c => c);
|
||||
var otherCategories = (other.Categories ?? Enumerable.Empty<string>()).OrderBy(c => c);
|
||||
var thisCategories = (Categories ?? Enumerable.Empty<QuiCategory>()).Select(c => c.CategoryId).OrderBy(c => c);
|
||||
var otherCategories = (other.Categories ?? Enumerable.Empty<QuiCategory>()).Select(c => c.CategoryId).OrderBy(c => c);
|
||||
|
||||
return other.BaseUrl == BaseUrl &&
|
||||
other.ApiKey == ApiKey &&
|
||||
|
|
@ -72,6 +81,8 @@ public bool Equals(QuiIndexer other)
|
|||
otherCategories.SequenceEqual(thisCategories);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj) => Equals(obj as QuiIndexer);
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return HashCode.Combine(BaseUrl, ApiKey, Name, Backend, Enabled, Priority, IndexerId);
|
||||
|
|
|
|||
|
|
@ -64,8 +64,7 @@ public QuiIndexer AddIndexer(QuiIndexer indexer, QuiSettings settings)
|
|||
request.SetContent(indexer.ToJson());
|
||||
request.ContentSummary = indexer.ToJson(Formatting.None);
|
||||
|
||||
var response = Execute<QuiIndexerResponse>(request);
|
||||
return response.TorznabIndexer;
|
||||
return Execute<QuiIndexer>(request);
|
||||
}
|
||||
|
||||
public QuiIndexer UpdateIndexer(QuiIndexer indexer, QuiSettings settings)
|
||||
|
|
@ -75,23 +74,22 @@ public QuiIndexer UpdateIndexer(QuiIndexer indexer, QuiSettings settings)
|
|||
request.SetContent(indexer.ToJson());
|
||||
request.ContentSummary = indexer.ToJson(Formatting.None);
|
||||
|
||||
var response = Execute<QuiIndexerResponse>(request);
|
||||
return response.TorznabIndexer;
|
||||
return Execute<QuiIndexer>(request);
|
||||
}
|
||||
|
||||
public void RemoveIndexer(int indexerId, QuiSettings settings)
|
||||
{
|
||||
var request = BuildRequest(settings, $"{AppIndexerApiRoute}/{indexerId}", HttpMethod.Delete);
|
||||
var response = _httpClient.Execute(request);
|
||||
|
||||
if (response.StatusCode == HttpStatusCode.NotFound)
|
||||
try
|
||||
{
|
||||
return;
|
||||
var request = BuildRequest(settings, $"{AppIndexerApiRoute}/{indexerId}", HttpMethod.Delete);
|
||||
_httpClient.Execute(request);
|
||||
}
|
||||
|
||||
if ((int)response.StatusCode >= 300)
|
||||
catch (HttpException ex)
|
||||
{
|
||||
throw new HttpException(response);
|
||||
if (ex.Response.StatusCode != HttpStatusCode.NotFound)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue