diff options
Diffstat (limited to 'MediaBrowser.Controller')
43 files changed, 605 insertions, 250 deletions
diff --git a/MediaBrowser.Controller/Channels/IChannelManager.cs b/MediaBrowser.Controller/Channels/IChannelManager.cs index f5c4ab373..8d3e0f596 100644 --- a/MediaBrowser.Controller/Channels/IChannelManager.cs +++ b/MediaBrowser.Controller/Channels/IChannelManager.cs @@ -121,10 +121,9 @@ namespace MediaBrowser.Controller.Channels /// <summary> /// Gets the channel folder. /// </summary> - /// <param name="userId">The user identifier.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>BaseItemDto.</returns> - Task<Folder> GetInternalChannelFolder(string userId, CancellationToken cancellationToken); + Task<Folder> GetInternalChannelFolder(CancellationToken cancellationToken); /// <summary> /// Gets the channel folder. diff --git a/MediaBrowser.Controller/Dlna/IDeviceDiscovery.cs b/MediaBrowser.Controller/Dlna/IDeviceDiscovery.cs new file mode 100644 index 000000000..e8083b363 --- /dev/null +++ b/MediaBrowser.Controller/Dlna/IDeviceDiscovery.cs @@ -0,0 +1,10 @@ +using System; + +namespace MediaBrowser.Controller.Dlna +{ + public interface IDeviceDiscovery + { + event EventHandler<SsdpMessageEventArgs> DeviceDiscovered; + event EventHandler<SsdpMessageEventArgs> DeviceLeft; + } +} diff --git a/MediaBrowser.Controller/Dto/IDtoService.cs b/MediaBrowser.Controller/Dto/IDtoService.cs index 5ec8f274b..e4ab29102 100644 --- a/MediaBrowser.Controller/Dto/IDtoService.cs +++ b/MediaBrowser.Controller/Dto/IDtoService.cs @@ -81,13 +81,11 @@ namespace MediaBrowser.Controller.Dto /// <summary> /// Gets the item by name dto. /// </summary> - /// <typeparam name="T"></typeparam> /// <param name="item">The item.</param> /// <param name="options">The options.</param> /// <param name="taggedItems">The tagged items.</param> /// <param name="user">The user.</param> /// <returns>BaseItemDto.</returns> - BaseItemDto GetItemByNameDto<T>(T item, DtoOptions options, List<BaseItem> taggedItems, User user = null) - where T : BaseItem, IItemByName; + BaseItemDto GetItemByNameDto(BaseItem item, DtoOptions options, List<BaseItem> taggedItems, User user = null); } } diff --git a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs index 8a77d7616..807beee52 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs @@ -54,6 +54,12 @@ namespace MediaBrowser.Controller.Entities.Audio get { return AlbumArtists.FirstOrDefault(); } } + [IgnoreDataMember] + public override bool SupportsPeople + { + get { return false; } + } + public List<string> AlbumArtists { get; set; } /// <summary> diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index d9dbf265f..594b5ca93 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -142,7 +142,7 @@ namespace MediaBrowser.Controller.Entities public virtual string Path { get; set; } [IgnoreDataMember] - protected internal bool IsOffline { get; set; } + public bool IsOffline { get; set; } /// <summary> /// Returns the folder containing the item. @@ -419,6 +419,10 @@ namespace MediaBrowser.Controller.Entities return _sortName ?? (_sortName = CreateSortName()); } + set + { + _sortName = value; + } } public string GetInternalMetadataPath() @@ -485,6 +489,7 @@ namespace MediaBrowser.Controller.Entities /// Gets or sets the parent. /// </summary> /// <value>The parent.</value> + [IgnoreDataMember] public Folder Parent { get @@ -1115,6 +1120,23 @@ namespace MediaBrowser.Controller.Entities return value.Value <= maxAllowedRating.Value; } + public int? GetParentalRatingValue() + { + var rating = CustomRatingForComparison; + + if (string.IsNullOrWhiteSpace(rating)) + { + rating = OfficialRatingForComparison; + } + + if (string.IsNullOrWhiteSpace(rating)) + { + return null; + } + + return LocalizationManager.GetRatingLevel(rating); + } + private bool IsVisibleViaTags(User user) { var hasTags = this as IHasTags; diff --git a/MediaBrowser.Controller/Entities/CollectionFolder.cs b/MediaBrowser.Controller/Entities/CollectionFolder.cs index 3a610be64..8821f35c8 100644 --- a/MediaBrowser.Controller/Entities/CollectionFolder.cs +++ b/MediaBrowser.Controller/Entities/CollectionFolder.cs @@ -35,6 +35,15 @@ namespace MediaBrowser.Controller.Entities } } + [IgnoreDataMember] + protected override bool SupportsShortcutChildren + { + get + { + return true; + } + } + public override bool CanDelete() { return false; diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index 22efb09e1..c3ac77328 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -1,7 +1,6 @@ using MediaBrowser.Common.Progress; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; -using MediaBrowser.Controller.Localization; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; @@ -14,7 +13,6 @@ using System.Linq; using System.Runtime.Serialization; using System.Threading; using System.Threading.Tasks; -using MediaBrowser.Model.Users; namespace MediaBrowser.Controller.Entities { @@ -50,7 +48,7 @@ namespace MediaBrowser.Controller.Entities [IgnoreDataMember] public virtual bool IsPreSorted { - get { return false; } + get { return ConfigurationManager.Configuration.EnableWindowsShortcuts; } } /// <summary> @@ -122,7 +120,7 @@ namespace MediaBrowser.Controller.Entities [IgnoreDataMember] protected virtual bool SupportsShortcutChildren { - get { return true; } + get { return false; } } /// <summary> @@ -176,7 +174,7 @@ namespace MediaBrowser.Controller.Entities protected void AddChildInternal(BaseItem child) { var actualChildren = ActualChildren; - + lock (_childrenSyncLock) { var newChildren = actualChildren.ToList(); @@ -1070,7 +1068,7 @@ namespace MediaBrowser.Controller.Entities { var changesFound = false; - if (SupportsShortcutChildren && LocationType == LocationType.FileSystem) + if (LocationType == LocationType.FileSystem) { if (RefreshLinkedChildren(fileSystemChildren)) { @@ -1092,37 +1090,43 @@ namespace MediaBrowser.Controller.Entities var currentManualLinks = LinkedChildren.Where(i => i.Type == LinkedChildType.Manual).ToList(); var currentShortcutLinks = LinkedChildren.Where(i => i.Type == LinkedChildType.Shortcut).ToList(); - var newShortcutLinks = fileSystemChildren - .Where(i => (i.Attributes & FileAttributes.Directory) != FileAttributes.Directory && FileSystem.IsShortcut(i.FullName)) - .Select(i => - { - try + List<LinkedChild> newShortcutLinks; + + if (SupportsShortcutChildren) + { + newShortcutLinks = fileSystemChildren + .Where(i => (i.Attributes & FileAttributes.Directory) != FileAttributes.Directory && FileSystem.IsShortcut(i.FullName)) + .Select(i => { - Logger.Debug("Found shortcut at {0}", i.FullName); + try + { + Logger.Debug("Found shortcut at {0}", i.FullName); - var resolvedPath = FileSystem.ResolveShortcut(i.FullName); + var resolvedPath = FileSystem.ResolveShortcut(i.FullName); - if (!string.IsNullOrEmpty(resolvedPath)) - { - return new LinkedChild + if (!string.IsNullOrEmpty(resolvedPath)) { - Path = resolvedPath, - Type = LinkedChildType.Shortcut - }; - } + return new LinkedChild + { + Path = resolvedPath, + Type = LinkedChildType.Shortcut + }; + } - Logger.Error("Error resolving shortcut {0}", i.FullName); + Logger.Error("Error resolving shortcut {0}", i.FullName); - return null; - } - catch (IOException ex) - { - Logger.ErrorException("Error resolving shortcut {0}", ex, i.FullName); - return null; - } - }) - .Where(i => i != null) - .ToList(); + return null; + } + catch (IOException ex) + { + Logger.ErrorException("Error resolving shortcut {0}", ex, i.FullName); + return null; + } + }) + .Where(i => i != null) + .ToList(); + } + else { newShortcutLinks = new List<LinkedChild>(); } if (!newShortcutLinks.SequenceEqual(currentShortcutLinks, new LinkedChildComparer())) { diff --git a/MediaBrowser.Controller/Entities/ICollectionFolder.cs b/MediaBrowser.Controller/Entities/ICollectionFolder.cs index f46d7ed6f..b55ca0a17 100644 --- a/MediaBrowser.Controller/Entities/ICollectionFolder.cs +++ b/MediaBrowser.Controller/Entities/ICollectionFolder.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; namespace MediaBrowser.Controller.Entities { @@ -14,4 +15,17 @@ namespace MediaBrowser.Controller.Entities Guid Id { get; } IEnumerable<string> PhysicalLocations { get; } } + + public static class CollectionFolderExtensions + { + public static string GetViewType(this ICollectionFolder folder, User user) + { + if (user.Configuration.PlainFolderViews.Contains(folder.Id.ToString("N"), StringComparer.OrdinalIgnoreCase)) + { + return null; + } + + return folder.CollectionType; + } + } } diff --git a/MediaBrowser.Controller/Entities/IHasProgramAttributes.cs b/MediaBrowser.Controller/Entities/IHasProgramAttributes.cs index 391c8f7a7..9938a4489 100644 --- a/MediaBrowser.Controller/Entities/IHasProgramAttributes.cs +++ b/MediaBrowser.Controller/Entities/IHasProgramAttributes.cs @@ -11,6 +11,7 @@ namespace MediaBrowser.Controller.Entities bool IsKids { get; set; } bool IsRepeat { get; set; } bool? IsHD { get; set; } + bool IsSeries { get; set; } bool IsLive { get; set; } bool IsPremiere { get; set; } ProgramAudio? Audio { get; set; } diff --git a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs index c5e60a73d..0af4972f7 100644 --- a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs +++ b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs @@ -1,6 +1,6 @@ -using System.Collections.Generic; -using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Entities; using System; +using System.Collections.Generic; namespace MediaBrowser.Controller.Entities { @@ -40,6 +40,7 @@ namespace MediaBrowser.Controller.Entities public string NameStartsWithOrGreater { get; set; } public string NameStartsWith { get; set; } public string NameLessThan { get; set; } + public string NameContains { get; set; } public string Person { get; set; } public string[] PersonIds { get; set; } @@ -93,7 +94,11 @@ namespace MediaBrowser.Controller.Entities public string[] ChannelIds { get; set; } internal List<Guid> ItemIdsFromPersonFilters { get; set; } + public int? MaxParentalRating { get; set; } + public bool? IsCurrentSchema { get; set; } + public bool? HasDeadParentId { get; set; } + public InternalItemsQuery() { Tags = new string[] { }; diff --git a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs index 02e9d4cf9..9317f688f 100644 --- a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs +++ b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs @@ -74,6 +74,15 @@ namespace MediaBrowser.Controller.Entities.Movies } } + [IgnoreDataMember] + protected override bool SupportsShortcutChildren + { + get + { + return true; + } + } + public override bool IsAuthorizedToDelete(User user) { return true; diff --git a/MediaBrowser.Controller/Entities/Movies/Movie.cs b/MediaBrowser.Controller/Entities/Movies/Movie.cs index fc07f6778..083ec0cb4 100644 --- a/MediaBrowser.Controller/Entities/Movies/Movie.cs +++ b/MediaBrowser.Controller/Entities/Movies/Movie.cs @@ -100,16 +100,23 @@ namespace MediaBrowser.Controller.Entities.Movies /// <returns>System.String.</returns> protected override string CreateUserDataKey() { - var key = this.GetProviderId(MetadataProviders.Tmdb); + var key = GetMovieUserDataKey(this); if (string.IsNullOrWhiteSpace(key)) { - key = this.GetProviderId(MetadataProviders.Imdb); + key = base.CreateUserDataKey(); } + return key; + } + + public static string GetMovieUserDataKey(BaseItem movie) + { + var key = movie.GetProviderId(MetadataProviders.Tmdb); + if (string.IsNullOrWhiteSpace(key)) { - key = base.CreateUserDataKey(); + key = movie.GetProviderId(MetadataProviders.Imdb); } return key; diff --git a/MediaBrowser.Controller/Entities/TV/Episode.cs b/MediaBrowser.Controller/Entities/TV/Episode.cs index 8f5b8f6cf..5163c3de4 100644 --- a/MediaBrowser.Controller/Entities/TV/Episode.cs +++ b/MediaBrowser.Controller/Entities/TV/Episode.cs @@ -150,7 +150,7 @@ namespace MediaBrowser.Controller.Entities.TV { var series = Series; - if (ParentIndexNumber.HasValue) + if (series != null && ParentIndexNumber.HasValue) { var findNumber = ParentIndexNumber.Value; diff --git a/MediaBrowser.Controller/Entities/UserRootFolder.cs b/MediaBrowser.Controller/Entities/UserRootFolder.cs index b065ae171..a78beb645 100644 --- a/MediaBrowser.Controller/Entities/UserRootFolder.cs +++ b/MediaBrowser.Controller/Entities/UserRootFolder.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Controller.Providers; +using System.Runtime.Serialization; +using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Library; using MediaBrowser.Model.Querying; @@ -36,6 +37,16 @@ namespace MediaBrowser.Controller.Entities return PostFilterAndSort(result.Where(filter), query); } + [IgnoreDataMember] + protected override bool SupportsShortcutChildren + { + get + { + return true; + } + } + + [IgnoreDataMember] public override bool IsPreSorted { get diff --git a/MediaBrowser.Controller/Entities/UserView.cs b/MediaBrowser.Controller/Entities/UserView.cs index dad6de01a..488e54cc3 100644 --- a/MediaBrowser.Controller/Entities/UserView.cs +++ b/MediaBrowser.Controller/Entities/UserView.cs @@ -1,10 +1,10 @@ -using System.Runtime.Serialization; -using MediaBrowser.Controller.Playlists; +using MediaBrowser.Controller.Playlists; using MediaBrowser.Controller.TV; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Querying; using System; using System.Collections.Generic; +using System.Runtime.Serialization; using System.Threading.Tasks; namespace MediaBrowser.Controller.Entities @@ -15,7 +15,7 @@ namespace MediaBrowser.Controller.Entities public Guid ParentId { get; set; } public Guid? UserId { get; set; } - + public static ITVSeriesManager TVSeriesManager; public static IPlaylistManager PlaylistManager; diff --git a/MediaBrowser.Controller/Entities/UserViewBuilder.cs b/MediaBrowser.Controller/Entities/UserViewBuilder.cs index b2d359277..cee5dadd2 100644 --- a/MediaBrowser.Controller/Entities/UserViewBuilder.cs +++ b/MediaBrowser.Controller/Entities/UserViewBuilder.cs @@ -66,7 +66,7 @@ namespace MediaBrowser.Controller.Entities { var result = await _channelManager.GetChannelsInternal(new ChannelQuery { - UserId = user.Id.ToString("N"), + UserId = user == null ? null : user.Id.ToString("N"), Limit = query.Limit, StartIndex = query.StartIndex @@ -264,10 +264,7 @@ namespace MediaBrowser.Controller.Entities private async Task<QueryResult<BaseItem>> FindPlaylists(Folder parent, User user, InternalItemsQuery query) { - var collectionFolders = user.RootFolder.GetChildren(user, true).Select(i => i.Id).ToList(); - - var list = _playlistManager.GetPlaylists(user.Id.ToString("N")) - .Where(i => i.GetChildren(user, true).Any(media => _libraryManager.GetCollectionFolders(media).Select(c => c.Id).Any(collectionFolders.Contains))); + var list = _playlistManager.GetPlaylists(user.Id.ToString("N")); return GetResult(list, parent, query); } @@ -288,14 +285,14 @@ namespace MediaBrowser.Controller.Entities var list = new List<BaseItem>(); - list.Add(await GetUserView(SpecialFolder.MusicLatest, user, "0", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.MusicPlaylists, user, "1", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.MusicAlbums, user, "2", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.MusicAlbumArtists, user, "3", parent).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.MusicLatest, "0", parent).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.MusicPlaylists, "1", parent).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.MusicAlbums, "2", parent).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.MusicAlbumArtists, "3", parent).ConfigureAwait(false)); //list.Add(await GetUserView(SpecialFolder.MusicArtists, user, "4", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.MusicSongs, user, "5", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.MusicGenres, user, "6", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.MusicFavorites, user, "7", parent).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.MusicSongs, "5", parent).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.MusicGenres, "6", parent).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.MusicFavorites, "7", parent).ConfigureAwait(false)); return GetResult(list, parent, query); } @@ -304,9 +301,9 @@ namespace MediaBrowser.Controller.Entities { var list = new List<BaseItem>(); - list.Add(await GetUserView(SpecialFolder.MusicFavoriteAlbums, user, "0", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.MusicFavoriteArtists, user, "1", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.MusicFavoriteSongs, user, "2", parent).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.MusicFavoriteAlbums, "0", parent).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.MusicFavoriteArtists, "1", parent).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.MusicFavoriteSongs, "2", parent).ConfigureAwait(false)); return GetResult(list, parent, query); } @@ -332,7 +329,7 @@ namespace MediaBrowser.Controller.Entities }) .Where(i => i != null) - .Select(i => GetUserView(i.Name, SpecialFolder.MusicGenre, user, i.SortName, parent)); + .Select(i => GetUserView(i.Name, SpecialFolder.MusicGenre, i.SortName, parent)); var genres = await Task.WhenAll(tasks).ConfigureAwait(false); @@ -344,94 +341,42 @@ namespace MediaBrowser.Controller.Entities var items = GetRecursiveChildren(queryParent, user, new[] { CollectionType.Music, CollectionType.MusicVideos }) .Where(i => !i.IsFolder) .Where(i => i.Genres.Contains(displayParent.Name, StringComparer.OrdinalIgnoreCase)) - .OfType<IHasAlbumArtist>() - .SelectMany(i => i.AlbumArtists) - .DistinctNames() - .Select(i => - { - try - { - return _libraryManager.GetArtist(i); - } - catch - { - // Already logged at lower levels - return null; - } - }) - .Where(i => i != null); + .OfType<IHasAlbumArtist>(); - return GetResult(items, queryParent, query); + var artists = _libraryManager.GetAlbumArtists(items); + + return GetResult(artists, queryParent, query); } private QueryResult<BaseItem> GetMusicAlbumArtists(Folder parent, User user, InternalItemsQuery query) { - var artists = GetRecursiveChildren(parent, user, new[] { CollectionType.Music, CollectionType.MusicVideos }) + var items = GetRecursiveChildren(parent, user, new[] { CollectionType.Music, CollectionType.MusicVideos }) .Where(i => !i.IsFolder) - .OfType<IHasAlbumArtist>() - .SelectMany(i => i.AlbumArtists) - .DistinctNames() - .Select(i => - { - try - { - return _libraryManager.GetArtist(i); - } - catch - { - // Already logged at lower levels - return null; - } - }) - .Where(i => i != null); + .OfType<IHasAlbumArtist>(); + + var artists = _libraryManager.GetAlbumArtists(items); return GetResult(artists, parent, query); } private QueryResult<BaseItem> GetMusicArtists(Folder parent, User user, InternalItemsQuery query) { - var artists = GetRecursiveChildren(parent, user, new[] { CollectionType.Music, CollectionType.MusicVideos }) + var items = GetRecursiveChildren(parent, user, new[] { CollectionType.Music, CollectionType.MusicVideos }) .Where(i => !i.IsFolder) - .OfType<IHasArtist>() - .SelectMany(i => i.Artists) - .DistinctNames() - .Select(i => - { - try - { - return _libraryManager.GetArtist(i); - } - catch - { - // Already logged at lower levels - return null; - } - }) - .Where(i => i != null); + .OfType<IHasArtist>(); + + var artists = _libraryManager.GetArtists(items); return GetResult(artists, parent, query); } private QueryResult<BaseItem> GetFavoriteArtists(Folder parent, User user, InternalItemsQuery query) { - var artists = GetRecursiveChildren(parent, user, new[] { CollectionType.Music, CollectionType.MusicVideos }) + var items = GetRecursiveChildren(parent, user, new[] { CollectionType.Music, CollectionType.MusicVideos }) .Where(i => !i.IsFolder) - .OfType<IHasAlbumArtist>() - .SelectMany(i => i.AlbumArtists) - .DistinctNames() - .Select(i => - { - try - { - return _libraryManager.GetArtist(i); - } - catch - { - // Already logged at lower levels - return null; - } - }) - .Where(i => i != null && _userDataManager.GetUserData(user.Id, i.GetUserDataKey()).IsFavorite); + .OfType<IHasAlbumArtist>(); + + var artists = _libraryManager.GetAlbumArtists(items).Where(i => _userDataManager.GetUserData(user.Id, i.GetUserDataKey()).IsFavorite); return GetResult(artists, parent, query); } @@ -498,12 +443,12 @@ namespace MediaBrowser.Controller.Entities var list = new List<BaseItem>(); - list.Add(await GetUserView(SpecialFolder.MovieResume, user, "0", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.MovieLatest, user, "1", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.MovieMovies, user, "2", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.MovieCollections, user, "3", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.MovieFavorites, user, "4", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.MovieGenres, user, "5", parent).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.MovieResume, "0", parent).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.MovieLatest, "1", parent).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.MovieMovies, "2", parent).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.MovieCollections, "3", parent).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.MovieFavorites, "4", parent).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.MovieGenres, "5", parent).ConfigureAwait(false)); return GetResult(list, parent, query); } @@ -609,7 +554,7 @@ namespace MediaBrowser.Controller.Entities }) .Where(i => i != null) - .Select(i => GetUserView(i.Name, SpecialFolder.MovieGenre, user, i.SortName, parent)); + .Select(i => GetUserView(i.Name, SpecialFolder.MovieGenre, i.SortName, parent)); var genres = await Task.WhenAll(tasks).ConfigureAwait(false); @@ -671,13 +616,13 @@ namespace MediaBrowser.Controller.Entities var list = new List<BaseItem>(); - list.Add(await GetUserView(SpecialFolder.TvResume, user, "0", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.TvNextUp, user, "1", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.TvLatest, user, "2", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.TvShowSeries, user, "3", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.TvFavoriteSeries, user, "4", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.TvFavoriteEpisodes, user, "5", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.TvGenres, user, "6", parent).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.TvResume, "0", parent).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.TvNextUp, "1", parent).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.TvLatest, "2", parent).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.TvShowSeries, "3", parent).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.TvFavoriteSeries, "4", parent).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.TvFavoriteEpisodes, "5", parent).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.TvGenres, "6", parent).ConfigureAwait(false)); return GetResult(list, parent, query); } @@ -692,11 +637,11 @@ namespace MediaBrowser.Controller.Entities var list = new List<BaseItem>(); - list.Add(await GetUserView(SpecialFolder.LatestGames, user, "0", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.RecentlyPlayedGames, user, "1", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.GameFavorites, user, "2", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.GameSystems, user, "3", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.GameGenres, user, "4", parent).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.LatestGames, "0", parent).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.RecentlyPlayedGames, "1", parent).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.GameFavorites, "2", parent).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.GameSystems, "3", parent).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.GameGenres, "4", parent).ConfigureAwait(false)); return GetResult(list, parent, query); } @@ -794,7 +739,7 @@ namespace MediaBrowser.Controller.Entities }) .Where(i => i != null) - .Select(i => GetUserView(i.Name, SpecialFolder.TvGenre, user, i.SortName, parent)); + .Select(i => GetUserView(i.Name, SpecialFolder.TvGenre, i.SortName, parent)); var genres = await Task.WhenAll(tasks).ConfigureAwait(false); @@ -846,7 +791,7 @@ namespace MediaBrowser.Controller.Entities }) .Where(i => i != null) - .Select(i => GetUserView(i.Name, SpecialFolder.GameGenre, user, i.SortName, parent)); + .Select(i => GetUserView(i.Name, SpecialFolder.GameGenre, i.SortName, parent)); var genres = await Task.WhenAll(tasks).ConfigureAwait(false); @@ -1926,26 +1871,20 @@ namespace MediaBrowser.Controller.Entities var list = new List<BaseItem>(); //list.Add(await GetUserSubView(SpecialFolder.LiveTvNowPlaying, user, "0", parent).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.LiveTvChannels, user, string.Empty, user.RootFolder).ConfigureAwait(false)); - list.Add(await GetUserView(SpecialFolder.LiveTvRecordingGroups, user, string.Empty, user.RootFolder).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.LiveTvChannels, string.Empty, user.RootFolder).ConfigureAwait(false)); + list.Add(await GetUserView(SpecialFolder.LiveTvRecordingGroups, string.Empty, user.RootFolder).ConfigureAwait(false)); return GetResult(list, queryParent, query); } - private async Task<UserView> GetUserView(string name, string type, User user, string sortName, BaseItem parent) + private Task<UserView> GetUserView(string name, string type, string sortName, BaseItem parent) { - var view = await _userViewManager.GetUserSubView(name, parent.Id.ToString("N"), type, user, sortName, CancellationToken.None) - .ConfigureAwait(false); - - return view; + return _userViewManager.GetUserSubView(name, parent.Id.ToString("N"), type, sortName, CancellationToken.None); } - private async Task<UserView> GetUserView(string type, User user, string sortName, BaseItem parent) + private Task<UserView> GetUserView(string type, string sortName, BaseItem parent) { - var view = await _userViewManager.GetUserSubView(parent.Id.ToString("N"), type, user, sortName, CancellationToken.None) - .ConfigureAwait(false); - - return view; + return _userViewManager.GetUserSubView(parent.Id.ToString("N"), type, sortName, CancellationToken.None); } public static bool IsYearMismatched(BaseItem item, ILibraryManager libraryManager) diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs index f0bfaaf66..9331ca759 100644 --- a/MediaBrowser.Controller/Library/ILibraryManager.cs +++ b/MediaBrowser.Controller/Library/ILibraryManager.cs @@ -5,12 +5,12 @@ 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.IO; using System.Threading; using System.Threading.Tasks; -using MediaBrowser.Model.Querying; namespace MediaBrowser.Controller.Library { @@ -61,7 +61,18 @@ namespace MediaBrowser.Controller.Library /// <param name="name">The name.</param> /// <returns>Task{Artist}.</returns> MusicArtist GetArtist(string name); - + /// <summary> + /// Gets the album artists. + /// </summary> + /// <param name="items">The items.</param> + /// <returns>IEnumerable<MusicArtist>.</returns> + IEnumerable<MusicArtist> GetAlbumArtists(IEnumerable<IHasAlbumArtist> items); + /// <summary> + /// Gets the artists. + /// </summary> + /// <param name="items">The items.</param> + /// <returns>IEnumerable<MusicArtist>.</returns> + IEnumerable<MusicArtist> GetArtists(IEnumerable<IHasArtist> items); /// <summary> /// Gets a Studio /// </summary> @@ -340,7 +351,37 @@ namespace MediaBrowser.Controller.Library Task<UserView> GetNamedView(User user, string name, string viewType, - string sortName, + string sortName, + CancellationToken cancellationToken); + + /// <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> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task<UserView>.</returns> + Task<UserView> GetNamedView(string name, + string viewType, + string sortName, + CancellationToken cancellationToken); + + /// <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> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task<UserView>.</returns> + Task<UserView> GetNamedView(string name, + string parentId, + string viewType, + string sortName, + string uniqueId, CancellationToken cancellationToken); /// <summary> @@ -461,5 +502,12 @@ namespace MediaBrowser.Controller.Library /// <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); } }
\ No newline at end of file diff --git a/MediaBrowser.Controller/Library/IMetadataFileSaver.cs b/MediaBrowser.Controller/Library/IMetadataFileSaver.cs index 0883da48f..e09e58302 100644 --- a/MediaBrowser.Controller/Library/IMetadataFileSaver.cs +++ b/MediaBrowser.Controller/Library/IMetadataFileSaver.cs @@ -11,4 +11,9 @@ namespace MediaBrowser.Controller.Library /// <returns>System.String.</returns> string GetSavePath(IHasMetadata item); } + + public interface IConfigurableProvider + { + bool IsEnabled { get; } + } }
\ No newline at end of file diff --git a/MediaBrowser.Controller/Library/IMusicManager.cs b/MediaBrowser.Controller/Library/IMusicManager.cs index 0ce0687cc..9baf8b6f1 100644 --- a/MediaBrowser.Controller/Library/IMusicManager.cs +++ b/MediaBrowser.Controller/Library/IMusicManager.cs @@ -16,10 +16,10 @@ namespace MediaBrowser.Controller.Library /// <summary> /// Gets the instant mix from artist. /// </summary> - /// <param name="name">The name.</param> + /// <param name="artist">The artist.</param> /// <param name="user">The user.</param> /// <returns>IEnumerable{Audio}.</returns> - IEnumerable<Audio> GetInstantMixFromArtist(string name, User user); + IEnumerable<Audio> GetInstantMixFromArtist(MusicArtist artist, User user); /// <summary> /// Gets the instant mix from genre. /// </summary> diff --git a/MediaBrowser.Controller/Library/IUserViewManager.cs b/MediaBrowser.Controller/Library/IUserViewManager.cs index f0b862c2d..5391d113e 100644 --- a/MediaBrowser.Controller/Library/IUserViewManager.cs +++ b/MediaBrowser.Controller/Library/IUserViewManager.cs @@ -12,10 +12,9 @@ namespace MediaBrowser.Controller.Library { Task<IEnumerable<Folder>> GetUserViews(UserViewQuery query, CancellationToken cancellationToken); - Task<UserView> GetUserSubView(string name, string parentId, string type, User user, string sortName, - CancellationToken cancellationToken); + Task<UserView> GetUserSubView(string name, string parentId, string type, string sortName, CancellationToken cancellationToken); - Task<UserView> GetUserSubView(string category, string type, User user, string sortName, CancellationToken cancellationToken); + Task<UserView> GetUserSubView(string category, string type, string sortName, CancellationToken cancellationToken); List<Tuple<BaseItem, List<BaseItem>>> GetLatestItems(LatestItemsQuery request); } diff --git a/MediaBrowser.Controller/LiveTv/ChannelInfo.cs b/MediaBrowser.Controller/LiveTv/ChannelInfo.cs index cdc9c76c8..32b8abdc5 100644 --- a/MediaBrowser.Controller/LiveTv/ChannelInfo.cs +++ b/MediaBrowser.Controller/LiveTv/ChannelInfo.cs @@ -48,6 +48,10 @@ namespace MediaBrowser.Controller.LiveTv /// </summary> /// <value><c>null</c> if [has image] contains no value, <c>true</c> if [has image]; otherwise, <c>false</c>.</value> public bool? HasImage { get; set; } - + /// <summary> + /// Gets or sets a value indicating whether this instance is favorite. + /// </summary> + /// <value><c>null</c> if [is favorite] contains no value, <c>true</c> if [is favorite]; otherwise, <c>false</c>.</value> + public bool? IsFavorite { get; set; } } } diff --git a/MediaBrowser.Controller/LiveTv/IHasRegistrationInfo.cs b/MediaBrowser.Controller/LiveTv/IHasRegistrationInfo.cs new file mode 100644 index 000000000..3626c18e5 --- /dev/null +++ b/MediaBrowser.Controller/LiveTv/IHasRegistrationInfo.cs @@ -0,0 +1,15 @@ +using MediaBrowser.Model.Entities; +using System.Threading.Tasks; + +namespace MediaBrowser.Controller.LiveTv +{ + public interface IHasRegistrationInfo + { + /// <summary> + /// Gets the registration information. + /// </summary> + /// <param name="feature">The feature.</param> + /// <returns>Task<MBRegistrationRecord>.</returns> + Task<MBRegistrationRecord> GetRegistrationInfo(string feature); + } +} diff --git a/MediaBrowser.Controller/LiveTv/IListingsProvider.cs b/MediaBrowser.Controller/LiveTv/IListingsProvider.cs new file mode 100644 index 000000000..e60183bd9 --- /dev/null +++ b/MediaBrowser.Controller/LiveTv/IListingsProvider.cs @@ -0,0 +1,19 @@ +using MediaBrowser.Model.Dto; +using MediaBrowser.Model.LiveTv; +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace MediaBrowser.Controller.LiveTv +{ + public interface IListingsProvider + { + string Name { get; } + string Type { get; } + Task<IEnumerable<ProgramInfo>> GetProgramsAsync(ListingsProviderInfo info, string channelNumber, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken); + Task AddMetadata(ListingsProviderInfo info, List<ChannelInfo> channels, CancellationToken cancellationToken); + Task Validate(ListingsProviderInfo info, bool validateLogin, bool validateListings); + Task<List<NameIdPair>> GetLineups(ListingsProviderInfo info, string country, string location); + } +} diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs index 3aa1f66ef..1458c1bc2 100644 --- a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs +++ b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs @@ -2,6 +2,7 @@ using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Entities; using MediaBrowser.Model.Dto; +using MediaBrowser.Model.Entities; using MediaBrowser.Model.LiveTv; using MediaBrowser.Model.Querying; using System.Collections.Generic; @@ -56,20 +57,23 @@ namespace MediaBrowser.Controller.LiveTv /// <param name="id">The identifier.</param> /// <returns>Task.</returns> Task CancelSeriesTimer(string id); - + /// <summary> /// Adds the parts. /// </summary> /// <param name="services">The services.</param> - void AddParts(IEnumerable<ILiveTvService> services); + /// <param name="tunerHosts">The tuner hosts.</param> + /// <param name="listingProviders">The listing providers.</param> + void AddParts(IEnumerable<ILiveTvService> services, IEnumerable<ITunerHost> tunerHosts, IEnumerable<IListingsProvider> listingProviders); /// <summary> /// Gets the channels. /// </summary> /// <param name="query">The query.</param> + /// <param name="options">The options.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>IEnumerable{Channel}.</returns> - Task<QueryResult<ChannelInfoDto>> GetChannels(LiveTvChannelQuery query, CancellationToken cancellationToken); + Task<QueryResult<ChannelInfoDto>> GetChannels(LiveTvChannelQuery query, DtoOptions options, CancellationToken cancellationToken); /// <summary> /// Gets the recording. @@ -171,14 +175,15 @@ namespace MediaBrowser.Controller.LiveTv /// <param name="user">The user.</param> /// <returns>Task{ProgramInfoDto}.</returns> Task<BaseItemDto> GetProgram(string id, CancellationToken cancellationToken, User user = null); - + /// <summary> /// Gets the programs. /// </summary> /// <param name="query">The query.</param> + /// <param name="options">The options.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>IEnumerable{ProgramInfo}.</returns> - Task<QueryResult<BaseItemDto>> GetPrograms(ProgramQuery query, CancellationToken cancellationToken); + Task<QueryResult<BaseItemDto>> GetPrograms(ProgramQuery query, DtoOptions options, CancellationToken cancellationToken); /// <summary> /// Updates the timer. @@ -238,10 +243,10 @@ namespace MediaBrowser.Controller.LiveTv /// Gets the recommended programs. /// </summary> /// <param name="query">The query.</param> + /// <param name="options">The options.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task{QueryResult{ProgramInfoDto}}.</returns> - Task<QueryResult<BaseItemDto>> GetRecommendedPrograms(RecommendedProgramQuery query, - CancellationToken cancellationToken); + Task<QueryResult<BaseItemDto>> GetRecommendedPrograms(RecommendedProgramQuery query, DtoOptions options, CancellationToken cancellationToken); /// <summary> /// Gets the recommended programs internal. @@ -249,8 +254,7 @@ namespace MediaBrowser.Controller.LiveTv /// <param name="query">The query.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task<QueryResult<LiveTvProgram>>.</returns> - Task<QueryResult<LiveTvProgram>> GetRecommendedProgramsInternal(RecommendedProgramQuery query, - CancellationToken cancellationToken); + Task<QueryResult<LiveTvProgram>> GetRecommendedProgramsInternal(RecommendedProgramQuery query, CancellationToken cancellationToken); /// <summary> /// Gets the live tv information. @@ -270,10 +274,9 @@ namespace MediaBrowser.Controller.LiveTv /// <summary> /// Gets the live tv folder. /// </summary> - /// <param name="userId">The user identifier.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>BaseItemDto.</returns> - Task<Folder> GetInternalLiveTvFolder(string userId, CancellationToken cancellationToken); + Task<Folder> GetInternalLiveTvFolder(CancellationToken cancellationToken); /// <summary> /// Gets the live tv folder. @@ -337,5 +340,46 @@ namespace MediaBrowser.Controller.LiveTv /// <param name="dto">The dto.</param> /// <param name="user">The user.</param> void AddInfoToProgramDto(BaseItem item, BaseItemDto dto, User user = null); + /// <summary> + /// Saves the tuner host. + /// </summary> + /// <param name="info">The information.</param> + /// <returns>Task.</returns> + Task<TunerHostInfo> SaveTunerHost(TunerHostInfo info); + /// <summary> + /// Saves the listing provider. + /// </summary> + /// <param name="info">The information.</param> + /// <param name="validateLogin">if set to <c>true</c> [validate login].</param> + /// <param name="validateListings">if set to <c>true</c> [validate listings].</param> + /// <returns>Task.</returns> + Task<ListingsProviderInfo> SaveListingProvider(ListingsProviderInfo info, bool validateLogin, bool validateListings); + /// <summary> + /// Gets the lineups. + /// </summary> + /// <param name="providerType">Type of the provider.</param> + /// <param name="providerId">The provider identifier.</param> + /// <param name="country">The country.</param> + /// <param name="location">The location.</param> + /// <returns>Task<List<NameIdPair>>.</returns> + Task<List<NameIdPair>> GetLineups(string providerType, string providerId, string country, string location); + + /// <summary> + /// Gets the registration information. + /// </summary> + /// <param name="channelId">The channel identifier.</param> + /// <param name="programId">The program identifier.</param> + /// <param name="feature">The feature.</param> + /// <returns>Task<MBRegistrationRecord>.</returns> + Task<MBRegistrationRecord> GetRegistrationInfo(string channelId, string programId, string feature); + + /// <summary> + /// Adds the channel information. + /// </summary> + /// <param name="dto">The dto.</param> + /// <param name="channel">The channel.</param> + /// <param name="options">The options.</param> + /// <param name="user">The user.</param> + void AddChannelInfo(BaseItemDto dto, LiveTvChannel channel, DtoOptions options, User user); } } diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs b/MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs index 1dd267c93..ba0b82a0b 100644 --- a/MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs +++ b/MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs @@ -37,10 +37,12 @@ namespace MediaBrowser.Controller.LiveTv string ExternalId { get; set; } string EpisodeTitle { get; set; } - bool IsSeries { get; set; } string SeriesTimerId { get; set; } RecordingStatus Status { get; set; } DateTime? EndDate { get; set; } ChannelType ChannelType { get; set; } + DateTime DateLastSaved { get; set; } + DateTime DateCreated { get; set; } + DateTime DateModified { get; set; } } } diff --git a/MediaBrowser.Controller/LiveTv/ITunerHost.cs b/MediaBrowser.Controller/LiveTv/ITunerHost.cs new file mode 100644 index 000000000..bedbcffe3 --- /dev/null +++ b/MediaBrowser.Controller/LiveTv/ITunerHost.cs @@ -0,0 +1,55 @@ +using MediaBrowser.Model.Dto; +using MediaBrowser.Model.LiveTv; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace MediaBrowser.Controller.LiveTv +{ + public interface ITunerHost + { + /// <summary> + /// Gets the name. + /// </summary> + /// <value>The name.</value> + string Name { get; } + /// <summary> + /// Gets the type. + /// </summary> + /// <value>The type.</value> + string Type { get; } + /// <summary> + /// Gets the channels. + /// </summary> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task<IEnumerable<ChannelInfo>>.</returns> + Task<IEnumerable<ChannelInfo>> GetChannels(CancellationToken cancellationToken); + /// <summary> + /// Gets the tuner infos. + /// </summary> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task<List<LiveTvTunerInfo>>.</returns> + Task<List<LiveTvTunerInfo>> GetTunerInfos(CancellationToken cancellationToken); + /// <summary> + /// Gets the channel stream. + /// </summary> + /// <param name="channelId">The channel identifier.</param> + /// <param name="streamId">The stream identifier.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task<MediaSourceInfo>.</returns> + Task<MediaSourceInfo> GetChannelStream(string channelId, string streamId, CancellationToken cancellationToken); + /// <summary> + /// Gets the channel stream media sources. + /// </summary> + /// <param name="channelId">The channel identifier.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task<List<MediaSourceInfo>>.</returns> + Task<List<MediaSourceInfo>> GetChannelStreamMediaSources(string channelId, CancellationToken cancellationToken); + /// <summary> + /// Validates the specified information. + /// </summary> + /// <param name="info">The information.</param> + /// <returns>Task.</returns> + Task Validate(TunerHostInfo info); + } +} diff --git a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs index 8232c5c7a..12052905f 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs @@ -1,4 +1,5 @@ using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.LiveTv; @@ -17,10 +18,25 @@ namespace MediaBrowser.Controller.LiveTv /// <returns>System.String.</returns> protected override string CreateUserDataKey() { + if (IsMovie) + { + var key = Movie.GetMovieUserDataKey(this); + + if (!string.IsNullOrWhiteSpace(key)) + { + return key; + } + } return GetClientTypeName() + "-" + Name; } /// <summary> + /// Gets or sets the etag. + /// </summary> + /// <value>The etag.</value> + public string Etag { get; set; } + + /// <summary> /// Id of the program. /// </summary> public string ExternalId { get; set; } @@ -227,5 +243,19 @@ namespace MediaBrowser.Controller.LiveTv info.IsMovie = IsMovie; return info; } + + public override bool SupportsPeople + { + get + { + // Optimization + if (IsNews || IsSports) + { + return false; + } + + return base.SupportsPeople; + } + } } } diff --git a/MediaBrowser.Controller/LiveTv/LiveTvServiceStatusInfo.cs b/MediaBrowser.Controller/LiveTv/LiveTvServiceStatusInfo.cs index 0cb064aba..4da238acf 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvServiceStatusInfo.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvServiceStatusInfo.cs @@ -34,10 +34,16 @@ namespace MediaBrowser.Controller.LiveTv /// </summary> /// <value>The tuners.</value> public List<LiveTvTunerInfo> Tuners { get; set; } - + /// <summary> + /// Gets or sets a value indicating whether this instance is visible. + /// </summary> + /// <value><c>true</c> if this instance is visible; otherwise, <c>false</c>.</value> + public bool IsVisible { get; set; } + public LiveTvServiceStatusInfo() { Tuners = new List<LiveTvTunerInfo>(); + IsVisible = true; } } } diff --git a/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs b/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs index aaaff6bdb..960f8054a 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs @@ -1,4 +1,5 @@ using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; @@ -40,6 +41,16 @@ namespace MediaBrowser.Controller.LiveTv /// <returns>System.String.</returns> protected override string CreateUserDataKey() { + if (IsMovie) + { + var key = Movie.GetMovieUserDataKey(this); + + if (!string.IsNullOrWhiteSpace(key)) + { + return key; + } + } + var name = GetClientTypeName(); if (!string.IsNullOrEmpty(ProgramId)) diff --git a/MediaBrowser.Controller/LiveTv/ProgramInfo.cs b/MediaBrowser.Controller/LiveTv/ProgramInfo.cs index 36f082b02..a6a3e6108 100644 --- a/MediaBrowser.Controller/LiveTv/ProgramInfo.cs +++ b/MediaBrowser.Controller/LiveTv/ProgramInfo.cs @@ -33,6 +33,11 @@ namespace MediaBrowser.Controller.LiveTv /// </summary> /// <value>The overview.</value> public string Overview { get; set; } + /// <summary> + /// Gets or sets the short overview. + /// </summary> + /// <value>The short overview.</value> + public string ShortOverview { get; set; } /// <summary> /// The start date of the program, in UTC. @@ -150,6 +155,36 @@ namespace MediaBrowser.Controller.LiveTv /// </summary> /// <value>The production year.</value> public int? ProductionYear { get; set; } + /// <summary> + /// Gets or sets the home page URL. + /// </summary> + /// <value>The home page URL.</value> + public string HomePageUrl { get; set; } + /// <summary> + /// Gets or sets the series identifier. + /// </summary> + /// <value>The series identifier.</value> + public string SeriesId { get; set; } + /// <summary> + /// Gets or sets the show identifier. + /// </summary> + /// <value>The show identifier.</value> + public string ShowId { get; set; } + /// <summary> + /// Gets or sets the season number. + /// </summary> + /// <value>The season number.</value> + public int? SeasonNumber { get; set; } + /// <summary> + /// Gets or sets the episode number. + /// </summary> + /// <value>The episode number.</value> + public int? EpisodeNumber { get; set; } + /// <summary> + /// Gets or sets the etag. + /// </summary> + /// <value>The etag.</value> + public string Etag { get; set; } public ProgramInfo() { diff --git a/MediaBrowser.Controller/LiveTv/RecordingInfo.cs b/MediaBrowser.Controller/LiveTv/RecordingInfo.cs index bf453ccf4..3006b9bbe 100644 --- a/MediaBrowser.Controller/LiveTv/RecordingInfo.cs +++ b/MediaBrowser.Controller/LiveTv/RecordingInfo.cs @@ -16,6 +16,12 @@ namespace MediaBrowser.Controller.LiveTv /// </summary> /// <value>The series timer identifier.</value> public string SeriesTimerId { get; set; } + + /// <summary> + /// Gets or sets the timer identifier. + /// </summary> + /// <value>The timer identifier.</value> + public string TimerId { get; set; } /// <summary> /// ChannelId of the recording. @@ -179,7 +185,17 @@ namespace MediaBrowser.Controller.LiveTv /// </summary> /// <value><c>null</c> if [has image] contains no value, <c>true</c> if [has image]; otherwise, <c>false</c>.</value> public bool? HasImage { get; set; } + /// <summary> + /// Gets or sets the show identifier. + /// </summary> + /// <value>The show identifier.</value> + public string ShowId { get; set; } + /// <summary> + /// Gets or sets the date last updated. + /// </summary> + /// <value>The date last updated.</value> + public DateTime DateLastUpdated { get; set; } public RecordingInfo() { diff --git a/MediaBrowser.Controller/LiveTv/SeriesTimerInfo.cs b/MediaBrowser.Controller/LiveTv/SeriesTimerInfo.cs index 1be6549ff..2d79473f0 100644 --- a/MediaBrowser.Controller/LiveTv/SeriesTimerInfo.cs +++ b/MediaBrowser.Controller/LiveTv/SeriesTimerInfo.cs @@ -94,6 +94,12 @@ namespace MediaBrowser.Controller.LiveTv /// </summary> /// <value><c>true</c> if this instance is post padding required; otherwise, <c>false</c>.</value> public bool IsPostPaddingRequired { get; set; } + + /// <summary> + /// Gets or sets the series identifier. + /// </summary> + /// <value>The series identifier.</value> + public string SeriesId { get; set; } public SeriesTimerInfo() { diff --git a/MediaBrowser.Controller/Localization/ILocalizationManager.cs b/MediaBrowser.Controller/Localization/ILocalizationManager.cs index f41940ed4..5742d235c 100644 --- a/MediaBrowser.Controller/Localization/ILocalizationManager.cs +++ b/MediaBrowser.Controller/Localization/ILocalizationManager.cs @@ -1,6 +1,5 @@ using MediaBrowser.Model.Entities; using MediaBrowser.Model.Globalization; -using System; using System.Collections.Generic; namespace MediaBrowser.Controller.Localization @@ -48,25 +47,9 @@ namespace MediaBrowser.Controller.Localization string GetLocalizedString(string phrase); /// <summary> - /// Localizes the document. - /// </summary> - /// <param name="document">The document.</param> - /// <param name="culture">The culture.</param> - /// <param name="tokenBuilder">The token builder.</param> - /// <returns>System.String.</returns> - string LocalizeDocument(string document, string culture, Func<string, string> tokenBuilder); - - /// <summary> /// Gets the localization options. /// </summary> /// <returns>IEnumerable{LocalizatonOption}.</returns> IEnumerable<LocalizatonOption> GetLocalizationOptions(); - - /// <summary> - /// Gets the java script localization dictionary. - /// </summary> - /// <param name="culture">The culture.</param> - /// <returns>Dictionary{System.StringSystem.String}.</returns> - Dictionary<string, string> GetJavaScriptLocalizationDictionary(string culture); } } diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index fcde6d8c0..24309734f 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -113,6 +113,7 @@ <Compile Include="Dlna\EventSubscriptionResponse.cs" /> <Compile Include="Dlna\IConnectionManager.cs" /> <Compile Include="Dlna\IContentDirectory.cs" /> + <Compile Include="Dlna\IDeviceDiscovery.cs" /> <Compile Include="Dlna\IDlnaManager.cs" /> <Compile Include="Dlna\IEventManager.cs" /> <Compile Include="Dlna\IMediaReceiverRegistrar.cs" /> @@ -198,7 +199,10 @@ <Compile Include="Library\NameExtensions.cs" /> <Compile Include="Library\PlaybackStopEventArgs.cs" /> <Compile Include="Library\UserDataSaveEventArgs.cs" /> + <Compile Include="LiveTv\IHasRegistrationInfo.cs" /> + <Compile Include="LiveTv\IListingsProvider.cs" /> <Compile Include="LiveTv\ILiveTvItem.cs" /> + <Compile Include="LiveTv\ITunerHost.cs" /> <Compile Include="LiveTv\RecordingGroup.cs" /> <Compile Include="LiveTv\RecordingStatusChangedEventArgs.cs" /> <Compile Include="LiveTv\ILiveTvRecording.cs" /> @@ -309,7 +313,6 @@ <Compile Include="Providers\ItemInfo.cs" /> <Compile Include="Providers\LiveTvProgramLookupInfo.cs" /> <Compile Include="Providers\LocalImageInfo.cs" /> - <Compile Include="Providers\LocalMetadataResult.cs" /> <Compile Include="Providers\MetadataRefreshMode.cs" /> <Compile Include="Providers\MetadataResult.cs" /> <Compile Include="Providers\MovieInfo.cs" /> diff --git a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs index 5bec7980a..23285b612 100644 --- a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs +++ b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs @@ -116,5 +116,12 @@ namespace MediaBrowser.Controller.MediaEncoding Task<string> EncodeVideo(EncodingJobOptions options, IProgress<double> progress, CancellationToken cancellationToken); + + /// <summary> + /// Escapes the subtitle filter path. + /// </summary> + /// <param name="path">The path.</param> + /// <returns>System.String.</returns> + string EscapeSubtitleFilterPath(string path); } } diff --git a/MediaBrowser.Controller/MediaEncoding/ISubtitleEncoder.cs b/MediaBrowser.Controller/MediaEncoding/ISubtitleEncoder.cs index e4a2cd007..826711e51 100644 --- a/MediaBrowser.Controller/MediaEncoding/ISubtitleEncoder.cs +++ b/MediaBrowser.Controller/MediaEncoding/ISubtitleEncoder.cs @@ -8,24 +8,6 @@ namespace MediaBrowser.Controller.MediaEncoding public interface ISubtitleEncoder { /// <summary> - /// Converts the subtitles. - /// </summary> - /// <param name="stream">The stream.</param> - /// <param name="inputFormat">The input format.</param> - /// <param name="outputFormat">The output format.</param> - /// <param name="startTimeTicks">The start time ticks.</param> - /// <param name="endTimeTicks">The end time ticks.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns>Task{Stream}.</returns> - Task<Stream> ConvertSubtitles( - Stream stream, - string inputFormat, - string outputFormat, - long startTimeTicks, - long? endTimeTicks, - CancellationToken cancellationToken); - - /// <summary> /// Gets the subtitles. /// </summary> /// <param name="itemId">The item identifier.</param> diff --git a/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs b/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs index c1a4fa765..383d0881e 100644 --- a/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs +++ b/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs @@ -74,6 +74,8 @@ namespace MediaBrowser.Controller.Providers /// <param name="cancellationToken">The cancellation token.</param> private void Fetch(MetadataResult<T> item, string metadataFile, XmlReaderSettings settings, Encoding encoding, CancellationToken cancellationToken) { + item.ResetPeople(); + using (var streamReader = new StreamReader(metadataFile, encoding)) { // Use XmlReader for best performance @@ -492,7 +494,7 @@ namespace MediaBrowser.Controller.Providers { continue; } - PeopleHelper.AddPerson(itemResult.People, p); + itemResult.AddPerson(p); } break; } @@ -504,7 +506,7 @@ namespace MediaBrowser.Controller.Providers { continue; } - PeopleHelper.AddPerson(itemResult.People, p); + itemResult.AddPerson(p); } break; } @@ -529,7 +531,7 @@ namespace MediaBrowser.Controller.Providers { continue; } - PeopleHelper.AddPerson(itemResult.People, p); + itemResult.AddPerson(p); } } break; @@ -543,7 +545,7 @@ namespace MediaBrowser.Controller.Providers { continue; } - PeopleHelper.AddPerson(itemResult.People, p); + itemResult.AddPerson(p); } break; } @@ -1156,7 +1158,7 @@ namespace MediaBrowser.Controller.Providers { continue; } - PeopleHelper.AddPerson(item.People, person); + item.AddPerson(person); } } break; diff --git a/MediaBrowser.Controller/Providers/DirectoryService.cs b/MediaBrowser.Controller/Providers/DirectoryService.cs index 9e549dcf3..79ffb0d01 100644 --- a/MediaBrowser.Controller/Providers/DirectoryService.cs +++ b/MediaBrowser.Controller/Providers/DirectoryService.cs @@ -58,8 +58,9 @@ namespace MediaBrowser.Controller.Providers try { - var list = new DirectoryInfo(path) - .EnumerateFileSystemInfos("*", SearchOption.TopDirectoryOnly); + // using EnumerateFileSystemInfos doesn't handle reparse points (symlinks) + var list = new DirectoryInfo(path).EnumerateDirectories("*", SearchOption.TopDirectoryOnly) + .Concat<FileSystemInfo>(new DirectoryInfo(path).EnumerateFiles("*", SearchOption.TopDirectoryOnly)); // Seeing dupes on some users file system for some reason foreach (var item in list) diff --git a/MediaBrowser.Controller/Providers/ILocalMetadataProvider.cs b/MediaBrowser.Controller/Providers/ILocalMetadataProvider.cs index 3a8ef7325..28a535310 100644 --- a/MediaBrowser.Controller/Providers/ILocalMetadataProvider.cs +++ b/MediaBrowser.Controller/Providers/ILocalMetadataProvider.cs @@ -18,7 +18,7 @@ namespace MediaBrowser.Controller.Providers /// <param name="directoryService">The directory service.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task{MetadataResult{`0}}.</returns> - Task<LocalMetadataResult<TItemType>> GetMetadata(ItemInfo info, + Task<MetadataResult<TItemType>> GetMetadata(ItemInfo info, IDirectoryService directoryService, CancellationToken cancellationToken); } diff --git a/MediaBrowser.Controller/Providers/LocalMetadataResult.cs b/MediaBrowser.Controller/Providers/LocalMetadataResult.cs deleted file mode 100644 index 76b7a3136..000000000 --- a/MediaBrowser.Controller/Providers/LocalMetadataResult.cs +++ /dev/null @@ -1,18 +0,0 @@ -using MediaBrowser.Controller.Entities; -using System.Collections.Generic; - -namespace MediaBrowser.Controller.Providers -{ - public class LocalMetadataResult<T> : MetadataResult<T> - where T : IHasMetadata - { - public List<LocalImageInfo> Images { get; set; } - public List<UserItemData> UserDataLIst { get; set; } - - public LocalMetadataResult() - { - Images = new List<LocalImageInfo>(); - UserDataLIst = new List<UserItemData>(); - } - } -}
\ No newline at end of file diff --git a/MediaBrowser.Controller/Providers/MetadataResult.cs b/MediaBrowser.Controller/Providers/MetadataResult.cs index a18dd83e8..17175f91c 100644 --- a/MediaBrowser.Controller/Providers/MetadataResult.cs +++ b/MediaBrowser.Controller/Providers/MetadataResult.cs @@ -1,18 +1,67 @@ using MediaBrowser.Controller.Entities; +using System; using System.Collections.Generic; +using System.Linq; namespace MediaBrowser.Controller.Providers { public class MetadataResult<T> { + public List<LocalImageInfo> Images { get; set; } + public List<UserItemData> UserDataList { get; set; } + + public MetadataResult() + { + Images = new List<LocalImageInfo>(); + } + public List<PersonInfo> People { get; set; } public bool HasMetadata { get; set; } public T Item { get; set; } - public MetadataResult() + public void AddPerson(PersonInfo p) { - People = new List<PersonInfo>(); + if (People == null) + { + People = new List<PersonInfo>(); + } + + PeopleHelper.AddPerson(People, p); + } + + /// <summary> + /// Not only does this clear, but initializes the list so that services can differentiate between a null list and zero people + /// </summary> + public void ResetPeople() + { + if (People == null) + { + People = new List<PersonInfo>(); + } + People.Clear(); + } + + public UserItemData GetOrAddUserData(string userId) + { + if (UserDataList == null) + { + UserDataList = new List<UserItemData>(); + } + + var userData = UserDataList.FirstOrDefault(i => string.Equals(userId, i.UserId.ToString("N"), StringComparison.OrdinalIgnoreCase)); + + if (userData == null) + { + userData = new UserItemData() + { + UserId = new Guid(userId) + }; + + UserDataList.Add(userData); + } + + return userData; } } }
\ No newline at end of file diff --git a/MediaBrowser.Controller/Session/SessionInfo.cs b/MediaBrowser.Controller/Session/SessionInfo.cs index 64b20c13e..b3e82f925 100644 --- a/MediaBrowser.Controller/Session/SessionInfo.cs +++ b/MediaBrowser.Controller/Session/SessionInfo.cs @@ -126,6 +126,12 @@ namespace MediaBrowser.Controller.Session public ISessionController SessionController { get; set; } /// <summary> + /// Gets or sets the application icon URL. + /// </summary> + /// <value>The application icon URL.</value> + public string AppIconUrl { get; set; } + + /// <summary> /// Gets or sets the supported commands. /// </summary> /// <value>The supported commands.</value> diff --git a/MediaBrowser.Controller/Sync/IServerSyncProvider.cs b/MediaBrowser.Controller/Sync/IServerSyncProvider.cs index 860c736ea..36ad27290 100644 --- a/MediaBrowser.Controller/Sync/IServerSyncProvider.cs +++ b/MediaBrowser.Controller/Sync/IServerSyncProvider.cs @@ -63,4 +63,15 @@ namespace MediaBrowser.Controller.Sync /// <returns>Task<SyncedFileInfo>.</returns> Task<SyncedFileInfo> SendFile(string path, string[] pathParts, SyncTarget target, IProgress<double> progress, CancellationToken cancellationToken); } + + public interface IHasDuplicateCheck + { + /// <summary> + /// Allows the duplicate job item. + /// </summary> + /// <param name="original">The original.</param> + /// <param name="duplicate">The duplicate.</param> + /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns> + bool AllowDuplicateJobItem(SyncJobItem original, SyncJobItem duplicate); + } } |
