From 1294990f4fa93b30ec9699d18af4de1cd1d562b8 Mon Sep 17 00:00:00 2001 From: Jakub Schmidtke Date: Tue, 7 Jul 2026 04:18:02 +0200 Subject: Added more aliases for attributes Adds tvdb alias for tvdbid and imdb alias for imdbid. It also fixes an issue where tmdb alias was being ignored if it was followed by something like "tmdbidfoo". The same issue prevented imdb pattern matching from working, if it was followed by something like "imdbidfoo". It also allows for detecting the first matching occurence, whether it was an alias or not. Finally, it ignores attributes with values consisting of only whitespaces. --- .../Library/PathExtensions.cs | 81 +++++++++++++++------- 1 file changed, 56 insertions(+), 25 deletions(-) (limited to 'Emby.Server.Implementations/Library') diff --git a/Emby.Server.Implementations/Library/PathExtensions.cs b/Emby.Server.Implementations/Library/PathExtensions.cs index 7591359ea4..8815e2785a 100644 --- a/Emby.Server.Implementations/Library/PathExtensions.cs +++ b/Emby.Server.Implementations/Library/PathExtensions.cs @@ -29,17 +29,41 @@ namespace Emby.Server.Implementations.Library throw new ArgumentException("String can't be empty.", nameof(attribute)); } - var attributeIndex = str.IndexOf(attribute, StringComparison.OrdinalIgnoreCase); + // Allow tmdb as an alias for tmdbid, tvdb for tvdbid, etc. + // The code below only supports aliases for attributes in the form of "id". + ReadOnlySpan shortAttr = attribute switch + { + _ when attribute.Equals("tmdbid", StringComparison.OrdinalIgnoreCase) => "tmdb", + _ when attribute.Equals("tvdbid", StringComparison.OrdinalIgnoreCase) => "tvdb", + _ when attribute.Equals("imdbid", StringComparison.OrdinalIgnoreCase) => "imdb", + _ => string.Empty + }; - // Must be at least 3 characters after the attribute =, ], any character, - // then we offset it by 1, because we want the index and not length. - var maxIndex = str.Length - attribute.Length - 2; - while (attributeIndex > -1 && attributeIndex < maxIndex) + for (int strIndex = 0, attributeIndex = 0; attributeIndex > -1;) { - var attributeEnd = attributeIndex + attribute.Length; + // We may want to use imdbid pattern matching later, so we don't want to modify the original 'str'. + var subStr = str[strIndex..]; + int attributeEnd = 0; + + if (shortAttr.Length > 0) + { + // If we are using an alias it should be shorter (and a prefix), so let's search for that. + attributeIndex = subStr.IndexOf(shortAttr, StringComparison.OrdinalIgnoreCase); + attributeEnd = attributeIndex + shortAttr.Length; + } + else + { + attributeIndex = subStr.IndexOf(attribute, StringComparison.OrdinalIgnoreCase); + attributeEnd = attributeIndex + attribute.Length; + } + + // The next iteration should start at the end of the attribute we just found. + // If attributeIndex < 0, the loop will end and strIndex won't be used again. + strIndex += attributeEnd; + if (attributeIndex > 0) { - var attributeOpener = str[attributeIndex - 1]; + var attributeOpener = subStr[attributeIndex - 1]; var attributeCloser = attributeOpener switch { '[' => ']', @@ -47,20 +71,37 @@ namespace Emby.Server.Implementations.Library '{' => '}', _ => '\0' }; - if (attributeCloser != '\0' && (str[attributeEnd] == '=' || str[attributeEnd] == '-')) + + if (attributeCloser != '\0') { - var closingIndex = str[attributeEnd..].IndexOf(attributeCloser); + if (shortAttr.Length > 0 + && attributeEnd + 1 < subStr.Length + && (subStr[attributeEnd] is 'i' or 'I') + && (subStr[attributeEnd + 1] is 'd' or 'D')) + { + // We were searching for a shortened attribute, but it's followed by "id" - let's skip it. + attributeEnd += 2; + } - // Must be at least 1 character before the closing bracket. - if (closingIndex > 1) + // attributeEnd points at '='. + // We need at least 1 more character and the closing bracket after that. + if (attributeEnd + 2 < subStr.Length && (subStr[attributeEnd] is '=' or '-')) { - return str[(attributeEnd + 1)..(attributeEnd + closingIndex)].Trim().ToString(); + var closingIndex = subStr[attributeEnd..].IndexOf(attributeCloser); + + // Must be at least 1 character before the closing bracket. + if (closingIndex > 1) + { + var trimmed = subStr[(attributeEnd + 1)..(attributeEnd + closingIndex)].Trim(); + + if (trimmed.Length > 0) + { + return trimmed.ToString(); + } + } } } } - - str = str[attributeEnd..]; - attributeIndex = str.IndexOf(attribute, StringComparison.OrdinalIgnoreCase); } // for imdbid we also accept pattern matching @@ -70,16 +111,6 @@ namespace Emby.Server.Implementations.Library return match ? imdbId.ToString() : null; } - // Allow tmdb as an alias for tmdbid - if (attribute.Equals("tmdbid", StringComparison.OrdinalIgnoreCase)) - { - var tmdbValue = str.GetAttributeValue("tmdb"); - if (tmdbValue is not null) - { - return tmdbValue; - } - } - return null; } -- cgit v1.2.3