This commit is contained in:
Francesco Bellini 2024-04-25 09:15:44 -04:00 committed by GitHub
commit 2b6eef4cec
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 225 additions and 0 deletions

View File

@ -9,6 +9,7 @@ using MediaBrowser.Common.Configuration;
using MediaBrowser.Controller.Collections;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Configuration;
@ -210,6 +211,7 @@ namespace Emby.Server.Implementations.Collections
List<BaseItem>? itemList = null;
var linkedChildrenList = collection.GetLinkedChildren();
var itemListForRunTimeTicks = collection.GetLinkedChildren();
var currentLinkedChildrenIds = linkedChildrenList.Select(i => i.Id).ToList();
foreach (var id in ids)
@ -226,6 +228,8 @@ namespace Emby.Server.Implementations.Collections
(itemList ??= new()).Add(item);
linkedChildrenList.Add(item);
GetItemsForRunTimeTicksCount(item).ToList<BaseItem>().ForEach((i) => itemListForRunTimeTicks.Add(i));
}
}
@ -243,6 +247,8 @@ namespace Emby.Server.Implementations.Collections
collection.LinkedChildren = newChildren;
collection.UpdateRatingToItems(linkedChildrenList);
collection.UpdateRunTimeTicksToItems(itemListForRunTimeTicks);
await collection.UpdateToRepositoryAsync(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false);
refreshOptions.ForceSave = true;
@ -291,6 +297,30 @@ namespace Emby.Server.Implementations.Collections
collection.LinkedChildren = collection.LinkedChildren.Except(list).ToArray();
}
var actualItems = new List<BaseItem>();
foreach (var child in collection.LinkedChildren)
{
if (child.ItemId.HasValue)
{
var item = _libraryManager.GetItemById((Guid)child.ItemId);
if (item != null)
{
GetItemsForRunTimeTicksCount(item).ToList<BaseItem>().ForEach((i) => actualItems.Add(i));
}
}
}
if (actualItems.Count > 0)
{
collection.UpdateRunTimeTicksToItems(actualItems);
}
else
{
collection.RunTimeTicks = 0;
}
await collection.UpdateToRepositoryAsync(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false);
_providerManager.QueueRefresh(
collection.Id,
@ -363,5 +393,41 @@ namespace Emby.Server.Implementations.Collections
return results.Values;
}
/// <inheritdoc />
public IEnumerable<BaseItem> GetItemsForRunTimeTicksCount(BaseItem item)
{
var itemsForCount = new List<BaseItem>();
if (item.GetType() == typeof(Series))
{
var seasons = _libraryManager.GetItemList(
new InternalItemsQuery()
{
ParentId = item.Id,
SeriesPresentationUniqueKey = item.PresentationUniqueKey
}).OfType<Season>();
foreach (var season in seasons.ToList())
{
var episodes = _libraryManager.GetItemList(
new InternalItemsQuery()
{
ParentId = season.Id
}).OfType<Episode>();
foreach (var e in episodes)
{
var episode = _libraryManager.GetItemById(e.Id);
itemsForCount.Add(episode);
}
}
}
else
{
itemsForCount.Add(item);
}
return itemsForCount;
}
}
}

View File

@ -108,6 +108,8 @@
"TaskRefreshLibrary": "Scan Media Library",
"TaskRefreshChapterImagesDescription": "Creates thumbnails for videos that have chapters.",
"TaskRefreshChapterImages": "Extract Chapter Images",
"TaskCollectionDurationDescription": "Calculate the total duration of all collections.",
"TaskCollectionDuration": "Calculate collections duration",
"TaskCleanCacheDescription": "Deletes cache files no longer needed by the system.",
"TaskCleanCache": "Clean Cache Directory",
"TasksChannelsCategory": "Internet Channels",

View File

@ -106,6 +106,8 @@
"TaskCleanCacheDescription": "Deletes cache files no longer needed by the system.",
"TaskRefreshChapterImages": "Extract Chapter Images",
"TaskRefreshChapterImagesDescription": "Creates thumbnails for videos that have chapters.",
"TaskCollectionDurationDescription": "Calculate the total duration of all collections.",
"TaskCollectionDuration": "Calculate collections duration",
"TaskRefreshLibrary": "Scan Media Library",
"TaskRefreshLibraryDescription": "Scans your media library for new files and refreshes metadata.",
"TaskCleanLogs": "Clean Log Directory",

View File

