diff options
| author | Luke Pulverenti <luke.pulverenti@gmail.com> | 2016-10-09 03:18:43 -0400 |
|---|---|---|
| committer | Luke Pulverenti <luke.pulverenti@gmail.com> | 2016-10-09 03:18:43 -0400 |
| commit | daaae69df575f1d7692ba29d6f5ddd4c59516f82 (patch) | |
| tree | 24c818ece042d36808fd0a68834b2853bf4512e1 | |
| parent | b3595eab6a94fda4f81f637007b2ac79e8a85065 (diff) | |
add playback of in-progress recordings
49 files changed, 570 insertions, 397 deletions
diff --git a/MediaBrowser.Api/Library/LibraryService.cs b/MediaBrowser.Api/Library/LibraryService.cs index c6b637f01..e0dfcb9ad 100644 --- a/MediaBrowser.Api/Library/LibraryService.cs +++ b/MediaBrowser.Api/Library/LibraryService.cs @@ -835,14 +835,14 @@ namespace MediaBrowser.Api.Library : (Folder)_libraryManager.RootFolder) : _libraryManager.GetItemById(request.Id); - while (GetThemeSongIds(item).Count == 0 && request.InheritFromParent && item.GetParent() != null) + while (item.ThemeSongIds.Count == 0 && request.InheritFromParent && item.GetParent() != null) { item = item.GetParent(); } var dtoOptions = GetDtoOptions(request); - var dtos = GetThemeSongIds(item).Select(_libraryManager.GetItemById) + var dtos = item.ThemeSongIds.Select(_libraryManager.GetItemById) .Where(i => i != null) .OrderBy(i => i.SortName) .Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user, item)); @@ -879,14 +879,14 @@ namespace MediaBrowser.Api.Library : (Folder)_libraryManager.RootFolder) : _libraryManager.GetItemById(request.Id); - while (GetThemeVideoIds(item).Count == 0 && request.InheritFromParent && item.GetParent() != null) + while (item.ThemeVideoIds.Count == 0 && request.InheritFromParent && item.GetParent() != null) { item = item.GetParent(); } var dtoOptions = GetDtoOptions(request); - var dtos = GetThemeVideoIds(item).Select(_libraryManager.GetItemById) + var dtos = item.ThemeVideoIds.Select(_libraryManager.GetItemById) .Where(i => i != null) .OrderBy(i => i.SortName) .Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user, item)); @@ -901,30 +901,6 @@ namespace MediaBrowser.Api.Library }; } - private List<Guid> GetThemeVideoIds(BaseItem item) - { - var i = item as IHasThemeMedia; - - if (i != null) - { - return i.ThemeVideoIds; - } - - return new List<Guid>(); - } - - private List<Guid> GetThemeSongIds(BaseItem item) - { - var i = item as IHasThemeMedia; - - if (i != null) - { - return i.ThemeSongIds; - } - - return new List<Guid>(); - } - private readonly CultureInfo _usCulture = new CultureInfo("en-US"); public object Get(GetYearIndex request) diff --git a/MediaBrowser.Api/LiveTv/LiveTvService.cs b/MediaBrowser.Api/LiveTv/LiveTvService.cs index ebfced0f4..4217cd6ab 100644 --- a/MediaBrowser.Api/LiveTv/LiveTvService.cs +++ b/MediaBrowser.Api/LiveTv/LiveTvService.cs @@ -677,6 +677,12 @@ namespace MediaBrowser.Api.LiveTv public string Container { get; set; } } + [Route("/LiveTv/LiveRecordings/{Id}/stream", "GET", Summary = "Gets a live tv channel")] + public class GetLiveRecordingFile + { + public string Id { get; set; } + } + public class LiveTvService : BaseApiService { private readonly ILiveTvManager _liveTvManager; @@ -698,13 +704,32 @@ namespace MediaBrowser.Api.LiveTv _fileSystem = fileSystem; } + public async Task<object> Get(GetLiveRecordingFile request) + { + var path = EmbyTV.Current.GetActiveRecordingPath(request.Id); + + if (path == null) + { + throw new FileNotFoundException(); + } + + var outputHeaders = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); + + outputHeaders["Content-Type"] = Model.Net.MimeTypes.GetMimeType(path); + + var streamSource = new ProgressiveFileCopier(_fileSystem, path, outputHeaders, null, Logger, CancellationToken.None) + { + AllowEndOfFile = false + }; + return ResultFactory.GetAsyncStreamWriter(streamSource); + } + public async Task<object> Get(GetLiveStreamFile request) { var directStreamProvider = (await EmbyTV.Current.GetLiveStream(request.Id).ConfigureAwait(false)) as IDirectStreamProvider; var outputHeaders = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); - // TODO: Don't hardcode this - outputHeaders["Content-Type"] = Model.Net.MimeTypes.GetMimeType("file.ts"); + outputHeaders["Content-Type"] = Model.Net.MimeTypes.GetMimeType("file." + request.Container); var streamSource = new ProgressiveFileCopier(directStreamProvider, outputHeaders, null, Logger, CancellationToken.None) { diff --git a/MediaBrowser.Controller/Channels/IChannelManager.cs b/MediaBrowser.Controller/Channels/IChannelManager.cs index 3c46247a7..9177e2d81 100644 --- a/MediaBrowser.Controller/Channels/IChannelManager.cs +++ b/MediaBrowser.Controller/Channels/IChannelManager.cs @@ -134,15 +134,5 @@ namespace MediaBrowser.Controller.Channels /// <param name="cancellationToken">The cancellation token.</param> /// <returns>BaseItemDto.</returns> Task<BaseItemDto> GetChannelFolder(string userId, CancellationToken cancellationToken); - - /// <summary> - /// Downloads the channel item. - /// </summary> - /// <param name="item">The item.</param> - /// <param name="destinationPath">The destination path.</param> - /// <param name="progress">The progress.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns>Task.</returns> - Task DownloadChannelItem(BaseItem item, string destinationPath, IProgress<double> progress, CancellationToken cancellationToken); } } diff --git a/MediaBrowser.Controller/Entities/AggregateFolder.cs b/MediaBrowser.Controller/Entities/AggregateFolder.cs index efc450248..9709813dc 100644 --- a/MediaBrowser.Controller/Entities/AggregateFolder.cs +++ b/MediaBrowser.Controller/Entities/AggregateFolder.cs @@ -34,6 +34,12 @@ namespace MediaBrowser.Controller.Entities } } + [IgnoreDataMember] + public override bool IsPhysicalRoot + { + get { return true; } + } + public override bool CanDelete() { return false; diff --git a/MediaBrowser.Controller/Entities/Audio/Audio.cs b/MediaBrowser.Controller/Entities/Audio/Audio.cs index 00657370e..891fb7d52 100644 --- a/MediaBrowser.Controller/Entities/Audio/Audio.cs +++ b/MediaBrowser.Controller/Entities/Audio/Audio.cs @@ -62,7 +62,7 @@ namespace MediaBrowser.Controller.Entities.Audio [IgnoreDataMember] public override bool SupportsAddingToPlaylist { - get { return LocationType == LocationType.FileSystem && RunTimeTicks.HasValue; } + get { return true; } } [IgnoreDataMember] diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index eb84765fb..cc4a8fdb9 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -37,6 +37,8 @@ namespace MediaBrowser.Controller.Entities { protected BaseItem() { + ThemeSongIds = new List<Guid>(); + ThemeVideoIds = new List<Guid>(); Keywords = new List<string>(); Tags = new List<string>(); Genres = new List<string>(); @@ -45,6 +47,7 @@ namespace MediaBrowser.Controller.Entities LockedFields = new List<MetadataFields>(); ImageInfos = new List<ItemImageInfo>(); InheritedTags = new List<string>(); + ProductionLocations = new List<string>(); } public static readonly char[] SlugReplaceChars = { '?', '/', '&' }; @@ -65,6 +68,9 @@ namespace MediaBrowser.Controller.Entities public static string ThemeSongFilename = "theme"; public static string ThemeVideosFolderName = "backdrops"; + public List<Guid> ThemeSongIds { get; set; } + public List<Guid> ThemeVideoIds { get; set; } + [IgnoreDataMember] public string PreferredMetadataCountryCode { get; set; } [IgnoreDataMember] @@ -876,6 +882,7 @@ namespace MediaBrowser.Controller.Entities public List<string> Tags { get; set; } public List<string> Keywords { get; set; } + public List<string> ProductionLocations { get; set; } /// <summary> /// Gets or sets the home page URL. @@ -991,7 +998,7 @@ namespace MediaBrowser.Controller.Entities /// Loads the theme songs. /// </summary> /// <returns>List{Audio.Audio}.</returns> - private IEnumerable<Audio.Audio> LoadThemeSongs(List<FileSystemMetadata> fileSystemChildren, IDirectoryService directoryService) + private static IEnumerable<Audio.Audio> LoadThemeSongs(List<FileSystemMetadata> fileSystemChildren, IDirectoryService directoryService) { var files = fileSystemChildren.Where(i => i.IsDirectory) .Where(i => string.Equals(i.Name, ThemeSongsFolderName, StringComparison.OrdinalIgnoreCase)) @@ -1027,7 +1034,7 @@ namespace MediaBrowser.Controller.Entities /// Loads the video backdrops. /// </summary> /// <returns>List{Video}.</returns> - private IEnumerable<Video> LoadThemeVideos(IEnumerable<FileSystemMetadata> fileSystemChildren, IDirectoryService directoryService) + private static IEnumerable<Video> LoadThemeVideos(IEnumerable<FileSystemMetadata> fileSystemChildren, IDirectoryService directoryService) { var files = fileSystemChildren.Where(i => i.IsDirectory) .Where(i => string.Equals(i.Name, ThemeVideosFolderName, StringComparison.OrdinalIgnoreCase)) @@ -1113,6 +1120,12 @@ namespace MediaBrowser.Controller.Entities get { return true; } } + [IgnoreDataMember] + public virtual bool SupportsThemeMedia + { + get { return false; } + } + /// <summary> /// Refreshes owned items such as trailers, theme videos, special features, etc. /// Returns true or false indicating if changes were found. @@ -1131,14 +1144,13 @@ namespace MediaBrowser.Controller.Entities if (LocationType == LocationType.FileSystem && GetParent() != null) { - var hasThemeMedia = this as IHasThemeMedia; - if (hasThemeMedia != null) + if (SupportsThemeMedia) { if (!DetectIsInMixedFolder()) { - themeSongsChanged = await RefreshThemeSongs(hasThemeMedia, options, fileSystemChildren, cancellationToken).ConfigureAwait(false); + themeSongsChanged = await RefreshThemeSongs(this, options, fileSystemChildren, cancellationToken).ConfigureAwait(false); - themeVideosChanged = await RefreshThemeVideos(hasThemeMedia, options, fileSystemChildren, cancellationToken).ConfigureAwait(false); + themeVideosChanged = await RefreshThemeVideos(this, options, fileSystemChildren, cancellationToken).ConfigureAwait(false); } } @@ -1176,7 +1188,7 @@ namespace MediaBrowser.Controller.Entities return itemsChanged; } - private async Task<bool> RefreshThemeVideos(IHasThemeMedia item, MetadataRefreshOptions options, IEnumerable<FileSystemMetadata> fileSystemChildren, CancellationToken cancellationToken) + private static async Task<bool> RefreshThemeVideos(BaseItem item, MetadataRefreshOptions options, IEnumerable<FileSystemMetadata> fileSystemChildren, CancellationToken cancellationToken) { var newThemeVideos = LoadThemeVideos(fileSystemChildren, options.DirectoryService).ToList(); @@ -1207,7 +1219,7 @@ namespace MediaBrowser.Controller.Entities /// <summary> /// Refreshes the theme songs. /// </summary> - private async Task<bool> RefreshThemeSongs(IHasThemeMedia item, MetadataRefreshOptions options, List<FileSystemMetadata> fileSystemChildren, CancellationToken cancellationToken) + private static async Task<bool> RefreshThemeSongs(BaseItem item, MetadataRefreshOptions options, List<FileSystemMetadata> fileSystemChildren, CancellationToken cancellationToken) { var newThemeSongs = LoadThemeSongs(fileSystemChildren, options.DirectoryService).ToList(); var newThemeSongIds = newThemeSongs.Select(i => i.Id).ToList(); diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index d1e089850..e5994fde5 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -22,13 +22,18 @@ namespace MediaBrowser.Controller.Entities /// <summary> /// Class Folder /// </summary> - public class Folder : BaseItem, IHasThemeMedia + public class Folder : BaseItem { public static IUserManager UserManager { get; set; } public static IUserViewManager UserViewManager { get; set; } - public List<Guid> ThemeSongIds { get; set; } - public List<Guid> ThemeVideoIds { get; set; } + /// <summary> + /// Gets or sets a value indicating whether this instance is root. + /// </summary> + /// <value><c>true</c> if this instance is root; otherwise, <c>false</c>.</value> + public bool IsRoot { get; set; } + + public virtual List<LinkedChild> LinkedChildren { get; set; } [IgnoreDataMember] public DateTime? DateLastMediaAdded { get; set; } @@ -36,9 +41,12 @@ namespace MediaBrowser.Controller.Entities public Folder() { LinkedChildren = new List<LinkedChild>(); + } - ThemeSongIds = new List<Guid>(); - ThemeVideoIds = new List<Guid>(); + [IgnoreDataMember] + public override bool SupportsThemeMedia + { + get { return true; } } [IgnoreDataMember] @@ -47,6 +55,12 @@ namespace MediaBrowser.Controller.Entities get { return false; } } + [IgnoreDataMember] + public virtual bool IsPhysicalRoot + { + get { return false; } + } + /// <summary> /// Gets a value indicating whether this instance is folder. /// </summary> @@ -117,19 +131,6 @@ namespace MediaBrowser.Controller.Entities return true; } - /// <summary> - /// Gets or sets 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; set; } - /// <summary> - /// Gets or sets a value indicating whether this instance is root. - /// </summary> - /// <value><c>true</c> if this instance is root; otherwise, <c>false</c>.</value> - public bool IsRoot { get; set; } - - public virtual List<LinkedChild> LinkedChildren { get; set; } - [IgnoreDataMember] protected virtual bool SupportsShortcutChildren { @@ -178,8 +179,6 @@ namespace MediaBrowser.Controller.Entities item.SetParent(null); } - #region Indexing - /// <summary> /// Returns the valid set of index by options for this folder type. /// Override or extend to modify. @@ -207,8 +206,6 @@ namespace MediaBrowser.Controller.Entities get { return GetIndexByOptions(); } } - #endregion - /// <summary> /// Gets the actual children. /// </summary> diff --git a/MediaBrowser.Controller/Entities/Game.cs b/MediaBrowser.Controller/Entities/Game.cs index a48b9f564..59bfc2363 100644 --- a/MediaBrowser.Controller/Entities/Game.cs +++ b/MediaBrowser.Controller/Entities/Game.cs @@ -8,11 +8,8 @@ using System.Runtime.Serialization; namespace MediaBrowser.Controller.Entities { - public class Game : BaseItem, IHasTrailers, IHasThemeMedia, IHasScreenshots, ISupportsPlaceHolders, IHasLookupInfo<GameInfo> + public class Game : BaseItem, IHasTrailers, IHasScreenshots, ISupportsPlaceHolders, IHasLookupInfo<GameInfo> { - public List<Guid> ThemeSongIds { get; set; } - public List<Guid> ThemeVideoIds { get; set; } - public Game() { MultiPartGameFiles = new List<string>(); @@ -39,6 +36,12 @@ namespace MediaBrowser.Controller.Entities get { return true; } } + [IgnoreDataMember] + public override bool SupportsThemeMedia + { + get { return true; } + } + /// <summary> /// Gets or sets the remote trailers. /// </summary> diff --git a/MediaBrowser.Controller/Entities/IHasThemeMedia.cs b/MediaBrowser.Controller/Entities/IHasThemeMedia.cs deleted file mode 100644 index acc0050ce..000000000 --- a/MediaBrowser.Controller/Entities/IHasThemeMedia.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace MediaBrowser.Controller.Entities -{ - /// <summary> - /// Interface IHasThemeMedia - /// </summary> - public interface IHasThemeMedia - { - /// <summary> - /// Gets or sets the theme song ids. - /// </summary> - /// <value>The theme song ids.</value> - List<Guid> ThemeSongIds { get; set; } - - /// <summary> - /// Gets or sets the theme video ids. - /// </summary> - /// <value>The theme video ids.</value> - List<Guid> ThemeVideoIds { get; set; } - } -} diff --git a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs index 0a857a477..444f472ab 100644 --- a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs +++ b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs @@ -165,6 +165,7 @@ namespace MediaBrowser.Controller.Entities { switch (name) { + case ItemFields.ProductionLocations: case ItemFields.Keywords: case ItemFields.Taglines: case ItemFields.ShortOverview: diff --git a/MediaBrowser.Controller/Entities/Movies/Movie.cs b/MediaBrowser.Controller/Entities/Movies/Movie.cs index 8120b0028..9a10a63bd 100644 --- a/MediaBrowser.Controller/Entities/Movies/Movie.cs +++ b/MediaBrowser.Controller/Entities/Movies/Movie.cs @@ -15,21 +15,16 @@ namespace MediaBrowser.Controller.Entities.Movies /// <summary> /// Class Movie /// </summary> - public class Movie : Video, IHasCriticRating, IHasSpecialFeatures, IHasBudget, IHasTrailers, IHasThemeMedia, IHasAwards, IHasMetascore, IHasLookupInfo<MovieInfo>, ISupportsBoxSetGrouping, IHasOriginalTitle + public class Movie : Video, IHasCriticRating, IHasSpecialFeatures, IHasBudget, IHasTrailers, IHasAwards, IHasMetascore, IHasLookupInfo<MovieInfo>, ISupportsBoxSetGrouping, IHasOriginalTitle { public List<Guid> SpecialFeatureIds { get; set; } - public List<Guid> ThemeSongIds { get; set; } - public List<Guid> ThemeVideoIds { get; set; } - public Movie() { SpecialFeatureIds = new List<Guid>(); RemoteTrailers = new List<MediaUrl>(); LocalTrailerIds = new List<Guid>(); RemoteTrailerIds = new List<Guid>(); - ThemeSongIds = new List<Guid>(); - ThemeVideoIds = new List<Guid>(); Taglines = new List<string>(); } diff --git a/MediaBrowser.Controller/Entities/TV/Season.cs b/MediaBrowser.Controller/Entities/TV/Season.cs index ff3e53b69..62af14159 100644 --- a/MediaBrowser.Controller/Entities/TV/Season.cs +++ b/MediaBrowser.Controller/Entities/TV/Season.cs @@ -154,8 +154,6 @@ namespace MediaBrowser.Controller.Entities.TV Func<BaseItem, bool> filter = i => UserViewBuilder.Filter(i, user, query, UserDataManager, LibraryManager); - var id = Guid.NewGuid().ToString("N"); - var items = GetEpisodes(user).Where(filter); var result = PostFilterAndSort(items, query, false, false); diff --git a/MediaBrowser.Controller/Entities/UserView.cs b/MediaBrowser.Controller/Entities/UserView.cs index 35375e7e6..92f8e8a9d 100644 --- a/MediaBrowser.Controller/Entities/UserView.cs +++ b/MediaBrowser.Controller/Entities/UserView.cs @@ -13,7 +13,6 @@ namespace MediaBrowser.Controller.Entities public class UserView : Folder { public string ViewType { get; set; } - public Guid ParentId { get; set; } public Guid DisplayParentId { get; set; } public Guid? UserId { get; set; } diff --git a/MediaBrowser.Controller/Entities/UserViewBuilder.cs b/MediaBrowser.Controller/Entities/UserViewBuilder.cs index 8a64be714..3b7e3c5d2 100644 --- a/MediaBrowser.Controller/Entities/UserViewBuilder.cs +++ b/MediaBrowser.Controller/Entities/UserViewBuilder.cs @@ -1497,13 +1497,7 @@ namespace MediaBrowser.Controller.Entities { var filterValue = query.HasThemeSong.Value; - var themeCount = 0; - var iHasThemeMedia = item as IHasThemeMedia; - - if (iHasThemeMedia != null) - { - themeCount = iHasThemeMedia.ThemeSongIds.Count; - } + var themeCount = item.ThemeSongIds.Count; var ok = filterValue ? themeCount > 0 : themeCount == 0; if (!ok) @@ -1516,13 +1510,7 @@ namespace MediaBrowser.Controller.Entities { var filterValue = query.HasThemeVideo.Value; - var themeCount = 0; - var iHasThemeMedia = item as IHasThemeMedia; - - if (iHasThemeMedia != null) - { - themeCount = iHasThemeMedia.ThemeVideoIds.Count; - } + var themeCount = item.ThemeVideoIds.Count; var ok = filterValue ? themeCount > 0 : themeCount == 0; if (!ok) diff --git a/MediaBrowser.Controller/Entities/Video.cs b/MediaBrowser.Controller/Entities/Video.cs index b94973e2b..baf9293bf 100644 --- a/MediaBrowser.Controller/Entities/Video.cs +++ b/MediaBrowser.Controller/Entities/Video.cs @@ -63,6 +63,12 @@ namespace MediaBrowser.Controller.Entities } } + [IgnoreDataMember] + public override bool SupportsThemeMedia + { + get { return true; } + } + public int? TotalBitrate { get; set; } public ExtraType? ExtraType { get; set; } @@ -164,7 +170,7 @@ namespace MediaBrowser.Controller.Entities [IgnoreDataMember] public override bool SupportsAddingToPlaylist { - get { return LocationType == LocationType.FileSystem && RunTimeTicks.HasValue; } + get { return true; } } [IgnoreDataMember] diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs index 7e48f3d21..8e3c1931b 100644 --- a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs +++ b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs @@ -301,18 +301,12 @@ namespace MediaBrowser.Controller.LiveTv /// <summary> /// Gets the recording media sources. /// </summary> - /// <param name="id">The identifier.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns>Task<IEnumerable<MediaSourceInfo>>.</returns> - Task<IEnumerable<MediaSourceInfo>> GetRecordingMediaSources(string id, CancellationToken cancellationToken); + Task<IEnumerable<MediaSourceInfo>> GetRecordingMediaSources(IHasMediaSources item, CancellationToken cancellationToken); /// <summary> /// Gets the channel media sources. /// </summary> - /// <param name="id">The identifier.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns>Task<IEnumerable<MediaSourceInfo>>.</returns> - Task<IEnumerable<MediaSourceInfo>> GetChannelMediaSources(string id, CancellationToken cancellationToken); + Task<IEnumerable<MediaSourceInfo>> GetChannelMediaSources(IHasMediaSources item, CancellationToken cancellationToken); /// <summary> /// Adds the information to recording dto. diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs b/MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs index 257024d01..1bbd1a008 100644 --- a/MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs +++ b/MediaBrowser.Controller/LiveTv/ILiveTvRecording.cs @@ -33,6 +33,7 @@ namespace MediaBrowser.Controller.LiveTv bool CanDelete(User user); string SeriesTimerId { get; set; } + string TimerId { get; set; } RecordingStatus Status { get; set; } DateTime? EndDate { get; set; } DateTime DateLastSaved { get; set; } diff --git a/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs b/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs index e6f472414..e6fefbf72 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs @@ -20,6 +20,7 @@ namespace MediaBrowser.Controller.LiveTv [IgnoreDataMember] public bool IsSeries { get; set; } public string SeriesTimerId { get; set; } + public string TimerId { get; set; } [IgnoreDataMember] public DateTime StartDate { get; set; } public RecordingStatus Status { get; set; } @@ -112,7 +113,7 @@ namespace MediaBrowser.Controller.LiveTv public override bool CanDelete() { - return true; + return Status == RecordingStatus.Completed; } public override bool IsAuthorizedToDelete(User user) diff --git a/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs b/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs index f4dba070d..e26dd6a77 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs @@ -19,6 +19,7 @@ namespace MediaBrowser.Controller.LiveTv [IgnoreDataMember] public bool IsSeries { get; set; } public string SeriesTimerId { get; set; } + public string TimerId { get; set; } [IgnoreDataMember] public DateTime StartDate { get; set; } public RecordingStatus Status { get; set; } @@ -111,7 +112,7 @@ namespace MediaBrowser.Controller.LiveTv public override bool CanDelete() { - return true; + return Status == RecordingStatus.Completed; } public override bool IsAuthorizedToDelete(User user) diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index 06ec43206..11ed0f674 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -149,7 +149,6 @@ <Compile Include="Entities\IHasShortOverview.cs" /> <Compile Include="Entities\IHasSpecialFeatures.cs" /> <Compile Include="Entities\IHasStartDate.cs" /> - <Compile Include="Entities\IHasThemeMedia.cs" /> <Compile Include="Entities\IHasTrailers.cs" /> <Compile Include="Entities\IHasUserData.cs" /> <Compile Include="Entities\IHiddenFromDisplay.cs" /> diff --git a/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs b/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs index d2125fd5e..13d43eee6 100644 --- a/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs +++ b/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs @@ -347,7 +347,7 @@ namespace MediaBrowser.Controller.Providers var person = item as Person; if (person != null) { - person.PlaceOfBirth = val; + person.ProductionLocations = new List<string> { val }; } } @@ -790,7 +790,7 @@ namespace MediaBrowser.Controller.Providers } default: - { + { string readerName = reader.Name; string providerIdValue; if (_validProviderIds.TryGetValue(readerName, out providerIdValue)) diff --git a/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs b/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs index 9b5030325..3d1e073f8 100644 --- a/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs +++ b/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs @@ -428,14 +428,6 @@ namespace MediaBrowser.Dlna.ContentDirectory return ApplyPaging(result, startIndex, limit); } - if (stubType.Value == StubType.Folder) - { - var movie = item as Movie; - if (movie != null) - { - return ApplyPaging(await GetMovieItems(movie).ConfigureAwait(false), startIndex, limit); - } - } var person = item as Person; if (person != null) @@ -468,14 +460,11 @@ namespace MediaBrowser.Dlna.ContentDirectory }).ConfigureAwait(false); - var options = _config.GetDlnaConfiguration(); - var serverItems = queryResult .Items .Select(i => new ServerItem { - Item = i, - StubType = GetDisplayStubType(i, item, options) + Item = i }) .ToArray(); @@ -519,29 +508,6 @@ namespace MediaBrowser.Dlna.ContentDirectory return result; } - private StubType? GetDisplayStubType(BaseItem item, BaseItem context, DlnaOptions options) - { - if (context == null || context.IsFolder) - { - var movie = item as Movie; - if (movie != null && options.EnableMovieFolders) - { - if (movie.GetTrailerIds().Count > 0 || - movie.SpecialFeatureIds.Count > 0) - { - return StubType.Folder; - } - - if (EnablePeopleDisplay(item)) - { - return StubType.Folder; - } - } - } - - return null; - } - private bool EnablePeopleDisplay(BaseItem item) { if (_libraryManager.GetPeopleNames(new InternalPeopleQuery @@ -556,31 +522,6 @@ namespace MediaBrowser.Dlna.ContentDirectory return false; } - private Task<QueryResult<ServerItem>> GetMovieItems(Movie item) - { - var list = new List<BaseItem>(); - - list.Add(item); - - list.AddRange(item.GetTrailerIds().Select(i => _libraryManager.GetItemById(i)).Where(i => i != null)); - list.AddRange(item.SpecialFeatureIds.Select(i => _libraryManager.GetItemById(i)).Where(i => i != null)); - - var serverItems = list.Select(i => new ServerItem { Item = i, StubType = null }) - .ToList(); - - serverItems.Add(new ServerItem - { - Item = item, - StubType = StubType.People - }); - - return Task.FromResult(new QueryResult<ServerItem> - { - Items = serverItems.ToArray(), - TotalRecordCount = serverItems.Count - }); - } - private ServerItem GetItemFromObjectId(string id, User user) { return DidlBuilder.IsIdRoot(id) diff --git a/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs b/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs index 51e115cc2..a8aedaed8 100644 --- a/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs +++ b/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs @@ -220,7 +220,7 @@ namespace MediaBrowser.Dlna.Main return; } - var cacheLength = _config.GetDlnaConfiguration().BlastAliveMessageIntervalSeconds * 2; + var cacheLength = _config.GetDlnaConfiguration().BlastAliveMessageIntervalSeconds; _Publisher.SupportPnpRootDevice = false; var addresses = (await _appHost.GetLocalIpAddresses().ConfigureAwait(false)).ToList(); diff --git a/MediaBrowser.LocalMetadata/Savers/PersonXmlSaver.cs b/MediaBrowser.LocalMetadata/Savers/PersonXmlSaver.cs index bf6ed03ad..295e64881 100644 --- a/MediaBrowser.LocalMetadata/Savers/PersonXmlSaver.cs +++ b/MediaBrowser.LocalMetadata/Savers/PersonXmlSaver.cs @@ -66,9 +66,9 @@ namespace MediaBrowser.LocalMetadata.Savers XmlSaverHelpers.AddCommonNodes(person, _libraryManager, builder); - if (!string.IsNullOrEmpty(person.PlaceOfBirth)) + if (person.ProductionLocations.Count > 0) { - builder.Append("<PlaceOfBirth>" + SecurityElement.Escape(person.PlaceOfBirth) + "</PlaceOfBirth>"); + builder.Append("<PlaceOfBirth>" + SecurityElement.Escape(person.ProductionLocations[0]) + "</PlaceOfBirth>"); } builder.Append("</Item>"); diff --git a/MediaBrowser.Model/Configuration/DlnaOptions.cs b/MediaBrowser.Model/Configuration/DlnaOptions.cs index 6eaf01c4a..71a24d707 100644 --- a/MediaBrowser.Model/Configuration/DlnaOptions.cs +++ b/MediaBrowser.Model/Configuration/DlnaOptions.cs @@ -10,7 +10,6 @@ namespace MediaBrowser.Model.Configuration public int ClientDiscoveryIntervalSeconds { get; set; } public int BlastAliveMessageIntervalSeconds { get; set; } public string DefaultUserId { get; set; } - public bool EnableMovieFolders { get; set; } public DlnaOptions() { diff --git a/MediaBrowser.Model/Dto/BaseItemDto.cs b/MediaBrowser.Model/Dto/BaseItemDto.cs index 598f8c58b..33aa8bb1c 100644 --- a/MediaBrowser.Model/Dto/BaseItemDto.cs +++ b/MediaBrowser.Model/Dto/BaseItemDto.cs @@ -1213,7 +1213,6 @@ namespace MediaBrowser.Model.Dto /// </summary> /// <value>The timer identifier.</value> public string TimerId { get; set; } - public RecordingStatus TimerStatus { get; set; } /// <summary> /// Gets or sets the current program. /// </summary> diff --git a/MediaBrowser.Model/LiveTv/RecordingStatus.cs b/MediaBrowser.Model/LiveTv/RecordingStatus.cs index 7ab716c4d..571ff9c99 100644 --- a/MediaBrowser.Model/LiveTv/RecordingStatus.cs +++ b/MediaBrowser.Model/LiveTv/RecordingStatus.cs @@ -7,7 +7,6 @@ namespace MediaBrowser.Model.LiveTv Scheduled, InProgress, Completed, - Aborted, Cancelled, ConflictedOk, ConflictedNotOk, diff --git a/MediaBrowser.Model/LiveTv/SeriesTimerInfoDto.cs b/MediaBrowser.Model/LiveTv/SeriesTimerInfoDto.cs index 43e335e38..997b090ff 100644 --- a/MediaBrowser.Model/LiveTv/SeriesTimerInfoDto.cs +++ b/MediaBrowser.Model/LiveTv/SeriesTimerInfoDto.cs @@ -68,6 +68,30 @@ namespace MediaBrowser.Model.LiveTv { get { return ImageTags != null && ImageTags.ContainsKey(ImageType.Primary); } } + + /// <summary> + /// Gets or sets the parent thumb item id. + /// </summary> + /// <value>The parent thumb item id.</value> + public string ParentThumbItemId { get; set; } + + /// <summary> + /// Gets or sets the parent thumb image tag. + /// </summary> + /// <value>The parent thumb image tag.</value> + public string ParentThumbImageTag { get; set; } + + /// <summary> + /// Gets or sets the parent primary image item identifier. + /// </summary> + /// <value>The parent primary image item identifier.</value> + public string ParentPrimaryImageItemId { get; set; } + + /// <summary> + /// Gets or sets the parent primary image tag. + /// </summary> + /// <value>The parent primary image tag.</value> + public string ParentPrimaryImageTag { get; set; } } public enum KeepUntil diff --git a/MediaBrowser.Model/Querying/ItemFields.cs b/MediaBrowser.Model/Querying/ItemFields.cs index c25fba8cf..fcacc621c 100644 --- a/MediaBrowser.Model/Querying/ItemFields.cs +++ b/MediaBrowser.Model/Querying/ItemFields.cs @@ -154,8 +154,6 @@ /// </summary> People, - PlaceOfBirth, - /// <summary> /// The production locations /// </summary> diff --git a/MediaBrowser.Providers/Manager/ProviderUtils.cs b/MediaBrowser.Providers/Manager/ProviderUtils.cs index d98b2e2b1..fabe08f33 100644 --- a/MediaBrowser.Providers/Manager/ProviderUtils.cs +++ b/MediaBrowser.Providers/Manager/ProviderUtils.cs @@ -170,6 +170,14 @@ namespace MediaBrowser.Providers.Manager } } + if (!lockedFields.Contains(MetadataFields.ProductionLocations)) + { + if (replaceData || target.ProductionLocations.Count == 0) + { + target.ProductionLocations = source.ProductionLocations; + } + } + if (replaceData || !target.VoteCount.HasValue) { target.VoteCount = source.VoteCount; diff --git a/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs b/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs index 5360a58c8..82a2dfbe9 100644 --- a/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs +++ b/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs @@ -148,14 +148,10 @@ namespace MediaBrowser.Providers.Movies if (movieData.production_countries != null) { - //var hasProductionLocations = movie as IHasProductionLocations; - //if (hasProductionLocations != null) - //{ - // hasProductionLocations.ProductionLocations = movieData - // .production_countries - // .Select(i => i.name) - // .ToList(); - //} + movie.ProductionLocations = movieData + .production_countries + .Select(i => i.name) + .ToList(); } movie.SetProviderId(MetadataProviders.Tmdb, movieData.id.ToString(_usCulture)); diff --git a/MediaBrowser.Providers/People/MovieDbPersonProvider.cs b/MediaBrowser.Providers/People/MovieDbPersonProvider.cs index bb17b83ec..c954e6323 100644 --- a/MediaBrowser.Providers/People/MovieDbPersonProvider.cs +++ b/MediaBrowser.Providers/People/MovieDbPersonProvider.cs @@ -179,7 +179,11 @@ namespace MediaBrowser.Providers.People item.Name = info.name; item.HomePageUrl = info.homepage; - item.PlaceOfBirth = info.place_of_birth; + + if (!string.IsNullOrWhiteSpace(info.place_of_birth)) + { + item.ProductionLocations = new List<string> { info.place_of_birth }; + } item.Overview = info.biography; DateTime date; diff --git a/MediaBrowser.Providers/People/PersonMetadataService.cs b/MediaBrowser.Providers/People/PersonMetadataService.cs index 0be5773db..0f8bd8b66 100644 --- a/MediaBrowser.Providers/People/PersonMetadataService.cs +++ b/MediaBrowser.Providers/People/PersonMetadataService.cs @@ -15,14 +15,6 @@ namespace MediaBrowser.Providers.People protected override void MergeData(MetadataResult<Person> source, MetadataResult<Person> target, List<MetadataFields> lockedFields, bool replaceData, bool mergeMetadataSettings) { ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings); - - var sourceItem = source.Item; - var targetItem = target.Item; - - if (replaceData || string.IsNullOrEmpty(targetItem.PlaceOfBirth)) - { - targetItem.PlaceOfBirth = sourceItem.PlaceOfBirth; - } } public PersonMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, fileSystem, userDataManager, libraryManager) diff --git a/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs b/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs index b76cf46b0..1369efae1 100644 --- a/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs +++ b/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs @@ -1577,97 +1577,5 @@ namespace MediaBrowser.Server.Implementations.Channels return await _libraryManager.GetNamedView(name, "channels", "zz_" + name, cancellationToken).ConfigureAwait(false); } - - public async Task DownloadChannelItem(BaseItem item, string destination, - IProgress<double> progress, CancellationToken cancellationToken) - { - var sources = await GetDynamicMediaSources(item, cancellationToken) - .ConfigureAwait(false); - - var list = sources.Where(i => i.Protocol == MediaProtocol.Http).ToList(); - - foreach (var source in list) - { - await TryDownloadChannelItem(source, item, destination, progress, cancellationToken).ConfigureAwait(false); - return; - } - } - - private async Task TryDownloadChannelItem(MediaSourceInfo source, - BaseItem item, - string destination, - IProgress<double> progress, - CancellationToken cancellationToken) - { - var options = new HttpRequestOptions - { - CancellationToken = cancellationToken, - Url = source.Path, - Progress = new Progress<double>() - }; - - var channel = GetChannel(item.ChannelId); - var channelProvider = GetChannelProvider(channel); - var features = channelProvider.GetChannelFeatures(); - - if (!features.SupportsContentDownloading) - { - throw new ArgumentException("The channel does not support downloading."); - } - - var limit = features.DailyDownloadLimit; - - foreach (var header in source.RequiredHttpHeaders) - { - options.RequestHeaders[header.Key] = header.Value; - } - - _fileSystem.CreateDirectory(Path.GetDirectoryName(destination)); - - // Determine output extension - var response = await _httpClient.GetTempFileResponse(options).ConfigureAwait(false); - - if (response.ContentType.StartsWith("text/html")) - { - throw new HttpException("File not found") - { - StatusCode = HttpStatusCode.NotFound - }; - } - - if (string.Equals(item.MediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase) && response.ContentType.StartsWith("video/", StringComparison.OrdinalIgnoreCase)) - { - var extension = response.ContentType.Split('/') - .Last() - .Replace("quicktime", "mov", StringComparison.OrdinalIgnoreCase); - - destination += "." + extension; - } - else if (string.Equals(item.MediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase) && response.ContentType.StartsWith("audio/", StringComparison.OrdinalIgnoreCase)) - { - var extension = response.ContentType.Replace("audio/mpeg", "audio/mp3", StringComparison.OrdinalIgnoreCase) - .Split('/') - .Last(); - - destination += "." + extension; - } - else - { - _fileSystem.DeleteFile(response.TempFilePath); - - throw new ApplicationException("Unexpected response type encountered: " + response.ContentType); - } - - _fileSystem.CopyFile(response.TempFilePath, destination, true); - - try - { - _fileSystem.DeleteFile(response.TempFilePath); - } - catch - { - - } - } } }
\ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index 47c1d8332..b878226de 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -907,15 +907,6 @@ namespace MediaBrowser.Server.Implementations.Dto dto.Keywords = item.Keywords; } - if (fields.Contains(ItemFields.PlaceOfBirth)) - { - var person = item as Person; - if (person != null) - { - dto.PlaceOfBirth = person.PlaceOfBirth; - } - } - var hasAspectRatio = item as IHasAspectRatio; if (hasAspectRatio != null) { @@ -1432,10 +1423,9 @@ namespace MediaBrowser.Server.Implementations.Dto SetBookProperties(dto, book); } - var movie = item as Movie; - if (movie != null) + if (item.ProductionLocations.Count > 0 || item is Movie) { - dto.ProductionLocations = new string[] { }; + dto.ProductionLocations = item.ProductionLocations.ToArray(); } var photo = item as Photo; diff --git a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpRequest.cs b/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpRequest.cs index 405b3114b..b5c8d0107 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpRequest.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpRequest.cs @@ -17,7 +17,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp public Container Container { get; set; } private readonly HttpListenerRequest request; private readonly IHttpResponse response; - private IMemoryStreamProvider _memoryStreamProvider; + private readonly IMemoryStreamProvider _memoryStreamProvider; public WebSocketSharpRequest(HttpListenerContext httpContext, string operationName, RequestAttributes requestAttributes, ILogger logger, IMemoryStreamProvider memoryStreamProvider) { diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index f7661f55b..b2302cf86 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -335,15 +335,6 @@ namespace MediaBrowser.Server.Implementations.Library } } - /// <summary> - /// Updates the item in library cache. - /// </summary> - /// <param name="item">The item.</param> - private void UpdateItemInLibraryCache(BaseItem item) - { - RegisterItem(item); - } - public void RegisterItem(BaseItem item) { if (item == null) @@ -1777,7 +1768,7 @@ namespace MediaBrowser.Server.Implementations.Library foreach (var item in list) { - UpdateItemInLibraryCache(item); + RegisterItem(item); } if (ItemAdded != null) @@ -1818,7 +1809,7 @@ namespace MediaBrowser.Server.Implementations.Library await ItemRepository.SaveItem(item, cancellationToken).ConfigureAwait(false); - UpdateItemInLibraryCache(item); + RegisterItem(item); if (ItemUpdated != null) { diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs index 1a8295800..7f35fc3ea 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs @@ -54,8 +54,8 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio if (!args.IsDirectory) return null; // Avoid mis-identifying top folders - if (args.Parent.IsRoot) return null; if (args.HasParent<MusicAlbum>()) return null; + if (args.Parent.IsRoot) return null; var collectionType = args.GetCollectionType(); diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs index dadcff877..686105ddb 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs @@ -51,9 +51,6 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio { if (!args.IsDirectory) return null; - // Avoid mis-identifying top folders - if (args.Parent.IsRoot) return null; - // Don't allow nested artists if (args.HasParent<MusicArtist>() || args.HasParent<MusicAlbum>()) { @@ -70,12 +67,9 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio return null; } - if (args.IsDirectory) + if (args.ContainsFileSystemEntryByName("artist.nfo")) { - if (args.ContainsFileSystemEntryByName("artist.nfo")) - { - return new MusicArtist(); - } + return new MusicArtist(); } if (_config.Configuration.EnableSimpleArtistDetection) @@ -83,6 +77,9 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio return null; } + // Avoid mis-identifying top folders + if (args.Parent.IsRoot) return null; + var directoryService = args.DirectoryService; var albumResolver = new MusicAlbumResolver(_logger, _fileSystem, _libraryManager); diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/FolderResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/FolderResolver.cs index 34237622d..ff07c5282 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/FolderResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/FolderResolver.cs @@ -51,7 +51,6 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers base.SetInitialItemValues(item, args); item.IsRoot = args.Parent == null; - item.IsPhysicalRoot = args.IsPhysicalRoot; } } } diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs index 207486f26..c82825007 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs @@ -59,6 +59,15 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV return null; } + if (args.ContainsFileSystemEntryByName("tvshow.nfo")) + { + return new Series + { + Path = args.Path, + Name = Path.GetFileName(args.Path) + }; + } + var collectionType = args.GetCollectionType(); if (string.Equals(collectionType, CollectionType.TvShows, StringComparison.OrdinalIgnoreCase)) { @@ -72,23 +81,20 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV }; } } - else + else if (string.IsNullOrWhiteSpace(collectionType)) { - if (string.IsNullOrWhiteSpace(collectionType)) + if (args.Parent.IsRoot) { - if (args.Parent.IsRoot) - { - return null; - } - if (IsSeriesFolder(args.Path, args.FileSystemChildren, args.DirectoryService, _fileSystem, _logger, _libraryManager, args.GetLibraryOptions(), false) || - args.ContainsFileSystemEntryByName("tvshow.nfo")) + return null; + } + + if (IsSeriesFolder(args.Path, args.FileSystemChildren, args.DirectoryService, _fileSystem, _logger, _libraryManager, args.GetLibraryOptions(), false)) + { + return new Series { - return new Series - { - Path = args.Path, - Name = Path.GetFileName(args.Path) - }; - } + Path = args.Path, + Name = Path.GetFileName(args.Path) + }; } } } diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 23066149a..ee8d40797 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -28,6 +28,7 @@ using System.Threading.Tasks; using System.Xml; using CommonIO; using MediaBrowser.Common.Extensions; +using MediaBrowser.Controller; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Model.Configuration; @@ -38,7 +39,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV { public class EmbyTV : ILiveTvService, ISupportsDirectStreamProvider, ISupportsNewTimerIds, IDisposable { - private readonly IApplicationHost _appHpst; + private readonly IServerApplicationHost _appHost; private readonly ILogger _logger; private readonly IHttpClient _httpClient; private readonly IServerConfigurationManager _config; @@ -64,11 +65,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV private readonly ConcurrentDictionary<string, ActiveRecordingInfo> _activeRecordings = new ConcurrentDictionary<string, ActiveRecordingInfo>(StringComparer.OrdinalIgnoreCase); - public EmbyTV(IApplicationHost appHost, ILogger logger, IJsonSerializer jsonSerializer, IHttpClient httpClient, IServerConfigurationManager config, ILiveTvManager liveTvManager, IFileSystem fileSystem, ILibraryManager libraryManager, ILibraryMonitor libraryMonitor, IProviderManager providerManager, IFileOrganizationService organizationService, IMediaEncoder mediaEncoder) + public EmbyTV(IServerApplicationHost appHost, ILogger logger, IJsonSerializer jsonSerializer, IHttpClient httpClient, IServerConfigurationManager config, ILiveTvManager liveTvManager, IFileSystem fileSystem, ILibraryManager libraryManager, ILibraryMonitor libraryMonitor, IProviderManager providerManager, IFileOrganizationService organizationService, IMediaEncoder mediaEncoder) { Current = this; - _appHpst = appHost; + _appHost = appHost; _logger = logger; _httpClient = httpClient; _config = config; @@ -293,7 +294,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV status.Tuners = list; status.Status = LiveTvServiceStatus.Ok; - status.Version = _appHpst.ApplicationVersion.ToString(); + status.Version = _appHost.ApplicationVersion.ToString(); status.IsVisible = false; return status; } @@ -659,7 +660,63 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV public async Task<IEnumerable<RecordingInfo>> GetRecordingsAsync(CancellationToken cancellationToken) { - return new List<RecordingInfo>(); + return _activeRecordings.Values.ToList().Select(GetRecordingInfo).ToList(); + } + + public string GetActiveRecordingPath(string id) + { + ActiveRecordingInfo info; + + if (_activeRecordings.TryGetValue(id, out info)) + { + return info.Path; + } + return null; + } + + private RecordingInfo GetRecordingInfo(ActiveRecordingInfo info) + { + var timer = info.Timer; + var program = info.Program; + + var result = new RecordingInfo + { + ChannelId = timer.ChannelId, + CommunityRating = timer.CommunityRating, + DateLastUpdated = DateTime.UtcNow, + EndDate = timer.EndDate, + EpisodeTitle = timer.EpisodeTitle, + Genres = timer.Genres, + Id = "recording" + timer.Id, + IsKids = timer.IsKids, + IsMovie = timer.IsMovie, + IsNews = timer.IsNews, + IsRepeat = timer.IsRepeat, + IsSeries = timer.IsProgramSeries, + IsSports = timer.IsSports, + Name = timer.Name, + OfficialRating = timer.OfficialRating, + OriginalAirDate = timer.OriginalAirDate, + Overview = timer.Overview, + ProgramId = timer.ProgramId, + SeriesTimerId = timer.SeriesTimerId, + StartDate = timer.StartDate, + Status = RecordingStatus.InProgress, + TimerId = timer.Id + }; + + if (program != null) + { + result.Audio = program.Audio; + result.ImagePath = program.ImagePath; + result.ImageUrl = program.ImageUrl; + result.IsHD = program.IsHD; + result.IsLive = program.IsLive; + result.IsPremiere = program.IsPremiere; + result.ShowId = program.ShowId; + } + + return result; } public Task<IEnumerable<TimerInfo>> GetTimersAsync(CancellationToken cancellationToken) @@ -954,7 +1011,31 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV public Task<List<MediaSourceInfo>> GetRecordingStreamMediaSources(string recordingId, CancellationToken cancellationToken) { - throw new NotImplementedException(); + ActiveRecordingInfo info; + + recordingId = recordingId.Replace("recording", string.Empty); + + if (_activeRecordings.TryGetValue(recordingId, out info)) + { + return Task.FromResult(new List<MediaSourceInfo> + { + new MediaSourceInfo + { + Path = _appHost.GetLocalApiUrl("localhost") + "/LiveTv/LiveRecordings/" + recordingId + "/stream", + Id = recordingId, + SupportsDirectPlay = false, + SupportsDirectStream = true, + SupportsTranscoding = true, + IsInfiniteStream = true, + RequiresOpening = false, + RequiresClosing = false, + Protocol = Model.MediaInfo.MediaProtocol.Http, + BufferMs = 0 + } + }); + } + + throw new FileNotFoundException(); } public async Task CloseLiveStream(string id, CancellationToken cancellationToken) @@ -1031,7 +1112,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV var activeRecordingInfo = new ActiveRecordingInfo { CancellationTokenSource = new CancellationTokenSource(), - TimerId = timer.Id + Timer = timer }; if (_activeRecordings.TryAdd(timer.Id, activeRecordingInfo)) @@ -1168,6 +1249,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV if (programInfo != null) { RecordingHelper.CopyProgramInfoToTimerInfo(programInfo, timer); + activeRecordingInfo.Program = programInfo; } string seriesPath = null; @@ -1394,7 +1476,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV return true; } - var hasRecordingAtPath = _activeRecordings.Values.ToList().Any(i => string.Equals(i.Path, path, StringComparison.OrdinalIgnoreCase) && !string.Equals(i.TimerId, timerId, StringComparison.OrdinalIgnoreCase)); + var hasRecordingAtPath = _activeRecordings + .Values + .ToList() + .Any(i => string.Equals(i.Path, path, StringComparison.OrdinalIgnoreCase) && !string.Equals(i.Timer.Id, timerId, StringComparison.OrdinalIgnoreCase)); if (hasRecordingAtPath) { @@ -1878,7 +1963,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV class ActiveRecordingInfo { public string Path { get; set; } - public string TimerId { get; set; } + public TimerInfo Timer { get; set; } + public ProgramInfo Program { get; set; } public CancellationTokenSource CancellationTokenSource { get; set; } } } diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs index 2189cf627..8c46b4597 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs @@ -10,6 +10,7 @@ using MediaBrowser.Model.LiveTv; using MediaBrowser.Model.Logging; using System; using System.Collections.Generic; +using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -125,6 +126,34 @@ namespace MediaBrowser.Server.Implementations.LiveTv dto.DayPattern = info.Days == null ? null : GetDayPattern(info.Days); + if (!string.IsNullOrWhiteSpace(info.SeriesId)) + { + var program = _libraryManager.GetItemList(new InternalItemsQuery + { + IncludeItemTypes = new string[] { typeof(LiveTvProgram).Name }, + ExternalSeriesId = info.SeriesId, + Limit = 1, + ImageTypes = new ImageType[] { ImageType.Primary } + + }).FirstOrDefault(); + + if (program != null) + { + var image = program.GetImageInfo(ImageType.Primary, 0); + if (image != null) + { + try + { + dto.ParentPrimaryImageTag = _imageProcessor.GetImageCacheTag(program, image); + dto.ParentPrimaryImageItemId = program.Id.ToString("N"); + } + catch (Exception ex) + { + } + } + } + } + return dto; } diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs index 93d8f8ef4..cf441f58e 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs @@ -235,20 +235,20 @@ namespace MediaBrowser.Server.Implementations.LiveTv return await GetLiveStream(id, mediaSourceId, true, cancellationToken).ConfigureAwait(false); } - public async Task<IEnumerable<MediaSourceInfo>> GetRecordingMediaSources(string id, CancellationToken cancellationToken) + public async Task<IEnumerable<MediaSourceInfo>> GetRecordingMediaSources(IHasMediaSources item, CancellationToken cancellationToken) { - var item = await GetInternalRecording(id, cancellationToken).ConfigureAwait(false); - var service = GetService(item); + var baseItem = (BaseItem)item; + var service = GetService(baseItem); - return await service.GetRecordingStreamMediaSources(id, cancellationToken).ConfigureAwait(false); + return await service.GetRecordingStreamMediaSources(baseItem.ExternalId, cancellationToken).ConfigureAwait(false); } - public async Task<IEnumerable<MediaSourceInfo>> GetChannelMediaSources(string id, CancellationToken cancellationToken) + public async Task<IEnumerable<MediaSourceInfo>> GetChannelMediaSources(IHasMediaSources item, CancellationToken cancellationToken) { - var item = GetInternalChannel(id); - var service = GetService(item); + var baseItem = (LiveTvChannel)item; + var service = GetService(baseItem); - var sources = await service.GetChannelStreamMediaSources(item.ExternalId, cancellationToken).ConfigureAwait(false); + var sources = await service.GetChannelStreamMediaSources(baseItem.ExternalId, cancellationToken).ConfigureAwait(false); if (sources.Count == 0) { @@ -259,7 +259,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv foreach (var source in list) { - Normalize(source, service, item.ChannelType == ChannelType.TV); + Normalize(source, service, baseItem.ChannelType == ChannelType.TV); } return list; @@ -738,6 +738,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv recording.IsRepeat = info.IsRepeat; recording.IsSports = info.IsSports; recording.SeriesTimerId = info.SeriesTimerId; + recording.TimerId = info.TimerId; recording.StartDate = info.StartDate; if (!dataChanged) @@ -1083,10 +1084,13 @@ namespace MediaBrowser.Server.Implementations.LiveTv if (timer != null) { - program.TimerId = _tvDtoService.GetInternalTimerId(serviceName, timer.Id) - .ToString("N"); + if (timer.Status != RecordingStatus.Cancelled && timer.Status != RecordingStatus.Error) + { + program.TimerId = _tvDtoService.GetInternalTimerId(serviceName, timer.Id) + .ToString("N"); - program.TimerStatus = timer.Status; + program.Status = timer.Status.ToString(); + } if (!string.IsNullOrEmpty(timer.SeriesTimerId)) { @@ -1432,7 +1436,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv private DateTime _lastRecordingRefreshTime; private async Task RefreshRecordings(CancellationToken cancellationToken) { - const int cacheMinutes = 5; + const int cacheMinutes = 3; if ((DateTime.UtcNow - _lastRecordingRefreshTime).TotalMinutes < cacheMinutes) { @@ -1482,7 +1486,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv private QueryResult<BaseItem> GetEmbyRecordings(RecordingQuery query, DtoOptions dtoOptions, User user) { - if (user == null || (query.IsInProgress ?? false)) + if (user == null) + { + return new QueryResult<BaseItem>(); + } + + if ((query.IsInProgress ?? false)) { return new QueryResult<BaseItem>(); } @@ -1628,7 +1637,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv return new QueryResult<BaseItem>(); } - if (_services.Count == 1) + if (_services.Count == 1 && !(query.IsInProgress ?? false)) { return GetEmbyRecordings(query, new DtoOptions(), user); } @@ -1824,6 +1833,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv ? null : _tvDtoService.GetInternalSeriesTimerId(service.Name, info.SeriesTimerId).ToString("N"); + dto.TimerId = string.IsNullOrEmpty(info.TimerId) + ? null + : _tvDtoService.GetInternalTimerId(service.Name, info.TimerId).ToString("N"); + dto.StartDate = info.StartDate; dto.RecordingStatus = info.Status; dto.IsRepeat = info.IsRepeat; diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs index ff9b2a143..521f33e1c 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs @@ -65,12 +65,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv { if (item is ILiveTvRecording) { - sources = await _liveTvManager.GetRecordingMediaSources(item.Id.ToString("N"), cancellationToken) + sources = await _liveTvManager.GetRecordingMediaSources(item, cancellationToken) .ConfigureAwait(false); } else { - sources = await _liveTvManager.GetChannelMediaSources(item.Id.ToString("N"), cancellationToken) + sources = await _liveTvManager.GetChannelMediaSources(item, cancellationToken) .ConfigureAwait(false); } } diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs index 77e2c36e2..1e3ec22fd 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs @@ -21,10 +21,13 @@ using System.Threading.Tasks; using MediaBrowser.Common.Extensions; using MediaBrowser.Common.IO; using MediaBrowser.Controller.Channels; +using MediaBrowser.Controller.Collections; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Playlists; using MediaBrowser.Model.Dto; using MediaBrowser.Model.LiveTv; +using MediaBrowser.Server.Implementations.Devices; +using MediaBrowser.Server.Implementations.Playlists; namespace MediaBrowser.Server.Implementations.Persistence { @@ -279,6 +282,9 @@ namespace MediaBrowser.Server.Implementations.Persistence _connection.AddColumn(Logger, "TypedBaseItems", "Keywords", "Text"); _connection.AddColumn(Logger, "TypedBaseItems", "ProviderIds", "Text"); _connection.AddColumn(Logger, "TypedBaseItems", "Images", "Text"); + _connection.AddColumn(Logger, "TypedBaseItems", "ProductionLocations", "Text"); + _connection.AddColumn(Logger, "TypedBaseItems", "ThemeSongIds", "Text"); + _connection.AddColumn(Logger, "TypedBaseItems", "ThemeVideoIds", "Text"); _connection.AddColumn(Logger, "UserDataKeys", "Priority", "INT"); _connection.AddColumn(Logger, "ItemValues", "CleanValue", "Text"); @@ -428,7 +434,10 @@ namespace MediaBrowser.Server.Implementations.Persistence "Tagline", "Keywords", "ProviderIds", - "Images" + "Images", + "ProductionLocations", + "ThemeSongIds", + "ThemeVideoIds" }; private readonly string[] _mediaStreamSaveColumns = @@ -556,7 +565,10 @@ namespace MediaBrowser.Server.Implementations.Persistence "Tagline", "Keywords", "ProviderIds", - "Images" + "Images", + "ProductionLocations", + "ThemeSongIds", + "ThemeVideoIds" }; _saveItemCommand = _connection.CreateCommand(); _saveItemCommand.CommandText = "replace into TypedBaseItems (" + string.Join(",", saveColumns.ToArray()) + ") values ("; @@ -1007,10 +1019,46 @@ namespace MediaBrowser.Server.Implementations.Persistence _saveItemCommand.GetParameter(index++).Value = item.ExternalSeriesId; _saveItemCommand.GetParameter(index++).Value = item.ShortOverview; _saveItemCommand.GetParameter(index++).Value = item.Tagline; - _saveItemCommand.GetParameter(index++).Value = string.Join("|", item.Keywords.ToArray()); + + if (item.Keywords.Count > 0) + { + _saveItemCommand.GetParameter(index++).Value = string.Join("|", item.Keywords.ToArray()); + } + else + { + _saveItemCommand.GetParameter(index++).Value = null; + } + _saveItemCommand.GetParameter(index++).Value = SerializeProviderIds(item); _saveItemCommand.GetParameter(index++).Value = SerializeImages(item); + if (item.ProductionLocations.Count > 0) + { + _saveItemCommand.GetParameter(index++).Value = string.Join("|", item.ProductionLocations.ToArray()); + } + else + { + _saveItemCommand.GetParameter(index++).Value = null; + } + + if (item.ThemeSongIds.Count > 0) + { + _saveItemCommand.GetParameter(index++).Value = string.Join("|", item.ThemeSongIds.Select(i => i.ToString("N")).ToArray()); + } + else + { + _saveItemCommand.GetParameter(index++).Value = null; + } + + if (item.ThemeVideoIds.Count > 0) + { + _saveItemCommand.GetParameter(index++).Value = string.Join("|", item.ThemeVideoIds.Select(i => i.ToString("N")).ToArray()); + } + else + { + _saveItemCommand.GetParameter(index++).Value = null; + } + _saveItemCommand.Transaction = transaction; _saveItemCommand.ExecuteNonQuery(); @@ -1217,6 +1265,46 @@ namespace MediaBrowser.Server.Implementations.Persistence { return false; } + if (type == typeof(Person)) + { + return false; + } + if (type == typeof(RecordingGroup)) + { + return false; + } + if (type == typeof(Channel)) + { + return false; + } + if (type == typeof(ManualCollectionsFolder)) + { + return false; + } + if (type == typeof(CameraUploadsFolder)) + { + return false; + } + if (type == typeof(PlaylistsFolder)) + { + return false; + } + if (type == typeof(UserRootFolder)) + { + return false; + } + if (type == typeof(PhotoAlbum)) + { + return false; + } + if (type == typeof(Season)) + { + return false; + } + if (type == typeof(MusicArtist)) + { + return false; + } } if (_config.Configuration.SkipDeserializationForPrograms) { @@ -1775,6 +1863,27 @@ namespace MediaBrowser.Server.Implementations.Persistence } index++; + if (query.HasField(ItemFields.ProductionLocations)) + { + if (!reader.IsDBNull(index)) + { + item.ProductionLocations = reader.GetString(index).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).ToList(); + } + index++; + } + + if (!reader.IsDBNull(index)) + { + item.ThemeSongIds = reader.GetString(index).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).Select(i => new Guid(i)).ToList(); + } + index++; + + if (!reader.IsDBNull(index)) + { + item.ThemeVideoIds = reader.GetString(index).Split('|').Where(i => !string.IsNullOrWhiteSpace(i)).Select(i => new Guid(i)).ToList(); + } + index++; + if (string.IsNullOrWhiteSpace(item.Tagline)) { var movie = item as Movie; @@ -1784,6 +1893,15 @@ namespace MediaBrowser.Server.Implementations.Persistence } } + if (type == typeof(Person) && item.ProductionLocations.Count == 0) + { + var person = (Person)item; + if (!string.IsNullOrWhiteSpace(person.PlaceOfBirth)) + { + item.ProductionLocations = new List<string> { person.PlaceOfBirth }; + } + } + return item; } diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index 538e9a6f6..39f4d26de 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -377,6 +377,7 @@ namespace MediaBrowser.Server.Startup.Common ServiceStack.Text.JsConfig<Movie>.ExcludePropertyNames = new[] { "Keywords" }; ServiceStack.Text.JsConfig<Trailer>.ExcludePropertyNames = new[] { "ShortOverview" }; ServiceStack.Text.JsConfig<Series>.ExcludePropertyNames = new[] { "ShortOverview" }; + ServiceStack.Text.JsConfig<Person>.ExcludePropertyNames = new[] { "PlaceOfBirth" }; ServiceStack.Text.JsConfig<LiveTvProgram>.ExcludePropertyNames = new[] { "ProviderIds" }; ServiceStack.Text.JsConfig<LiveTvChannel>.ExcludePropertyNames = new[] { "ProviderIds" }; @@ -448,6 +449,111 @@ namespace MediaBrowser.Server.Startup.Common ServiceStack.Text.JsConfig<Channel>.ExcludePropertyNames = new[] { "ImageInfos" }; ServiceStack.Text.JsConfig<AggregateFolder>.ExcludePropertyNames = new[] { "ImageInfos" }; + ServiceStack.Text.JsConfig<LiveTvProgram>.ExcludePropertyNames = new[] { "ProductionLocations" }; + ServiceStack.Text.JsConfig<LiveTvChannel>.ExcludePropertyNames = new[] { "ProductionLocations" }; + ServiceStack.Text.JsConfig<LiveTvVideoRecording>.ExcludePropertyNames = new[] { "ProductionLocations" }; + ServiceStack.Text.JsConfig<LiveTvAudioRecording>.ExcludePropertyNames = new[] { "ProductionLocations" }; + ServiceStack.Text.JsConfig<Series>.ExcludePropertyNames = new[] { "ProductionLocations" }; + ServiceStack.Text.JsConfig<Audio>.ExcludePropertyNames = new[] { "ProductionLocations" }; + ServiceStack.Text.JsConfig<MusicAlbum>.ExcludePropertyNames = new[] { "ProductionLocations" }; + ServiceStack.Text.JsConfig<MusicArtist>.ExcludePropertyNames = new[] { "ProductionLocations" }; + ServiceStack.Text.JsConfig<MusicGenre>.ExcludePropertyNames = new[] { "ProductionLocations" }; + ServiceStack.Text.JsConfig<MusicVideo>.ExcludePropertyNames = new[] { "ProductionLocations" }; + ServiceStack.Text.JsConfig<Movie>.ExcludePropertyNames = new[] { "ProductionLocations" }; + ServiceStack.Text.JsConfig<Playlist>.ExcludePropertyNames = new[] { "ProductionLocations" }; + ServiceStack.Text.JsConfig<AudioPodcast>.ExcludePropertyNames = new[] { "ProductionLocations" }; + ServiceStack.Text.JsConfig<Trailer>.ExcludePropertyNames = new[] { "ProductionLocations" }; + ServiceStack.Text.JsConfig<BoxSet>.ExcludePropertyNames = new[] { "ProductionLocations" }; + ServiceStack.Text.JsConfig<Episode>.ExcludePropertyNames = new[] { "ProductionLocations" }; + ServiceStack.Text.JsConfig<Season>.ExcludePropertyNames = new[] { "ProductionLocations" }; + ServiceStack.Text.JsConfig<Book>.ExcludePropertyNames = new[] { "ProductionLocations" }; + ServiceStack.Text.JsConfig<CollectionFolder>.ExcludePropertyNames = new[] { "ProductionLocations" }; + ServiceStack.Text.JsConfig<Folder>.ExcludePropertyNames = new[] { "ProductionLocations" }; + ServiceStack.Text.JsConfig<Game>.ExcludePropertyNames = new[] { "ProductionLocations" }; + ServiceStack.Text.JsConfig<GameGenre>.ExcludePropertyNames = new[] { "ProductionLocations" }; + ServiceStack.Text.JsConfig<GameSystem>.ExcludePropertyNames = new[] { "ProductionLocations" }; + ServiceStack.Text.JsConfig<Genre>.ExcludePropertyNames = new[] { "ProductionLocations" }; + ServiceStack.Text.JsConfig<Person>.ExcludePropertyNames = new[] { "ProductionLocations" }; + ServiceStack.Text.JsConfig<Photo>.ExcludePropertyNames = new[] { "ProductionLocations" }; + ServiceStack.Text.JsConfig<PhotoAlbum>.ExcludePropertyNames = new[] { "ProductionLocations" }; + ServiceStack.Text.JsConfig<Studio>.ExcludePropertyNames = new[] { "ProductionLocations" }; + ServiceStack.Text.JsConfig<UserRootFolder>.ExcludePropertyNames = new[] { "ProductionLocations" }; + ServiceStack.Text.JsConfig<UserView>.ExcludePropertyNames = new[] { "ProductionLocations" }; + ServiceStack.Text.JsConfig<Video>.ExcludePropertyNames = new[] { "ProductionLocations" }; + ServiceStack.Text.JsConfig<Year>.ExcludePropertyNames = new[] { "ProductionLocations" }; + ServiceStack.Text.JsConfig<Channel>.ExcludePropertyNames = new[] { "ProductionLocations" }; + ServiceStack.Text.JsConfig<AggregateFolder>.ExcludePropertyNames = new[] { "ProductionLocations" }; + + ServiceStack.Text.JsConfig<LiveTvProgram>.ExcludePropertyNames = new[] { "ThemeSongIds" }; + ServiceStack.Text.JsConfig<LiveTvChannel>.ExcludePropertyNames = new[] { "ThemeSongIds" }; + ServiceStack.Text.JsConfig<LiveTvVideoRecording>.ExcludePropertyNames = new[] { "ThemeSongIds" }; + ServiceStack.Text.JsConfig<LiveTvAudioRecording>.ExcludePropertyNames = new[] { "ThemeSongIds" }; + ServiceStack.Text.JsConfig<Series>.ExcludePropertyNames = new[] { "ThemeSongIds" }; + ServiceStack.Text.JsConfig<Audio>.ExcludePropertyNames = new[] { "ThemeSongIds" }; + ServiceStack.Text.JsConfig<MusicAlbum>.ExcludePropertyNames = new[] { "ThemeSongIds" }; + ServiceStack.Text.JsConfig<MusicArtist>.ExcludePropertyNames = new[] { "ThemeSongIds" }; + ServiceStack.Text.JsConfig<MusicGenre>.ExcludePropertyNames = new[] { "ThemeSongIds" }; + ServiceStack.Text.JsConfig<MusicVideo>.ExcludePropertyNames = new[] { "ThemeSongIds" }; + ServiceStack.Text.JsConfig<Movie>.ExcludePropertyNames = new[] { "ThemeSongIds" }; + ServiceStack.Text.JsConfig<Playlist>.ExcludePropertyNames = new[] { "ThemeSongIds" }; + ServiceStack.Text.JsConfig<AudioPodcast>.ExcludePropertyNames = new[] { "ThemeSongIds" }; + ServiceStack.Text.JsConfig<Trailer>.ExcludePropertyNames = new[] { "ThemeSongIds" }; + ServiceStack.Text.JsConfig<BoxSet>.ExcludePropertyNames = new[] { "ThemeSongIds" }; + ServiceStack.Text.JsConfig<Episode>.ExcludePropertyNames = new[] { "ThemeSongIds" }; + ServiceStack.Text.JsConfig<Season>.ExcludePropertyNames = new[] { "ThemeSongIds" }; + ServiceStack.Text.JsConfig<Book>.ExcludePropertyNames = new[] { "ThemeSongIds" }; + ServiceStack.Text.JsConfig<CollectionFolder>.ExcludePropertyNames = new[] { "ThemeSongIds" }; + ServiceStack.Text.JsConfig<Folder>.ExcludePropertyNames = new[] { "ThemeSongIds" }; + ServiceStack.Text.JsConfig<Game>.ExcludePropertyNames = new[] { "ThemeSongIds" }; + ServiceStack.Text.JsConfig<GameGenre>.ExcludePropertyNames = new[] { "ThemeSongIds" }; + ServiceStack.Text.JsConfig<GameSystem>.ExcludePropertyNames = new[] { "ThemeSongIds" }; + ServiceStack.Text.JsConfig<Genre>.ExcludePropertyNames = new[] { "ThemeSongIds" }; + ServiceStack.Text.JsConfig<Person>.ExcludePropertyNames = new[] { "ThemeSongIds" }; + ServiceStack.Text.JsConfig<Photo>.ExcludePropertyNames = new[] { "ThemeSongIds" }; + ServiceStack.Text.JsConfig<PhotoAlbum>.ExcludePropertyNames = new[] { "ThemeSongIds" }; + ServiceStack.Text.JsConfig<Studio>.ExcludePropertyNames = new[] { "ThemeSongIds" }; + ServiceStack.Text.JsConfig<UserRootFolder>.ExcludePropertyNames = new[] { "ThemeSongIds" }; + ServiceStack.Text.JsConfig<UserView>.ExcludePropertyNames = new[] { "ThemeSongIds" }; + ServiceStack.Text.JsConfig<Video>.ExcludePropertyNames = new[] { "ThemeSongIds" }; + ServiceStack.Text.JsConfig<Year>.ExcludePropertyNames = new[] { "ThemeSongIds" }; + ServiceStack.Text.JsConfig<Channel>.ExcludePropertyNames = new[] { "ThemeSongIds" }; + ServiceStack.Text.JsConfig<AggregateFolder>.ExcludePropertyNames = new[] { "ThemeSongIds" }; + + ServiceStack.Text.JsConfig<LiveTvProgram>.ExcludePropertyNames = new[] { "ThemeVideoIds" }; + ServiceStack.Text.JsConfig<LiveTvChannel>.ExcludePropertyNames = new[] { "ThemeVideoIds" }; + ServiceStack.Text.JsConfig<LiveTvVideoRecording>.ExcludePropertyNames = new[] { "ThemeVideoIds" }; + ServiceStack.Text.JsConfig<LiveTvAudioRecording>.ExcludePropertyNames = new[] { "ThemeVideoIds" }; + ServiceStack.Text.JsConfig<Series>.ExcludePropertyNames = new[] { "ThemeVideoIds" }; + ServiceStack.Text.JsConfig<Audio>.ExcludePropertyNames = new[] { "ThemeVideoIds" }; + ServiceStack.Text.JsConfig<MusicAlbum>.ExcludePropertyNames = new[] { "ThemeVideoIds" }; + ServiceStack.Text.JsConfig<MusicArtist>.ExcludePropertyNames = new[] { "ThemeVideoIds" }; + ServiceStack.Text.JsConfig<MusicGenre>.ExcludePropertyNames = new[] { "ThemeVideoIds" }; + ServiceStack.Text.JsConfig<MusicVideo>.ExcludePropertyNames = new[] { "ThemeVideoIds" }; + ServiceStack.Text.JsConfig<Movie>.ExcludePropertyNames = new[] { "ThemeVideoIds" }; + ServiceStack.Text.JsConfig<Playlist>.ExcludePropertyNames = new[] { "ThemeVideoIds" }; + ServiceStack.Text.JsConfig<AudioPodcast>.ExcludePropertyNames = new[] { "ThemeVideoIds" }; + ServiceStack.Text.JsConfig<Trailer>.ExcludePropertyNames = new[] { "ThemeVideoIds" }; + ServiceStack.Text.JsConfig<BoxSet>.ExcludePropertyNames = new[] { "ThemeVideoIds" }; + ServiceStack.Text.JsConfig<Episode>.ExcludePropertyNames = new[] { "ThemeVideoIds" }; + ServiceStack.Text.JsConfig<Season>.ExcludePropertyNames = new[] { "ThemeVideoIds" }; + ServiceStack.Text.JsConfig<Book>.ExcludePropertyNames = new[] { "ThemeVideoIds" }; + ServiceStack.Text.JsConfig<CollectionFolder>.ExcludePropertyNames = new[] { "ThemeVideoIds" }; + ServiceStack.Text.JsConfig<Folder>.ExcludePropertyNames = new[] { "ThemeVideoIds" }; + ServiceStack.Text.JsConfig<Game>.ExcludePropertyNames = new[] { "ThemeVideoIds" }; + ServiceStack.Text.JsConfig<GameGenre>.ExcludePropertyNames = new[] { "ThemeVideoIds" }; + ServiceStack.Text.JsConfig<GameSystem>.ExcludePropertyNames = new[] { "ThemeVideoIds" }; + ServiceStack.Text.JsConfig<Genre>.ExcludePropertyNames = new[] { "ThemeVideoIds" }; + ServiceStack.Text.JsConfig<Person>.ExcludePropertyNames = new[] { "ThemeVideoIds" }; + ServiceStack.Text.JsConfig<Photo>.ExcludePropertyNames = new[] { "ThemeVideoIds" }; + ServiceStack.Text.JsConfig<PhotoAlbum>.ExcludePropertyNames = new[] { "ThemeVideoIds" }; + ServiceStack.Text.JsConfig<Studio>.ExcludePropertyNames = new[] { "ThemeVideoIds" }; + ServiceStack.Text.JsConfig<UserRootFolder>.ExcludePropertyNames = new[] { "ThemeVideoIds" }; + ServiceStack.Text.JsConfig<UserView>.ExcludePropertyNames = new[] { "ThemeVideoIds" }; + ServiceStack.Text.JsConfig<Video>.ExcludePropertyNames = new[] { "ThemeVideoIds" }; + ServiceStack.Text.JsConfig<Year>.ExcludePropertyNames = new[] { "ThemeVideoIds" }; + ServiceStack.Text.JsConfig<Channel>.ExcludePropertyNames = new[] { "ThemeVideoIds" }; + ServiceStack.Text.JsConfig<AggregateFolder>.ExcludePropertyNames = new[] { "ThemeVideoIds" }; + return result; } diff --git a/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs b/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs index ed47bfb95..8c45b8001 100644 --- a/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs +++ b/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs @@ -505,9 +505,10 @@ namespace MediaBrowser.XbmcMetadata.Parsers if (!string.IsNullOrWhiteSpace(val)) { - //var countries = val.Split('/') - // .Select(i => i.Trim()) - // .Where(i => !string.IsNullOrWhiteSpace(i)); + item.ProductionLocations = val.Split('/') + .Select(i => i.Trim()) + .Where(i => !string.IsNullOrWhiteSpace(i)) + .ToList(); } break; } diff --git a/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs b/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs index 6265ecf9e..0b071fceb 100644 --- a/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs +++ b/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs @@ -80,7 +80,7 @@ namespace MediaBrowser.XbmcMetadata.Savers "imdbid", "imdb_id", "plotkeyword", - //"country", + "country", "audiodbalbumid", "audiodbartistid", "awardsummary", @@ -723,10 +723,10 @@ namespace MediaBrowser.XbmcMetadata.Savers writer.WriteElementString("tagline", item.Tagline); } - //foreach (var country in hasProductionLocations.ProductionLocations) - //{ - // writer.WriteElementString("country", country); - //} + foreach (var country in item.ProductionLocations) + { + writer.WriteElementString("country", country); + } foreach (var genre in item.Genres) { |
