Skip to content

Commit

Permalink
Lidarr optimizations
Browse files Browse the repository at this point in the history
  • Loading branch information
PCJones committed Feb 14, 2024
1 parent 96f8ff9 commit b741239
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 24 deletions.
2 changes: 1 addition & 1 deletion UmlautAdaptarr/Controllers/SearchController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ public async Task<IActionResult> GenericSearch([FromRoute] string options, [From
if (categories.Split(',').Any(category => AUDIO_CATEGORY_IDS.Contains(category)))
{
var mediaType = "audio";
searchItem = await searchItemLookupService.GetOrFetchSearchItemByExternalId(mediaType, title.ToLower());
searchItem = await searchItemLookupService.GetOrFetchSearchItemByExternalId(mediaType, title.GetLidarrTitleForExternalId());
}
}
}
Expand Down
30 changes: 23 additions & 7 deletions UmlautAdaptarr/Models/SearchItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ public partial class SearchItem
public bool HasUmlaut => Title?.HasUmlauts() ?? false;
public string ExpectedTitle { get; set; }
public string? ExpectedAuthor { get; set; }
// TODO rename GermanTitle into Foreign or LocalTitle?
public string? GermanTitle { get; set; }
public string[] TitleSearchVariations { get; set; }
public string[] TitleMatchVariations { get; set; }
Expand Down Expand Up @@ -42,6 +43,11 @@ public SearchItem(
if (expectedTitle.Contains(expectedAuthor))
{
var titleWithoutAuthorName = expectedTitle.Replace(expectedAuthor, string.Empty).RemoveExtraWhitespaces().Trim();

if (titleWithoutAuthorName.Length < 2)
{
// TODO log warning that this album can't be searched for automatically
}
TitleMatchVariations = GenerateVariations(titleWithoutAuthorName, mediaType).ToArray();
}
else
Expand Down Expand Up @@ -86,13 +92,18 @@ public SearchItem(
}
}

private IEnumerable<string> GenerateVariations(string? germanTitle, string mediaType)
private IEnumerable<string> GenerateVariations(string? title, string mediaType)
{
if (germanTitle == null)
if (title == null)
{
return [];
}
var cleanTitle = title.GetCleanTitle();

if (cleanTitle?.Length == 0)
{
return [];
}
var cleanTitle = germanTitle.RemoveAccentButKeepGermanUmlauts().GetCleanTitle();

// Start with base variations including handling umlauts
var baseVariations = new List<string>
Expand Down Expand Up @@ -121,12 +132,17 @@ private IEnumerable<string> GenerateVariations(string? germanTitle, string media
});
}

// If a german title starts with der/die/das also accept variations without it
if (mediaType != "audio" && cleanTitle.StartsWith("Der") || cleanTitle.StartsWith("Die") || cleanTitle.StartsWith("Das"))
// If a title starts with der/die/das also accept variations without it
// Same for english the, an, a
if (cleanTitle.StartsWith("Der ") || cleanTitle.StartsWith("Die ") || cleanTitle.StartsWith("Das ")
|| cleanTitle.StartsWith("The ") || cleanTitle.StartsWith("An "))
{
var cleanTitleWithoutArticle = germanTitle[3..].Trim();
var cleanTitleWithoutArticle = title[3..].Trim();
baseVariations.AddRange(GenerateVariations(cleanTitleWithoutArticle, mediaType));
}
} else if (cleanTitle.StartsWith("A "))
{
var cleanTitleWithoutArticle = title[2..].Trim();
}

// Remove multiple spaces
var cleanedVariations = baseVariations.Select(variation => variation.RemoveExtraWhitespaces());
Expand Down
23 changes: 12 additions & 11 deletions UmlautAdaptarr/Providers/LidarrClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,17 @@ public override async Task<IEnumerable<SearchItem>> FetchAllItemsAsync()

var lidarrAlbumUrl = $"{_lidarrHost}/api/v1/album?artistId={artistId}&apikey={_lidarrApiKey}";

