aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Controller
diff options
context:
space:
mode:
Diffstat (limited to 'MediaBrowser.Controller')
-rw-r--r--MediaBrowser.Controller/Entities/AggregateFolder.cs5
-rw-r--r--MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs2
-rw-r--r--MediaBrowser.Controller/Entities/BaseItem.cs35
-rw-r--r--MediaBrowser.Controller/Entities/BaseItemExtensions.cs10
-rw-r--r--MediaBrowser.Controller/Entities/Extensions.cs2
-rw-r--r--MediaBrowser.Controller/Entities/Folder.cs20
-rw-r--r--MediaBrowser.Controller/Entities/PeopleHelper.cs5
-rw-r--r--MediaBrowser.Controller/IO/FileData.cs5
-rw-r--r--MediaBrowser.Controller/Lyrics/ILyricManager.cs24
-rw-r--r--MediaBrowser.Controller/Lyrics/ILyricProvider.cs36
-rw-r--r--MediaBrowser.Controller/Lyrics/LyricInfo.cs49
-rw-r--r--MediaBrowser.Controller/Lyrics/LyricLine.cs28
-rw-r--r--MediaBrowser.Controller/Lyrics/LyricMetadata.cs54
-rw-r--r--MediaBrowser.Controller/Lyrics/LyricResponse.cs20
-rw-r--r--MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs10
-rw-r--r--MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs1
-rw-r--r--MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs10
-rw-r--r--MediaBrowser.Controller/Net/ISessionContext.cs20
-rw-r--r--MediaBrowser.Controller/Net/IWebSocketConnection.cs1
-rw-r--r--MediaBrowser.Controller/Playlists/Playlist.cs1
-rw-r--r--MediaBrowser.Controller/Providers/ICustomMetadataProvider.cs6
21 files changed, 236 insertions, 108 deletions
diff --git a/MediaBrowser.Controller/Entities/AggregateFolder.cs b/MediaBrowser.Controller/Entities/AggregateFolder.cs
index 77a857b78..e671e5c71 100644
--- a/MediaBrowser.Controller/Entities/AggregateFolder.cs
+++ b/MediaBrowser.Controller/Entities/AggregateFolder.cs
@@ -171,10 +171,7 @@ namespace MediaBrowser.Controller.Entities
/// <exception cref="ArgumentNullException">Throws if child is null.</exception>
public void AddVirtualChild(BaseItem child)
{
- if (child == null)
- {
- throw new ArgumentNullException(nameof(child));
- }
+ ArgumentNullException.ThrowIfNull(child);
_virtualChildren.Add(child);
}
diff --git a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs
index bd397bdd1..6555de855 100644
--- a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs
+++ b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs
@@ -54,7 +54,7 @@ namespace MediaBrowser.Controller.Entities.Audio
public string AlbumArtist => AlbumArtists.FirstOrDefault();
[JsonIgnore]
- public override bool SupportsPeople => false;
+ public override bool SupportsPeople => true;
/// <summary>
/// Gets the tracks.
diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs
index 9461b01e3..41fce67fa 100644
--- a/MediaBrowser.Controller/Entities/BaseItem.cs
+++ b/MediaBrowser.Controller/Entities/BaseItem.cs
@@ -1101,10 +1101,7 @@ namespace MediaBrowser.Controller.Entities
private MediaSourceInfo GetVersionInfo(bool enablePathSubstitution, BaseItem item, MediaSourceType type)
{
- if (item == null)
- {
- throw new ArgumentNullException(nameof(item));
- }
+ ArgumentNullException.ThrowIfNull(item);
var protocol = item.PathProtocol;
@@ -1544,10 +1541,7 @@ namespace MediaBrowser.Controller.Entities
/// <exception cref="ArgumentNullException">If user is null.</exception>
public bool IsParentalAllowed(User user)
{
- if (user == null)
- {
- throw new ArgumentNullException(nameof(user));
- }
+ ArgumentNullException.ThrowIfNull(user);
if (!IsVisibleViaTags(user))
{
@@ -1667,10 +1661,7 @@ namespace MediaBrowser.Controller.Entities
/// <exception cref="ArgumentNullException"><paramref name="user" /> is <c>null</c>.</exception>
public virtual bool IsVisible(User user)
{
- if (user == null)
- {
- throw new ArgumentNullException(nameof(user));
- }
+ ArgumentNullException.ThrowIfNull(user);
return IsParentalAllowed(user);
}
@@ -1842,10 +1833,7 @@ namespace MediaBrowser.Controller.Entities
DateTime? datePlayed,
bool resetPosition)
{
- if (user == null)
- {
- throw new ArgumentNullException(nameof(user));
- }
+ ArgumentNullException.ThrowIfNull(user);
var data = UserDataManager.GetUserData(user, this);
@@ -1876,10 +1864,7 @@ namespace MediaBrowser.Controller.Entities
/// <exception cref="ArgumentNullException">Throws if user is null.</exception>
public virtual void MarkUnplayed(User user)
{
- if (user == null)
- {
- throw new ArgumentNullException(nameof(user));
- }
+ ArgumentNullException.ThrowIfNull(user);
var data = UserDataManager.GetUserData(user, this);
@@ -2110,10 +2095,7 @@ namespace MediaBrowser.Controller.Entities
/// <returns>Image index.</returns>
public int GetImageIndex(ItemImageInfo image)
{
- if (image == null)
- {
- throw new ArgumentNullException(nameof(image));
- }
+ ArgumentNullException.ThrowIfNull(image);
if (image.Type == ImageType.Chapter)
{
@@ -2320,10 +2302,7 @@ namespace MediaBrowser.Controller.Entities
public virtual bool IsUnplayed(User user)
{
- if (user == null)
- {
- throw new ArgumentNullException(nameof(user));
- }
+ ArgumentNullException.ThrowIfNull(user);
var userdata = UserDataManager.GetUserData(user, this);
diff --git a/MediaBrowser.Controller/Entities/BaseItemExtensions.cs b/MediaBrowser.Controller/Entities/BaseItemExtensions.cs
index e0583e630..948eb4375 100644
--- a/MediaBrowser.Controller/Entities/BaseItemExtensions.cs
+++ b/MediaBrowser.Controller/Entities/BaseItemExtensions.cs
@@ -71,15 +71,9 @@ namespace MediaBrowser.Controller.Entities
where T : BaseItem
where TU : BaseItem
{
- if (source == null)
- {
- throw new ArgumentNullException(nameof(source));
- }
+ ArgumentNullException.ThrowIfNull(source);
- if (dest == null)
- {
- throw new ArgumentNullException(nameof(dest));
- }
+ ArgumentNullException.ThrowIfNull(dest);
var destProps = typeof(TU).GetProperties().Where(x => x.CanWrite).ToList();
diff --git a/MediaBrowser.Controller/Entities/Extensions.cs b/MediaBrowser.Controller/Entities/Extensions.cs
index 14534aa50..1acb92fdc 100644
--- a/MediaBrowser.Controller/Entities/Extensions.cs
+++ b/MediaBrowser.Controller/Entities/Extensions.cs
@@ -17,7 +17,7 @@ namespace MediaBrowser.Controller.Entities
/// <param name="url">Trailer URL.</param>
public static void AddTrailerUrl(this BaseItem item, string url)
{
- ArgumentNullException.ThrowIfNull(url, nameof(url));
+ ArgumentNullException.ThrowIfNull(url);
if (url.Length == 0)
{
diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs
index 92d12a86c..808f91810 100644
--- a/MediaBrowser.Controller/Entities/Folder.cs
+++ b/MediaBrowser.Controller/Entities/Folder.cs
@@ -1023,10 +1023,7 @@ namespace MediaBrowser.Controller.Entities
IServerConfigurationManager configurationManager,
ICollectionManager collectionManager)
{
- if (items == null)
- {
- throw new ArgumentNullException(nameof(items));
- }
+ ArgumentNullException.ThrowIfNull(items);
if (CollapseBoxSetItems(query, queryParent, user, configurationManager))
{
@@ -1273,20 +1270,14 @@ namespace MediaBrowser.Controller.Entities
public List<BaseItem> GetChildren(User user, bool includeLinkedChildren)
{
- if (user == null)
- {
- throw new ArgumentNullException(nameof(user));
- }
+ ArgumentNullException.ThrowIfNull(user);
return GetChildren(user, includeLinkedChildren, null);
}
public virtual List<BaseItem> GetChildren(User user, bool includeLinkedChildren, InternalItemsQuery query)
{
- if (user == null)
- {
- throw new ArgumentNullException(nameof(user));
- }
+ ArgumentNullException.ThrowIfNull(user);
// the true root should return our users root folder children
if (IsPhysicalRoot)
@@ -1367,10 +1358,7 @@ namespace MediaBrowser.Controller.Entities
public virtual IEnumerable<BaseItem> GetRecursiveChildren(User user, InternalItemsQuery query)
{
- if (user == null)
- {
- throw new ArgumentNullException(nameof(user));
- }
+ ArgumentNullException.ThrowIfNull(user);
var result = new Dictionary<Guid, BaseItem>();
diff --git a/MediaBrowser.Controller/Entities/PeopleHelper.cs b/MediaBrowser.Controller/Entities/PeopleHelper.cs
index 687ce1ec8..8571bfcea 100644
--- a/MediaBrowser.Controller/Entities/PeopleHelper.cs
+++ b/MediaBrowser.Controller/Entities/PeopleHelper.cs
@@ -11,10 +11,7 @@ namespace MediaBrowser.Controller.Entities
{
public static void AddPerson(List<PersonInfo> people, PersonInfo person)
{
- if (person == null)
- {
- throw new ArgumentNullException(nameof(person));
- }
+ ArgumentNullException.ThrowIfNull(person);
if (string.IsNullOrEmpty(person.Name))
{
diff --git a/MediaBrowser.Controller/IO/FileData.cs b/MediaBrowser.Controller/IO/FileData.cs
index 2429ac42d..71feae536 100644
--- a/MediaBrowser.Controller/IO/FileData.cs
+++ b/MediaBrowser.Controller/IO/FileData.cs
@@ -40,10 +40,7 @@ namespace MediaBrowser.Controller.IO
throw new ArgumentNullException(nameof(path));
}
- if (args == null)
- {
- throw new ArgumentNullException(nameof(args));
- }
+ ArgumentNullException.ThrowIfNull(args);
var entries = directoryService.GetFileSystemEntries(path);
diff --git a/MediaBrowser.Controller/Lyrics/ILyricManager.cs b/MediaBrowser.Controller/Lyrics/ILyricManager.cs
new file mode 100644
index 000000000..bb93e1e4c
--- /dev/null
+++ b/MediaBrowser.Controller/Lyrics/ILyricManager.cs
@@ -0,0 +1,24 @@
+using System.Threading.Tasks;
+using MediaBrowser.Controller.Entities;
+
+namespace MediaBrowser.Controller.Lyrics;
+
+/// <summary>
+/// Interface ILyricManager.
+/// </summary>
+public interface ILyricManager
+{
+ /// <summary>
+ /// Gets the lyrics.
+ /// </summary>
+ /// <param name="item">The media item.</param>
+ /// <returns>A task representing found lyrics the passed item.</returns>
+ Task<LyricResponse?> GetLyrics(BaseItem item);
+
+ /// <summary>
+ /// Checks if requested item has a matching local lyric file.
+ /// </summary>
+ /// <param name="item">The media item.</param>
+ /// <returns>True if item has a matching lyric file; otherwise false.</returns>
+ bool HasLyricFile(BaseItem item);
+}
diff --git a/MediaBrowser.Controller/Lyrics/ILyricProvider.cs b/MediaBrowser.Controller/Lyrics/ILyricProvider.cs
new file mode 100644
index 000000000..2a04c6152
--- /dev/null
+++ b/MediaBrowser.Controller/Lyrics/ILyricProvider.cs
@@ -0,0 +1,36 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Resolvers;
+
+namespace MediaBrowser.Controller.Lyrics;
+
+/// <summary>
+/// Interface ILyricsProvider.
+/// </summary>
+public interface ILyricProvider
+{
+ /// <summary>
+ /// Gets a value indicating the provider name.
+ /// </summary>
+ string Name { get; }
+
+ /// <summary>
+ /// Gets the priority.
+ /// </summary>
+ /// <value>The priority.</value>
+ ResolverPriority Priority { get; }
+
+ /// <summary>
+ /// Gets the supported media types for this provider.
+ /// </summary>
+ /// <value>The supported media types.</value>
+ IReadOnlyCollection<string> SupportedMediaTypes { get; }
+
+ /// <summary>
+ /// Gets the lyrics.
+ /// </summary>
+ /// <param name="item">The media item.</param>
+ /// <returns>A task representing found lyrics.</returns>
+ Task<LyricResponse?> GetLyrics(BaseItem item);
+}
diff --git a/MediaBrowser.Controller/Lyrics/LyricInfo.cs b/MediaBrowser.Controller/Lyrics/LyricInfo.cs
new file mode 100644
index 000000000..6ec6df582
--- /dev/null
+++ b/MediaBrowser.Controller/Lyrics/LyricInfo.cs
@@ -0,0 +1,49 @@
+using System;
+using System.IO;
+using Jellyfin.Extensions;
+
+namespace MediaBrowser.Controller.Lyrics;
+
+/// <summary>
+/// Lyric helper methods.
+/// </summary>
+public static class LyricInfo
+{
+ /// <summary>
+ /// Gets matching lyric file for a requested item.
+ /// </summary>
+ /// <param name="lyricProvider">The lyricProvider interface to use.</param>
+ /// <param name="itemPath">Path of requested item.</param>
+ /// <returns>Lyric file path if passed lyric provider's supported media type is found; otherwise, null.</returns>
+ public static string? GetLyricFilePath(this ILyricProvider lyricProvider, string itemPath)
+ {
+ // Ensure we have a provider
+ if (lyricProvider is null)
+ {
+ return null;
+ }
+
+ // Ensure the path to the item is not null
+ string? itemDirectoryPath = Path.GetDirectoryName(itemPath);
+ if (itemDirectoryPath is null)
+ {
+ return null;
+ }
+
+ // Ensure the directory path exists
+ if (!Directory.Exists(itemDirectoryPath))
+ {
+ return null;
+ }
+
+ foreach (var lyricFilePath in Directory.GetFiles(itemDirectoryPath, $"{Path.GetFileNameWithoutExtension(itemPath)}.*"))
+ {
+ if (lyricProvider.SupportedMediaTypes.Contains(Path.GetExtension(lyricFilePath.AsSpan())[1..], StringComparison.OrdinalIgnoreCase))
+ {
+ return lyricFilePath;
+ }
+ }
+
+ return null;
+ }
+}
diff --git a/MediaBrowser.Controller/Lyrics/LyricLine.cs b/MediaBrowser.Controller/Lyrics/LyricLine.cs
new file mode 100644
index 000000000..c406f92fc
--- /dev/null
+++ b/MediaBrowser.Controller/Lyrics/LyricLine.cs
@@ -0,0 +1,28 @@
+namespace MediaBrowser.Controller.Lyrics;
+
+/// <summary>
+/// Lyric model.
+/// </summary>
+public class LyricLine
+{
+ /// <summary>
+ /// Initializes a new instance of the <see cref="LyricLine"/> class.
+ /// </summary>
+ /// <param name="text">The lyric text.</param>
+ /// <param name="start">The lyric start time in ticks.</param>
+ public LyricLine(string text, long? start = null)
+ {
+ Text = text;
+ Start = start;
+ }
+
+ /// <summary>
+ /// Gets the text of this lyric line.
+ /// </summary>
+ public string Text { get; }
+
+ /// <summary>
+ /// Gets the start time in ticks.
+ /// </summary>
+ public long? Start { get; }
+}
diff --git a/MediaBrowser.Controller/Lyrics/LyricMetadata.cs b/MediaBrowser.Controller/Lyrics/LyricMetadata.cs
new file mode 100644
index 000000000..6091ede52
--- /dev/null
+++ b/MediaBrowser.Controller/Lyrics/LyricMetadata.cs
@@ -0,0 +1,54 @@
+using System;
+
+namespace MediaBrowser.Controller.Lyrics;
+
+/// <summary>
+/// LyricMetadata model.
+/// </summary>
+public class LyricMetadata
+{
+ /// <summary>
+ /// Gets or sets the song artist.
+ /// </summary>
+ public string? Artist { get; set; }
+
+ /// <summary>
+ /// Gets or sets the album this song is on.
+ /// </summary>
+ public string? Album { get; set; }
+
+ /// <summary>
+ /// Gets or sets the title of the song.
+ /// </summary>
+ public string? Title { get; set; }
+
+ /// <summary>
+ /// Gets or sets the author of the lyric data.
+ /// </summary>
+ public string? Author { get; set; }
+
+ /// <summary>
+ /// Gets or sets the length of the song in ticks.
+ /// </summary>
+ public long? Length { get; set; }
+
+ /// <summary>
+ /// Gets or sets who the LRC file was created by.
+ /// </summary>
+ public string? By { get; set; }
+
+ /// <summary>
+ /// Gets or sets the lyric offset compared to audio in ticks.
+ /// </summary>
+ public long? Offset { get; set; }
+
+ /// <summary>
+ /// Gets or sets the software used to create the LRC file.
+ /// </summary>
+ public string? Creator { get; set; }
+
+ /// <summary>
+ /// Gets or sets the version of the creator used.
+ /// </summary>
+ public string? Version { get; set; }
+}
diff --git a/MediaBrowser.Controller/Lyrics/LyricResponse.cs b/MediaBrowser.Controller/Lyrics/LyricResponse.cs
new file mode 100644
index 000000000..0d52b5ec5
--- /dev/null
+++ b/MediaBrowser.Controller/Lyrics/LyricResponse.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+
+namespace MediaBrowser.Controller.Lyrics;
+
+/// <summary>
+/// LyricResponse model.
+/// </summary>
+public class LyricResponse
+{
+ /// <summary>
+ /// Gets or sets Metadata for the lyrics.
+ /// </summary>
+ public LyricMetadata Metadata { get; set; } = new();
+
+ /// <summary>
+ /// Gets or sets a collection of individual lyric lines.
+ /// </summary>
+ public IReadOnlyList<LyricLine> Lyrics { get; set; } = Array.Empty<LyricLine>();
+}
diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
index 42c5517f9..d0362b128 100644
--- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
+++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
@@ -5105,15 +5105,9 @@ namespace MediaBrowser.Controller.MediaEncoding
MediaSourceInfo mediaSource,
string requestedUrl)
{
- if (state == null)
- {
- throw new ArgumentNullException(nameof(state));
- }
+ ArgumentNullException.ThrowIfNull(state);
- if (mediaSource == null)
- {
- throw new ArgumentNullException(nameof(mediaSource));
- }
+ ArgumentNullException.ThrowIfNull(mediaSource);
var path = mediaSource.Path;
var protocol = mediaSource.Protocol;
diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs b/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs
index 491662861..c9625cf1d 100644
--- a/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs
+++ b/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs
@@ -6,7 +6,6 @@ using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
-using System.Text.Json.Serialization;
using Jellyfin.Data.Entities;
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Drawing;
diff --git a/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs b/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs
index eadc09fd4..647de5003 100644
--- a/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs
+++ b/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs
@@ -38,10 +38,7 @@ namespace MediaBrowser.Controller.Net
protected BasePeriodicWebSocketListener(ILogger<BasePeriodicWebSocketListener<TReturnDataType, TStateType>> logger)
{
- if (logger == null)
- {
- throw new ArgumentNullException(nameof(logger));
- }
+ ArgumentNullException.ThrowIfNull(logger);
Logger = logger;
}
@@ -77,10 +74,7 @@ namespace MediaBrowser.Controller.Net
/// <returns>Task.</returns>
public Task ProcessMessageAsync(WebSocketMessageInfo message)
{
- if (message == null)
- {
- throw new ArgumentNullException(nameof(message));
- }
+ ArgumentNullException.ThrowIfNull(message);
if (message.MessageType == StartType)
{
diff --git a/MediaBrowser.Controller/Net/ISessionContext.cs b/MediaBrowser.Controller/Net/ISessionContext.cs
deleted file mode 100644
index b48181b3f..000000000
--- a/MediaBrowser.Controller/Net/ISessionContext.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-#pragma warning disable CS1591
-
-using System.Threading.Tasks;
-using Jellyfin.Data.Entities;
-using MediaBrowser.Controller.Session;
-using Microsoft.AspNetCore.Http;
-
-namespace MediaBrowser.Controller.Net
-{
- public interface ISessionContext
- {
- Task<SessionInfo> GetSession(object requestContext);
-
- Task<User?> GetUser(object requestContext);
-
- Task<SessionInfo> GetSession(HttpContext requestContext);
-
- Task<User?> GetUser(HttpContext requestContext);
- }
-}
diff --git a/MediaBrowser.Controller/Net/IWebSocketConnection.cs b/MediaBrowser.Controller/Net/IWebSocketConnection.cs
index 43c7ce370..4f2492b89 100644
--- a/MediaBrowser.Controller/Net/IWebSocketConnection.cs
+++ b/MediaBrowser.Controller/Net/IWebSocketConnection.cs
@@ -6,7 +6,6 @@ using System.Net.WebSockets;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Model.Net;
-using Microsoft.AspNetCore.Http;
namespace MediaBrowser.Controller.Net
{
diff --git a/MediaBrowser.Controller/Playlists/Playlist.cs b/MediaBrowser.Controller/Playlists/Playlist.cs
index 828ecb2c5..7ae9ff746 100644
--- a/MediaBrowser.Controller/Playlists/Playlist.cs
+++ b/MediaBrowser.Controller/Playlists/Playlist.cs
@@ -4,7 +4,6 @@
using System;
using System.Collections.Generic;
-using System.Globalization;
using System.IO;
using System.Linq;
using System.Text.Json.Serialization;
diff --git a/MediaBrowser.Controller/Providers/ICustomMetadataProvider.cs b/MediaBrowser.Controller/Providers/ICustomMetadataProvider.cs
index 32a9cbef2..14428df5b 100644
--- a/MediaBrowser.Controller/Providers/ICustomMetadataProvider.cs
+++ b/MediaBrowser.Controller/Providers/ICustomMetadataProvider.cs
@@ -18,9 +18,9 @@ namespace MediaBrowser.Controller.Providers
/// Fetches the metadata asynchronously.
/// </summary>
/// <param name="item">The item.</param>
- /// <param name="options">The options.</param>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <returns>Task{ItemUpdateType}.</returns>
+ /// <param name="options">The <see cref="MetadataRefreshOptions"/>.</param>
+ /// <param name="cancellationToken">The <see cref="CancellationToken"/>.</param>
+ /// <returns>A <see cref="Task"/> fetching the <see cref="ItemUpdateType"/>.</returns>
Task<ItemUpdateType> FetchAsync(TItemType item, MetadataRefreshOptions options, CancellationToken cancellationToken);
}
}