diff options
Diffstat (limited to 'MediaBrowser.Controller/Library')
28 files changed, 1840 insertions, 0 deletions
diff --git a/MediaBrowser.Controller/Library/DeleteOptions.cs b/MediaBrowser.Controller/Library/DeleteOptions.cs new file mode 100644 index 000000000..822fc3dc3 --- /dev/null +++ b/MediaBrowser.Controller/Library/DeleteOptions.cs @@ -0,0 +1,14 @@ + +namespace MediaBrowser.Controller.Library +{ + public class DeleteOptions + { + public bool DeleteFileLocation { get; set; } + public bool DeleteFromExternalProvider { get; set; } + + public DeleteOptions() + { + DeleteFromExternalProvider = true; + } + } +} diff --git a/MediaBrowser.Controller/Library/IIntroProvider.cs b/MediaBrowser.Controller/Library/IIntroProvider.cs new file mode 100644 index 000000000..611aab387 --- /dev/null +++ b/MediaBrowser.Controller/Library/IIntroProvider.cs @@ -0,0 +1,32 @@ +using MediaBrowser.Controller.Entities; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace MediaBrowser.Controller.Library +{ + /// <summary> + /// Class BaseIntroProvider + /// </summary> + public interface IIntroProvider + { + /// <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); + + /// <summary> + /// Gets all intro files. + /// </summary> + /// <returns>IEnumerable{System.String}.</returns> + IEnumerable<string> GetAllIntroFiles(); + + /// <summary> + /// Gets the name. + /// </summary> + /// <value>The name.</value> + string Name { get; } + } +} diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs new file mode 100644 index 000000000..d572716fa --- /dev/null +++ b/MediaBrowser.Controller/Library/ILibraryManager.cs @@ -0,0 +1,550 @@ +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities.Audio; +using MediaBrowser.Controller.Entities.TV; +using MediaBrowser.Controller.Providers; +using MediaBrowser.Controller.Resolvers; +using MediaBrowser.Controller.Sorting; +using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Querying; +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.Dto; +using MediaBrowser.Controller.IO; +using MediaBrowser.Model.Configuration; +using MediaBrowser.Model.Dto; +using MediaBrowser.Model.IO; + +namespace MediaBrowser.Controller.Library +{ + /// <summary> + /// Interface ILibraryManager + /// </summary> + public interface ILibraryManager + { + /// <summary> + /// Resolves the path. + /// </summary> + /// <param name="fileInfo">The file information.</param> + /// <param name="parent">The parent.</param> + /// <returns>BaseItem.</returns> + BaseItem ResolvePath(FileSystemMetadata fileInfo, + Folder parent = null); + + /// <summary> + /// Resolves a set of files into a list of BaseItem + /// </summary> + IEnumerable<BaseItem> ResolvePaths(IEnumerable<FileSystemMetadata> files, + IDirectoryService directoryService, + Folder parent, + LibraryOptions libraryOptions, + string collectionType = null); + + /// <summary> + /// Gets the root folder. + /// </summary> + /// <value>The root folder.</value> + AggregateFolder RootFolder { get; } + + /// <summary> + /// Gets a Person + /// </summary> + /// <param name="name">The name.</param> + /// <returns>Task{Person}.</returns> + Person GetPerson(string name); + + /// <summary> + /// Finds the by path. + /// </summary> + /// <param name="path">The path.</param> + /// <returns>BaseItem.</returns> + BaseItem FindByPath(string path, bool? isFolder); + + /// <summary> + /// Gets the artist. + /// </summary> + /// <param name="name">The name.</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.</param> + /// <returns>Task{Studio}.</returns> + Studio GetStudio(string name); + + /// <summary> + /// Gets a Genre + /// </summary> + /// <param name="name">The name.</param> + /// <returns>Task{Genre}.</returns> + Genre GetGenre(string name); + + /// <summary> + /// Gets the genre. + /// </summary> + /// <param name="name">The name.</param> + /// <returns>Task{MusicGenre}.</returns> + MusicGenre GetMusicGenre(string name); + + /// <summary> + /// Gets the game genre. + /// </summary> + /// <param name="name">The name.</param> + /// <returns>Task{GameGenre}.</returns> + GameGenre GetGameGenre(string name); + + /// <summary> + /// Gets a Year + /// </summary> + /// <param name="value">The value.</param> + /// <returns>Task{Year}.</returns> + /// <exception cref="System.ArgumentOutOfRangeException"></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="cancellationToken">The cancellation token.</param> + /// <param name="progress">The progress.</param> + /// <returns>Task.</returns> + Task ValidatePeople(CancellationToken cancellationToken, IProgress<double> progress); + + /// <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> + /// Queues the library scan. + /// </summary> + void QueueLibraryScan(); + + void UpdateImages(BaseItem item); + + /// <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> + BaseItem GetItemById(Guid id); + + /// <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> + /// Gets all intro files. + /// </summary> + /// <returns>IEnumerable{System.String}.</returns> + IEnumerable<string> GetAllIntroFiles(); + + /// <summary> + /// Adds the parts. + /// </summary> + /// <param name="rules">The rules.</param> + /// <param name="pluginFolders">The plugin folders.</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 postscan 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<string> sortBy, SortOrder sortOrder); + IEnumerable<BaseItem> Sort(IEnumerable<BaseItem> items, User user, IEnumerable<ValueTuple<string, SortOrder>> orderBy); + + /// <summary> + /// Gets the user root folder. + /// </summary> + /// <returns>UserRootFolder.</returns> + Folder GetUserRootFolder(); + + /// <summary> + /// Creates the item. + /// </summary> + void CreateItem(BaseItem item, BaseItem parent); + + /// <summary> + /// Creates the items. + /// </summary> + void CreateItems(IEnumerable<BaseItem> items, BaseItem parent, CancellationToken cancellationToken); + + /// <summary> + /// Updates the item. + /// </summary> + void UpdateItems(List<BaseItem> items, BaseItem parent, ItemUpdateType updateReason, CancellationToken cancellationToken); + void UpdateItem(BaseItem item, BaseItem parent, ItemUpdateType updateReason, CancellationToken cancellationToken); + + /// <summary> + /// Retrieves the item. + /// </summary> + /// <param name="id">The id.</param> + /// <returns>BaseItem.</returns> + BaseItem RetrieveItem(Guid id); + + bool IsScanRunning { get; } + + /// <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> + /// Finds the type of the collection. + /// </summary> + /// <param name="item">The item.</param> + /// <returns>System.String.</returns> + string GetContentType(BaseItem item); + + /// <summary> + /// Gets the type of the inherited content. + /// </summary> + /// <param name="item">The item.</param> + /// <returns>System.String.</returns> + string GetInheritedContentType(BaseItem item); + + /// <summary> + /// Gets the type of the configured content. + /// </summary> + /// <param name="item">The item.</param> + /// <returns>System.String.</returns> + string GetConfiguredContentType(BaseItem item); + + /// <summary> + /// Gets the type of the configured content. + /// </summary> + /// <param name="path">The path.</param> + /// <returns>System.String.</returns> + string 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> + void DeleteItem(BaseItem item, DeleteOptions options); + + /// <summary> + /// Deletes the item. + /// </summary> + void DeleteItem(BaseItem item, DeleteOptions options, bool notifyParentItem); + + /// <summary> + /// Deletes the item. + /// </summary> + 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> + UserView GetNamedView(User user, + string name, + Guid parentId, + string viewType, + string sortNamen); + + /// <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> + UserView GetNamedView(User user, + string name, + string 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> + UserView GetNamedView(string name, + string 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> + UserView GetNamedView(string name, + Guid parentId, + string 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> + UserView GetShadowView(BaseItem parent, + string viewType, + string sortName); + + /// <summary> + /// Determines whether [is video file] [the specified path]. + /// </summary> + /// <param name="path">The path.</param> + /// <returns><c>true</c> if [is video file] [the specified path]; otherwise, <c>false</c>.</returns> + bool IsVideoFile(string path); + + /// <summary> + /// Determines whether [is audio file] [the specified path]. + /// </summary> + /// <param name="path">The path.</param> + /// <returns><c>true</c> if [is audio file] [the specified path]; otherwise, <c>false</c>.</returns> + bool IsAudioFile(string path); + + bool IsAudioFile(string path, LibraryOptions libraryOptions); + bool IsVideoFile(string path, LibraryOptions libraryOptions); + + /// <summary> + /// Gets the season number from path. + /// </summary> + /// <param name="path">The path.</param> + /// <returns>System.Nullable<System.Int32>.</returns> + int? GetSeasonNumberFromPath(string path); + + /// <summary> + /// Fills the missing episode numbers from path. + /// </summary> + 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 trailers. + /// </summary> + /// <param name="owner">The owner.</param> + /// <param name="fileSystemChildren">The file system children.</param> + /// <param name="directoryService">The directory service.</param> + /// <returns>IEnumerable<Trailer>.</returns> + IEnumerable<Video> FindTrailers(BaseItem owner, List<FileSystemMetadata> fileSystemChildren, + IDirectoryService directoryService); + + /// <summary> + /// Finds the extras. + /// </summary> + /// <param name="owner">The owner.</param> + /// <param name="fileSystemChildren">The file system children.</param> + /// <param name="directoryService">The directory service.</param> + /// <returns>IEnumerable<Video>.</returns> + IEnumerable<Video> FindExtras(BaseItem owner, List<FileSystemMetadata> fileSystemChildren, + IDirectoryService directoryService); + + /// <summary> + /// Gets the collection folders. + /// </summary> + /// <param name="item">The item.</param> + /// <returns>IEnumerable<Folder>.</returns> + List<Folder> GetCollectionFolders(BaseItem item); + + List<Folder> GetCollectionFolders(BaseItem item, List<Folder> allUserRootChildren); + + LibraryOptions GetLibraryOptions(BaseItem item); + + /// <summary> + /// Gets the people. + /// </summary> + /// <param name="item">The item.</param> + /// <returns>List<PersonInfo>.</returns> + List<PersonInfo> GetPeople(BaseItem item); + + /// <summary> + /// Gets the people. + /// </summary> + /// <param name="query">The query.</param> + /// <returns>List<PersonInfo>.</returns> + List<PersonInfo> GetPeople(InternalPeopleQuery query); + + /// <summary> + /// Gets the people items. + /// </summary> + /// <param name="query">The query.</param> + /// <returns>List<Person>.</returns> + List<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> + /// Gets the item ids. + /// </summary> + /// <param name="query">The query.</param> + /// <returns>List<Guid>.</returns> + List<Guid> GetItemIds(InternalItemsQuery query); + + /// <summary> + /// Gets the people names. + /// </summary> + /// <param name="query">The query.</param> + /// <returns>List<System.String>.</returns> + List<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> + /// Substitutes the path. + /// </summary> + /// <param name="path">The path.</param> + /// <param name="from">From.</param> + /// <param name="to">To.</param> + /// <returns>System.String.</returns> + string SubstitutePath(string path, string from, string to); + + /// <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> + /// <returns>Task.</returns> + Task<ItemImageInfo> ConvertImageToLocal(BaseItem item, ItemImageInfo image, int imageIndex); + + /// <summary> + /// Gets the items. + /// </summary> + /// <param name="query">The query.</param> + /// <returns>QueryResult<BaseItem>.</returns> + List<BaseItem> GetItemList(InternalItemsQuery query); + + List<BaseItem> GetItemList(InternalItemsQuery query, bool allowExternalContent); + + /// <summary> + /// Gets the items. + /// </summary> + List<BaseItem> GetItemList(InternalItemsQuery query, List<BaseItem> parents); + + /// <summary> + /// Gets the items result. + /// </summary> + /// <param name="query">The query.</param> + /// <returns>QueryResult<BaseItem>.</returns> + QueryResult<BaseItem> GetItemsResult(InternalItemsQuery query); + + /// <summary> + /// Ignores the file. + /// </summary> + /// <param name="file">The file.</param> + /// <param name="parent">The parent.</param> + /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns> + bool IgnoreFile(FileSystemMetadata file, BaseItem parent); + + Guid GetStudioId(string name); + + Guid GetGenreId(string name); + + Guid GetMusicGenreId(string name); + + Guid GetGameGenreId(string name); + + Task AddVirtualFolder(string name, string collectionType, LibraryOptions options, bool refreshLibrary); + Task RemoveVirtualFolder(string name, bool refreshLibrary); + void AddMediaPath(string virtualFolderName, MediaPathInfo path); + void UpdateMediaPath(string virtualFolderName, MediaPathInfo path); + void RemoveMediaPath(string virtualFolderName, string path); + + QueryResult<Tuple<BaseItem, ItemCounts>> GetGenres(InternalItemsQuery query); + QueryResult<Tuple<BaseItem, ItemCounts>> GetMusicGenres(InternalItemsQuery query); + QueryResult<Tuple<BaseItem, ItemCounts>> GetGameGenres(InternalItemsQuery query); + QueryResult<Tuple<BaseItem, ItemCounts>> GetStudios(InternalItemsQuery query); + QueryResult<Tuple<BaseItem, ItemCounts>> GetArtists(InternalItemsQuery query); + QueryResult<Tuple<BaseItem, ItemCounts>> GetAlbumArtists(InternalItemsQuery query); + QueryResult<Tuple<BaseItem, ItemCounts>> GetAllArtists(InternalItemsQuery query); + + int GetCount(InternalItemsQuery query); + + void AddExternalSubtitleStreams(List<MediaStream> streams, + string videoPath, + string[] files); + } +}
\ No newline at end of file diff --git a/MediaBrowser.Controller/Library/ILibraryMonitor.cs b/MediaBrowser.Controller/Library/ILibraryMonitor.cs new file mode 100644 index 000000000..e965e47d6 --- /dev/null +++ b/MediaBrowser.Controller/Library/ILibraryMonitor.cs @@ -0,0 +1,43 @@ +using System; + +namespace MediaBrowser.Controller.Library +{ + public interface ILibraryMonitor : IDisposable + { + /// <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); + + /// <summary> + /// Determines whether [is path locked] [the specified path]. + /// </summary> + /// <param name="path">The path.</param> + /// <returns><c>true</c> if [is path locked] [the specified path]; otherwise, <c>false</c>.</returns> + bool IsPathLocked(string path); + } +}
\ No newline at end of file diff --git a/MediaBrowser.Controller/Library/ILibraryPostScanTask.cs b/MediaBrowser.Controller/Library/ILibraryPostScanTask.cs new file mode 100644 index 000000000..694422907 --- /dev/null +++ b/MediaBrowser.Controller/Library/ILibraryPostScanTask.cs @@ -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); + } +} diff --git a/MediaBrowser.Controller/Library/ILiveStream.cs b/MediaBrowser.Controller/Library/ILiveStream.cs new file mode 100644 index 000000000..e00da7340 --- /dev/null +++ b/MediaBrowser.Controller/Library/ILiveStream.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using MediaBrowser.Model.Dto; + +namespace MediaBrowser.Controller.Library +{ + public interface ILiveStream + { + Task Open(CancellationToken openCancellationToken); + Task Close(); + int ConsumerCount { get; set; } + string OriginalStreamId { get; set; } + string TunerHostId { get; } + bool EnableStreamSharing { get; } + MediaSourceInfo MediaSource { get; set; } + string UniqueId { get; } + } +} diff --git a/MediaBrowser.Controller/Library/IMediaSourceManager.cs b/MediaBrowser.Controller/Library/IMediaSourceManager.cs new file mode 100644 index 000000000..8541c4fd9 --- /dev/null +++ b/MediaBrowser.Controller/Library/IMediaSourceManager.cs @@ -0,0 +1,100 @@ +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Persistence; +using MediaBrowser.Model.Dto; +using MediaBrowser.Model.Entities; +using MediaBrowser.Model.MediaInfo; +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using System.IO; + +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> + List<MediaStream> GetMediaStreams(Guid itemId); + /// <summary> + /// Gets the media streams. + /// </summary> + /// <param name="mediaSourceId">The media source identifier.</param> + /// <returns>IEnumerable<MediaStream>.</returns> + List<MediaStream> GetMediaStreams(string mediaSourceId); + /// <summary> + /// Gets the media streams. + /// </summary> + /// <param name="query">The query.</param> + /// <returns>IEnumerable<MediaStream>.</returns> + List<MediaStream> GetMediaStreams(MediaStreamQuery query); + + /// <summary> + /// Gets the playack media sources. + /// </summary> + Task<List<MediaSourceInfo>> GetPlayackMediaSources(BaseItem item, User user, bool allowMediaProbe, bool enablePathSubstitution, CancellationToken cancellationToken); + + /// <summary> + /// Gets the static media sources. + /// </summary> + List<MediaSourceInfo> GetStaticMediaSources(BaseItem item, bool enablePathSubstitution, User user = null); + + /// <summary> + /// Gets the static media source. + /// </summary> + 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> + /// 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 SetDefaultAudioAndSubtitleStreamIndexes(BaseItem item, MediaSourceInfo source, User user); + + Task AddMediaInfoWithProbe(MediaSourceInfo mediaSource, bool isAudio, string cacheKey, bool addProbeDelay, bool isLiveStream, CancellationToken cancellationToken); + + Task<IDirectStreamProvider> GetDirectStreamProviderByUniqueId(string uniqueId, CancellationToken cancellationToken); + } + + public interface IDirectStreamProvider + { + Task CopyToAsync(Stream stream, CancellationToken cancellationToken); + } +} diff --git a/MediaBrowser.Controller/Library/IMediaSourceProvider.cs b/MediaBrowser.Controller/Library/IMediaSourceProvider.cs new file mode 100644 index 000000000..eec138532 --- /dev/null +++ b/MediaBrowser.Controller/Library/IMediaSourceProvider.cs @@ -0,0 +1,25 @@ +using MediaBrowser.Controller.Entities; +using MediaBrowser.Model.Dto; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using System; + +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> + Task<ILiveStream> OpenMediaSource(string openToken, List<ILiveStream> currentLiveStreams, CancellationToken cancellationToken); + } +} diff --git a/MediaBrowser.Controller/Library/IMetadataFileSaver.cs b/MediaBrowser.Controller/Library/IMetadataFileSaver.cs new file mode 100644 index 000000000..e66fbcbc8 --- /dev/null +++ b/MediaBrowser.Controller/Library/IMetadataFileSaver.cs @@ -0,0 +1,19 @@ +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); + } + + public interface IConfigurableProvider + { + bool IsEnabled { get; } + } +}
\ No newline at end of file diff --git a/MediaBrowser.Controller/Library/IMetadataSaver.cs b/MediaBrowser.Controller/Library/IMetadataSaver.cs new file mode 100644 index 000000000..f71afa656 --- /dev/null +++ b/MediaBrowser.Controller/Library/IMetadataSaver.cs @@ -0,0 +1,33 @@ +using MediaBrowser.Controller.Entities; +using System.Threading; + +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>Task.</returns> + void Save(BaseItem item, CancellationToken cancellationToken); + } +} diff --git a/MediaBrowser.Controller/Library/IMusicManager.cs b/MediaBrowser.Controller/Library/IMusicManager.cs new file mode 100644 index 000000000..535e6df7e --- /dev/null +++ b/MediaBrowser.Controller/Library/IMusicManager.cs @@ -0,0 +1,25 @@ +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities.Audio; +using System.Collections.Generic; +using MediaBrowser.Controller.Dto; + +namespace MediaBrowser.Controller.Library +{ + public interface IMusicManager + { + /// <summary> + /// Gets the instant mix from song. + /// </summary> + List<BaseItem> GetInstantMixFromItem(BaseItem item, User user, DtoOptions dtoOptions); + + /// <summary> + /// Gets the instant mix from artist. + /// </summary> + List<BaseItem> GetInstantMixFromArtist(MusicArtist artist, User user, DtoOptions dtoOptions); + + /// <summary> + /// Gets the instant mix from genre. + /// </summary> + List<BaseItem> GetInstantMixFromGenres(IEnumerable<string> genres, User user, DtoOptions dtoOptions); + } +} diff --git a/MediaBrowser.Controller/Library/ISearchEngine.cs b/MediaBrowser.Controller/Library/ISearchEngine.cs new file mode 100644 index 000000000..715f16407 --- /dev/null +++ b/MediaBrowser.Controller/Library/ISearchEngine.cs @@ -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); + } +} diff --git a/MediaBrowser.Controller/Library/IUserDataManager.cs b/MediaBrowser.Controller/Library/IUserDataManager.cs new file mode 100644 index 000000000..11d77f81a --- /dev/null +++ b/MediaBrowser.Controller/Library/IUserDataManager.cs @@ -0,0 +1,67 @@ +using System.Collections.Generic; +using MediaBrowser.Controller.Dto; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Model.Dto; +using MediaBrowser.Model.Entities; +using System; +using System.Threading; +using MediaBrowser.Model.Querying; + +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="userId">The user id.</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> + /// <returns>Task.</returns> + void SaveUserData(Guid userId, BaseItem item, UserItemData userData, UserDataSaveReason reason, CancellationToken cancellationToken); + void SaveUserData(User userId, BaseItem item, UserItemData userData, UserDataSaveReason reason, CancellationToken cancellationToken); + + UserItemData GetUserData(User user, BaseItem item); + + UserItemData GetUserData(string userId, BaseItem item); + UserItemData GetUserData(Guid userId, BaseItem item); + + /// <summary> + /// Gets the user data dto. + /// </summary> + UserItemDataDto GetUserDataDto(BaseItem item, User user); + + UserItemDataDto GetUserDataDto(BaseItem item, BaseItemDto itemDto, User user, DtoOptions dto_options); + + /// <summary> + /// Get all user data for the given user + /// </summary> + /// <param name="userId"></param> + /// <returns></returns> + List<UserItemData> GetAllUserData(Guid userId); + + /// <summary> + /// Save the all provided user data for the given user + /// </summary> + /// <param name="userId"></param> + /// <param name="userData"></param> + /// <param name="cancellationToken"></param> + /// <returns></returns> + void SaveAllUserData(Guid userId, UserItemData[] userData, CancellationToken cancellationToken); + + /// <summary> + /// Updates playstate for an item and returns true or false indicating if it was played to completion + /// </summary> + bool UpdatePlayState(BaseItem item, UserItemData data, long? positionTicks); + } +} diff --git a/MediaBrowser.Controller/Library/IUserManager.cs b/MediaBrowser.Controller/Library/IUserManager.cs new file mode 100644 index 000000000..d29b164ef --- /dev/null +++ b/MediaBrowser.Controller/Library/IUserManager.cs @@ -0,0 +1,207 @@ +using MediaBrowser.Controller.Entities; +using MediaBrowser.Model.Configuration; +using MediaBrowser.Model.Dto; +using MediaBrowser.Model.Events; +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using MediaBrowser.Model.Users; +using MediaBrowser.Controller.Authentication; + +namespace MediaBrowser.Controller.Library +{ + /// <summary> + /// Interface IUserManager + /// </summary> + public interface IUserManager + { + /// <summary> + /// Gets the users. + /// </summary> + /// <value>The users.</value> + IEnumerable<User> Users { get; } + + /// <summary> + /// Occurs when [user updated]. + /// </summary> + event EventHandler<GenericEventArgs<User>> UserUpdated; + + /// <summary> + /// Occurs when [user deleted]. + /// </summary> + event EventHandler<GenericEventArgs<User>> UserDeleted; + + event EventHandler<GenericEventArgs<User>> UserCreated; + event EventHandler<GenericEventArgs<User>> UserPolicyUpdated; + event EventHandler<GenericEventArgs<User>> UserConfigurationUpdated; + event EventHandler<GenericEventArgs<User>> UserPasswordChanged; + event EventHandler<GenericEventArgs<User>> UserLockedOut; + + /// <summary> + /// Gets a User by Id + /// </summary> + /// <param name="id">The id.</param> + /// <returns>User.</returns> + /// <exception cref="System.ArgumentNullException"></exception> + User GetUserById(Guid id); + + /// <summary> + /// Gets the user by identifier. + /// </summary> + /// <param name="id">The identifier.</param> + /// <returns>User.</returns> + User GetUserById(string id); + + /// <summary> + /// Gets the name of the user by. + /// </summary> + /// <param name="name">The name.</param> + /// <returns>User.</returns> + User GetUserByName(string name); + + /// <summary> + /// Refreshes metadata for each user + /// </summary> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task.</returns> + Task RefreshUsersMetadata(CancellationToken cancellationToken); + + /// <summary> + /// Renames the user. + /// </summary> + /// <param name="user">The user.</param> + /// <param name="newName">The new name.</param> + /// <returns>Task.</returns> + /// <exception cref="System.ArgumentNullException">user</exception> + /// <exception cref="System.ArgumentException"></exception> + Task RenameUser(User user, string newName); + + /// <summary> + /// Updates the user. + /// </summary> + /// <param name="user">The user.</param> + /// <exception cref="System.ArgumentNullException">user</exception> + /// <exception cref="System.ArgumentException"></exception> + void UpdateUser(User user); + + /// <summary> + /// Creates the user. + /// </summary> + /// <param name="name">The name.</param> + /// <returns>User.</returns> + /// <exception cref="System.ArgumentNullException">name</exception> + /// <exception cref="System.ArgumentException"></exception> + Task<User> CreateUser(string name); + + /// <summary> + /// Deletes the user. + /// </summary> + /// <param name="user">The user.</param> + /// <returns>Task.</returns> + /// <exception cref="System.ArgumentNullException">user</exception> + /// <exception cref="System.ArgumentException"></exception> + Task DeleteUser(User user); + + /// <summary> + /// Resets the password. + /// </summary> + /// <param name="user">The user.</param> + /// <returns>Task.</returns> + Task ResetPassword(User user); + + /// <summary> + /// Gets the offline user dto. + /// </summary> + /// <param name="user">The user.</param> + /// <returns>UserDto.</returns> + UserDto GetOfflineUserDto(User user); + + /// <summary> + /// Resets the easy password. + /// </summary> + /// <param name="user">The user.</param> + /// <returns>Task.</returns> + void ResetEasyPassword(User user); + + /// <summary> + /// Changes the password. + /// </summary> + Task ChangePassword(User user, string newPassword); + + /// <summary> + /// Changes the easy password. + /// </summary> + void ChangeEasyPassword(User user, string newPassword, string newPasswordSha1); + + /// <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> + Task<User> AuthenticateUser(string username, string password, string passwordSha1, 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); + + /// <summary> + /// Gets the user policy. + /// </summary> + /// <param name="user">The user.</param> + /// <returns>UserPolicy.</returns> + UserPolicy GetUserPolicy(User user); + + /// <summary> + /// Gets the user configuration. + /// </summary> + /// <param name="user">The user.</param> + /// <returns>UserConfiguration.</returns> + UserConfiguration GetUserConfiguration(User user); + + /// <summary> + /// Updates the configuration. + /// </summary> + /// <param name="userId">The user identifier.</param> + /// <param name="newConfiguration">The new configuration.</param> + /// <returns>Task.</returns> + void UpdateConfiguration(Guid userId, UserConfiguration newConfiguration); + + void UpdateConfiguration(User user, UserConfiguration newConfiguration); + + /// <summary> + /// Updates the user policy. + /// </summary> + /// <param name="userId">The user identifier.</param> + /// <param name="userPolicy">The user policy.</param> + void UpdateUserPolicy(Guid userId, UserPolicy userPolicy); + + /// <summary> + /// Makes the valid username. + /// </summary> + /// <param name="username">The username.</param> + /// <returns>System.String.</returns> + string MakeValidUsername(string username); + + void AddParts(IEnumerable<IAuthenticationProvider> authenticationProviders); + + NameIdPair[] GetAuthenticationProviders(); + } +} diff --git a/MediaBrowser.Controller/Library/IUserViewManager.cs b/MediaBrowser.Controller/Library/IUserViewManager.cs new file mode 100644 index 000000000..f4649777c --- /dev/null +++ b/MediaBrowser.Controller/Library/IUserViewManager.cs @@ -0,0 +1,19 @@ +using MediaBrowser.Controller.Entities; +using MediaBrowser.Model.Library; +using MediaBrowser.Model.Querying; +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using MediaBrowser.Controller.Dto; + +namespace MediaBrowser.Controller.Library +{ + public interface IUserViewManager + { + Folder[] GetUserViews(UserViewQuery query); + UserView GetUserSubView(Guid parentId, string type, string localizationKey, string sortName); + + List<Tuple<BaseItem, List<BaseItem>>> GetLatestItems(LatestItemsQuery request, DtoOptions options); + } +} diff --git a/MediaBrowser.Controller/Library/IntroInfo.cs b/MediaBrowser.Controller/Library/IntroInfo.cs new file mode 100644 index 000000000..d0e61d0f0 --- /dev/null +++ b/MediaBrowser.Controller/Library/IntroInfo.cs @@ -0,0 +1,19 @@ +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; } + } +}
\ No newline at end of file diff --git a/MediaBrowser.Controller/Library/ItemChangeEventArgs.cs b/MediaBrowser.Controller/Library/ItemChangeEventArgs.cs new file mode 100644 index 000000000..e671490d3 --- /dev/null +++ b/MediaBrowser.Controller/Library/ItemChangeEventArgs.cs @@ -0,0 +1,24 @@ +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; } + } +} diff --git a/MediaBrowser.Controller/Library/ItemResolveArgs.cs b/MediaBrowser.Controller/Library/ItemResolveArgs.cs new file mode 100644 index 000000000..7197425f3 --- /dev/null +++ b/MediaBrowser.Controller/Library/ItemResolveArgs.cs @@ -0,0 +1,281 @@ +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Providers; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.IO; +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 : EventArgs + { + /// <summary> + /// The _app paths + /// </summary> + private readonly IServerApplicationPaths _appPaths; + + public IDirectoryService DirectoryService { get; private set; } + + /// <summary> + /// Initializes a new instance of the <see cref="ItemResolveArgs" /> class. + /// </summary> + /// <param name="appPaths">The app paths.</param> + /// <param name="directoryService">The directory service.</param> + public ItemResolveArgs(IServerApplicationPaths appPaths, IDirectoryService directoryService) + { + _appPaths = appPaths; + DirectoryService = directoryService; + } + + /// <summary> + /// Gets the file system children. + /// </summary> + /// <value>The file system children.</value> + public FileSystemMetadata[] FileSystemChildren { get; set; } + + public LibraryOptions LibraryOptions { get; set; } + + public LibraryOptions GetLibraryOptions() + { + return LibraryOptions ?? (LibraryOptions = (Parent == null ? new LibraryOptions() : BaseItem.LibraryManager.GetLibraryOptions(Parent))); + } + + /// <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 or sets the path. + /// </summary> + /// <value>The path.</value> + public string Path { get; set; } + + /// <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 + { + get + { + return 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 = BaseItem.FileSystem.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 + { + get + { + return 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; } + + public bool HasParent<T>() + where T : Folder + { + var parent = Parent; + + if (parent != 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 == null) + { + var parents = parent.GetParents(); + foreach (var currentParent in parents) + { + if (currentParent is T) + { + return true; + } + } + } + + return item != null; + + } + return false; + } + + /// <summary> + /// Adds the additional location. + /// </summary> + /// <param name="path">The path.</param> + /// <exception cref="System.ArgumentNullException"></exception> + public void AddAdditionalLocation(string path) + { + if (string.IsNullOrEmpty(path)) + { + throw new ArgumentNullException(); + } + + if (AdditionalLocations == null) + { + AdditionalLocations = new List<string>(); + } + + AdditionalLocations.Add(path); + } + + /// <summary> + /// Gets the physical locations. + /// </summary> + /// <value>The physical locations.</value> + public string[] PhysicalLocations + { + get + { + var paths = string.IsNullOrEmpty(Path) ? new string[] { } : new[] { Path }; + return AdditionalLocations == null ? paths : paths.Concat(AdditionalLocations).ToArray(); + } + } + + /// <summary> + /// Gets the name of the file system entry by. + /// </summary> + /// <param name="name">The name.</param> + /// <returns>FileSystemInfo.</returns> + /// <exception cref="System.ArgumentNullException"></exception> + public FileSystemMetadata GetFileSystemEntryByName(string name) + { + if (string.IsNullOrEmpty(name)) + { + throw new ArgumentNullException(); + } + + 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="System.ArgumentNullException"></exception> + public FileSystemMetadata GetFileSystemEntryByPath(string path) + { + if (string.IsNullOrEmpty(path)) + { + throw new ArgumentNullException(); + } + + 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) != null; + } + + public string GetCollectionType() + { + return CollectionType; + } + + public string CollectionType { get; set; } + + #region Equality Overrides + + /// <summary> + /// Determines whether the specified <see cref="System.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="System.Object" /> is equal to this instance; otherwise, <c>false</c>.</returns> + public override bool Equals(object obj) + { + return Equals(obj as ItemResolveArgs); + } + + /// <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(); + } + + /// <summary> + /// Equalses the specified args. + /// </summary> + /// <param name="args">The args.</param> + /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns> + protected bool Equals(ItemResolveArgs args) + { + if (args != null) + { + if (args.Path == null && Path == null) return true; + return args.Path != null && BaseItem.FileSystem.AreEqual(args.Path, Path); + } + return false; + } + + #endregion + } + +} diff --git a/MediaBrowser.Controller/Library/ItemUpdateType.cs b/MediaBrowser.Controller/Library/ItemUpdateType.cs new file mode 100644 index 000000000..cf6263356 --- /dev/null +++ b/MediaBrowser.Controller/Library/ItemUpdateType.cs @@ -0,0 +1,14 @@ +using System; + +namespace MediaBrowser.Controller.Library +{ + [Flags] + public enum ItemUpdateType + { + None = 1, + MetadataImport = 2, + ImageUpdate = 4, + MetadataDownload = 8, + MetadataEdit = 16 + } +} diff --git a/MediaBrowser.Controller/Library/LibraryManagerExtensions.cs b/MediaBrowser.Controller/Library/LibraryManagerExtensions.cs new file mode 100644 index 000000000..ec69bea6e --- /dev/null +++ b/MediaBrowser.Controller/Library/LibraryManagerExtensions.cs @@ -0,0 +1,13 @@ +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)); + } + } +}
\ No newline at end of file diff --git a/MediaBrowser.Controller/Library/MetadataConfigurationStore.cs b/MediaBrowser.Controller/Library/MetadataConfigurationStore.cs new file mode 100644 index 000000000..dc2fa0f99 --- /dev/null +++ b/MediaBrowser.Controller/Library/MetadataConfigurationStore.cs @@ -0,0 +1,29 @@ +using MediaBrowser.Common.Configuration; +using MediaBrowser.Model.Configuration; +using System.Collections.Generic; + +namespace MediaBrowser.Controller.Library +{ + public class MetadataConfigurationStore : IConfigurationFactory + { + public IEnumerable<ConfigurationStore> GetConfigurations() + { + return new ConfigurationStore[] + { + new ConfigurationStore + { + Key = "metadata", + ConfigurationType = typeof(MetadataConfiguration) + } + }; + } + } + + public static class MetadataConfigurationExtensions + { + public static MetadataConfiguration GetMetadataConfiguration(this IConfigurationManager config) + { + return config.GetConfiguration<MetadataConfiguration>("metadata"); + } + } +} diff --git a/MediaBrowser.Controller/Library/NameExtensions.cs b/MediaBrowser.Controller/Library/NameExtensions.cs new file mode 100644 index 000000000..bab334a6d --- /dev/null +++ b/MediaBrowser.Controller/Library/NameExtensions.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using MediaBrowser.Controller.Extensions; +using MediaBrowser.Model.Extensions; + +namespace MediaBrowser.Controller.Library +{ + public static class NameExtensions + { + private static string RemoveDiacritics(string name) + { + if (name == null) + { + return string.Empty; + } + + //return name; + return name.RemoveDiacritics(); + } + + public static IEnumerable<string> DistinctNames(this IEnumerable<string> names) + { + return names.DistinctBy(RemoveDiacritics, StringComparer.OrdinalIgnoreCase); + } + } +} diff --git a/MediaBrowser.Controller/Library/PlaybackProgressEventArgs.cs b/MediaBrowser.Controller/Library/PlaybackProgressEventArgs.cs new file mode 100644 index 000000000..00d9932a7 --- /dev/null +++ b/MediaBrowser.Controller/Library/PlaybackProgressEventArgs.cs @@ -0,0 +1,34 @@ +using MediaBrowser.Controller.Entities; +using MediaBrowser.Model.Dto; +using System; +using System.Collections.Generic; +using MediaBrowser.Controller.Session; + +namespace MediaBrowser.Controller.Library +{ + /// <summary> + /// Holds information about a playback progress event + /// </summary> + public class PlaybackProgressEventArgs : EventArgs + { + 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; } + + public PlaybackProgressEventArgs() + { + Users = new List<User>(); + } + } +} diff --git a/MediaBrowser.Controller/Library/PlaybackStopEventArgs.cs b/MediaBrowser.Controller/Library/PlaybackStopEventArgs.cs new file mode 100644 index 000000000..b0f6799fc --- /dev/null +++ b/MediaBrowser.Controller/Library/PlaybackStopEventArgs.cs @@ -0,0 +1,11 @@ +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; } + } +}
\ No newline at end of file diff --git a/MediaBrowser.Controller/Library/Profiler.cs b/MediaBrowser.Controller/Library/Profiler.cs new file mode 100644 index 000000000..3957c3020 --- /dev/null +++ b/MediaBrowser.Controller/Library/Profiler.cs @@ -0,0 +1,76 @@ +using MediaBrowser.Model.Logging; +using System; +using System.Diagnostics; + +namespace MediaBrowser.Controller.Library +{ + /// <summary> + /// Class Profiler + /// </summary> + public class Profiler : IDisposable + { + /// <summary> + /// The name + /// </summary> + readonly string _name; + /// <summary> + /// The stopwatch + /// </summary> + readonly Stopwatch _stopwatch; + + /// <summary> + /// The _logger + /// </summary> + private readonly ILogger _logger; + + /// <summary> + /// Initializes a new instance of the <see cref="Profiler" /> class. + /// </summary> + /// <param name="name">The name.</param> + /// <param name="logger">The logger.</param> + public Profiler(string name, ILogger logger) + { + this._name = name; + + _logger = logger; + + _stopwatch = new Stopwatch(); + _stopwatch.Start(); + } + #region IDisposable Members + + /// <summary> + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// </summary> + public void Dispose() + { + Dispose(true); + } + + /// <summary> + /// Releases unmanaged and - optionally - managed resources. + /// </summary> + /// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param> + protected virtual void Dispose(bool dispose) + { + if (dispose) + { + _stopwatch.Stop(); + string message; + if (_stopwatch.ElapsedMilliseconds > 300000) + { + message = string.Format("{0} took {1} minutes.", + _name, ((float)_stopwatch.ElapsedMilliseconds / 60000).ToString("F")); + } + else + { + message = string.Format("{0} took {1} seconds.", + _name, ((float)_stopwatch.ElapsedMilliseconds / 1000).ToString("#0.000")); + } + _logger.Info(message); + } + } + + #endregion + } +} diff --git a/MediaBrowser.Controller/Library/SearchHintInfo.cs b/MediaBrowser.Controller/Library/SearchHintInfo.cs new file mode 100644 index 000000000..f832811c2 --- /dev/null +++ b/MediaBrowser.Controller/Library/SearchHintInfo.cs @@ -0,0 +1,22 @@ +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; } + } +} diff --git a/MediaBrowser.Controller/Library/TVUtils.cs b/MediaBrowser.Controller/Library/TVUtils.cs new file mode 100644 index 000000000..dc95ba112 --- /dev/null +++ b/MediaBrowser.Controller/Library/TVUtils.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; + +namespace MediaBrowser.Controller.Library +{ + /// <summary> + /// Class TVUtils + /// </summary> + public static class TVUtils + { + /// <summary> + /// The TVDB API key + /// </summary> + public static readonly string TvdbApiKey = "B89CE93890E9419B"; + public static readonly string TvdbBaseUrl = "https://www.thetvdb.com/"; + /// <summary> + /// The banner URL + /// </summary> + public static readonly string BannerUrl = TvdbBaseUrl + "banners/"; + + /// <summary> + /// Gets the air days. + /// </summary> + /// <param name="day">The day.</param> + /// <returns>List{DayOfWeek}.</returns> + public static DayOfWeek[] GetAirDays(string day) + { + if (!string.IsNullOrEmpty(day)) + { + if (string.Equals(day, "Daily", StringComparison.OrdinalIgnoreCase)) + { + return new DayOfWeek[] + { + DayOfWeek.Sunday, + DayOfWeek.Monday, + DayOfWeek.Tuesday, + DayOfWeek.Wednesday, + DayOfWeek.Thursday, + DayOfWeek.Friday, + DayOfWeek.Saturday + }; + } + + DayOfWeek value; + + if (Enum.TryParse(day, true, out value)) + { + return new DayOfWeek[] + { + value + }; + } + + return new DayOfWeek[]{}; + } + return null; + } + } +} diff --git a/MediaBrowser.Controller/Library/UserDataSaveEventArgs.cs b/MediaBrowser.Controller/Library/UserDataSaveEventArgs.cs new file mode 100644 index 000000000..d921a7077 --- /dev/null +++ b/MediaBrowser.Controller/Library/UserDataSaveEventArgs.cs @@ -0,0 +1,39 @@ +using MediaBrowser.Controller.Entities; +using MediaBrowser.Model.Entities; +using System; +using System.Collections.Generic; + +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; } + } +} |