@ -108,6 +108,8 @@
"TaskRefreshLibrary": "Scan Librerie",
"TaskRefreshChapterImagesDescription": "Crea le thumbnail per i video che hanno capitoli.",
"TaskRefreshChapterImages": "Estrai immagini capitolo",
"TaskCollectionDurationDescription": "Calcola la durata totale di tutte le collezioni.",
"TaskCollectionDuration": "Calcola durata collezioni",
"TaskCleanCacheDescription": "Cancella i file di cache non più necessari al sistema.",
"TaskCleanCache": "Pulisci la directory della cache",
"TasksChannelsCategory": "Canali su Internet",

View File

@ -0,0 +1,123 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Controller.Collections;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.Tasks;
namespace Emby.Server.Implementations.ScheduledTasks.Tasks
{
/// <summary>
/// Class CollectionDurationTask.
/// </summary>
public class CollectionDurationTask : IScheduledTask
{
/// <summary>
/// The _library manager.
/// </summary>
private readonly ILibraryManager _libraryManager;
private readonly ICollectionManager _collectionManager;
private readonly ILocalizationManager _localization;
/// <summary>
/// Initializes a new instance of the <see cref="CollectionDurationTask" /> class.
/// </summary>
/// <param name="libraryManager">The library manager.</param>.
/// <param name="collectionManager">The collection manager.</param>.
/// <param name="localization">The localization manager.</param>
public CollectionDurationTask(
ILibraryManager libraryManager,
ICollectionManager collectionManager,
ILocalizationManager localization)
{
_libraryManager = libraryManager;
_collectionManager = collectionManager;
_localization = localization;
}
/// <inheritdoc />
public string Name => _localization.GetLocalizedString("TaskCollectionDuration");
/// <inheritdoc />
public string Description => _localization.GetLocalizedString("TaskCollectionDurationDescription");
/// <inheritdoc />
public string Category => _localization.GetLocalizedString("TasksLibraryCategory");
/// <inheritdoc />
public string Key => "CollectionDuration";
/// <inheritdoc />
public IEnumerable<TaskTriggerInfo> GetDefaultTriggers()
{
return new[]
{
new TaskTriggerInfo
{
Type = TaskTriggerInfo.TriggerDaily,
TimeOfDayTicks = TimeSpan.FromHours(4).Ticks,
MaxRuntimeTicks = TimeSpan.FromHours(5).Ticks
}
};
}
/// <inheritdoc />
public async Task ExecuteAsync(IProgress<double> progress, CancellationToken cancellationToken)
{
var collections = _libraryManager.GetItemList(new InternalItemsQuery
{
IsFolder = true,
Recursive = true,
SourceTypes = new SourceType[] { SourceType.Library },
})
.OfType<BoxSet>()
.ToList();
var numComplete = 0;
foreach (var collection in collections)
{
cancellationToken.ThrowIfCancellationRequested();
try
{
var collectionChildren = new List<BaseItem>();
foreach (var child in collection.LinkedChildren)
{
if (child.ItemId.HasValue)
{
var item = _libraryManager.GetItemById((Guid)child.ItemId);
if (item != null)
{
_collectionManager.GetItemsForRunTimeTicksCount(item).ToList<BaseItem>().ForEach((i) => collectionChildren.Add(i));
}
}
}
collection.UpdateRunTimeTicksToItems(collectionChildren);
await collection.UpdateToRepositoryAsync(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(true);
numComplete++;
double percent = numComplete;
percent /= collections.Count;
progress.Report(100 * percent);
}
catch (Exception)
{
break;
}
}
}
}
}

View File

@ -63,5 +63,12 @@ namespace MediaBrowser.Controller.Collections
/// <param name="createIfNeeded">Will create the collection folder on the storage if set to true.</param>
/// <returns>The folder instance referencing the collection storage.</returns>
Task<Folder?> GetCollectionsFolder(bool createIfNeeded);
/// <summary>
/// Get Items For RunTimeTicks Count.
/// </summary>
/// <param name="item">The item.</param>
/// <returns>IList{BaseItem}.</returns>
IEnumerable<BaseItem> GetItemsForRunTimeTicksCount(BaseItem item);
}
}

View File

@ -228,5 +228,28 @@ namespace MediaBrowser.Controller.Entities.Movies
return new[] { item };
}
/// <summary>
/// Updates the RunTimeTicks based on content and returns true or false indicating if it changed.
/// </summary>
/// <param name="children">Media children.</param>
/// <returns><c>true</c> if the total duration in ticks was updated; otherwise <c>false</c>.</returns>
public bool UpdateRunTimeTicksToItems(IList<BaseItem> children)
{
var currentRunTimeTicks = RunTimeTicks;
long ticks = 0;
foreach (var item in children)
{
if (item.RunTimeTicks != null && item.RunTimeTicks > 0)
{
ticks = ticks + (long)item.RunTimeTicks;
}
}
RunTimeTicks = ticks;
return currentRunTimeTicks != RunTimeTicks;
}
}
}