aboutsummaryrefslogtreecommitdiff
path: root/Emby.Server.Implementations/Library/LibraryManager.cs
diff options
context:
space:
mode:
authorJPVenson <github@jpb.software>2025-02-21 11:08:09 +0000
committerJPVenson <github@jpb.software>2025-02-21 11:08:09 +0000
commit8c0b0d910229d7691b638d2aee5aa5a8aa07fe17 (patch)
tree2e4177bd57586f9e41747f582dddae9d70d78466 /Emby.Server.Implementations/Library/LibraryManager.cs
parent963f2357a966dd7a5a6ab248155cc52ce066753b (diff)
parent712908d53c7ca38d13e03ea7809e0c40e862a5fb (diff)
Merge remote-tracking branch 'jellyfinorigin/master' into feature/10.10/DetachedMigration
Diffstat (limited to 'Emby.Server.Implementations/Library/LibraryManager.cs')
-rw-r--r--Emby.Server.Implementations/Library/LibraryManager.cs83
1 files changed, 44 insertions, 39 deletions
diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs
index 28f7ed659..c483f3c61 100644
--- a/Emby.Server.Implementations/Library/LibraryManager.cs
+++ b/Emby.Server.Implementations/Library/LibraryManager.cs
@@ -76,13 +76,14 @@ namespace Emby.Server.Implementations.Library
private readonly IItemRepository _itemRepository;
private readonly IImageProcessor _imageProcessor;
private readonly NamingOptions _namingOptions;
+ private readonly IPeopleRepository _peopleRepository;
private readonly ExtraResolver _extraResolver;
/// <summary>
/// The _root folder sync lock.
/// </summary>
- private readonly object _rootFolderSyncLock = new object();
- private readonly object _userRootFolderSyncLock = new object();
+ private readonly Lock _rootFolderSyncLock = new();
+ private readonly Lock _userRootFolderSyncLock = new();
private readonly TimeSpan _viewRefreshInterval = TimeSpan.FromHours(24);
@@ -112,6 +113,7 @@ namespace Emby.Server.Implementations.Library
/// <param name="imageProcessor">The image processor.</param>
/// <param name="namingOptions">The naming options.</param>
/// <param name="directoryService">The directory service.</param>
+ /// <param name="peopleRepository">The People Repository.</param>
public LibraryManager(
IServerApplicationHost appHost,
ILoggerFactory loggerFactory,
@@ -127,7 +129,8 @@ namespace Emby.Server.Implementations.Library
IItemRepository itemRepository,
IImageProcessor imageProcessor,
NamingOptions namingOptions,
- IDirectoryService directoryService)
+ IDirectoryService directoryService,
+ IPeopleRepository peopleRepository)
{
_appHost = appHost;
_logger = loggerFactory.CreateLogger<LibraryManager>();
@@ -144,7 +147,7 @@ namespace Emby.Server.Implementations.Library
_imageProcessor = imageProcessor;
_cache = new ConcurrentDictionary<Guid, BaseItem>();
_namingOptions = namingOptions;
-
+ _peopleRepository = peopleRepository;
_extraResolver = new ExtraResolver(loggerFactory.CreateLogger<ExtraResolver>(), namingOptions, directoryService);
_configurationManager.ConfigurationUpdated += ConfigurationUpdated;
@@ -751,14 +754,7 @@ namespace Emby.Server.Implementations.Library
if (folder.Id.IsEmpty())
{
- if (string.IsNullOrEmpty(folder.Path))
- {
- folder.Id = GetNewItemId(folder.GetType().Name, folder.GetType());
- }
- else
- {
- folder.Id = GetNewItemId(folder.Path, folder.GetType());
- }
+ folder.Id = GetNewItemId(folder.Path, folder.GetType());
}
var dbItem = GetItemById(folder.Id) as BasePluginFolder;
@@ -1053,9 +1049,17 @@ namespace Emby.Server.Implementations.Library
cancellationToken: cancellationToken).ConfigureAwait(false);
// Quickly scan CollectionFolders for changes
- foreach (var folder in GetUserRootFolder().Children.OfType<Folder>())
+ foreach (var child in GetUserRootFolder().Children.OfType<Folder>())
{
- await folder.RefreshMetadata(cancellationToken).ConfigureAwait(false);
+ // If the user has somehow deleted the collection directory, remove the metadata from the database.
+ if (child is CollectionFolder collectionFolder && !Directory.Exists(collectionFolder.Path))
+ {
+ _itemRepository.DeleteItem(collectionFolder.Id);
+ }
+ else
+ {
+ await child.RefreshMetadata(cancellationToken).ConfigureAwait(false);
+ }
}
}
@@ -1274,7 +1278,7 @@ namespace Emby.Server.Implementations.Library
return ItemIsVisible(item, user) ? item : null;
}
- public List<BaseItem> GetItemList(InternalItemsQuery query, bool allowExternalContent)
+ public IReadOnlyList<BaseItem> GetItemList(InternalItemsQuery query, bool allowExternalContent)
{
if (query.Recursive && !query.ParentId.IsEmpty())
{
@@ -1300,7 +1304,7 @@ namespace Emby.Server.Implementations.Library
return itemList;
}
- public List<BaseItem> GetItemList(InternalItemsQuery query)
+ public IReadOnlyList<BaseItem> GetItemList(InternalItemsQuery query)
{
return GetItemList(query, true);
}
@@ -1324,7 +1328,7 @@ namespace Emby.Server.Implementations.Library
return _itemRepository.GetCount(query);
}
- public List<BaseItem> GetItemList(InternalItemsQuery query, List<BaseItem> parents)
+ public IReadOnlyList<BaseItem> GetItemList(InternalItemsQuery query, List<BaseItem> parents)
{
SetTopParentIdsOrAncestors(query, parents);
@@ -1357,7 +1361,7 @@ namespace Emby.Server.Implementations.Library
_itemRepository.GetItemList(query));
}
- public List<Guid> GetItemIds(InternalItemsQuery query)
+ public IReadOnlyList<Guid> GetItemIds(InternalItemsQuery query)
{
if (query.User is not null)
{
@@ -1955,13 +1959,13 @@ namespace Emby.Server.Implementations.Library
/// <inheritdoc />
public async Task UpdateItemsAsync(IReadOnlyList<BaseItem> items, BaseItem parent, ItemUpdateType updateReason, CancellationToken cancellationToken)
{
+ _itemRepository.SaveItems(items, cancellationToken);
+
foreach (var item in items)
{
await RunMetadataSavers(item, updateReason).ConfigureAwait(false);
}
- _itemRepository.SaveItems(items, cancellationToken);
-
if (ItemUpdated is not null)
{
foreach (var item in items)
@@ -2736,12 +2740,12 @@ namespace Emby.Server.Implementations.Library
return path;
}
- public List<PersonInfo> GetPeople(InternalPeopleQuery query)
+ public IReadOnlyList<PersonInfo> GetPeople(InternalPeopleQuery query)
{
- return _itemRepository.GetPeople(query);
+ return _peopleRepository.GetPeople(query);
}
- public List<PersonInfo> GetPeople(BaseItem item)
+ public IReadOnlyList<PersonInfo> GetPeople(BaseItem item)
{
if (item.SupportsPeople)
{
@@ -2756,12 +2760,12 @@ namespace Emby.Server.Implementations.Library
}
}
- return new List<PersonInfo>();
+ return [];
}
- public List<Person> GetPeopleItems(InternalPeopleQuery query)
+ public IReadOnlyList<Person> GetPeopleItems(InternalPeopleQuery query)
{
- return _itemRepository.GetPeopleNames(query)
+ return _peopleRepository.GetPeopleNames(query)
.Select(i =>
{
try
@@ -2779,9 +2783,9 @@ namespace Emby.Server.Implementations.Library
.ToList()!; // null values are filtered out
}
- public List<string> GetPeopleNames(InternalPeopleQuery query)
+ public IReadOnlyList<string> GetPeopleNames(InternalPeopleQuery query)
{
- return _itemRepository.GetPeopleNames(query);
+ return _peopleRepository.GetPeopleNames(query);
}
public void UpdatePeople(BaseItem item, List<PersonInfo> people)
@@ -2790,16 +2794,17 @@ namespace Emby.Server.Implementations.Library
}
/// <inheritdoc />
- public async Task UpdatePeopleAsync(BaseItem item, List<PersonInfo> people, CancellationToken cancellationToken)
+ public async Task UpdatePeopleAsync(BaseItem item, IReadOnlyList<PersonInfo> people, CancellationToken cancellationToken)
{
if (!item.SupportsPeople)
{
return;
}
- _itemRepository.UpdatePeople(item.Id, people);
if (people is not null)
{
+ people = people.Where(e => e is not null).ToArray();
+ _peopleRepository.UpdatePeople(item.Id, people);
await SavePeopleMetadataAsync(people, cancellationToken).ConfigureAwait(false);
}
}
@@ -2914,14 +2919,13 @@ namespace Emby.Server.Implementations.Library
private async Task SavePeopleMetadataAsync(IEnumerable<PersonInfo> people, CancellationToken cancellationToken)
{
- List<BaseItem>? personsToSave = null;
-
foreach (var person in people)
{
cancellationToken.ThrowIfCancellationRequested();
var itemUpdateType = ItemUpdateType.MetadataDownload;
var saveEntity = false;
+ var createEntity = false;
var personEntity = GetPerson(person.Name);
if (personEntity is null)
@@ -2938,6 +2942,7 @@ namespace Emby.Server.Implementations.Library
personEntity.PresentationUniqueKey = personEntity.CreatePresentationUniqueKey();
saveEntity = true;
+ createEntity = true;
}
foreach (var id in person.ProviderIds)
@@ -2965,15 +2970,15 @@ namespace Emby.Server.Implementations.Library
if (saveEntity)
{
- (personsToSave ??= new()).Add(personEntity);
+ if (createEntity)
+ {
+ CreateItems([personEntity], null, CancellationToken.None);
+ }
+
await RunMetadataSavers(personEntity, itemUpdateType).ConfigureAwait(false);
+ CreateItems([personEntity], null, CancellationToken.None);
}
}
-
- if (personsToSave is not null)
- {
- CreateItems(personsToSave, null, CancellationToken.None);
- }
}
private void StartScanInBackground()
@@ -3027,7 +3032,7 @@ namespace Emby.Server.Implementations.Library
{
var libraryOptions = CollectionFolder.GetLibraryOptions(virtualFolderPath);
- libraryOptions.PathInfos = [..libraryOptions.PathInfos, pathInfo];
+ libraryOptions.PathInfos = [.. libraryOptions.PathInfos, pathInfo];
SyncLibraryOptionsToLocations(virtualFolderPath, libraryOptions);