if (cache.TryGetValue(lidarrAlbumUrl, out List<dynamic>? albums))
{
logger.LogInformation($"Using cached albums for {UrlUtilities.RedactApiKey(lidarrAlbumUrl)}");
}
else
{
logger.LogInformation($"Fetching all albums from artistId {artistId} from Lidarr: {UrlUtilities.RedactApiKey(lidarrArtistsUrl)}");
var albumApiResponse = await httpClient.GetStringAsync(lidarrAlbumUrl);
albums = JsonConvert.DeserializeObject<List<dynamic>>(albumApiResponse);
}
// Disable cache for now as it can result in problems when adding new albums that aren't displayed on the artists page initially
//if (cache.TryGetValue(lidarrAlbumUrl, out List<dynamic>? albums))
//{
// logger.LogInformation($"Using cached albums for {UrlUtilities.RedactApiKey(lidarrAlbumUrl)}");
//}
//else
//{
logger.LogInformation($"Fetching all albums from artistId {artistId} from Lidarr: {UrlUtilities.RedactApiKey(lidarrArtistsUrl)}");
var albumApiResponse = await httpClient.GetStringAsync(lidarrAlbumUrl);
var albums = JsonConvert.DeserializeObject<List<dynamic>>(albumApiResponse);
//}

if (albums == null)
{
Expand All @@ -74,7 +75,7 @@ public override async Task<IEnumerable<SearchItem>> FetchAllItemsAsync()
string[]? aliases = null;

// Abuse externalId to set the search string Lidarr uses
var externalId = expectedTitle.RemoveGermanUmlautDots().RemoveAccent().RemoveSpecialCharacters().RemoveExtraWhitespaces().ToLower();
var externalId = expectedTitle.GetLidarrTitleForExternalId();

var searchItem = new SearchItem
(
Expand Down
42 changes: 37 additions & 5 deletions UmlautAdaptarr/Utilities/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,20 +47,46 @@ public static string RemoveAccentButKeepGermanUmlauts(this string text)
return stringBuilder.ToString().Normalize(NormalizationForm.FormC);
}

// TODO possibly replace GetCleanTitle with RemoveSpecialCharacters
public static string GetLidarrTitleForExternalId(this string text)
{
text = text.RemoveGermanUmlautDots()
.GetCleanTitle()
.ToLower();

// Lidarr removes the, an and a
return TitlePrefixRegex()
.Replace(text, "")
.RemoveExtraWhitespaces()
.Trim();
}

public static string GetCleanTitle(this string text)
{
return text.Replace("(", "").Replace(")", "").Replace("?","").Replace(":", "").Replace("'", "");
return text
.Replace(".", " ")
.Replace(":", " ")
.RemoveAccentButKeepGermanUmlauts()
.RemoveSpecialCharacters(removeUmlauts: false)
.RemoveExtraWhitespaces()
.Trim();
}

public static string NormalizeForComparison(this string text)
{
// TODO see if we can replace RemoveGermanUmlautDots() with RemoveSpecialCharacters(removeUmlauts: false);
return text.RemoveGermanUmlautDots().RemoveAccent().RemoveSpecialCharacters().Replace(" ", "").Trim().ToLower();
}

public static string RemoveSpecialCharacters(this string text)
public static string RemoveSpecialCharacters(this string text, bool removeUmlauts = true)
{
return SpecialCharactersRegex().Replace(text, "");
if (removeUmlauts)
{
return NoSpecialCharactersRegex().Replace(text, "");
}
else
{
return NoSpecialCharactersExceptUmlautsRegex().Replace(text, "");
}
}


Expand Down Expand Up @@ -101,9 +127,15 @@ public static bool HasUmlauts(this string text)
}

[GeneratedRegex("[^a-zA-Z0-9 ]+", RegexOptions.Compiled)]
private static partial Regex SpecialCharactersRegex();
private static partial Regex NoSpecialCharactersRegex();

[GeneratedRegex("[^a-zA-Z0-9 öäüßÖÄÜ]+", RegexOptions.Compiled)]
private static partial Regex NoSpecialCharactersExceptUmlautsRegex();

[GeneratedRegex(@"\s+")]
private static partial Regex MultipleWhitespaceRegex();

[GeneratedRegex(@"\b(the|an|a)\b", RegexOptions.IgnoreCase, "de-DE")]
private static partial Regex TitlePrefixRegex();
}
}

0 comments on commit b741239

Please sign in to comment.