aboutsummaryrefslogtreecommitdiff
path: root/Emby.Server.Implementations
diff options
context:
space:
mode:
Diffstat (limited to 'Emby.Server.Implementations')
-rw-r--r--Emby.Server.Implementations/Collections/CollectionManager.cs3
-rw-r--r--Emby.Server.Implementations/Library/LibraryManager.cs65
-rw-r--r--Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs2
-rw-r--r--Emby.Server.Implementations/Library/UserViewManager.cs6
-rw-r--r--Emby.Server.Implementations/Library/Validators/PeopleValidator.cs10
-rw-r--r--Emby.Server.Implementations/Localization/Core/en-GB.json3
6 files changed, 73 insertions, 16 deletions
diff --git a/Emby.Server.Implementations/Collections/CollectionManager.cs b/Emby.Server.Implementations/Collections/CollectionManager.cs
index 295efd456c..84d50f5121 100644
--- a/Emby.Server.Implementations/Collections/CollectionManager.cs
+++ b/Emby.Server.Implementations/Collections/CollectionManager.cs
@@ -107,7 +107,8 @@ namespace Emby.Server.Implementations.Collections
SaveLocalMetadata = true
};
- var name = _localizationManager.GetLocalizedString("Collections");
+ // This names a library for the whole server, so ignore the requesting client's language.
+ var name = _localizationManager.GetServerLocalizedString("Collections");
await _libraryManager.AddVirtualFolder(name, CollectionTypeOptions.boxsets, libraryOptions, true).ConfigureAwait(false);
diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs
index 2bba659a23..dd8c883684 100644
--- a/Emby.Server.Implementations/Library/LibraryManager.cs
+++ b/Emby.Server.Implementations/Library/LibraryManager.cs
@@ -2527,9 +2527,15 @@ namespace Emby.Server.Implementations.Library
}
}
- if (!File.Exists(image.Path))
- {
- _logger.LogWarning("Image not found at {ImagePath}", image.Path);
+ if (string.IsNullOrEmpty(image.Path) || !File.Exists(image.Path))
+ {
+ _logger.LogWarning(
+ "{ImageType} image for {ItemName} ({ItemId}) not found at \"{ImagePath}\", source was {SourcePath}",
+ img.Type,
+ item.Name,
+ item.Id,
+ image.Path,
+ img.Path);
continue;
}
@@ -2927,7 +2933,8 @@ namespace Emby.Server.Implementations.Library
"views",
_fileSystem.GetValidFilename(viewType.ToString()));
- var id = GetNewItemId(path + "_namedview_" + name, typeof(UserView));
+ // The display name is localized, so it must not take part in the id.
+ var id = GetNewItemId(path + "_namedview_" + viewType.ToString(), typeof(UserView));
var item = GetItemById(id) as UserView;
@@ -2951,6 +2958,13 @@ namespace Emby.Server.Implementations.Library
refresh = true;
}
+ else if (!string.Equals(item.Name, name, StringComparison.Ordinal))
+ {
+ item.Name = name;
+ item.ForcedSortName = sortName;
+
+ refresh = true;
+ }
if (refresh)
{
@@ -2971,7 +2985,9 @@ namespace Emby.Server.Implementations.Library
var parentIdString = parentId.IsEmpty()
? null
: parentId.ToString("N", CultureInfo.InvariantCulture);
- var idValues = "38_namedview_" + name + user.Id.ToString("N", CultureInfo.InvariantCulture) + (parentIdString ?? string.Empty) + (viewType?.ToString() ?? string.Empty);
+
+ // The name is either localized (grouped views) or the library folder's own name.
+ var idValues = "38_namedview_" + user.Id.ToString("N", CultureInfo.InvariantCulture) + (parentIdString ?? string.Empty) + (viewType?.ToString() ?? string.Empty);
var id = GetNewItemId(idValues, typeof(UserView));
@@ -3001,6 +3017,11 @@ namespace Emby.Server.Implementations.Library
isNew = true;
}
+ else if (!string.Equals(item.Name, name, StringComparison.Ordinal))
+ {
+ item.Name = name;
+ item.UpdateToRepositoryAsync(ItemUpdateType.MetadataEdit, CancellationToken.None).GetAwaiter().GetResult();
+ }
var lastRefreshedUtc = item.DateLastRefreshed;
var refresh = isNew || DateTime.UtcNow - lastRefreshedUtc >= _viewRefreshInterval;
@@ -3102,7 +3123,7 @@ namespace Emby.Server.Implementations.Library
var parentIdString = parentId.IsEmpty()
? null
: parentId.ToString("N", CultureInfo.InvariantCulture);
- var idValues = "37_namedview_" + name + (parentIdString ?? string.Empty) + (viewType?.ToString() ?? string.Empty);
+ var idValues = "37_namedview_" + (parentIdString ?? string.Empty) + (viewType?.ToString() ?? string.Empty);
if (!string.IsNullOrEmpty(uniqueId))
{
idValues += uniqueId;
@@ -3136,9 +3157,10 @@ namespace Emby.Server.Implementations.Library
isNew = true;
}
- if (viewType != item.ViewType)
+ if (viewType != item.ViewType || !string.Equals(item.Name, name, StringComparison.Ordinal))
{
item.ViewType = viewType;
+ item.Name = name;
item.UpdateToRepositoryAsync(ItemUpdateType.MetadataEdit, CancellationToken.None).GetAwaiter().GetResult();
}
@@ -3559,6 +3581,12 @@ namespace Emby.Server.Implementations.Library
}
/// <inheritdoc/>
+ public int DeleteOrphanedCredits()
+ {
+ return _peopleRepository.DeleteOrphanedCredits();
+ }
+
+ /// <inheritdoc/>
public IReadOnlyDictionary<Guid, IReadOnlyList<string>> GetPeopleNamesByItems(IReadOnlyList<Guid> itemIds, IReadOnlyList<string> personTypes)
{
return _peopleRepository.GetPeopleNamesByItems(itemIds, personTypes);
@@ -3603,7 +3631,20 @@ namespace Emby.Server.Implementations.Library
await item.UpdateToRepositoryAsync(ItemUpdateType.ImageUpdate, CancellationToken.None).ConfigureAwait(false);
- return item.GetImageInfo(image.Type, imageIndex);
+ var localImage = item.GetImageInfo(image.Type, imageIndex);
+ if (localImage is null)
+ {
+ throw new InvalidOperationException(string.Format(
+ CultureInfo.InvariantCulture,
+ "Downloaded {0} image {1} from {2} is not attached to {3} ({4})",
+ image.Type,
+ imageIndex,
+ url,
+ item.Name,
+ item.Id));
+ }
+
+ return localImage;
}
catch (HttpRequestException ex)
{
@@ -3625,7 +3666,13 @@ namespace Emby.Server.Implementations.Library
await item.UpdateToRepositoryAsync(ItemUpdateType.ImageUpdate, CancellationToken.None).ConfigureAwait(false);
}
- throw new InvalidOperationException("Unable to convert any images to local");
+ throw new InvalidOperationException(string.Format(
+ CultureInfo.InvariantCulture,
+ "Unable to convert any {0} image url in \"{1}\" to a local file for {2} ({3})",
+ image.Type,
+ image.Path,
+ item.Name,
+ item.Id));
}
public async Task AddVirtualFolder(string name, CollectionTypeOptions? collectionType, LibraryOptions options, bool refreshLibrary)
diff --git a/Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs b/Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs
index 6e9a38fd34..6624d0125f 100644
--- a/Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs
+++ b/Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs
@@ -99,7 +99,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV
args.LibraryOptions.SeasonZeroDisplayName :
string.Format(
CultureInfo.InvariantCulture,
- _localization.GetLocalizedString("NameSeasonNumber"),
+ _localization.GetServerLocalizedString("NameSeasonNumber"),
seasonNumber,
args.LibraryOptions.PreferredMetadataLanguage);
}
diff --git a/Emby.Server.Implementations/Library/UserViewManager.cs b/Emby.Server.Implementations/Library/UserViewManager.cs
index 49d76e195d..47b3891901 100644
--- a/Emby.Server.Implementations/Library/UserViewManager.cs
+++ b/Emby.Server.Implementations/Library/UserViewManager.cs
@@ -112,7 +112,7 @@ namespace Emby.Server.Implementations.Library
if (_config.Configuration.EnableFolderView)
{
- var name = _localizationManager.GetLocalizedString("Folders");
+ var name = _localizationManager.GetServerLocalizedString("Folders");
list.Add(_libraryManager.GetNamedView(name, CollectionType.folders, string.Empty));
}
@@ -168,7 +168,7 @@ namespace Emby.Server.Implementations.Library
public UserView GetUserSubView(Guid parentId, CollectionType? type, string localizationKey, string sortName)
{
- var name = _localizationManager.GetLocalizedString(localizationKey);
+ var name = _localizationManager.GetServerLocalizedString(localizationKey);
return GetUserSubViewWithName(name, parentId, type, sortName);
}
@@ -191,7 +191,7 @@ namespace Emby.Server.Implementations.Library
return GetUserView((Folder)parents[0], viewType, string.Empty);
}
- var name = _localizationManager.GetLocalizedString(localizationKey);
+ var name = _localizationManager.GetServerLocalizedString(localizationKey);
return _libraryManager.GetNamedView(user, name, viewType, sortName);
}
diff --git a/Emby.Server.Implementations/Library/Validators/PeopleValidator.cs b/Emby.Server.Implementations/Library/Validators/PeopleValidator.cs
index dacef102dd..078a0b921d 100644
--- a/Emby.Server.Implementations/Library/Validators/PeopleValidator.cs
+++ b/Emby.Server.Implementations/Library/Validators/PeopleValidator.cs
@@ -49,6 +49,14 @@ public class PeopleValidator
/// <returns>Task.</returns>
public async Task ValidatePeople(CancellationToken cancellationToken, IProgress<double> progress)
{
+ // Before the refresh below walks them: a credit no item maps to any more stands for nothing,
+ // and while it is there the person it names cannot reach the dead-person sweep either.
+ var numOrphaned = _libraryManager.DeleteOrphanedCredits();
+ if (numOrphaned > 0)
+ {
+ _logger.LogDebug("Deleted {Amount} credits no item maps to", numOrphaned);
+ }
+
var people = _libraryManager.GetPeopleNames(new InternalPeopleQuery());
var numComplete = 0;
@@ -115,6 +123,6 @@ public class PeopleValidator
progress.Report(100);
- _logger.LogInformation("People validation complete");
+ _logger.LogInformation("People validation complete, deleted {Orphaned} orphaned credits", numOrphaned);
}
}
diff --git a/Emby.Server.Implementations/Localization/Core/en-GB.json b/Emby.Server.Implementations/Localization/Core/en-GB.json
index 1f69fc1f55..a053fc2da9 100644
--- a/Emby.Server.Implementations/Localization/Core/en-GB.json
+++ b/Emby.Server.Implementations/Localization/Core/en-GB.json
@@ -120,5 +120,6 @@
"NameExtraThemeSong": "Theme Song",
"NameExtraThemeVideo": "Theme Video",
"NameExtraTrailer": "Trailer",
- "NameExtraUnknown": "Extra"
+ "NameExtraUnknown": "Extra",
+ "NameExtraNumbered": "{0} {1}"
}