aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShadowghost <Ghost_of_Stone@web.de>2026-08-25 20:12:52 +0200
committerShadowghost <Ghost_of_Stone@web.de>2026-08-25 20:43:44 +0200
commit1d24c1df170d743d5b0d2c1c8c503e44486c6875 (patch)
tree9acea13fd86a4885164c255b3b4b05b4411b632c
parent4147a83b9356a9b6d101dde8217aec21fefb51f4 (diff)
Keep an OMDb credit whole when its annotation holds a comma
-rw-r--r--MediaBrowser.Providers/Plugins/Omdb/OmdbProvider.cs32
-rw-r--r--tests/Jellyfin.Providers.Tests/Omdb/OmdbProviderTests.cs14
2 files changed, 44 insertions, 2 deletions
diff --git a/MediaBrowser.Providers/Plugins/Omdb/OmdbProvider.cs b/MediaBrowser.Providers/Plugins/Omdb/OmdbProvider.cs
index 7262cddd33..d51d913caa 100644
--- a/MediaBrowser.Providers/Plugins/Omdb/OmdbProvider.cs
+++ b/MediaBrowser.Providers/Plugins/Omdb/OmdbProvider.cs
@@ -443,7 +443,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb
var names = new List<string>();
- foreach (var credit in credits.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries))
+ foreach (var credit in SplitCredits(credits))
{
// OMDb annotates the credited role in parentheses, e.g. "Mari Okada (screenplay)". The same
// person can be credited more than once this way, so strip it and let AddPerson deduplicate.
@@ -451,9 +451,10 @@ namespace MediaBrowser.Providers.Plugins.Omdb
var annotation = name.IndexOf('(', StringComparison.Ordinal);
if (annotation >= 0)
{
- name = name[..annotation].TrimEnd();
+ name = name[..annotation];
}
+ name = name.Trim();
if (name.Length == 0)
{
continue;
@@ -480,6 +481,33 @@ namespace MediaBrowser.Providers.Plugins.Omdb
}
}
+ // Only the commas between credits, never one inside an annotation: "Jerry Siegel (created by:
+ // Superman, Superboy)" is one credit, and splitting it blindly invents a person called "Superboy)".
+ private static IEnumerable<string> SplitCredits(string credits)
+ {
+ var depth = 0;
+ var start = 0;
+
+ for (var i = 0; i < credits.Length; i++)
+ {
+ switch (credits[i])
+ {
+ case '(':
+ depth++;
+ break;
+ case ')':
+ depth = Math.Max(0, depth - 1);
+ break;
+ case ',' when depth == 0:
+ yield return credits[start..i];
+ start = i + 1;
+ break;
+ }
+ }
+
+ yield return credits[start..];
+ }
+
private static bool IsNameSuffix(string value)
{
var suffix = value.EndsWith('.') ? value[..^1] : value;
diff --git a/tests/Jellyfin.Providers.Tests/Omdb/OmdbProviderTests.cs b/tests/Jellyfin.Providers.Tests/Omdb/OmdbProviderTests.cs
index 5e053943af..bd50a903f1 100644
--- a/tests/Jellyfin.Providers.Tests/Omdb/OmdbProviderTests.cs
+++ b/tests/Jellyfin.Providers.Tests/Omdb/OmdbProviderTests.cs
@@ -35,6 +35,20 @@ namespace Jellyfin.Providers.Tests.Omdb
}
[Theory]
+ [InlineData(
+ "Jerry Siegel (created by: Superman, Superboy), Bob Kane (created by: Batman)",
+ "Jerry Siegel|Bob Kane")]
+ [InlineData("Alan Moore (created by: John Constantine)", "Alan Moore")]
+ public void AddPeople_CommaInsideAnAnnotation_StaysOneCredit(string credits, string expected)
+ {
+ var result = new MetadataResult<Movie>();
+
+ OmdbProvider.AddPeople(result, credits, PersonKind.Writer);
+
+ Assert.Equal(expected.Split('|'), result.People!.Select(p => p.Name));
+ }
+
+ [Theory]
[InlineData("Jack Salvatore, Jr.", "Jack Salvatore, Jr.")]
[InlineData("Efrem Zimbalist, Jr., Tom Hanks", "Efrem Zimbalist, Jr.|Tom Hanks")]
[InlineData("Tom Hanks, Sammy Davis, Jr", "Tom Hanks|Sammy Davis, Jr")]