repo creation with initial code after cloning public repo
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
namespace MediaBrowser.Controller.Library
|
||||
{
|
||||
public class DeleteOptions
|
||||
{
|
||||
public DeleteOptions()
|
||||
{
|
||||
DeleteFromExternalProvider = true;
|
||||
}
|
||||
|
||||
public bool DeleteFileLocation { get; set; }
|
||||
|
||||
public bool DeleteFromExternalProvider { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using System.IO;
|
||||
|
||||
namespace MediaBrowser.Controller.Library
|
||||
{
|
||||
/// <summary>
|
||||
/// The direct live TV stream provider.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Deprecated.
|
||||
/// </remarks>
|
||||
public interface IDirectStreamProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the live stream, shared streams seek to the end of the file first.
|
||||
/// </summary>
|
||||
/// <returns>The stream.</returns>
|
||||
Stream GetStream();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
#nullable disable
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Jellyfin.Database.Implementations.Entities;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
|
||||
namespace MediaBrowser.Controller.Library
|
||||
{
|
||||
/// <summary>
|
||||
/// Class BaseIntroProvider.
|
||||
/// </summary>
|
||||
public interface IIntroProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the name.
|
||||
/// </summary>
|
||||
/// <value>The name.</value>
|
||||
string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the intros.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <returns>IEnumerable{System.String}.</returns>
|
||||
Task<IEnumerable<IntroInfo>> GetIntros(BaseItem item, User user);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Jellyfin.MediaEncoding.Keyframes;
|
||||
|
||||
namespace MediaBrowser.Controller.IO;
|
||||
|
||||
/// <summary>
|
||||
/// Interface IKeyframeManager.
|
||||
/// </summary>
|
||||
public interface IKeyframeManager
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the keyframe data.
|
||||
/// </summary>
|
||||
/// <param name="itemId">The item id.</param>
|
||||
/// <returns>The keyframe data.</returns>
|
||||
IReadOnlyList<KeyframeData> GetKeyframeData(Guid itemId);
|
||||
|
||||
/// <summary>
|
||||
/// Saves the keyframe data.
|
||||
/// </summary>
|
||||
/// <param name="itemId">The item id.</param>
|
||||
/// <param name="data">The keyframe data.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>The task object representing the asynchronous operation.</returns>
|
||||
Task SaveKeyframeDataAsync(Guid itemId, KeyframeData data, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Deletes the keyframe data.
|
||||
/// </summary>
|
||||
/// <param name="itemId">The item id.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>The task object representing the asynchronous operation.</returns>
|
||||
Task DeleteKeyframeDataAsync(Guid itemId, CancellationToken cancellationToken);
|
||||
}
|
||||
@@ -0,0 +1,671 @@
|
||||
#pragma warning disable CA1002, CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Jellyfin.Data.Enums;
|
||||
using Jellyfin.Database.Implementations.Entities;
|
||||
using Jellyfin.Database.Implementations.Enums;
|
||||
using MediaBrowser.Controller.Dto;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Controller.Resolvers;
|
||||
using MediaBrowser.Controller.Sorting;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using MediaBrowser.Model.Dto;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.IO;
|
||||
using MediaBrowser.Model.Querying;
|
||||
using Episode = MediaBrowser.Controller.Entities.TV.Episode;
|
||||
using Genre = MediaBrowser.Controller.Entities.Genre;
|
||||
using Person = MediaBrowser.Controller.Entities.Person;
|
||||
|
||||
namespace MediaBrowser.Controller.Library
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface ILibraryManager.
|
||||
/// </summary>
|
||||
public interface ILibraryManager
|
||||
{
|
||||
/// <summary>
|
||||
/// Occurs when [item added].
|
||||
/// </summary>
|
||||
event EventHandler<ItemChangeEventArgs>? ItemAdded;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when [item updated].
|
||||
/// </summary>
|
||||
event EventHandler<ItemChangeEventArgs>? ItemUpdated;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when [item removed].
|
||||
/// </summary>
|
||||
event EventHandler<ItemChangeEventArgs>? ItemRemoved;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the root folder.
|
||||
/// </summary>
|
||||
/// <value>The root folder.</value>
|
||||
AggregateFolder RootFolder { get; }
|
||||
|
||||
bool IsScanRunning { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Resolves the path.
|
||||
/// </summary>
|
||||
/// <param name="fileInfo">The file information.</param>
|
||||
/// <param name="parent">The parent.</param>
|
||||
/// <param name="directoryService">An instance of <see cref="IDirectoryService"/>.</param>
|
||||
/// <returns>BaseItem.</returns>
|
||||
BaseItem? ResolvePath(
|
||||
FileSystemMetadata fileInfo,
|
||||
Folder? parent = null,
|
||||
IDirectoryService? directoryService = null);
|
||||
|
||||
/// <summary>
|
||||
/// Resolves a set of files into a list of BaseItem.
|
||||
/// </summary>
|
||||
/// <param name="files">The list of tiles.</param>
|
||||
/// <param name="directoryService">Instance of the <see cref="IDirectoryService"/> interface.</param>
|
||||
/// <param name="parent">The parent folder.</param>
|
||||
/// <param name="libraryOptions">The library options.</param>
|
||||
/// <param name="collectionType">The collection type.</param>
|
||||
/// <returns>The items resolved from the paths.</returns>
|
||||
IEnumerable<BaseItem> ResolvePaths(
|
||||
IEnumerable<FileSystemMetadata> files,
|
||||
IDirectoryService directoryService,
|
||||
Folder parent,
|
||||
LibraryOptions libraryOptions,
|
||||
CollectionType? collectionType = null);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a Person.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the person.</param>
|
||||
/// <returns>Task{Person}.</returns>
|
||||
Person? GetPerson(string name);
|
||||
|
||||
/// <summary>
|
||||
/// Finds the by path.
|
||||
/// </summary>
|
||||
/// <param name="path">The path.</param>
|
||||
/// <param name="isFolder"><c>true</c> is the path is a directory; otherwise <c>false</c>.</param>
|
||||
/// <returns>BaseItem.</returns>
|
||||
BaseItem? FindByPath(string path, bool? isFolder);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the artist.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the artist.</param>
|
||||
/// <returns>Task{Artist}.</returns>
|
||||
MusicArtist GetArtist(string name);
|
||||
|
||||
MusicArtist GetArtist(string name, DtoOptions options);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a Studio.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the studio.</param>
|
||||
/// <returns>Task{Studio}.</returns>
|
||||
Studio GetStudio(string name);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a Genre.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the genre.</param>
|
||||
/// <returns>Task{Genre}.</returns>
|
||||
Genre GetGenre(string name);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the genre.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the music genre.</param>
|
||||
/// <returns>Task{MusicGenre}.</returns>
|
||||
MusicGenre GetMusicGenre(string name);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a Year.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>Task{Year}.</returns>
|
||||
/// <exception cref="ArgumentOutOfRangeException">Throws if year is invalid.</exception>
|
||||
Year GetYear(int value);
|
||||
|
||||
/// <summary>
|
||||
/// Validate and refresh the People sub-set of the IBN.
|
||||
/// The items are stored in the db but not loaded into memory until actually requested by an operation.
|
||||
/// </summary>
|
||||
/// <param name="progress">The progress.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task.</returns>
|
||||
Task ValidatePeopleAsync(IProgress<double> progress, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Reloads the root media folder.
|
||||
/// </summary>
|
||||
/// <param name="progress">The progress.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task.</returns>
|
||||
Task ValidateMediaLibrary(IProgress<double> progress, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Reloads the root media folder.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <param name="removeRoot">Is remove the library itself allowed.</param>
|
||||
/// <returns>Task.</returns>
|
||||
Task ValidateTopLibraryFolders(CancellationToken cancellationToken, bool removeRoot = false);
|
||||
|
||||
Task UpdateImagesAsync(BaseItem item, bool forceUpdate = false);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the default view.
|
||||
/// </summary>
|
||||
/// <returns>IEnumerable{VirtualFolderInfo}.</returns>
|
||||
List<VirtualFolderInfo> GetVirtualFolders();
|
||||
|
||||
List<VirtualFolderInfo> GetVirtualFolders(bool includeRefreshState);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the item by id.
|
||||
/// </summary>
|
||||
/// <param name="id">The id.</param>
|
||||
/// <returns>BaseItem.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="id"/> is <c>null</c>.</exception>
|
||||
BaseItem? GetItemById(Guid id);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the item by id, as T.
|
||||
/// </summary>
|
||||
/// <param name="id">The item id.</param>
|
||||
/// <typeparam name="T">The type of item.</typeparam>
|
||||
/// <returns>The item.</returns>
|
||||
T? GetItemById<T>(Guid id)
|
||||
where T : BaseItem;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the item by id, as T, and validates user access.
|
||||
/// </summary>
|
||||
/// <param name="id">The item id.</param>
|
||||
/// <param name="userId">The user id to validate against.</param>
|
||||
/// <typeparam name="T">The type of item.</typeparam>
|
||||
/// <returns>The item if found.</returns>
|
||||
public T? GetItemById<T>(Guid id, Guid userId)
|
||||
where T : BaseItem;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the item by id, as T, and validates user access.
|
||||
/// </summary>
|
||||
/// <param name="id">The item id.</param>
|
||||
/// <param name="user">The user to validate against.</param>
|
||||
/// <typeparam name="T">The type of item.</typeparam>
|
||||
/// <returns>The item if found.</returns>
|
||||
public T? GetItemById<T>(Guid id, User? user)
|
||||
where T : BaseItem;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the intros.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <returns>IEnumerable{System.String}.</returns>
|
||||
Task<IEnumerable<Video>> GetIntros(BaseItem item, User user);
|
||||
|
||||
/// <summary>
|
||||
/// Adds the parts.
|
||||
/// </summary>
|
||||
/// <param name="rules">The rules.</param>
|
||||
/// <param name="resolvers">The resolvers.</param>
|
||||
/// <param name="introProviders">The intro providers.</param>
|
||||
/// <param name="itemComparers">The item comparers.</param>
|
||||
/// <param name="postScanTasks">The post scan tasks.</param>
|
||||
void AddParts(
|
||||
IEnumerable<IResolverIgnoreRule> rules,
|
||||
IEnumerable<IItemResolver> resolvers,
|
||||
IEnumerable<IIntroProvider> introProviders,
|
||||
IEnumerable<IBaseItemComparer> itemComparers,
|
||||
IEnumerable<ILibraryPostScanTask> postScanTasks);
|
||||
|
||||
/// <summary>
|
||||
/// Sorts the specified items.
|
||||
/// </summary>
|
||||
/// <param name="items">The items.</param>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <param name="sortBy">The sort by.</param>
|
||||
/// <param name="sortOrder">The sort order.</param>
|
||||
/// <returns>IEnumerable{BaseItem}.</returns>
|
||||
IEnumerable<BaseItem> Sort(IEnumerable<BaseItem> items, User? user, IEnumerable<ItemSortBy> sortBy, SortOrder sortOrder);
|
||||
|
||||
IEnumerable<BaseItem> Sort(IEnumerable<BaseItem> items, User? user, IEnumerable<(ItemSortBy OrderBy, SortOrder SortOrder)> orderBy);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user root folder.
|
||||
/// </summary>
|
||||
/// <returns>UserRootFolder.</returns>
|
||||
Folder GetUserRootFolder();
|
||||
|
||||
/// <summary>
|
||||
/// Creates the item.
|
||||
/// </summary>
|
||||
/// <param name="item">Item to create.</param>
|
||||
/// <param name="parent">Parent of new item.</param>
|
||||
void CreateItem(BaseItem item, BaseItem? parent);
|
||||
|
||||
/// <summary>
|
||||
/// Creates the items.
|
||||
/// </summary>
|
||||
/// <param name="items">Items to create.</param>
|
||||
/// <param name="parent">Parent of new items.</param>
|
||||
/// <param name="cancellationToken">CancellationToken to use for operation.</param>
|
||||
void CreateItems(IReadOnlyList<BaseItem> items, BaseItem? parent, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Updates the item.
|
||||
/// </summary>
|
||||
/// <param name="items">Items to update.</param>
|
||||
/// <param name="parent">Parent of updated items.</param>
|
||||
/// <param name="updateReason">Reason for update.</param>
|
||||
/// <param name="cancellationToken">CancellationToken to use for operation.</param>
|
||||
/// <returns>Returns a Task that can be awaited.</returns>
|
||||
Task UpdateItemsAsync(IReadOnlyList<BaseItem> items, BaseItem parent, ItemUpdateType updateReason, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Updates the item.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="parent">The parent item.</param>
|
||||
/// <param name="updateReason">The update reason.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Returns a Task that can be awaited.</returns>
|
||||
Task UpdateItemAsync(BaseItem item, BaseItem parent, ItemUpdateType updateReason, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Reattaches the user data to the item.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>A task that represents the asynchronous reattachment operation.</returns>
|
||||
Task ReattachUserDataAsync(BaseItem item, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the item.
|
||||
/// </summary>
|
||||
/// <param name="id">The id.</param>
|
||||
/// <returns>BaseItem.</returns>
|
||||
BaseItem RetrieveItem(Guid id);
|
||||
|
||||
/// <summary>
|
||||
/// Finds the type of the collection.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <returns>System.String.</returns>
|
||||
CollectionType? GetContentType(BaseItem item);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the type of the inherited content.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <returns>System.String.</returns>
|
||||
CollectionType? GetInheritedContentType(BaseItem item);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the type of the configured content.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <returns>System.String.</returns>
|
||||
CollectionType? GetConfiguredContentType(BaseItem item);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the type of the configured content.
|
||||
/// </summary>
|
||||
/// <param name="path">The path.</param>
|
||||
/// <returns>System.String.</returns>
|
||||
CollectionType? GetConfiguredContentType(string path);
|
||||
|
||||
/// <summary>
|
||||
/// Normalizes the root path list.
|
||||
/// </summary>
|
||||
/// <param name="paths">The paths.</param>
|
||||
/// <returns>IEnumerable{System.String}.</returns>
|
||||
List<FileSystemMetadata> NormalizeRootPathList(IEnumerable<FileSystemMetadata> paths);
|
||||
|
||||
/// <summary>
|
||||
/// Registers the item.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
void RegisterItem(BaseItem item);
|
||||
|
||||
/// <summary>
|
||||
/// Deletes the item.
|
||||
/// </summary>
|
||||
/// <param name="item">Item to delete.</param>
|
||||
/// <param name="options">Options to use for deletion.</param>
|
||||
void DeleteItem(BaseItem item, DeleteOptions options);
|
||||
|
||||
/// <summary>
|
||||
/// Deletes items that are not having any children like Actors.
|
||||
/// </summary>
|
||||
/// <param name="items">Items to delete.</param>
|
||||
/// <remarks>In comparison to <see cref="DeleteItem(BaseItem, DeleteOptions, BaseItem, bool)"/> this method skips a lot of steps assuming there are no children to recusively delete nor does it define the special handling for channels and alike.</remarks>
|
||||
public void DeleteItemsUnsafeFast(IEnumerable<BaseItem> items);
|
||||
|
||||
/// <summary>
|
||||
/// Deletes the item.
|
||||
/// </summary>
|
||||
/// <param name="item">Item to delete.</param>
|
||||
/// <param name="options">Options to use for deletion.</param>
|
||||
/// <param name="notifyParentItem">Notify parent of deletion.</param>
|
||||
void DeleteItem(BaseItem item, DeleteOptions options, bool notifyParentItem);
|
||||
|
||||
/// <summary>
|
||||
/// Deletes the item.
|
||||
/// </summary>
|
||||
/// <param name="item">Item to delete.</param>
|
||||
/// <param name="options">Options to use for deletion.</param>
|
||||
/// <param name="parent">Parent of item.</param>
|
||||
/// <param name="notifyParentItem">Notify parent of deletion.</param>
|
||||
void DeleteItem(BaseItem item, DeleteOptions options, BaseItem parent, bool notifyParentItem);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the named view.
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="parentId">The parent identifier.</param>
|
||||
/// <param name="viewType">Type of the view.</param>
|
||||
/// <param name="sortName">Name of the sort.</param>
|
||||
/// <returns>The named view.</returns>
|
||||
UserView GetNamedView(
|
||||
User user,
|
||||
string name,
|
||||
Guid parentId,
|
||||
CollectionType? viewType,
|
||||
string sortName);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the named view.
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="viewType">Type of the view.</param>
|
||||
/// <param name="sortName">Name of the sort.</param>
|
||||
/// <returns>The named view.</returns>
|
||||
UserView GetNamedView(
|
||||
User user,
|
||||
string name,
|
||||
CollectionType? viewType,
|
||||
string sortName);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the named view.
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="viewType">Type of the view.</param>
|
||||
/// <param name="sortName">Name of the sort.</param>
|
||||
/// <returns>The named view.</returns>
|
||||
UserView GetNamedView(
|
||||
string name,
|
||||
CollectionType viewType,
|
||||
string sortName);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the named view.
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="parentId">The parent identifier.</param>
|
||||
/// <param name="viewType">Type of the view.</param>
|
||||
/// <param name="sortName">Name of the sort.</param>
|
||||
/// <param name="uniqueId">The unique identifier.</param>
|
||||
/// <returns>The named view.</returns>
|
||||
UserView GetNamedView(
|
||||
string name,
|
||||
Guid parentId,
|
||||
CollectionType? viewType,
|
||||
string sortName,
|
||||
string uniqueId);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the shadow view.
|
||||
/// </summary>
|
||||
/// <param name="parent">The parent.</param>
|
||||
/// <param name="viewType">Type of the view.</param>
|
||||
/// <param name="sortName">Name of the sort.</param>
|
||||
/// <returns>The shadow view.</returns>
|
||||
UserView GetShadowView(
|
||||
BaseItem parent,
|
||||
CollectionType? viewType,
|
||||
string sortName);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the season number from path.
|
||||
/// </summary>
|
||||
/// <param name="path">The path.</param>
|
||||
/// <param name="parentId">The parent id.</param>
|
||||
/// <returns>System.Nullable<System.Int32>.</returns>
|
||||
int? GetSeasonNumberFromPath(string path, Guid? parentId);
|
||||
|
||||
/// <summary>
|
||||
/// Fills the missing episode numbers from path.
|
||||
/// </summary>
|
||||
/// <param name="episode">Episode to use.</param>
|
||||
/// <param name="forceRefresh">Option to force refresh of episode numbers.</param>
|
||||
/// <returns>True if successful.</returns>
|
||||
bool FillMissingEpisodeNumbersFromPath(Episode episode, bool forceRefresh);
|
||||
|
||||
/// <summary>
|
||||
/// Parses the name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <returns>ItemInfo.</returns>
|
||||
ItemLookupInfo ParseName(string name);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the new item identifier.
|
||||
/// </summary>
|
||||
/// <param name="key">The key.</param>
|
||||
/// <param name="type">The type.</param>
|
||||
/// <returns>Guid.</returns>
|
||||
Guid GetNewItemId(string key, Type type);
|
||||
|
||||
/// <summary>
|
||||
/// Finds the extras.
|
||||
/// </summary>
|
||||
/// <param name="owner">The owner.</param>
|
||||
/// <param name="fileSystemChildren">The file system children.</param>
|
||||
/// <param name="directoryService">An instance of <see cref="IDirectoryService"/>.</param>
|
||||
/// <returns>IEnumerable<BaseItem>.</returns>
|
||||
IEnumerable<BaseItem> FindExtras(BaseItem owner, IReadOnlyList<FileSystemMetadata> fileSystemChildren, IDirectoryService directoryService);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the collection folders.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <returns>The folders that contain the item.</returns>
|
||||
List<Folder> GetCollectionFolders(BaseItem item);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the collection folders.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="allUserRootChildren">The root folders to consider.</param>
|
||||
/// <returns>The folders that contain the item.</returns>
|
||||
List<Folder> GetCollectionFolders(BaseItem item, IEnumerable<Folder> allUserRootChildren);
|
||||
|
||||
LibraryOptions GetLibraryOptions(BaseItem item);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the people.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <returns>List<PersonInfo>.</returns>
|
||||
IReadOnlyList<PersonInfo> GetPeople(BaseItem item);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the people.
|
||||
/// </summary>
|
||||
/// <param name="query">The query.</param>
|
||||
/// <returns>List<PersonInfo>.</returns>
|
||||
IReadOnlyList<PersonInfo> GetPeople(InternalPeopleQuery query);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the people items.
|
||||
/// </summary>
|
||||
/// <param name="query">The query.</param>
|
||||
/// <returns>List<Person>.</returns>
|
||||
IReadOnlyList<Person> GetPeopleItems(InternalPeopleQuery query);
|
||||
|
||||
/// <summary>
|
||||
/// Updates the people.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="people">The people.</param>
|
||||
void UpdatePeople(BaseItem item, List<PersonInfo> people);
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously updates the people.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="people">The people.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>The async task.</returns>
|
||||
Task UpdatePeopleAsync(BaseItem item, IReadOnlyList<PersonInfo> people, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the item ids.
|
||||
/// </summary>
|
||||
/// <param name="query">The query.</param>
|
||||
/// <returns>List<Guid>.</returns>
|
||||
IReadOnlyList<Guid> GetItemIds(InternalItemsQuery query);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the people names.
|
||||
/// </summary>
|
||||
/// <param name="query">The query.</param>
|
||||
/// <returns>List<System.String>.</returns>
|
||||
IReadOnlyList<string> GetPeopleNames(InternalPeopleQuery query);
|
||||
|
||||
/// <summary>
|
||||
/// Queries the items.
|
||||
/// </summary>
|
||||
/// <param name="query">The query.</param>
|
||||
/// <returns>QueryResult<BaseItem>.</returns>
|
||||
QueryResult<BaseItem> QueryItems(InternalItemsQuery query);
|
||||
|
||||
string GetPathAfterNetworkSubstitution(string path, BaseItem? ownerItem = null);
|
||||
|
||||
/// <summary>
|
||||
/// Converts the image to local.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="image">The image.</param>
|
||||
/// <param name="imageIndex">Index of the image.</param>
|
||||
/// <param name="removeOnFailure">Whether to remove the image from the item on failure.</param>
|
||||
/// <returns>Task.</returns>
|
||||
Task<ItemImageInfo> ConvertImageToLocal(BaseItem item, ItemImageInfo image, int imageIndex, bool removeOnFailure = true);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the items.
|
||||
/// </summary>
|
||||
/// <param name="query">The query.</param>
|
||||
/// <returns>QueryResult<BaseItem>.</returns>
|
||||
IReadOnlyList<BaseItem> GetItemList(InternalItemsQuery query);
|
||||
|
||||
IReadOnlyList<BaseItem> GetItemList(InternalItemsQuery query, bool allowExternalContent);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the items.
|
||||
/// </summary>
|
||||
/// <param name="query">The query to use.</param>
|
||||
/// <param name="parents">Items to use for query.</param>
|
||||
/// <returns>List of items.</returns>
|
||||
IReadOnlyList<BaseItem> GetItemList(InternalItemsQuery query, List<BaseItem> parents);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the TVShow/Album items for Latest api.
|
||||
/// </summary>
|
||||
/// <param name="query">The query to use.</param>
|
||||
/// <param name="parents">Items to use for query.</param>
|
||||
/// <param name="collectionType">Collection Type.</param>
|
||||
/// <returns>List of items.</returns>
|
||||
IReadOnlyList<BaseItem> GetLatestItemList(InternalItemsQuery query, IReadOnlyList<BaseItem> parents, CollectionType collectionType);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of series presentation keys for next up.
|
||||
/// </summary>
|
||||
/// <param name="query">The query to use.</param>
|
||||
/// <param name="parents">Items to use for query.</param>
|
||||
/// <param name="dateCutoff">The minimum date for a series to have been most recently watched.</param>
|
||||
/// <returns>List of series presentation keys.</returns>
|
||||
IReadOnlyList<string> GetNextUpSeriesKeys(InternalItemsQuery query, IReadOnlyCollection<BaseItem> parents, DateTime dateCutoff);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the items result.
|
||||
/// </summary>
|
||||
/// <param name="query">The query.</param>
|
||||
/// <returns>QueryResult<BaseItem>.</returns>
|
||||
QueryResult<BaseItem> GetItemsResult(InternalItemsQuery query);
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the file is ignored.
|
||||
/// </summary>
|
||||
/// <param name="file">The file.</param>
|
||||
/// <param name="parent">The parent.</param>
|
||||
/// <returns><c>true</c> if ignored, <c>false</c> otherwise.</returns>
|
||||
bool IgnoreFile(FileSystemMetadata file, BaseItem parent);
|
||||
|
||||
Guid GetStudioId(string name);
|
||||
|
||||
Guid GetGenreId(string name);
|
||||
|
||||
Guid GetMusicGenreId(string name);
|
||||
|
||||
Task AddVirtualFolder(string name, CollectionTypeOptions? collectionType, LibraryOptions options, bool refreshLibrary);
|
||||
|
||||
Task RemoveVirtualFolder(string name, bool refreshLibrary);
|
||||
|
||||
void AddMediaPath(string virtualFolderName, MediaPathInfo mediaPath);
|
||||
|
||||
void UpdateMediaPath(string virtualFolderName, MediaPathInfo mediaPath);
|
||||
|
||||
void RemoveMediaPath(string virtualFolderName, string mediaPath);
|
||||
|
||||
QueryResult<(BaseItem Item, ItemCounts ItemCounts)> GetGenres(InternalItemsQuery query);
|
||||
|
||||
QueryResult<(BaseItem Item, ItemCounts ItemCounts)> GetMusicGenres(InternalItemsQuery query);
|
||||
|
||||
QueryResult<(BaseItem Item, ItemCounts ItemCounts)> GetStudios(InternalItemsQuery query);
|
||||
|
||||
QueryResult<(BaseItem Item, ItemCounts ItemCounts)> GetArtists(InternalItemsQuery query);
|
||||
|
||||
IReadOnlyDictionary<string, MusicArtist[]> GetArtists(IReadOnlyList<string> names);
|
||||
|
||||
QueryResult<(BaseItem Item, ItemCounts ItemCounts)> GetAlbumArtists(InternalItemsQuery query);
|
||||
|
||||
QueryResult<(BaseItem Item, ItemCounts ItemCounts)> GetAllArtists(InternalItemsQuery query);
|
||||
|
||||
int GetCount(InternalItemsQuery query);
|
||||
|
||||
ItemCounts GetItemCounts(InternalItemsQuery query);
|
||||
|
||||
Task RunMetadataSavers(BaseItem item, ItemUpdateType updateReason);
|
||||
|
||||
BaseItem GetParentItem(Guid? parentId, Guid? userId);
|
||||
|
||||
/// <summary>
|
||||
/// Queue a library scan.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This exists so plugins can trigger a library scan.
|
||||
/// </remarks>
|
||||
void QueueLibraryScan();
|
||||
|
||||
/// <summary>
|
||||
/// Add mblink file for a media path.
|
||||
/// </summary>
|
||||
/// <param name="virtualFolderPath">The path to the virtualfolder.</param>
|
||||
/// <param name="pathInfo">The new virtualfolder.</param>
|
||||
public void CreateShortcut(string virtualFolderPath, MediaPathInfo pathInfo);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
namespace MediaBrowser.Controller.Library
|
||||
{
|
||||
/// <summary>
|
||||
/// Service responsible for monitoring library filesystems for changes.
|
||||
/// </summary>
|
||||
public interface ILibraryMonitor
|
||||
{
|
||||
/// <summary>
|
||||
/// Starts this instance.
|
||||
/// </summary>
|
||||
void Start();
|
||||
|
||||
/// <summary>
|
||||
/// Stops this instance.
|
||||
/// </summary>
|
||||
void Stop();
|
||||
|
||||
/// <summary>
|
||||
/// Reports the file system change beginning.
|
||||
/// </summary>
|
||||
/// <param name="path">The path.</param>
|
||||
void ReportFileSystemChangeBeginning(string path);
|
||||
|
||||
/// <summary>
|
||||
/// Reports the file system change complete.
|
||||
/// </summary>
|
||||
/// <param name="path">The path.</param>
|
||||
/// <param name="refreshPath">if set to <c>true</c> [refresh path].</param>
|
||||
void ReportFileSystemChangeComplete(string path, bool refreshPath);
|
||||
|
||||
/// <summary>
|
||||
/// Reports the file system changed.
|
||||
/// </summary>
|
||||
/// <param name="path">The path.</param>
|
||||
void ReportFileSystemChanged(string path);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MediaBrowser.Controller.Library
|
||||
{
|
||||
/// <summary>
|
||||
/// An interface for tasks that run after the media library scan.
|
||||
/// </summary>
|
||||
public interface ILibraryPostScanTask
|
||||
{
|
||||
/// <summary>
|
||||
/// Runs the specified progress.
|
||||
/// </summary>
|
||||
/// <param name="progress">The progress.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task.</returns>
|
||||
Task Run(IProgress<double> progress, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CA1711, CS1591
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Model.Dto;
|
||||
|
||||
namespace MediaBrowser.Controller.Library
|
||||
{
|
||||
public interface ILiveStream : IDisposable
|
||||
{
|
||||
int ConsumerCount { get; set; }
|
||||
|
||||
string OriginalStreamId { get; set; }
|
||||
|
||||
string TunerHostId { get; }
|
||||
|
||||
bool EnableStreamSharing { get; }
|
||||
|
||||
MediaSourceInfo MediaSource { get; set; }
|
||||
|
||||
string UniqueId { get; }
|
||||
|
||||
Task Open(CancellationToken openCancellationToken);
|
||||
|
||||
Task Close();
|
||||
|
||||
Stream GetStream();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CA1002, CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Jellyfin.Database.Implementations.Entities;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.LiveTv;
|
||||
using MediaBrowser.Controller.Persistence;
|
||||
using MediaBrowser.Model.Dto;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.MediaInfo;
|
||||
|
||||
namespace MediaBrowser.Controller.Library
|
||||
{
|
||||
public interface IMediaSourceManager
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds the parts.
|
||||
/// </summary>
|
||||
/// <param name="providers">The providers.</param>
|
||||
void AddParts(IEnumerable<IMediaSourceProvider> providers);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the media streams.
|
||||
/// </summary>
|
||||
/// <param name="itemId">The item identifier.</param>
|
||||
/// <returns>IEnumerable<MediaStream>.</returns>
|
||||
IReadOnlyList<MediaStream> GetMediaStreams(Guid itemId);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the media streams.
|
||||
/// </summary>
|
||||
/// <param name="query">The query.</param>
|
||||
/// <returns>IEnumerable<MediaStream>.</returns>
|
||||
IReadOnlyList<MediaStream> GetMediaStreams(MediaStreamQuery query);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the media attachments.
|
||||
/// </summary>
|
||||
/// <param name="itemId">The item identifier.</param>
|
||||
/// <returns>IEnumerable<MediaAttachment>.</returns>
|
||||
IReadOnlyList<MediaAttachment> GetMediaAttachments(Guid itemId);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the media attachments.
|
||||
/// </summary>
|
||||
/// <param name="query">The query.</param>
|
||||
/// <returns>IEnumerable<MediaAttachment>.</returns>
|
||||
IReadOnlyList<MediaAttachment> GetMediaAttachments(MediaAttachmentQuery query);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the playback media sources.
|
||||
/// </summary>
|
||||
/// <param name="item">Item to use.</param>
|
||||
/// <param name="user">User to use for operation.</param>
|
||||
/// <param name="allowMediaProbe">Option to allow media probe.</param>
|
||||
/// <param name="enablePathSubstitution">Option to enable path substitution.</param>
|
||||
/// <param name="cancellationToken">CancellationToken to use for operation.</param>
|
||||
/// <returns>List of media sources wrapped in an awaitable task.</returns>
|
||||
Task<IReadOnlyList<MediaSourceInfo>> GetPlaybackMediaSources(BaseItem item, User user, bool allowMediaProbe, bool enablePathSubstitution, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the static media sources.
|
||||
/// </summary>
|
||||
/// <param name="item">Item to use.</param>
|
||||
/// <param name="enablePathSubstitution">Option to enable path substitution.</param>
|
||||
/// <param name="user">User to use for operation.</param>
|
||||
/// <returns>List of media sources.</returns>
|
||||
IReadOnlyList<MediaSourceInfo> GetStaticMediaSources(BaseItem item, bool enablePathSubstitution, User user = null);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the static media source.
|
||||
/// </summary>
|
||||
/// <param name="item">Item to use.</param>
|
||||
/// <param name="mediaSourceId">Media source to get.</param>
|
||||
/// <param name="liveStreamId">Live stream to use.</param>
|
||||
/// <param name="enablePathSubstitution">Option to enable path substitution.</param>
|
||||
/// <param name="cancellationToken">CancellationToken to use for operation.</param>
|
||||
/// <returns>The static media source wrapped in an awaitable task.</returns>
|
||||
Task<MediaSourceInfo> GetMediaSource(BaseItem item, string mediaSourceId, string liveStreamId, bool enablePathSubstitution, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Opens the media source.
|
||||
/// </summary>
|
||||
/// <param name="request">The request.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task<MediaSourceInfo>.</returns>
|
||||
Task<LiveStreamResponse> OpenLiveStream(LiveStreamRequest request, CancellationToken cancellationToken);
|
||||
|
||||
Task<Tuple<LiveStreamResponse, IDirectStreamProvider>> OpenLiveStreamInternal(LiveStreamRequest request, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the live stream.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task<MediaSourceInfo>.</returns>
|
||||
Task<MediaSourceInfo> GetLiveStream(string id, CancellationToken cancellationToken);
|
||||
|
||||
Task<Tuple<MediaSourceInfo, IDirectStreamProvider>> GetLiveStreamWithDirectStreamProvider(string id, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the live stream info.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier.</param>
|
||||
/// <returns>An instance of <see cref="ILiveStream"/>.</returns>
|
||||
public ILiveStream GetLiveStreamInfo(string id);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the live stream info using the stream's unique id.
|
||||
/// </summary>
|
||||
/// <param name="uniqueId">The unique identifier.</param>
|
||||
/// <returns>An instance of <see cref="ILiveStream"/>.</returns>
|
||||
public ILiveStream GetLiveStreamInfoByUniqueId(string uniqueId);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the media sources for an active recording.
|
||||
/// </summary>
|
||||
/// <param name="info">The <see cref="ActiveRecordingInfo"/>.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/>.</param>
|
||||
/// <returns>A task containing the <see cref="MediaSourceInfo"/>'s for the recording.</returns>
|
||||
Task<IReadOnlyList<MediaSourceInfo>> GetRecordingStreamMediaSources(ActiveRecordingInfo info, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Closes the media source.
|
||||
/// </summary>
|
||||
/// <param name="id">The live stream identifier.</param>
|
||||
/// <returns>Task.</returns>
|
||||
Task CloseLiveStream(string id);
|
||||
|
||||
Task<MediaSourceInfo> GetLiveStreamMediaInfo(string id, CancellationToken cancellationToken);
|
||||
|
||||
bool SupportsDirectStream(string path, MediaProtocol protocol);
|
||||
|
||||
MediaProtocol GetPathProtocol(string path);
|
||||
|
||||
void SetDefaultAudioAndSubtitleStreamIndices(BaseItem item, MediaSourceInfo source, User user);
|
||||
|
||||
Task AddMediaInfoWithProbe(MediaSourceInfo mediaSource, bool isAudio, string cacheKey, bool addProbeDelay, bool isLiveStream, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
#pragma warning disable CA1002, CS1591
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Model.Dto;
|
||||
|
||||
namespace MediaBrowser.Controller.Library
|
||||
{
|
||||
public interface IMediaSourceProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the media sources.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task<IEnumerable<MediaSourceInfo>>.</returns>
|
||||
Task<IEnumerable<MediaSourceInfo>> GetMediaSources(BaseItem item, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Opens the media source.
|
||||
/// </summary>
|
||||
/// <param name="openToken">Token to use.</param>
|
||||
/// <param name="currentLiveStreams">List of live streams.</param>
|
||||
/// <param name="cancellationToken">CancellationToken to use for operation.</param>
|
||||
/// <returns>The media source wrapped as an awaitable task.</returns>
|
||||
Task<ILiveStream> OpenMediaSource(string openToken, List<ILiveStream> currentLiveStreams, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using MediaBrowser.Controller.Entities;
|
||||
|
||||
namespace MediaBrowser.Controller.Library
|
||||
{
|
||||
public interface IMetadataFileSaver : IMetadataSaver
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the save path.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <returns>System.String.</returns>
|
||||
string GetSavePath(BaseItem item);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
|
||||
namespace MediaBrowser.Controller.Library
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface IMetadataSaver.
|
||||
/// </summary>
|
||||
public interface IMetadataSaver
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the name.
|
||||
/// </summary>
|
||||
/// <value>The name.</value>
|
||||
string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether [is enabled for] [the specified item].
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="updateType">Type of the update.</param>
|
||||
/// <returns><c>true</c> if [is enabled for] [the specified item]; otherwise, <c>false</c>.</returns>
|
||||
bool IsEnabledFor(BaseItem item, ItemUpdateType updateType);
|
||||
|
||||
/// <summary>
|
||||
/// Saves the specified item.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>The task object representing the asynchronous operation.</returns>
|
||||
Task SaveAsync(BaseItem item, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
#pragma warning disable CA1002, CS1591
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Jellyfin.Database.Implementations.Entities;
|
||||
using MediaBrowser.Controller.Dto;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
|
||||
namespace MediaBrowser.Controller.Library
|
||||
{
|
||||
public interface IMusicManager
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the instant mix from song.
|
||||
/// </summary>
|
||||
/// <param name="item">The item to use.</param>
|
||||
/// <param name="user">The user to use.</param>
|
||||
/// <param name="dtoOptions">The options to use.</param>
|
||||
/// <returns>List of items.</returns>
|
||||
IReadOnlyList<BaseItem> GetInstantMixFromItem(BaseItem item, User? user, DtoOptions dtoOptions);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the instant mix from artist.
|
||||
/// </summary>
|
||||
/// <param name="artist">The artist to use.</param>
|
||||
/// <param name="user">The user to use.</param>
|
||||
/// <param name="dtoOptions">The options to use.</param>
|
||||
/// <returns>List of items.</returns>
|
||||
IReadOnlyList<BaseItem> GetInstantMixFromArtist(MusicArtist artist, User? user, DtoOptions dtoOptions);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the instant mix from genre.
|
||||
/// </summary>
|
||||
/// <param name="genres">The genres to use.</param>
|
||||
/// <param name="user">The user to use.</param>
|
||||
/// <param name="dtoOptions">The options to use.</param>
|
||||
/// <returns>List of items.</returns>
|
||||
IReadOnlyList<BaseItem> GetInstantMixFromGenres(IEnumerable<string> genres, User? user, DtoOptions dtoOptions);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using MediaBrowser.Model.Querying;
|
||||
using MediaBrowser.Model.Search;
|
||||
|
||||
namespace MediaBrowser.Controller.Library
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface ILibrarySearchEngine.
|
||||
/// </summary>
|
||||
public interface ISearchEngine
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the search hints.
|
||||
/// </summary>
|
||||
/// <param name="query">The query.</param>
|
||||
/// <returns>Task{IEnumerable{SearchHintInfo}}.</returns>
|
||||
QueryResult<SearchHintInfo> GetSearchHints(SearchQuery query);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using Jellyfin.Database.Implementations.Entities;
|
||||
using MediaBrowser.Controller.Dto;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Model.Dto;
|
||||
using MediaBrowser.Model.Entities;
|
||||
|
||||
namespace MediaBrowser.Controller.Library
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface IUserDataManager.
|
||||
/// </summary>
|
||||
public interface IUserDataManager
|
||||
{
|
||||
/// <summary>
|
||||
/// Occurs when [user data saved].
|
||||
/// </summary>
|
||||
event EventHandler<UserDataSaveEventArgs>? UserDataSaved;
|
||||
|
||||
/// <summary>
|
||||
/// Saves the user data.
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="userData">The user data.</param>
|
||||
/// <param name="reason">The reason.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
void SaveUserData(User user, BaseItem item, UserItemData userData, UserDataSaveReason reason, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Save the provided user data for the given user.
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="userDataDto">The reason for updating the user data.</param>
|
||||
/// <param name="reason">The reason.</param>
|
||||
void SaveUserData(User user, BaseItem item, UpdateUserItemDataDto userDataDto, UserDataSaveReason reason);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user data.
|
||||
/// </summary>
|
||||
/// <param name="user">User to use.</param>
|
||||
/// <param name="item">Item to use.</param>
|
||||
/// <returns>User data.</returns>
|
||||
UserItemData? GetUserData(User user, BaseItem item);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user data dto.
|
||||
/// </summary>
|
||||
/// <param name="item">Item to use.</param>
|
||||
/// <param name="user">User to use.</param>
|
||||
/// <returns>User data dto.</returns>
|
||||
UserItemDataDto? GetUserDataDto(BaseItem item, User user);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user data dto.
|
||||
/// </summary>
|
||||
/// <param name="item">Item to use.</param>
|
||||
/// <param name="itemDto">Item dto to use.</param>
|
||||
/// <param name="user">User to use.</param>
|
||||
/// <param name="options">Dto options to use.</param>
|
||||
/// <returns>User data dto.</returns>
|
||||
UserItemDataDto? GetUserDataDto(BaseItem item, BaseItemDto? itemDto, User user, DtoOptions options);
|
||||
|
||||
/// <summary>
|
||||
/// Updates playstate for an item and returns true or false indicating if it was played to completion.
|
||||
/// </summary>
|
||||
/// <param name="item">Item to update.</param>
|
||||
/// <param name="data">Data to update.</param>
|
||||
/// <param name="reportedPositionTicks">New playstate.</param>
|
||||
/// <returns>True if playstate was updated.</returns>
|
||||
bool UpdatePlayState(BaseItem item, UserItemData data, long? reportedPositionTicks);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Jellyfin.Data.Events;
|
||||
using Jellyfin.Database.Implementations.Entities;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using MediaBrowser.Model.Dto;
|
||||
using MediaBrowser.Model.Users;
|
||||
|
||||
namespace MediaBrowser.Controller.Library
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface IUserManager.
|
||||
/// </summary>
|
||||
public interface IUserManager
|
||||
{
|
||||
/// <summary>
|
||||
/// Occurs when a user is updated.
|
||||
/// </summary>
|
||||
event EventHandler<GenericEventArgs<User>> OnUserUpdated;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the users.
|
||||
/// </summary>
|
||||
/// <value>The users.</value>
|
||||
IEnumerable<User> Users { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user ids.
|
||||
/// </summary>
|
||||
/// <value>The users ids.</value>
|
||||
IEnumerable<Guid> UsersIds { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the user manager and ensures that a user exists.
|
||||
/// </summary>
|
||||
/// <returns>Awaitable task.</returns>
|
||||
Task InitializeAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a user by Id.
|
||||
/// </summary>
|
||||
/// <param name="id">The id.</param>
|
||||
/// <returns>The user with the specified Id, or <c>null</c> if the user doesn't exist.</returns>
|
||||
/// <exception cref="ArgumentException"><c>id</c> is an empty Guid.</exception>
|
||||
User? GetUserById(Guid id);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the user by.
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <returns>User.</returns>
|
||||
User? GetUserByName(string name);
|
||||
|
||||
/// <summary>
|
||||
/// Renames the user.
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <param name="newName">The new name.</param>
|
||||
/// <returns>Task.</returns>
|
||||
/// <exception cref="ArgumentNullException">If user is <c>null</c>.</exception>
|
||||
/// <exception cref="ArgumentException">If the provided user doesn't exist.</exception>
|
||||
Task RenameUser(User user, string newName);
|
||||
|
||||
/// <summary>
|
||||
/// Updates the user.
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <exception cref="ArgumentNullException">If user is <c>null</c>.</exception>
|
||||
/// <exception cref="ArgumentException">If the provided user doesn't exist.</exception>
|
||||
/// <returns>A task representing the update of the user.</returns>
|
||||
Task UpdateUserAsync(User user);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a user with the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the new user.</param>
|
||||
/// <returns>The created user.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="name"/> is <c>null</c> or empty.</exception>
|
||||
/// <exception cref="ArgumentException"><paramref name="name"/> already exists.</exception>
|
||||
Task<User> CreateUserAsync(string name);
|
||||
|
||||
/// <summary>
|
||||
/// Deletes the specified user.
|
||||
/// </summary>
|
||||
/// <param name="userId">The id of the user to be deleted.</param>
|
||||
/// <returns>A task representing the deletion of the user.</returns>
|
||||
Task DeleteUserAsync(Guid userId);
|
||||
|
||||
/// <summary>
|
||||
/// Resets the password.
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <returns>Task.</returns>
|
||||
Task ResetPassword(User user);
|
||||
|
||||
/// <summary>
|
||||
/// Changes the password.
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <param name="newPassword">New password to use.</param>
|
||||
/// <returns>Awaitable task.</returns>
|
||||
Task ChangePassword(User user, string newPassword);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user dto.
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <param name="remoteEndPoint">The remote end point.</param>
|
||||
/// <returns>UserDto.</returns>
|
||||
UserDto GetUserDto(User user, string? remoteEndPoint = null);
|
||||
|
||||
/// <summary>
|
||||
/// Authenticates the user.
|
||||
/// </summary>
|
||||
/// <param name="username">The user.</param>
|
||||
/// <param name="password">The password to use.</param>
|
||||
/// <param name="remoteEndPoint">Remove endpoint to use.</param>
|
||||
/// <param name="isUserSession">Specifies if a user session.</param>
|
||||
/// <returns>User wrapped in awaitable task.</returns>
|
||||
Task<User?> AuthenticateUser(string username, string password, string remoteEndPoint, bool isUserSession);
|
||||
|
||||
/// <summary>
|
||||
/// Starts the forgot password process.
|
||||
/// </summary>
|
||||
/// <param name="enteredUsername">The entered username.</param>
|
||||
/// <param name="isInNetwork">if set to <c>true</c> [is in network].</param>
|
||||
/// <returns>ForgotPasswordResult.</returns>
|
||||
Task<ForgotPasswordResult> StartForgotPasswordProcess(string enteredUsername, bool isInNetwork);
|
||||
|
||||
/// <summary>
|
||||
/// Redeems the password reset pin.
|
||||
/// </summary>
|
||||
/// <param name="pin">The pin.</param>
|
||||
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
|
||||
Task<PinRedeemResult> RedeemPasswordResetPin(string pin);
|
||||
|
||||
NameIdPair[] GetAuthenticationProviders();
|
||||
|
||||
NameIdPair[] GetPasswordResetProviders();
|
||||
|
||||
/// <summary>
|
||||
/// This method updates the user's configuration.
|
||||
/// This is only included as a stopgap until the new API, using this internally is not recommended.
|
||||
/// Instead, modify the user object directly, then call <see cref="UpdateUserAsync"/>.
|
||||
/// </summary>
|
||||
/// <param name="userId">The user's Id.</param>
|
||||
/// <param name="config">The request containing the new user configuration.</param>
|
||||
/// <returns>A task representing the update.</returns>
|
||||
Task UpdateConfigurationAsync(Guid userId, UserConfiguration config);
|
||||
|
||||
/// <summary>
|
||||
/// This method updates the user's policy.
|
||||
/// This is only included as a stopgap until the new API, using this internally is not recommended.
|
||||
/// Instead, modify the user object directly, then call <see cref="UpdateUserAsync"/>.
|
||||
/// </summary>
|
||||
/// <param name="userId">The user's Id.</param>
|
||||
/// <param name="policy">The request containing the new user policy.</param>
|
||||
/// <returns>A task representing the update.</returns>
|
||||
Task UpdatePolicyAsync(Guid userId, UserPolicy policy);
|
||||
|
||||
/// <summary>
|
||||
/// Clears the user's profile image.
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <returns>A task representing the clearing of the profile image.</returns>
|
||||
Task ClearProfileImageAsync(User user);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CA1002, CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Jellyfin.Data.Enums;
|
||||
using MediaBrowser.Controller.Dto;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Model.Library;
|
||||
using MediaBrowser.Model.Querying;
|
||||
|
||||
namespace MediaBrowser.Controller.Library
|
||||
{
|
||||
public interface IUserViewManager
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets user views.
|
||||
/// </summary>
|
||||
/// <param name="query">Query to use.</param>
|
||||
/// <returns>Set of folders.</returns>
|
||||
Folder[] GetUserViews(UserViewQuery query);
|
||||
|
||||
/// <summary>
|
||||
/// Gets user sub views.
|
||||
/// </summary>
|
||||
/// <param name="parentId">Parent to use.</param>
|
||||
/// <param name="type">Type to use.</param>
|
||||
/// <param name="localizationKey">Localization key to use.</param>
|
||||
/// <param name="sortName">Sort to use.</param>
|
||||
/// <returns>User view.</returns>
|
||||
UserView GetUserSubView(Guid parentId, CollectionType? type, string localizationKey, string sortName);
|
||||
|
||||
/// <summary>
|
||||
/// Gets latest items.
|
||||
/// </summary>
|
||||
/// <param name="request">Query to use.</param>
|
||||
/// <param name="options">Options to use.</param>
|
||||
/// <returns>Set of items.</returns>
|
||||
List<Tuple<BaseItem, List<BaseItem>>> GetLatestItems(LatestItemsQuery request, DtoOptions options);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
|
||||
namespace MediaBrowser.Controller.Library
|
||||
{
|
||||
public class IntroInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the path.
|
||||
/// </summary>
|
||||
/// <value>The path.</value>
|
||||
public string Path { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the item id.
|
||||
/// </summary>
|
||||
/// <value>The item id.</value>
|
||||
public Guid? ItemId { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CA1711, CS1591
|
||||
|
||||
using MediaBrowser.Controller.Entities;
|
||||
|
||||
namespace MediaBrowser.Controller.Library
|
||||
{
|
||||
/// <summary>
|
||||
/// Class ItemChangeEventArgs.
|
||||
/// </summary>
|
||||
public class ItemChangeEventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the item.
|
||||
/// </summary>
|
||||
/// <value>The item.</value>
|
||||
public BaseItem Item { get; set; }
|
||||
|
||||
public BaseItem Parent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the item.
|
||||
/// </summary>
|
||||
/// <value>The item.</value>
|
||||
public ItemUpdateType UpdateReason { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,286 @@
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Jellyfin.Data.Enums;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using MediaBrowser.Model.IO;
|
||||
|
||||
namespace MediaBrowser.Controller.Library
|
||||
{
|
||||
/// <summary>
|
||||
/// These are arguments relating to the file system that are collected once and then referred to
|
||||
/// whenever needed. Primarily for entity resolution.
|
||||
/// </summary>
|
||||
public class ItemResolveArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// The _app paths.
|
||||
/// </summary>
|
||||
private readonly IServerApplicationPaths _appPaths;
|
||||
|
||||
private readonly ILibraryManager _libraryManager;
|
||||
private LibraryOptions _libraryOptions;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ItemResolveArgs" /> class.
|
||||
/// </summary>
|
||||
/// <param name="appPaths">The app paths.</param>
|
||||
/// <param name="libraryManager">The library manager.</param>
|
||||
public ItemResolveArgs(IServerApplicationPaths appPaths, ILibraryManager libraryManager)
|
||||
{
|
||||
_appPaths = appPaths;
|
||||
_libraryManager = libraryManager;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the file system children.
|
||||
/// </summary>
|
||||
/// <value>The file system children.</value>
|
||||
public FileSystemMetadata[] FileSystemChildren { get; set; }
|
||||
|
||||
public LibraryOptions LibraryOptions
|
||||
{
|
||||
get => _libraryOptions ??= Parent is null ? new LibraryOptions() : _libraryManager.GetLibraryOptions(Parent);
|
||||
set => _libraryOptions = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the parent.
|
||||
/// </summary>
|
||||
/// <value>The parent.</value>
|
||||
public Folder Parent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the file info.
|
||||
/// </summary>
|
||||
/// <value>The file info.</value>
|
||||
public FileSystemMetadata FileInfo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the path.
|
||||
/// </summary>
|
||||
/// <value>The path.</value>
|
||||
public string Path => FileInfo.FullName;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this instance is directory.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if this instance is directory; otherwise, <c>false</c>.</value>
|
||||
public bool IsDirectory => FileInfo.IsDirectory;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this instance is vf.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if this instance is vf; otherwise, <c>false</c>.</value>
|
||||
public bool IsVf
|
||||
{
|
||||
// we should be considered a virtual folder if we are a child of one of the children of the system root folder.
|
||||
// this is a bit of a trick to determine that... the directory name of a sub-child of the root will start with
|
||||
// the root but not be equal to it
|
||||
get
|
||||
{
|
||||
if (!IsDirectory)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var parentDir = System.IO.Path.GetDirectoryName(Path) ?? string.Empty;
|
||||
|
||||
return parentDir.Length > _appPaths.RootFolderPath.Length
|
||||
&& parentDir.StartsWith(_appPaths.RootFolderPath, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this instance is physical root.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if this instance is physical root; otherwise, <c>false</c>.</value>
|
||||
public bool IsPhysicalRoot => IsDirectory && BaseItem.FileSystem.AreEqual(Path, _appPaths.RootFolderPath);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the additional locations.
|
||||
/// </summary>
|
||||
/// <value>The additional locations.</value>
|
||||
private List<string> AdditionalLocations { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the physical locations.
|
||||
/// </summary>
|
||||
/// <value>The physical locations.</value>
|
||||
public string[] PhysicalLocations
|
||||
{
|
||||
get
|
||||
{
|
||||
var paths = string.IsNullOrEmpty(Path) ? Array.Empty<string>() : [Path];
|
||||
return AdditionalLocations is null ? paths : [..paths, ..AdditionalLocations];
|
||||
}
|
||||
}
|
||||
|
||||
public CollectionType? CollectionType { get; set; }
|
||||
|
||||
public bool HasParent<T>()
|
||||
where T : Folder
|
||||
{
|
||||
var parent = Parent;
|
||||
|
||||
if (parent is not null)
|
||||
{
|
||||
var item = parent as T;
|
||||
|
||||
// Just in case the user decided to nest episodes.
|
||||
// Not officially supported but in some cases we can handle it.
|
||||
if (item is null)
|
||||
{
|
||||
var parents = parent.GetParents();
|
||||
foreach (var currentParent in parents)
|
||||
{
|
||||
if (currentParent is T)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return item is not null;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref="object" /> is equal to this instance.
|
||||
/// </summary>
|
||||
/// <param name="obj">The object to compare with the current object.</param>
|
||||
/// <returns><c>true</c> if the specified <see cref="object" /> is equal to this instance; otherwise, <c>false</c>.</returns>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return Equals(obj as ItemResolveArgs);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the additional location.
|
||||
/// </summary>
|
||||
/// <param name="path">The path.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="path"/> is <c>null</c> or empty.</exception>
|
||||
public void AddAdditionalLocation(string path)
|
||||
{
|
||||
ArgumentException.ThrowIfNullOrEmpty(path);
|
||||
|
||||
AdditionalLocations ??= new List<string>();
|
||||
AdditionalLocations.Add(path);
|
||||
}
|
||||
|
||||
// REVIEW: @bond
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the file system entry by.
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <returns>FileSystemInfo.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="name"/> is <c>null</c> or empty.</exception>
|
||||
public FileSystemMetadata GetFileSystemEntryByName(string name)
|
||||
{
|
||||
ArgumentException.ThrowIfNullOrEmpty(name);
|
||||
|
||||
return GetFileSystemEntryByPath(System.IO.Path.Combine(Path, name));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the file system entry by path.
|
||||
/// </summary>
|
||||
/// <param name="path">The path.</param>
|
||||
/// <returns>FileSystemInfo.</returns>
|
||||
/// <exception cref="ArgumentNullException">Throws if path is invalid.</exception>
|
||||
public FileSystemMetadata GetFileSystemEntryByPath(string path)
|
||||
{
|
||||
ArgumentException.ThrowIfNullOrEmpty(path);
|
||||
|
||||
foreach (var file in FileSystemChildren)
|
||||
{
|
||||
if (string.Equals(file.FullName, path, StringComparison.Ordinal))
|
||||
{
|
||||
return file;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether [contains file system entry by name] [the specified name].
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <returns><c>true</c> if [contains file system entry by name] [the specified name]; otherwise, <c>false</c>.</returns>
|
||||
public bool ContainsFileSystemEntryByName(string name)
|
||||
{
|
||||
return GetFileSystemEntryByName(name) is not null;
|
||||
}
|
||||
|
||||
public CollectionType? GetCollectionType()
|
||||
{
|
||||
return CollectionType;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the configured content type for the path.
|
||||
/// </summary>
|
||||
/// <returns>The configured content type.</returns>
|
||||
public CollectionType? GetConfiguredContentType()
|
||||
{
|
||||
return _libraryManager.GetConfiguredContentType(Path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the file system children that do not hit the ignore file check.
|
||||
/// </summary>
|
||||
/// <returns>The file system children that are not ignored.</returns>
|
||||
public IEnumerable<FileSystemMetadata> GetActualFileSystemChildren()
|
||||
{
|
||||
var numberOfChildren = FileSystemChildren.Length;
|
||||
for (var i = 0; i < numberOfChildren; i++)
|
||||
{
|
||||
var child = FileSystemChildren[i];
|
||||
if (_libraryManager.IgnoreFile(child, Parent))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
yield return child;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a hash code for this instance.
|
||||
/// </summary>
|
||||
/// <returns>A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.</returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Path.GetHashCode(StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Equals the specified args.
|
||||
/// </summary>
|
||||
/// <param name="args">The args.</param>
|
||||
/// <returns><c>true</c> if the arguments are the same, <c>false</c> otherwise.</returns>
|
||||
protected bool Equals(ItemResolveArgs args)
|
||||
{
|
||||
if (args is not null)
|
||||
{
|
||||
if (args.Path is null && Path is null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return args.Path is not null && BaseItem.FileSystem.AreEqual(args.Path, Path);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
|
||||
namespace MediaBrowser.Controller.Library
|
||||
{
|
||||
[Flags]
|
||||
public enum ItemUpdateType
|
||||
{
|
||||
None = 1,
|
||||
MetadataImport = 2,
|
||||
ImageUpdate = 4,
|
||||
MetadataDownload = 8,
|
||||
MetadataEdit = 16
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
|
||||
namespace MediaBrowser.Controller.Library
|
||||
{
|
||||
public static class LibraryManagerExtensions
|
||||
{
|
||||
public static BaseItem? GetItemById(this ILibraryManager manager, string id)
|
||||
{
|
||||
return manager.GetItemById(new Guid(id));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
|
||||
namespace MediaBrowser.Controller.Library
|
||||
{
|
||||
public static class MetadataConfigurationExtensions
|
||||
{
|
||||
public static MetadataConfiguration GetMetadataConfiguration(this IConfigurationManager config)
|
||||
=> config.GetConfiguration<MetadataConfiguration>("metadata");
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="MetadataOptions" /> for the specified type.
|
||||
/// </summary>
|
||||
/// <param name="config">The <see cref="IServerConfigurationManager"/>.</param>
|
||||
/// <param name="type">The type to get the <see cref="MetadataOptions" /> for.</param>
|
||||
/// <returns>The <see cref="MetadataOptions" /> for the specified type or <c>null</c>.</returns>
|
||||
public static MetadataOptions? GetMetadataOptionsForType(this IServerConfigurationManager config, string type)
|
||||
=> Array.Find(config.Configuration.MetadataOptions, i => string.Equals(i.ItemType, type, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System.Collections.Generic;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
|
||||
namespace MediaBrowser.Controller.Library
|
||||
{
|
||||
public class MetadataConfigurationStore : IConfigurationFactory
|
||||
{
|
||||
public IEnumerable<ConfigurationStore> GetConfigurations()
|
||||
{
|
||||
return new ConfigurationStore[]
|
||||
{
|
||||
new ConfigurationStore
|
||||
{
|
||||
Key = "metadata",
|
||||
ConfigurationType = typeof(MetadataConfiguration)
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Jellyfin.Extensions;
|
||||
|
||||
namespace MediaBrowser.Controller.Library
|
||||
{
|
||||
public static class NameExtensions
|
||||
{
|
||||
public static IEnumerable<string> DistinctNames(this IEnumerable<string> names)
|
||||
=> names.DistinctBy(RemoveDiacritics, StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
private static string RemoveDiacritics(string? name)
|
||||
{
|
||||
if (name is null)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
return name.RemoveDiacritics();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CA1002, CA2227, CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Jellyfin.Database.Implementations.Entities;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Session;
|
||||
using MediaBrowser.Model.Dto;
|
||||
|
||||
namespace MediaBrowser.Controller.Library
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds information about a playback progress event.
|
||||
/// </summary>
|
||||
public class PlaybackProgressEventArgs : EventArgs
|
||||
{
|
||||
public PlaybackProgressEventArgs()
|
||||
{
|
||||
Users = new List<User>();
|
||||
}
|
||||
|
||||
public List<User> Users { get; set; }
|
||||
|
||||
public long? PlaybackPositionTicks { get; set; }
|
||||
|
||||
public BaseItem Item { get; set; }
|
||||
|
||||
public BaseItemDto MediaInfo { get; set; }
|
||||
|
||||
public string MediaSourceId { get; set; }
|
||||
|
||||
public bool IsPaused { get; set; }
|
||||
|
||||
public bool IsAutomated { get; set; }
|
||||
|
||||
public string DeviceId { get; set; }
|
||||
|
||||
public string DeviceName { get; set; }
|
||||
|
||||
public string ClientName { get; set; }
|
||||
|
||||
public string PlaySessionId { get; set; }
|
||||
|
||||
public SessionInfo Session { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace MediaBrowser.Controller.Library
|
||||
{
|
||||
/// <summary>
|
||||
/// An event that occurs when playback is started.
|
||||
/// </summary>
|
||||
public class PlaybackStartEventArgs : PlaybackProgressEventArgs
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
namespace MediaBrowser.Controller.Library
|
||||
{
|
||||
public class PlaybackStopEventArgs : PlaybackProgressEventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether [played to completion].
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if [played to completion]; otherwise, <c>false</c>.</value>
|
||||
public bool PlayedToCompletion { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
#nullable disable
|
||||
|
||||
using MediaBrowser.Controller.Entities;
|
||||
|
||||
namespace MediaBrowser.Controller.Library
|
||||
{
|
||||
/// <summary>
|
||||
/// Class SearchHintInfo.
|
||||
/// </summary>
|
||||
public class SearchHintInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the item.
|
||||
/// </summary>
|
||||
/// <value>The item.</value>
|
||||
public BaseItem Item { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the matched term.
|
||||
/// </summary>
|
||||
/// <value>The matched term.</value>
|
||||
public string MatchedTerm { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace MediaBrowser.Controller.Library
|
||||
{
|
||||
/// <summary>
|
||||
/// Class TVUtils.
|
||||
/// </summary>
|
||||
public static class TVUtils
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the air days.
|
||||
/// </summary>
|
||||
/// <param name="day">The day.</param>
|
||||
/// <returns>List{DayOfWeek}.</returns>
|
||||
[return: NotNullIfNotNull("day")]
|
||||
public static DayOfWeek[]? GetAirDays(string? day)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(day))
|
||||
{
|
||||
if (string.Equals(day, "Daily", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return new[]
|
||||
{
|
||||
DayOfWeek.Sunday,
|
||||
DayOfWeek.Monday,
|
||||
DayOfWeek.Tuesday,
|
||||
DayOfWeek.Wednesday,
|
||||
DayOfWeek.Thursday,
|
||||
DayOfWeek.Friday,
|
||||
DayOfWeek.Saturday
|
||||
};
|
||||
}
|
||||
|
||||
if (Enum.TryParse(day, true, out DayOfWeek value))
|
||||
{
|
||||
return new[]
|
||||
{
|
||||
value
|
||||
};
|
||||
}
|
||||
|
||||
return Array.Empty<DayOfWeek>();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CA1002, CA2227, CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Model.Entities;
|
||||
|
||||
namespace MediaBrowser.Controller.Library
|
||||
{
|
||||
/// <summary>
|
||||
/// Class UserDataSaveEventArgs.
|
||||
/// </summary>
|
||||
public class UserDataSaveEventArgs : EventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the user id.
|
||||
/// </summary>
|
||||
/// <value>The user id.</value>
|
||||
public Guid UserId { get; set; }
|
||||
|
||||
public List<string> Keys { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the save reason.
|
||||
/// </summary>
|
||||
/// <value>The save reason.</value>
|
||||
public UserDataSaveReason SaveReason { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the user data.
|
||||
/// </summary>
|
||||
/// <value>The user data.</value>
|
||||
public UserItemData UserData { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the item.
|
||||
/// </summary>
|
||||
/// <value>The item.</value>
|
||||
public BaseItem Item { get; set; }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user