From e55ab989d2077d70568965198139793ca7c116b4 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 18 Dec 2014 23:20:07 -0500 Subject: add more sync buttons --- MediaBrowser.Server.Implementations/Localization/Server/server.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'MediaBrowser.Server.Implementations/Localization/Server/server.json') diff --git a/MediaBrowser.Server.Implementations/Localization/Server/server.json b/MediaBrowser.Server.Implementations/Localization/Server/server.json index 09cd286b4..2db5ac634 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/server.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/server.json @@ -1295,5 +1295,6 @@ "LabelEnableSingleImageInDidlLimit": "Limit to single embedded image", "LabelEnableSingleImageInDidlLimitHelp": "Some devices will not render properly if multiple images are embedded within Didl.", "TabActivity": "Activity", - "TitleSync": "Sync" + "TitleSync": "Sync", + "OptionAllowSyncContent": "Allow syncing media to devices" } -- cgit v1.2.3 From 8807e80d0a04cf0c13a2113fab9917065cb0fdd9 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 20 Dec 2014 01:06:27 -0500 Subject: start using user policy --- MediaBrowser.Api/Library/LibraryService.cs | 4 +- MediaBrowser.Api/LiveTv/LiveTvService.cs | 2 +- MediaBrowser.Api/NotificationsService.cs | 2 +- MediaBrowser.Api/Playback/BaseStreamingService.cs | 48 ++++-- MediaBrowser.Api/Playback/Hls/BaseHlsService.cs | 2 +- MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs | 2 +- MediaBrowser.Api/Playback/Hls/MpegDashService.cs | 2 +- .../Playback/Progressive/AudioService.cs | 2 +- .../Playback/Progressive/VideoService.cs | 2 +- MediaBrowser.Api/Session/SessionsService.cs | 4 +- MediaBrowser.Api/UserService.cs | 72 +++++---- MediaBrowser.Controller/Channels/Channel.cs | 2 +- .../Channels/ChannelAudioItem.cs | 5 +- .../Channels/ChannelFolderItem.cs | 3 +- .../Channels/ChannelVideoItem.cs | 3 +- MediaBrowser.Controller/Entities/Audio/Audio.cs | 3 +- .../Entities/Audio/MusicAlbum.cs | 3 +- .../Entities/Audio/MusicArtist.cs | 3 +- MediaBrowser.Controller/Entities/BaseItem.cs | 11 +- MediaBrowser.Controller/Entities/Book.cs | 3 +- MediaBrowser.Controller/Entities/Folder.cs | 4 +- MediaBrowser.Controller/Entities/Game.cs | 3 +- MediaBrowser.Controller/Entities/GameSystem.cs | 3 +- MediaBrowser.Controller/Entities/Movies/BoxSet.cs | 3 +- MediaBrowser.Controller/Entities/Movies/Movie.cs | 3 +- MediaBrowser.Controller/Entities/MusicVideo.cs | 3 +- MediaBrowser.Controller/Entities/Photo.cs | 5 +- MediaBrowser.Controller/Entities/PhotoAlbum.cs | 5 +- MediaBrowser.Controller/Entities/TV/Episode.cs | 3 +- MediaBrowser.Controller/Entities/TV/Season.cs | 3 +- MediaBrowser.Controller/Entities/TV/Series.cs | 3 +- MediaBrowser.Controller/Entities/Trailer.cs | 3 +- MediaBrowser.Controller/Entities/User.cs | 72 ++------- MediaBrowser.Controller/Entities/UserView.cs | 3 +- MediaBrowser.Controller/Library/IUserManager.cs | 22 ++- .../LiveTv/LiveTvAudioRecording.cs | 3 +- MediaBrowser.Controller/LiveTv/LiveTvChannel.cs | 3 +- MediaBrowser.Controller/LiveTv/LiveTvProgram.cs | 3 +- .../LiveTv/LiveTvVideoRecording.cs | 3 +- MediaBrowser.Controller/LiveTv/RecordingGroup.cs | 3 +- .../MediaBrowser.Model.Portable.csproj | 3 + .../MediaBrowser.Model.net35.csproj | 3 + .../Configuration/UserConfiguration.cs | 13 +- MediaBrowser.Model/MediaBrowser.Model.csproj | 1 + MediaBrowser.Model/Users/UserPolicy.cs | 63 +++++++- .../Channels/ChannelDownloadScheduledTask.cs | 2 +- .../Connect/ConnectManager.cs | 35 +++-- .../HttpServer/HttpListenerHost.cs | 4 +- .../HttpServer/Security/AuthService.cs | 8 +- .../Library/Resolvers/Audio/MusicAlbumResolver.cs | 18 +-- .../Library/Resolvers/Audio/MusicArtistResolver.cs | 18 +-- .../Library/Resolvers/FolderResolver.cs | 50 +------ .../Library/Resolvers/Movies/MovieResolver.cs | 6 - .../Library/Resolvers/PhotoAlbumResolver.cs | 12 +- .../Library/Resolvers/SpecialFolderResolver.cs | 79 ++++++++++ .../Library/Resolvers/TV/SeriesResolver.cs | 16 +- .../Library/UserManager.cs | 163 +++++++++++++++++---- .../LiveTv/LiveTvManager.cs | 4 +- .../Localization/JavaScript/javascript.json | 9 +- .../Localization/Server/server.json | 1 - .../MediaBrowser.Server.Implementations.csproj | 1 + .../Notifications/NotificationManager.cs | 2 +- .../Sync/SyncManager.cs | 3 +- .../Sync/SyncRepository.cs | 13 +- .../ApplicationHost.cs | 2 +- .../MediaBrowser.WebDashboard.csproj | 9 -- 66 files changed, 546 insertions(+), 323 deletions(-) create mode 100644 MediaBrowser.Server.Implementations/Library/Resolvers/SpecialFolderResolver.cs (limited to 'MediaBrowser.Server.Implementations/Localization/Server/server.json') diff --git a/MediaBrowser.Api/Library/LibraryService.cs b/MediaBrowser.Api/Library/LibraryService.cs index 5cb007f8f..e85f2cbf9 100644 --- a/MediaBrowser.Api/Library/LibraryService.cs +++ b/MediaBrowser.Api/Library/LibraryService.cs @@ -479,14 +479,14 @@ namespace MediaBrowser.Api.Library } else if (item is ILiveTvRecording) { - if (!user.Configuration.EnableLiveTvManagement) + if (!user.Policy.EnableLiveTvManagement) { throw new UnauthorizedAccessException(); } } else { - if (!user.Configuration.EnableContentDeletion) + if (!user.Policy.EnableContentDeletion) { throw new UnauthorizedAccessException(); } diff --git a/MediaBrowser.Api/LiveTv/LiveTvService.cs b/MediaBrowser.Api/LiveTv/LiveTvService.cs index 3afe72866..f3dcf57e0 100644 --- a/MediaBrowser.Api/LiveTv/LiveTvService.cs +++ b/MediaBrowser.Api/LiveTv/LiveTvService.cs @@ -319,7 +319,7 @@ namespace MediaBrowser.Api.LiveTv throw new UnauthorizedAccessException("Anonymous live tv management is not allowed."); } - if (!user.Configuration.EnableLiveTvManagement) + if (!user.Policy.EnableLiveTvManagement) { throw new UnauthorizedAccessException("The current user does not have permission to manage live tv."); } diff --git a/MediaBrowser.Api/NotificationsService.cs b/MediaBrowser.Api/NotificationsService.cs index 69f1f3489..5103d1b5c 100644 --- a/MediaBrowser.Api/NotificationsService.cs +++ b/MediaBrowser.Api/NotificationsService.cs @@ -135,7 +135,7 @@ namespace MediaBrowser.Api Level = request.Level, Name = request.Name, Url = request.Url, - UserIds = _userManager.Users.Where(i => i.Configuration.IsAdministrator).Select(i => i.Id.ToString("N")).ToList() + UserIds = _userManager.Users.Where(i => i.Policy.IsAdministrator).Select(i => i.Id.ToString("N")).ToList() }; await _notificationManager.SendNotification(notification, CancellationToken.None).ConfigureAwait(false); diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index 1a8c1d849..203a62dfc 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -202,6 +202,10 @@ namespace MediaBrowser.Api.Playback { args += " -map -0:s"; } + else if (state.SubtitleStream.IsExternal && !state.SubtitleStream.IsTextSubtitleStream) + { + args += " -map 1:0 -sn"; + } return args; } @@ -273,7 +277,7 @@ namespace MediaBrowser.Api.Playback // Recommended per docs return Math.Max(Environment.ProcessorCount - 1, 2); } - + // Use more when this is true. -re will keep cpu usage under control if (state.ReadInputAtNativeFramerate) { @@ -666,9 +670,18 @@ namespace MediaBrowser.Api.Playback videoSizeParam = string.Format(",scale={0}:{1}", state.VideoStream.Width.Value.ToString(UsCulture), state.VideoStream.Height.Value.ToString(UsCulture)); } - return string.Format(" -filter_complex \"[0:{0}]format=yuva444p{3},lut=u=128:v=128:y=gammaval(.3)[sub] ; [0:{1}] [sub] overlay{2}\"", - state.SubtitleStream.Index, - state.VideoStream.Index, + var mapPrefix = state.SubtitleStream.IsExternal ? + 1 : + 0; + + var subtitleStreamIndex = state.SubtitleStream.IsExternal + ? 0 + : state.SubtitleStream.Index; + + return string.Format(" -filter_complex \"[{0}:{1}]format=yuva444p{4},lut=u=128:v=128:y=gammaval(.3)[sub] ; [0:{2}] [sub] overlay{3}\"", + mapPrefix.ToString(UsCulture), + subtitleStreamIndex.ToString(UsCulture), + state.VideoStream.Index.ToString(UsCulture), outputSizeParam, videoSizeParam); } @@ -812,6 +825,21 @@ namespace MediaBrowser.Api.Playback /// The state. /// System.String. protected string GetInputArgument(string transcodingJobId, StreamState state) + { + var arg = "-i " + GetInputPathArgument(transcodingJobId, state); + + if (state.SubtitleStream != null) + { + if (state.SubtitleStream.IsExternal && !state.SubtitleStream.IsTextSubtitleStream) + { + arg += " -i " + state.SubtitleStream.Path; + } + } + + return arg; + } + + private string GetInputPathArgument(string transcodingJobId, StreamState state) { if (state.InputProtocol == MediaProtocol.File && state.RunTimeTicks.HasValue && @@ -883,7 +911,7 @@ namespace MediaBrowser.Api.Playback state.InputProtocol = streamInfo.Protocol; await Task.Delay(1500, cancellationTokenSource.Token).ConfigureAwait(false); - + AttachMediaStreamInfo(state, streamInfo, state.VideoRequest, state.RequestedUrl); checkCodecs = true; } @@ -913,8 +941,8 @@ namespace MediaBrowser.Api.Playback /// The cancellation token source. /// The working directory. /// Task. - protected async Task StartFfMpeg(StreamState state, - string outputPath, + protected async Task StartFfMpeg(StreamState state, + string outputPath, CancellationTokenSource cancellationTokenSource, string workingDirectory = null) { @@ -1103,7 +1131,7 @@ namespace MediaBrowser.Api.Playback if (scale.HasValue) { long val; - + if (long.TryParse(size, NumberStyles.Any, UsCulture, out val)) { bytesTranscoded = val * scale.Value; @@ -1642,7 +1670,7 @@ namespace MediaBrowser.Api.Playback if (string.IsNullOrEmpty(container)) { - container = request.Static ? + container = request.Static ? state.InputContainer : (Path.GetExtension(GetOutputFilePath(state)) ?? string.Empty).TrimStart('.'); } @@ -1717,7 +1745,7 @@ namespace MediaBrowser.Api.Playback AttachMediaStreamInfo(state, mediaSource.MediaStreams, videoRequest, requestedUrl); } - + private void AttachMediaStreamInfo(StreamState state, List mediaStreams, VideoStreamRequest videoRequest, diff --git a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs index c2a9b963c..94198d974 100644 --- a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs @@ -239,7 +239,7 @@ namespace MediaBrowser.Api.Playback.Hls "hls/" + Path.GetFileNameWithoutExtension(outputPath)); } - var args = string.Format("{0} {1} -i {2} -map_metadata -1 -threads {3} {4} {5} -sc_threshold 0 {6} -hls_time {7} -start_number {8} -hls_list_size {9}{10} -y \"{11}\"", + var args = string.Format("{0} {1} {2} -map_metadata -1 -threads {3} {4} {5} -sc_threshold 0 {6} -hls_time {7} -start_number {8} -hls_list_size {9}{10} -y \"{11}\"", itsOffset, inputModifier, GetInputArgument(transcodingJobId, state), diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs index 7903724e8..489259334 100644 --- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs @@ -677,7 +677,7 @@ namespace MediaBrowser.Api.Playback.Hls // If isEncoding is true we're actually starting ffmpeg var startNumberParam = isEncoding ? GetStartNumber(state).ToString(UsCulture) : "0"; - var args = string.Format("{0} -i {1} -map_metadata -1 -threads {2} {3} {4} -copyts -flags -global_header {5} -hls_time {6} -start_number {7} -hls_list_size {8} -y \"{9}\"", + var args = string.Format("{0} {1} -map_metadata -1 -threads {2} {3} {4} -copyts -flags -global_header {5} -hls_time {6} -start_number {7} -hls_list_size {8} -y \"{9}\"", inputModifier, GetInputArgument(transcodingJobId, state), threads, diff --git a/MediaBrowser.Api/Playback/Hls/MpegDashService.cs b/MediaBrowser.Api/Playback/Hls/MpegDashService.cs index ca46df05d..e91ed98d1 100644 --- a/MediaBrowser.Api/Playback/Hls/MpegDashService.cs +++ b/MediaBrowser.Api/Playback/Hls/MpegDashService.cs @@ -627,7 +627,7 @@ namespace MediaBrowser.Api.Playback.Hls var segmentFilename = Path.GetFileNameWithoutExtension(outputPath) + "%03d" + GetSegmentFileExtension(state); - var args = string.Format("{0} -i {1} -map_metadata -1 -threads {2} {3} {4} -copyts {5} -f ssegment -segment_time {6} -segment_list_size {8} -segment_list \"{9}\" {10}", + var args = string.Format("{0} {1} -map_metadata -1 -threads {2} {3} {4} -copyts {5} -f ssegment -segment_time {6} -segment_list_size {8} -segment_list \"{9}\" {10}", inputModifier, GetInputArgument(transcodingJobId, state), threads, diff --git a/MediaBrowser.Api/Playback/Progressive/AudioService.cs b/MediaBrowser.Api/Playback/Progressive/AudioService.cs index ae592c428..725526ecd 100644 --- a/MediaBrowser.Api/Playback/Progressive/AudioService.cs +++ b/MediaBrowser.Api/Playback/Progressive/AudioService.cs @@ -82,7 +82,7 @@ namespace MediaBrowser.Api.Playback.Progressive var inputModifier = GetInputModifier(state); - return string.Format("{0} -i {1} -threads {2}{3} {4} -id3v2_version 3 -write_id3v1 1 -y \"{5}\"", + return string.Format("{0} {1} -threads {2}{3} {4} -id3v2_version 3 -write_id3v1 1 -y \"{5}\"", inputModifier, GetInputArgument(transcodingJobId, state), threads, diff --git a/MediaBrowser.Api/Playback/Progressive/VideoService.cs b/MediaBrowser.Api/Playback/Progressive/VideoService.cs index a64866d68..fb2d30732 100644 --- a/MediaBrowser.Api/Playback/Progressive/VideoService.cs +++ b/MediaBrowser.Api/Playback/Progressive/VideoService.cs @@ -103,7 +103,7 @@ namespace MediaBrowser.Api.Playback.Progressive var inputModifier = GetInputModifier(state); - return string.Format("{0} -i {1}{2} {3} {4} -map_metadata -1 -threads {5} {6}{7} -y \"{8}\"", + return string.Format("{0} {1}{2} {3} {4} -map_metadata -1 -threads {5} {6}{7} -y \"{8}\"", inputModifier, GetInputArgument(transcodingJobId, state), keyFrame, diff --git a/MediaBrowser.Api/Session/SessionsService.cs b/MediaBrowser.Api/Session/SessionsService.cs index d2881893b..4f47b9f54 100644 --- a/MediaBrowser.Api/Session/SessionsService.cs +++ b/MediaBrowser.Api/Session/SessionsService.cs @@ -373,12 +373,12 @@ namespace MediaBrowser.Api.Session var user = _userManager.GetUserById(request.ControllableByUserId.Value); - if (!user.Configuration.EnableRemoteControlOfOtherUsers) + if (!user.Policy.EnableRemoteControlOfOtherUsers) { result = result.Where(i => i.ContainsUser(request.ControllableByUserId.Value)); } - if (!user.Configuration.EnableSharedDeviceControl) + if (!user.Policy.EnableSharedDeviceControl) { result = result.Where(i => !i.UserId.HasValue); } diff --git a/MediaBrowser.Api/UserService.cs b/MediaBrowser.Api/UserService.cs index 9c8216a03..760cb07fd 100644 --- a/MediaBrowser.Api/UserService.cs +++ b/MediaBrowser.Api/UserService.cs @@ -264,12 +264,12 @@ namespace MediaBrowser.Api if (request.IsDisabled.HasValue) { - users = users.Where(i => i.Configuration.IsDisabled == request.IsDisabled.Value); + users = users.Where(i => i.Policy.IsDisabled == request.IsDisabled.Value); } if (request.IsHidden.HasValue) { - users = users.Where(i => i.Configuration.IsHidden == request.IsHidden.Value); + users = users.Where(i => i.Policy.IsHidden == request.IsHidden.Value); } if (request.IsGuest.HasValue) @@ -445,39 +445,13 @@ namespace MediaBrowser.Api var user = _userManager.GetUserById(id); - // If removing admin access - if (!dtoUser.Configuration.IsAdministrator && user.Configuration.IsAdministrator) - { - if (_userManager.Users.Count(i => i.Configuration.IsAdministrator) == 1) - { - throw new ArgumentException("There must be at least one user in the system with administrative access."); - } - } - - // If disabling - if (dtoUser.Configuration.IsDisabled && user.Configuration.IsAdministrator) - { - throw new ArgumentException("Administrators cannot be disabled."); - } - - // If disabling - if (dtoUser.Configuration.IsDisabled && !user.Configuration.IsDisabled) - { - if (_userManager.Users.Count(i => !i.Configuration.IsDisabled) == 1) - { - throw new ArgumentException("There must be at least one enabled user in the system."); - } - - await _sessionMananger.RevokeUserTokens(user.Id.ToString("N")).ConfigureAwait(false); - } - var task = user.Name.Equals(dtoUser.Name, StringComparison.Ordinal) ? _userManager.UpdateUser(user) : _userManager.RenameUser(user, dtoUser.Name); await task.ConfigureAwait(false); - user.UpdateConfiguration(dtoUser.Configuration); + await _userManager.UpdateConfiguration(dtoUser.Id, dtoUser.Configuration); } /// @@ -515,14 +489,48 @@ namespace MediaBrowser.Api public void Post(UpdateUserConfiguration request) { - var user = _userManager.GetUserById(request.Id); - user.UpdateConfiguration(request); + var task = _userManager.UpdateConfiguration(request.Id, request); + + Task.WaitAll(task); } public void Post(UpdateUserPolicy request) { - var task = _userManager.UpdateUserPolicy(request.Id, request); + var task = UpdateUserPolicy(request); Task.WaitAll(task); } + + private async Task UpdateUserPolicy(UpdateUserPolicy request) + { + var user = _userManager.GetUserById(request.Id); + + // If removing admin access + if (!request.IsAdministrator && user.Policy.IsAdministrator) + { + if (_userManager.Users.Count(i => i.Policy.IsAdministrator) == 1) + { + throw new ArgumentException("There must be at least one user in the system with administrative access."); + } + } + + // If disabling + if (request.IsDisabled && user.Policy.IsAdministrator) + { + throw new ArgumentException("Administrators cannot be disabled."); + } + + // If disabling + if (request.IsDisabled && !user.Policy.IsDisabled) + { + if (_userManager.Users.Count(i => !i.Policy.IsDisabled) == 1) + { + throw new ArgumentException("There must be at least one enabled user in the system."); + } + + await _sessionMananger.RevokeUserTokens(user.Id.ToString("N")).ConfigureAwait(false); + } + + await _userManager.UpdateUserPolicy(request.Id, request).ConfigureAwait(false); + } } } diff --git a/MediaBrowser.Controller/Channels/Channel.cs b/MediaBrowser.Controller/Channels/Channel.cs index f618c8a25..5a9fc3322 100644 --- a/MediaBrowser.Controller/Channels/Channel.cs +++ b/MediaBrowser.Controller/Channels/Channel.cs @@ -14,7 +14,7 @@ namespace MediaBrowser.Controller.Channels public override bool IsVisible(User user) { - if (user.Configuration.BlockedChannels.Contains(Id.ToString("N"), StringComparer.OrdinalIgnoreCase)) + if (user.Policy.BlockedChannels.Contains(Id.ToString("N"), StringComparer.OrdinalIgnoreCase)) { return false; } diff --git a/MediaBrowser.Controller/Channels/ChannelAudioItem.cs b/MediaBrowser.Controller/Channels/ChannelAudioItem.cs index ede366dab..896d598bb 100644 --- a/MediaBrowser.Controller/Channels/ChannelAudioItem.cs +++ b/MediaBrowser.Controller/Channels/ChannelAudioItem.cs @@ -6,6 +6,7 @@ using MediaBrowser.Model.Entities; using System.Collections.Generic; using System.Linq; using System.Threading; +using MediaBrowser.Model.Users; namespace MediaBrowser.Controller.Channels { @@ -25,8 +26,8 @@ namespace MediaBrowser.Controller.Channels public string OriginalImageUrl { get; set; } public List ChannelMediaSources { get; set; } - - protected override bool GetBlockUnratedValue(UserConfiguration config) + + protected override bool GetBlockUnratedValue(UserPolicy config) { return config.BlockUnratedItems.Contains(UnratedItem.ChannelContent); } diff --git a/MediaBrowser.Controller/Channels/ChannelFolderItem.cs b/MediaBrowser.Controller/Channels/ChannelFolderItem.cs index 5362cc195..8482e38df 100644 --- a/MediaBrowser.Controller/Channels/ChannelFolderItem.cs +++ b/MediaBrowser.Controller/Channels/ChannelFolderItem.cs @@ -5,6 +5,7 @@ using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Querying; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Model.Users; namespace MediaBrowser.Controller.Channels { @@ -20,7 +21,7 @@ namespace MediaBrowser.Controller.Channels public string OriginalImageUrl { get; set; } - protected override bool GetBlockUnratedValue(UserConfiguration config) + protected override bool GetBlockUnratedValue(UserPolicy config) { // Don't block. return false; diff --git a/MediaBrowser.Controller/Channels/ChannelVideoItem.cs b/MediaBrowser.Controller/Channels/ChannelVideoItem.cs index 72e2b110a..f0eafcbdf 100644 --- a/MediaBrowser.Controller/Channels/ChannelVideoItem.cs +++ b/MediaBrowser.Controller/Channels/ChannelVideoItem.cs @@ -8,6 +8,7 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Threading; +using MediaBrowser.Model.Users; namespace MediaBrowser.Controller.Channels { @@ -51,7 +52,7 @@ namespace MediaBrowser.Controller.Channels return ExternalId; } - protected override bool GetBlockUnratedValue(UserConfiguration config) + protected override bool GetBlockUnratedValue(UserPolicy config) { return config.BlockUnratedItems.Contains(UnratedItem.ChannelContent); } diff --git a/MediaBrowser.Controller/Entities/Audio/Audio.cs b/MediaBrowser.Controller/Entities/Audio/Audio.cs index 447328ea1..623ae8968 100644 --- a/MediaBrowser.Controller/Entities/Audio/Audio.cs +++ b/MediaBrowser.Controller/Entities/Audio/Audio.cs @@ -8,6 +8,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; +using MediaBrowser.Model.Users; namespace MediaBrowser.Controller.Entities.Audio { @@ -173,7 +174,7 @@ namespace MediaBrowser.Controller.Entities.Audio return base.GetUserDataKey(); } - protected override bool GetBlockUnratedValue(UserConfiguration config) + protected override bool GetBlockUnratedValue(UserPolicy config) { return config.BlockUnratedItems.Contains(UnratedItem.Music); } diff --git a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs index 1f7c62de0..90edfcce7 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; +using MediaBrowser.Model.Users; namespace MediaBrowser.Controller.Entities.Audio { @@ -154,7 +155,7 @@ namespace MediaBrowser.Controller.Entities.Audio return base.GetUserDataKey(); } - protected override bool GetBlockUnratedValue(UserConfiguration config) + protected override bool GetBlockUnratedValue(UserPolicy config) { return config.BlockUnratedItems.Contains(UnratedItem.Music); } diff --git a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs index 2d9e052b1..e9cc13c66 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs @@ -8,6 +8,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Model.Users; namespace MediaBrowser.Controller.Entities.Audio { @@ -114,7 +115,7 @@ namespace MediaBrowser.Controller.Entities.Audio return "Artist-" + item.Name; } - protected override bool GetBlockUnratedValue(UserConfiguration config) + protected override bool GetBlockUnratedValue(UserPolicy config) { return config.BlockUnratedItems.Contains(UnratedItem.Music); } diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 1d57c46e6..aea04187d 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -21,6 +21,7 @@ using System.Linq; using System.Runtime.Serialization; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Model.Users; namespace MediaBrowser.Controller.Entities { @@ -595,7 +596,7 @@ namespace MediaBrowser.Controller.Entities /// PlayAccess. public PlayAccess GetPlayAccess(User user) { - if (!user.Configuration.EnableMediaPlayback) + if (!user.Policy.EnableMediaPlayback) { return PlayAccess.None; } @@ -987,7 +988,7 @@ namespace MediaBrowser.Controller.Entities return false; } - var maxAllowedRating = user.Configuration.MaxParentalRating; + var maxAllowedRating = user.Policy.MaxParentalRating; if (maxAllowedRating == null) { @@ -1003,7 +1004,7 @@ namespace MediaBrowser.Controller.Entities if (string.IsNullOrWhiteSpace(rating)) { - return !GetBlockUnratedValue(user.Configuration); + return !GetBlockUnratedValue(user.Policy); } var value = LocalizationManager.GetRatingLevel(rating); @@ -1023,7 +1024,7 @@ namespace MediaBrowser.Controller.Entities if (hasTags != null) { - if (user.Configuration.BlockedTags.Any(i => hasTags.Tags.Contains(i, StringComparer.OrdinalIgnoreCase))) + if (user.Policy.BlockedTags.Any(i => hasTags.Tags.Contains(i, StringComparer.OrdinalIgnoreCase))) { return false; } @@ -1037,7 +1038,7 @@ namespace MediaBrowser.Controller.Entities /// /// The configuration. /// true if XXXX, false otherwise. - protected virtual bool GetBlockUnratedValue(UserConfiguration config) + protected virtual bool GetBlockUnratedValue(UserPolicy config) { return config.BlockUnratedItems.Contains(UnratedItem.Other); } diff --git a/MediaBrowser.Controller/Entities/Book.cs b/MediaBrowser.Controller/Entities/Book.cs index ea7ecfb4a..381b2101d 100644 --- a/MediaBrowser.Controller/Entities/Book.cs +++ b/MediaBrowser.Controller/Entities/Book.cs @@ -2,6 +2,7 @@ using MediaBrowser.Model.Configuration; using System.Collections.Generic; using System.Linq; +using MediaBrowser.Model.Users; namespace MediaBrowser.Controller.Entities { @@ -36,7 +37,7 @@ namespace MediaBrowser.Controller.Entities Tags = new List(); } - protected override bool GetBlockUnratedValue(UserConfiguration config) + protected override bool GetBlockUnratedValue(UserPolicy config) { return config.BlockUnratedItems.Contains(UnratedItem.Book); } diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index 87ad9c380..fba5d082d 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -303,10 +303,10 @@ namespace MediaBrowser.Controller.Entities { if (this is ICollectionFolder) { - if (user.Configuration.BlockedMediaFolders.Contains(Id.ToString("N"), StringComparer.OrdinalIgnoreCase) || + if (user.Policy.BlockedMediaFolders.Contains(Id.ToString("N"), StringComparer.OrdinalIgnoreCase) || // Backwards compatibility - user.Configuration.BlockedMediaFolders.Contains(Name, StringComparer.OrdinalIgnoreCase)) + user.Policy.BlockedMediaFolders.Contains(Name, StringComparer.OrdinalIgnoreCase)) { return false; } diff --git a/MediaBrowser.Controller/Entities/Game.cs b/MediaBrowser.Controller/Entities/Game.cs index e4d032359..bf32d3e63 100644 --- a/MediaBrowser.Controller/Entities/Game.cs +++ b/MediaBrowser.Controller/Entities/Game.cs @@ -4,6 +4,7 @@ using MediaBrowser.Model.Entities; using System; using System.Collections.Generic; using System.Linq; +using MediaBrowser.Model.Users; namespace MediaBrowser.Controller.Entities { @@ -108,7 +109,7 @@ namespace MediaBrowser.Controller.Entities return base.GetDeletePaths(); } - protected override bool GetBlockUnratedValue(UserConfiguration config) + protected override bool GetBlockUnratedValue(UserPolicy config) { return config.BlockUnratedItems.Contains(UnratedItem.Game); } diff --git a/MediaBrowser.Controller/Entities/GameSystem.cs b/MediaBrowser.Controller/Entities/GameSystem.cs index f2fec4397..758498977 100644 --- a/MediaBrowser.Controller/Entities/GameSystem.cs +++ b/MediaBrowser.Controller/Entities/GameSystem.cs @@ -2,6 +2,7 @@ using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Configuration; using System; +using MediaBrowser.Model.Users; namespace MediaBrowser.Controller.Entities { @@ -43,7 +44,7 @@ namespace MediaBrowser.Controller.Entities return base.GetUserDataKey(); } - protected override bool GetBlockUnratedValue(UserConfiguration config) + protected override bool GetBlockUnratedValue(UserPolicy config) { // Don't block. Determine by game return false; diff --git a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs index 9dc600675..6563da8de 100644 --- a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs +++ b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs @@ -9,6 +9,7 @@ using System.Linq; using System.Runtime.Serialization; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Model.Users; namespace MediaBrowser.Controller.Entities.Movies { @@ -67,7 +68,7 @@ namespace MediaBrowser.Controller.Entities.Movies /// The display order. public string DisplayOrder { get; set; } - protected override bool GetBlockUnratedValue(UserConfiguration config) + protected override bool GetBlockUnratedValue(UserPolicy config) { return config.BlockUnratedItems.Contains(UnratedItem.Movie); } diff --git a/MediaBrowser.Controller/Entities/Movies/Movie.cs b/MediaBrowser.Controller/Entities/Movies/Movie.cs index 30bf0fefc..4c1aac700 100644 --- a/MediaBrowser.Controller/Entities/Movies/Movie.cs +++ b/MediaBrowser.Controller/Entities/Movies/Movie.cs @@ -8,6 +8,7 @@ using System.Linq; using System.Runtime.Serialization; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Model.Users; namespace MediaBrowser.Controller.Entities.Movies { @@ -146,7 +147,7 @@ namespace MediaBrowser.Controller.Entities.Movies return itemsChanged; } - protected override bool GetBlockUnratedValue(UserConfiguration config) + protected override bool GetBlockUnratedValue(UserPolicy config) { return config.BlockUnratedItems.Contains(UnratedItem.Movie); } diff --git a/MediaBrowser.Controller/Entities/MusicVideo.cs b/MediaBrowser.Controller/Entities/MusicVideo.cs index d7cd62aa6..4ca8cf1c5 100644 --- a/MediaBrowser.Controller/Entities/MusicVideo.cs +++ b/MediaBrowser.Controller/Entities/MusicVideo.cs @@ -6,6 +6,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; +using MediaBrowser.Model.Users; namespace MediaBrowser.Controller.Entities { @@ -80,7 +81,7 @@ namespace MediaBrowser.Controller.Entities return this.GetProviderId(MetadataProviders.Tmdb) ?? this.GetProviderId(MetadataProviders.Imdb) ?? base.GetUserDataKey(); } - protected override bool GetBlockUnratedValue(UserConfiguration config) + protected override bool GetBlockUnratedValue(UserPolicy config) { return config.BlockUnratedItems.Contains(UnratedItem.Music); } diff --git a/MediaBrowser.Controller/Entities/Photo.cs b/MediaBrowser.Controller/Entities/Photo.cs index 367db5dcb..a3d892181 100644 --- a/MediaBrowser.Controller/Entities/Photo.cs +++ b/MediaBrowser.Controller/Entities/Photo.cs @@ -3,6 +3,7 @@ using MediaBrowser.Model.Drawing; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; +using MediaBrowser.Model.Users; namespace MediaBrowser.Controller.Entities { @@ -69,8 +70,8 @@ namespace MediaBrowser.Controller.Entities public double? Longitude { get; set; } public double? Altitude { get; set; } public int? IsoSpeedRating { get; set; } - - protected override bool GetBlockUnratedValue(UserConfiguration config) + + protected override bool GetBlockUnratedValue(UserPolicy config) { return config.BlockUnratedItems.Contains(UnratedItem.Other); } diff --git a/MediaBrowser.Controller/Entities/PhotoAlbum.cs b/MediaBrowser.Controller/Entities/PhotoAlbum.cs index 982b1ef17..24ebf8815 100644 --- a/MediaBrowser.Controller/Entities/PhotoAlbum.cs +++ b/MediaBrowser.Controller/Entities/PhotoAlbum.cs @@ -1,6 +1,7 @@ using MediaBrowser.Model.Configuration; using System.Linq; using System.Runtime.Serialization; +using MediaBrowser.Model.Users; namespace MediaBrowser.Controller.Entities { @@ -22,8 +23,8 @@ namespace MediaBrowser.Controller.Entities return true; } } - - protected override bool GetBlockUnratedValue(UserConfiguration config) + + protected override bool GetBlockUnratedValue(UserPolicy config) { return config.BlockUnratedItems.Contains(UnratedItem.Other); } diff --git a/MediaBrowser.Controller/Entities/TV/Episode.cs b/MediaBrowser.Controller/Entities/TV/Episode.cs index e270bbdf3..6b6f07d4c 100644 --- a/MediaBrowser.Controller/Entities/TV/Episode.cs +++ b/MediaBrowser.Controller/Entities/TV/Episode.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; +using MediaBrowser.Model.Users; namespace MediaBrowser.Controller.Entities.TV { @@ -274,7 +275,7 @@ namespace MediaBrowser.Controller.Entities.TV return new[] { Path }; } - protected override bool GetBlockUnratedValue(UserConfiguration config) + protected override bool GetBlockUnratedValue(UserPolicy config) { return config.BlockUnratedItems.Contains(UnratedItem.Series); } diff --git a/MediaBrowser.Controller/Entities/TV/Season.cs b/MediaBrowser.Controller/Entities/TV/Season.cs index 2df90244c..ceddbbc3b 100644 --- a/MediaBrowser.Controller/Entities/TV/Season.cs +++ b/MediaBrowser.Controller/Entities/TV/Season.cs @@ -7,6 +7,7 @@ using MediaBrowser.Model.Querying; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; +using MediaBrowser.Model.Users; namespace MediaBrowser.Controller.Entities.TV { @@ -249,7 +250,7 @@ namespace MediaBrowser.Controller.Entities.TV return GetEpisodes(user); } - protected override bool GetBlockUnratedValue(UserConfiguration config) + protected override bool GetBlockUnratedValue(UserPolicy config) { // Don't block. Let either the entire series rating or episode rating determine it return false; diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs index 4c0d1fdfb..8e43c45e0 100644 --- a/MediaBrowser.Controller/Entities/TV/Series.cs +++ b/MediaBrowser.Controller/Entities/TV/Series.cs @@ -7,6 +7,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; +using MediaBrowser.Model.Users; namespace MediaBrowser.Controller.Entities.TV { @@ -246,7 +247,7 @@ namespace MediaBrowser.Controller.Entities.TV }); } - protected override bool GetBlockUnratedValue(UserConfiguration config) + protected override bool GetBlockUnratedValue(UserPolicy config) { return config.BlockUnratedItems.Contains(UnratedItem.Series); } diff --git a/MediaBrowser.Controller/Entities/Trailer.cs b/MediaBrowser.Controller/Entities/Trailer.cs index bb165d790..7a1eef8db 100644 --- a/MediaBrowser.Controller/Entities/Trailer.cs +++ b/MediaBrowser.Controller/Entities/Trailer.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Runtime.Serialization; +using MediaBrowser.Model.Users; namespace MediaBrowser.Controller.Entities { @@ -98,7 +99,7 @@ namespace MediaBrowser.Controller.Entities return base.GetUserDataKey(); } - protected override bool GetBlockUnratedValue(UserConfiguration config) + protected override bool GetBlockUnratedValue(UserPolicy config) { return config.BlockUnratedItems.Contains(UnratedItem.Trailer); } diff --git a/MediaBrowser.Controller/Entities/User.cs b/MediaBrowser.Controller/Entities/User.cs index 3dfc8cc7d..626afcfdf 100644 --- a/MediaBrowser.Controller/Entities/User.cs +++ b/MediaBrowser.Controller/Entities/User.cs @@ -1,5 +1,4 @@ -using MediaBrowser.Common.Configuration; -using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Connect; @@ -107,37 +106,27 @@ namespace MediaBrowser.Controller.Entities /// The last activity date. public DateTime? LastActivityDate { get; set; } - /// - /// The _configuration - /// - private UserConfiguration _configuration; - /// - /// The _configuration initialized - /// - private bool _configurationInitialized; - /// - /// The _configuration sync lock - /// - private object _configurationSyncLock = new object(); - /// - /// Gets the user's configuration - /// - /// The configuration. + private UserConfiguration _config; + private readonly object _configSyncLock = new object(); [IgnoreDataMember] public UserConfiguration Configuration { get { - // Lazy load - LazyInitializer.EnsureInitialized(ref _configuration, ref _configurationInitialized, ref _configurationSyncLock, () => (UserConfiguration)ConfigurationHelper.GetXmlConfiguration(typeof(UserConfiguration), ConfigurationFilePath, XmlSerializer)); - return _configuration; - } - private set - { - _configuration = value; + if (_config == null) + { + lock (_configSyncLock) + { + if (_config == null) + { + _config = UserManager.GetUserConfiguration(this); + } + } + } - _configurationInitialized = value != null; + return _config; } + set { _config = value; } } private UserPolicy _policy; @@ -256,35 +245,6 @@ namespace MediaBrowser.Controller.Entities return System.IO.Path.Combine(parentPath, Id.ToString("N")); } - /// - /// Gets the path to the user's configuration file - /// - /// The configuration file path. - [IgnoreDataMember] - public string ConfigurationFilePath - { - get - { - return System.IO.Path.Combine(ConfigurationDirectoryPath, "config.xml"); - } - } - - /// - /// Updates the configuration. - /// - /// The config. - /// config - public void UpdateConfiguration(UserConfiguration config) - { - if (config == null) - { - throw new ArgumentNullException("config"); - } - - Configuration = config; - UserManager.UpdateConfiguration(this, Configuration); - } - public bool IsParentalScheduleAllowed() { return IsParentalScheduleAllowed(DateTime.UtcNow); @@ -292,7 +252,7 @@ namespace MediaBrowser.Controller.Entities public bool IsParentalScheduleAllowed(DateTime date) { - var schedules = Configuration.AccessSchedules; + var schedules = Policy.AccessSchedules; if (schedules.Length == 0) { diff --git a/MediaBrowser.Controller/Entities/UserView.cs b/MediaBrowser.Controller/Entities/UserView.cs index 926ffa19c..0364ff678 100644 --- a/MediaBrowser.Controller/Entities/UserView.cs +++ b/MediaBrowser.Controller/Entities/UserView.cs @@ -63,7 +63,8 @@ namespace MediaBrowser.Controller.Entities { CollectionType.Books, CollectionType.HomeVideos, - CollectionType.Photos + CollectionType.Photos, + string.Empty }; var collectionFolder = folder as ICollectionFolder; diff --git a/MediaBrowser.Controller/Library/IUserManager.cs b/MediaBrowser.Controller/Library/IUserManager.cs index 9dc16ba4d..f7fbc9c20 100644 --- a/MediaBrowser.Controller/Library/IUserManager.cs +++ b/MediaBrowser.Controller/Library/IUserManager.cs @@ -35,13 +35,6 @@ namespace MediaBrowser.Controller.Library event EventHandler> UserConfigurationUpdated; event EventHandler> UserPasswordChanged; - /// - /// Updates the configuration. - /// - /// The user. - /// The new configuration. - void UpdateConfiguration(User user, UserConfiguration newConfiguration); - /// /// Gets a User by Id /// @@ -172,6 +165,21 @@ namespace MediaBrowser.Controller.Library /// UserPolicy. UserPolicy GetUserPolicy(User user); + /// + /// Gets the user configuration. + /// + /// The user. + /// UserConfiguration. + UserConfiguration GetUserConfiguration(User user); + + /// + /// Updates the configuration. + /// + /// The user identifier. + /// The new configuration. + /// Task. + Task UpdateConfiguration(string userId, UserConfiguration newConfiguration); + /// /// Updates the user policy. /// diff --git a/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs b/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs index 9f8d67a48..b95d67ad8 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvAudioRecording.cs @@ -2,6 +2,7 @@ using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Entities; using System.Linq; +using MediaBrowser.Model.Users; namespace MediaBrowser.Controller.LiveTv { @@ -78,7 +79,7 @@ namespace MediaBrowser.Controller.LiveTv } } - protected override bool GetBlockUnratedValue(UserConfiguration config) + protected override bool GetBlockUnratedValue(UserPolicy config) { return config.BlockUnratedItems.Contains(UnratedItem.LiveTvProgram); } diff --git a/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs b/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs index df118b25f..de72accff 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs @@ -6,6 +6,7 @@ using MediaBrowser.Model.LiveTv; using MediaBrowser.Model.MediaInfo; using System.Collections.Generic; using System.Linq; +using MediaBrowser.Model.Users; namespace MediaBrowser.Controller.LiveTv { @@ -33,7 +34,7 @@ namespace MediaBrowser.Controller.LiveTv } } - protected override bool GetBlockUnratedValue(UserConfiguration config) + protected override bool GetBlockUnratedValue(UserPolicy config) { return config.BlockUnratedItems.Contains(UnratedItem.LiveTvChannel); } diff --git a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs index 266eaabee..29b23a551 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs @@ -6,6 +6,7 @@ using System; using System.Threading; using System.Threading.Tasks; using System.Linq; +using MediaBrowser.Model.Users; namespace MediaBrowser.Controller.LiveTv { @@ -199,7 +200,7 @@ namespace MediaBrowser.Controller.LiveTv return ItemRepository.SaveItem(this, cancellationToken); } - protected override bool GetBlockUnratedValue(UserConfiguration config) + protected override bool GetBlockUnratedValue(UserPolicy config) { return config.BlockUnratedItems.Contains(UnratedItem.LiveTvProgram); } diff --git a/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs b/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs index 66de81213..6fc985643 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvVideoRecording.cs @@ -2,6 +2,7 @@ using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Entities; using System.Linq; +using MediaBrowser.Model.Users; namespace MediaBrowser.Controller.LiveTv { @@ -78,7 +79,7 @@ namespace MediaBrowser.Controller.LiveTv } } - protected override bool GetBlockUnratedValue(UserConfiguration config) + protected override bool GetBlockUnratedValue(UserPolicy config) { return config.BlockUnratedItems.Contains(UnratedItem.LiveTvProgram); } diff --git a/MediaBrowser.Controller/LiveTv/RecordingGroup.cs b/MediaBrowser.Controller/LiveTv/RecordingGroup.cs index 7bd810b8d..d7250d9d2 100644 --- a/MediaBrowser.Controller/LiveTv/RecordingGroup.cs +++ b/MediaBrowser.Controller/LiveTv/RecordingGroup.cs @@ -1,11 +1,12 @@ using MediaBrowser.Controller.Entities; using MediaBrowser.Model.Configuration; +using MediaBrowser.Model.Users; namespace MediaBrowser.Controller.LiveTv { public class RecordingGroup : Folder { - protected override bool GetBlockUnratedValue(UserConfiguration config) + protected override bool GetBlockUnratedValue(UserPolicy config) { // Don't block. return false; diff --git a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj index 2629dac8b..8994b16c3 100644 --- a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj +++ b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj @@ -1034,6 +1034,9 @@ Sync\SyncDialogOptions.cs + + Sync\SyncItem.cs + Sync\SyncJob.cs diff --git a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj index 4840777a5..fbde4c92d 100644 --- a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj +++ b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj @@ -993,6 +993,9 @@ Sync\SyncDialogOptions.cs + + Sync\SyncItem.cs + Sync\SyncJob.cs diff --git a/MediaBrowser.Model/Configuration/UserConfiguration.cs b/MediaBrowser.Model/Configuration/UserConfiguration.cs index f0a27a2b9..01f90a0ba 100644 --- a/MediaBrowser.Model/Configuration/UserConfiguration.cs +++ b/MediaBrowser.Model/Configuration/UserConfiguration.cs @@ -42,6 +42,10 @@ namespace MediaBrowser.Model.Configuration /// true if this instance is hidden; otherwise, false. public bool IsHidden { get; set; } + /// + /// Gets or sets a value indicating whether this instance is disabled. + /// + /// true if this instance is disabled; otherwise, false. public bool IsDisabled { get; set; } public bool DisplayMissingEpisodes { get; set; } @@ -74,9 +78,6 @@ namespace MediaBrowser.Model.Configuration public string[] OrderedViews { get; set; } - public bool SyncConnectName { get; set; } - public bool SyncConnectImage { get; set; } - public bool IncludeTrailersInSuggestions { get; set; } public bool EnableCinemaMode { get; set; } @@ -87,7 +88,9 @@ namespace MediaBrowser.Model.Configuration public string[] LatestItemsExcludes { get; set; } public string[] BlockedTags { get; set; } - + + public bool ValuesMigratedToPolicy { get; set; } + /// /// Initializes a new instance of the class. /// @@ -110,8 +113,6 @@ namespace MediaBrowser.Model.Configuration ExcludeFoldersFromGrouping = new string[] { }; DisplayCollectionsView = true; - SyncConnectName = true; - SyncConnectImage = true; IncludeTrailersInSuggestions = true; EnableCinemaMode = true; EnableUserPreferenceAccess = true; diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj index b81b4c1fd..47bb62a32 100644 --- a/MediaBrowser.Model/MediaBrowser.Model.csproj +++ b/MediaBrowser.Model/MediaBrowser.Model.csproj @@ -366,6 +366,7 @@ + diff --git a/MediaBrowser.Model/Users/UserPolicy.cs b/MediaBrowser.Model/Users/UserPolicy.cs index b458e2854..4d09ae8e8 100644 --- a/MediaBrowser.Model/Users/UserPolicy.cs +++ b/MediaBrowser.Model/Users/UserPolicy.cs @@ -1,8 +1,69 @@ - +using MediaBrowser.Model.Configuration; + namespace MediaBrowser.Model.Users { public class UserPolicy { + /// + /// Gets or sets a value indicating whether this instance is administrator. + /// + /// true if this instance is administrator; otherwise, false. + public bool IsAdministrator { get; set; } + + /// + /// Gets or sets a value indicating whether this instance is hidden. + /// + /// true if this instance is hidden; otherwise, false. + public bool IsHidden { get; set; } + + /// + /// Gets or sets a value indicating whether this instance is disabled. + /// + /// true if this instance is disabled; otherwise, false. + public bool IsDisabled { get; set; } + + /// + /// Gets or sets the max parental rating. + /// + /// The max parental rating. + public int? MaxParentalRating { get; set; } + + public string[] BlockedTags { get; set; } + public bool EnableUserPreferenceAccess { get; set; } + public AccessSchedule[] AccessSchedules { get; set; } + public UnratedItem[] BlockUnratedItems { get; set; } + public string[] BlockedMediaFolders { get; set; } + public string[] BlockedChannels { get; set; } + public bool EnableRemoteControlOfOtherUsers { get; set; } + public bool EnableSharedDeviceControl { get; set; } + + public bool EnableLiveTvManagement { get; set; } + public bool EnableLiveTvAccess { get; set; } + + public bool EnableMediaPlayback { get; set; } + public bool EnableContentDeletion { get; set; } + + /// + /// Gets or sets a value indicating whether [enable synchronize]. + /// + /// true if [enable synchronize]; otherwise, false. public bool EnableSync { get; set; } + + public UserPolicy() + { + EnableLiveTvManagement = true; + EnableMediaPlayback = true; + EnableLiveTvAccess = true; + EnableSharedDeviceControl = true; + + BlockedMediaFolders = new string[] { }; + BlockedTags = new string[] { }; + BlockedChannels = new string[] { }; + BlockUnratedItems = new UnratedItem[] { }; + + EnableUserPreferenceAccess = true; + + AccessSchedules = new AccessSchedule[] { }; + } } } diff --git a/MediaBrowser.Server.Implementations/Channels/ChannelDownloadScheduledTask.cs b/MediaBrowser.Server.Implementations/Channels/ChannelDownloadScheduledTask.cs index bfdbb8ccf..ce939aeb4 100644 --- a/MediaBrowser.Server.Implementations/Channels/ChannelDownloadScheduledTask.cs +++ b/MediaBrowser.Server.Implementations/Channels/ChannelDownloadScheduledTask.cs @@ -95,7 +95,7 @@ namespace MediaBrowser.Server.Implementations.Channels public static string GetUserDistinctValue(User user) { - var channels = user.Configuration.BlockedChannels + var channels = user.Policy.BlockedChannels .OrderBy(i => i) .ToList(); diff --git a/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs b/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs index cbd75cdeb..376dc3548 100644 --- a/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs +++ b/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs @@ -432,9 +432,7 @@ namespace MediaBrowser.Server.Implementations.Connect await user.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false); - user.Configuration.SyncConnectImage = false; - user.Configuration.SyncConnectName = false; - _userManager.UpdateConfiguration(user, user.Configuration); + await _userManager.UpdateConfiguration(user.Id.ToString("N"), user.Configuration); await RefreshAuthorizationsInternal(false, CancellationToken.None).ConfigureAwait(false); @@ -800,23 +798,21 @@ namespace MediaBrowser.Server.Implementations.Connect await _userManager.UpdateUser(user).ConfigureAwait(false); - user.Configuration.SyncConnectImage = true; - user.Configuration.SyncConnectName = true; - user.Configuration.IsHidden = true; - user.Configuration.EnableLiveTvManagement = false; - user.Configuration.EnableContentDeletion = false; - user.Configuration.EnableRemoteControlOfOtherUsers = false; - user.Configuration.EnableSharedDeviceControl = false; - user.Configuration.IsAdministrator = false; + user.Policy.IsHidden = true; + user.Policy.EnableLiveTvManagement = false; + user.Policy.EnableContentDeletion = false; + user.Policy.EnableRemoteControlOfOtherUsers = false; + user.Policy.EnableSharedDeviceControl = false; + user.Policy.IsAdministrator = false; if (currentPendingEntry != null) { - user.Configuration.EnableLiveTvAccess = currentPendingEntry.EnableLiveTv; - user.Configuration.BlockedMediaFolders = currentPendingEntry.ExcludedLibraries; - user.Configuration.BlockedChannels = currentPendingEntry.ExcludedChannels; + user.Policy.EnableLiveTvAccess = currentPendingEntry.EnableLiveTv; + user.Policy.BlockedMediaFolders = currentPendingEntry.ExcludedLibraries; + user.Policy.BlockedChannels = currentPendingEntry.ExcludedChannels; } - _userManager.UpdateConfiguration(user, user.Configuration); + await _userManager.UpdateConfiguration(user.Id.ToString("N"), user.Configuration); } } else if (string.Equals(connectEntry.AcceptStatus, "waiting", StringComparison.OrdinalIgnoreCase)) @@ -844,7 +840,7 @@ namespace MediaBrowser.Server.Implementations.Connect { var users = _userManager.Users .Where(i => !string.IsNullOrEmpty(i.ConnectUserId) && - (i.Configuration.SyncConnectImage || i.Configuration.SyncConnectName)) + (i.ConnectLinkType.HasValue && i.ConnectLinkType.Value == UserLinkType.Guest)) .ToList(); foreach (var user in users) @@ -857,7 +853,10 @@ namespace MediaBrowser.Server.Implementations.Connect continue; } - if (user.Configuration.SyncConnectName) + var syncConnectName = true; + var syncConnectImage = true; + + if (syncConnectName) { var changed = !string.Equals(authorization.UserName, user.Name, StringComparison.OrdinalIgnoreCase); @@ -867,7 +866,7 @@ namespace MediaBrowser.Server.Implementations.Connect } } - if (user.Configuration.SyncConnectImage) + if (syncConnectImage) { var imageUrl = authorization.UserImageUrl; diff --git a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs index 56e2e5247..b754a943a 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs @@ -206,8 +206,8 @@ namespace MediaBrowser.Server.Implementations.HttpServer HostContext.Config.HandlerFactoryPath = ListenerRequest.GetHandlerPathIfAny(UrlPrefixes.First()); _listener = _supportsNativeWebSocket && NativeWebSocket.IsSupported - ? _listener = new HttpListenerServer(_logger, OnRequestReceived) - //? _listener = new WebSocketSharpListener(_logger, OnRequestReceived) + //? _listener = new HttpListenerServer(_logger, OnRequestReceived) + ? _listener = new WebSocketSharpListener(_logger, OnRequestReceived) : _listener = new WebSocketSharpListener(_logger, OnRequestReceived); _listener.WebSocketHandler = WebSocketHandler; diff --git a/MediaBrowser.Server.Implementations/HttpServer/Security/AuthService.cs b/MediaBrowser.Server.Implementations/HttpServer/Security/AuthService.cs index 57d87749c..13563ce19 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/Security/AuthService.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/Security/AuthService.cs @@ -68,7 +68,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.Security if (user != null) { - if (user.Configuration.IsDisabled) + if (user.Policy.IsDisabled) { throw new SecurityException("User account has been disabled.") { @@ -76,7 +76,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.Security }; } - if (!user.Configuration.IsAdministrator && + if (!user.Policy.IsAdministrator && !authAttribtues.EscapeParentalControl && !user.IsParentalScheduleAllowed()) { @@ -135,7 +135,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.Security { if (roles.Contains("admin", StringComparer.OrdinalIgnoreCase)) { - if (user == null || !user.Configuration.IsAdministrator) + if (user == null || !user.Policy.IsAdministrator) { throw new SecurityException("User does not have admin access.") { @@ -145,7 +145,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.Security } if (roles.Contains("delete", StringComparer.OrdinalIgnoreCase)) { - if (user == null || !user.Configuration.EnableContentDeletion) + if (user == null || !user.Policy.EnableContentDeletion) { throw new SecurityException("User does not have delete access.") { diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs index f32ed2b20..05ff270fc 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs @@ -37,7 +37,11 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio /// The priority. public override ResolverPriority Priority { - get { return ResolverPriority.Third; } // we need to be ahead of the generic folder resolver but behind the movie one + get + { + // Behind special folder resolver + return ResolverPriority.Second; + } } /// @@ -49,21 +53,13 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio { if (!args.IsDirectory) return null; - //Avoid mis-identifying top folders - if (args.Parent == null) return null; + // Avoid mis-identifying top folders if (args.Parent.IsRoot) return null; if (args.HasParent()) return null; - // Optimization - if (args.HasParent() || args.HasParent() || args.HasParent()) - { - return null; - } - var collectionType = args.GetCollectionType(); - var isMusicMediaFolder = string.Equals(collectionType, CollectionType.Music, - StringComparison.OrdinalIgnoreCase); + var isMusicMediaFolder = string.Equals(collectionType, CollectionType.Music, StringComparison.OrdinalIgnoreCase); // If there's a collection type and it's not music, don't allow it. if (!isMusicMediaFolder) diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs index 71b6c0843..edbc87415 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs @@ -34,7 +34,11 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio /// The priority. public override ResolverPriority Priority { - get { return ResolverPriority.Third; } // we need to be ahead of the generic folder resolver but behind the movie one + get + { + // Behind special folder resolver + return ResolverPriority.Second; + } } /// @@ -46,8 +50,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio { if (!args.IsDirectory) return null; - //Avoid mis-identifying top folders - if (args.Parent == null) return null; + // Avoid mis-identifying top folders if (args.Parent.IsRoot) return null; // Don't allow nested artists @@ -56,16 +59,9 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio return null; } - // Optimization - if (args.HasParent() || args.HasParent() || args.HasParent()) - { - return null; - } - var collectionType = args.GetCollectionType(); - var isMusicMediaFolder = string.Equals(collectionType, CollectionType.Music, - StringComparison.OrdinalIgnoreCase); + var isMusicMediaFolder = string.Equals(collectionType, CollectionType.Music, StringComparison.OrdinalIgnoreCase); // If there's a collection type and it's not music, it can't be a series if (!isMusicMediaFolder) diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/FolderResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/FolderResolver.cs index 166465f72..34237622d 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/FolderResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/FolderResolver.cs @@ -1,10 +1,6 @@ -using MediaBrowser.Common.IO; -using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Resolvers; -using System; -using System.IO; -using System.Linq; namespace MediaBrowser.Server.Implementations.Library.Resolvers { @@ -13,13 +9,6 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers /// public class FolderResolver : FolderResolver { - private readonly IFileSystem _fileSystem; - - public FolderResolver(IFileSystem fileSystem) - { - _fileSystem = fileSystem; - } - /// /// Gets the priority. /// @@ -38,48 +27,11 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers { if (args.IsDirectory) { - if (args.IsPhysicalRoot) - { - return new AggregateFolder(); - } - if (args.IsRoot) - { - return new UserRootFolder(); //if we got here and still a root - must be user root - } - if (args.IsVf) - { - return new CollectionFolder - { - CollectionType = GetCollectionType(args) - }; - } - return new Folder(); } return null; } - - private string GetCollectionType(ItemResolveArgs args) - { - return args.FileSystemChildren - .Where(i => - { - - try - { - return (i.Attributes & FileAttributes.Directory) != FileAttributes.Directory && - string.Equals(".collection", i.Extension, StringComparison.OrdinalIgnoreCase); - } - catch (IOException) - { - return false; - } - - }) - .Select(i => _fileSystem.GetFileNameWithoutExtension(i)) - .FirstOrDefault(); - } } /// diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs index 0e5ed1825..58b5dbc6a 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs @@ -183,12 +183,6 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies return FindMovie /// The item. /// System.String. - string FindCollectionType(BaseItem item); + string GetContentType(BaseItem item); + /// + /// Gets the type of the inherited content. + /// + /// The item. + /// System.String. + string GetInheritedContentType(BaseItem item); + /// /// Normalizes the root path list. /// diff --git a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj index ec41ffe0b..f18c53cd3 100644 --- a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj +++ b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj @@ -464,6 +464,9 @@ Dto\MetadataEditorInfo.cs + + Dto\NameValuePair.cs + Dto\RatingType.cs diff --git a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj index 01aaad2ac..f17215988 100644 --- a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj +++ b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj @@ -429,6 +429,9 @@ Dto\MetadataEditorInfo.cs + + Dto\NameValuePair.cs + Dto\RatingType.cs diff --git a/MediaBrowser.Model/Dto/MetadataEditorInfo.cs b/MediaBrowser.Model/Dto/MetadataEditorInfo.cs index 66bdb8ce3..9bd15fc8f 100644 --- a/MediaBrowser.Model/Dto/MetadataEditorInfo.cs +++ b/MediaBrowser.Model/Dto/MetadataEditorInfo.cs @@ -12,12 +12,16 @@ namespace MediaBrowser.Model.Dto public List Cultures { get; set; } public List ExternalIdInfos { get; set; } + public string ContentType { get; set; } + public List ContentTypeOptions { get; set; } + public MetadataEditorInfo() { ParentalRatingOptions = new List(); Countries = new List(); Cultures = new List(); ExternalIdInfos = new List(); + ContentTypeOptions = new List(); } } } diff --git a/MediaBrowser.Model/Dto/NameValuePair.cs b/MediaBrowser.Model/Dto/NameValuePair.cs new file mode 100644 index 000000000..2d55e8f2a --- /dev/null +++ b/MediaBrowser.Model/Dto/NameValuePair.cs @@ -0,0 +1,17 @@ + +namespace MediaBrowser.Model.Dto +{ + public class NameValuePair + { + /// + /// Gets or sets the name. + /// + /// The name. + public string Name { get; set; } + /// + /// Gets or sets the value. + /// + /// The value. + public string Value { get; set; } + } +} diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj index 0dd5442ed..759c671e9 100644 --- a/MediaBrowser.Model/MediaBrowser.Model.csproj +++ b/MediaBrowser.Model/MediaBrowser.Model.csproj @@ -129,6 +129,7 @@ + diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index 9647461bf..ab50c30fb 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -1546,12 +1546,17 @@ namespace MediaBrowser.Server.Implementations.Library return ItemRepository.RetrieveItem(id); } - /// - /// Finds the type of the collection. - /// - /// The item. - /// System.String. - public string FindCollectionType(BaseItem item) + public string GetContentType(BaseItem item) + { + return GetInheritedContentType(item); + } + + public string GetInheritedContentType(BaseItem item) + { + return GetTopFolderContentType(item); + } + + private string GetTopFolderContentType(BaseItem item) { while (!(item.Parent is AggregateFolder) && item.Parent != null) { diff --git a/MediaBrowser.Server.Implementations/Localization/Server/server.json b/MediaBrowser.Server.Implementations/Localization/Server/server.json index 9bf06c50b..9a515d492 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/server.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/server.json @@ -37,6 +37,18 @@ "ButtonOk": "Ok", "ButtonCancel": "Cancel", "ButtonNew": "New", + "FolderTypeMixed": "Mixed videos", + "FolderTypeMovies": "Movies", + "FolderTypeMusic": "Music", + "FolderTypeAdultVideos": "Adult videos", + "FolderTypePhotos": "Photos", + "FolderTypeMusicVideos": "Music videos", + "FolderTypeHomeVideos": "Home videos", + "FolderTypeGames": "Games", + "FolderTypeBooks": "Books", + "FolderTypeTvShows": "TV", + "FolderTypeInherit": "Inherit", + "LabelContentType": "Content type:", "HeaderSetupLibrary": "Setup your media library", "ButtonAddMediaFolder": "Add media folder", "LabelFolderType": "Folder type:", -- cgit v1.2.3 From 42b14166029d5251e952b72f5c16cd9ae96aa8cb Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 22 Dec 2014 22:58:14 -0500 Subject: begin work on daily episodes --- MediaBrowser.Api/ItemUpdateService.cs | 3 +- .../Configuration/BaseConfigurationManager.cs | 4 + .../Devices/DeviceId.cs | 5 +- .../Security/MBLicenseFile.cs | 4 + MediaBrowser.Common/Extensions/BaseExtensions.cs | 11 +++ MediaBrowser.Common/Plugins/BasePlugin.cs | 4 + MediaBrowser.Controller/Entities/TV/Episode.cs | 11 ++- MediaBrowser.Controller/Entities/TV/Season.cs | 78 ++++++++++++------- MediaBrowser.Controller/Library/IUserManager.cs | 7 ++ MediaBrowser.LocalMetadata/BaseXmlProvider.cs | 6 -- .../Subtitles/SubtitleEncoder.cs | 4 + MediaBrowser.Model/ApiClient/IApiClient.cs | 18 ----- .../Movies/FanartMovieImageProvider.cs | 4 + .../Music/FanArtAlbumProvider.cs | 4 + .../Music/FanArtArtistProvider.cs | 4 + .../People/TvdbPersonImageProvider.cs | 4 + MediaBrowser.Providers/TV/FanArtSeasonProvider.cs | 4 + MediaBrowser.Providers/TV/FanartSeriesProvider.cs | 4 + .../TV/MissingEpisodeProvider.cs | 63 +++++++++------- MediaBrowser.Providers/TV/SeriesPostScanTask.cs | 11 ++- MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs | 15 +++- .../TV/TvdbSeasonImageProvider.cs | 4 + .../TV/TvdbSeriesImageProvider.cs | 4 + .../Connect/ConnectManager.cs | 3 +- .../Drawing/ImageProcessor.cs | 5 ++ .../FileOrganization/EpisodeFileOrganizer.cs | 10 ++- .../Library/LibraryManager.cs | 88 ++++++++++++++++++---- .../Library/Resolvers/TV/EpisodeResolver.cs | 2 - .../Library/UserManager.cs | 68 +++++++++++++---- .../Localization/JavaScript/javascript.json | 4 +- .../Localization/Server/server.json | 9 ++- .../News/NewsService.cs | 8 ++ MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs | 4 + 33 files changed, 349 insertions(+), 128 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Localization/Server/server.json') diff --git a/MediaBrowser.Api/ItemUpdateService.cs b/MediaBrowser.Api/ItemUpdateService.cs index 020908ddd..272dff3ec 100644 --- a/MediaBrowser.Api/ItemUpdateService.cs +++ b/MediaBrowser.Api/ItemUpdateService.cs @@ -3,6 +3,7 @@ using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.LiveTv; using MediaBrowser.Controller.Localization; using MediaBrowser.Controller.Net; using MediaBrowser.Controller.Providers; @@ -73,7 +74,7 @@ namespace MediaBrowser.Api if (locationType == LocationType.FileSystem || locationType == LocationType.Offline) { - if (!(item is ICollectionFolder) && !(item is UserView) && !(item is AggregateFolder)) + if (!(item is ICollectionFolder) && !(item is UserView) && !(item is AggregateFolder) && !(item is LiveTvChannel) && !(item is IItemByName)) { var collectionType = _libraryManager.GetInheritedContentType(item); if (string.IsNullOrWhiteSpace(collectionType)) diff --git a/MediaBrowser.Common.Implementations/Configuration/BaseConfigurationManager.cs b/MediaBrowser.Common.Implementations/Configuration/BaseConfigurationManager.cs index 89f6229ac..c53947e44 100644 --- a/MediaBrowser.Common.Implementations/Configuration/BaseConfigurationManager.cs +++ b/MediaBrowser.Common.Implementations/Configuration/BaseConfigurationManager.cs @@ -223,6 +223,10 @@ namespace MediaBrowser.Common.Implementations.Configuration { return Activator.CreateInstance(configurationType); } + catch (DirectoryNotFoundException) + { + return Activator.CreateInstance(configurationType); + } catch (Exception ex) { Logger.ErrorException("Error loading configuration file: {0}", ex, path); diff --git a/MediaBrowser.Common.Implementations/Devices/DeviceId.cs b/MediaBrowser.Common.Implementations/Devices/DeviceId.cs index 5af236026..7c0dc1e1f 100644 --- a/MediaBrowser.Common.Implementations/Devices/DeviceId.cs +++ b/MediaBrowser.Common.Implementations/Devices/DeviceId.cs @@ -38,7 +38,10 @@ namespace MediaBrowser.Common.Implementations.Devices _logger.Error("Invalid value found in device id file"); } } - catch (FileNotFoundException ex) + catch (DirectoryNotFoundException) + { + } + catch (FileNotFoundException) { } catch (Exception ex) diff --git a/MediaBrowser.Common.Implementations/Security/MBLicenseFile.cs b/MediaBrowser.Common.Implementations/Security/MBLicenseFile.cs index 8f3225f4e..63381efcd 100644 --- a/MediaBrowser.Common.Implementations/Security/MBLicenseFile.cs +++ b/MediaBrowser.Common.Implementations/Security/MBLicenseFile.cs @@ -101,6 +101,10 @@ namespace MediaBrowser.Common.Implementations.Security { contents = File.ReadAllLines(licenseFile); } + catch (DirectoryNotFoundException) + { + (File.Create(licenseFile)).Close(); + } catch (FileNotFoundException) { (File.Create(licenseFile)).Close(); diff --git a/MediaBrowser.Common/Extensions/BaseExtensions.cs b/MediaBrowser.Common/Extensions/BaseExtensions.cs index 8e96373f4..4c94f3aa2 100644 --- a/MediaBrowser.Common/Extensions/BaseExtensions.cs +++ b/MediaBrowser.Common/Extensions/BaseExtensions.cs @@ -1,4 +1,6 @@ using System; +using System.Globalization; +using System.Linq; using System.Security.Cryptography; using System.Text; using System.Text.RegularExpressions; @@ -54,6 +56,15 @@ namespace MediaBrowser.Common.Extensions return sb.ToString(); } + public static string RemoveDiacritics(this string text) + { + return String.Concat( + text.Normalize(NormalizationForm.FormD) + .Where(ch => CharUnicodeInfo.GetUnicodeCategory(ch) != + UnicodeCategory.NonSpacingMark) + ).Normalize(NormalizationForm.FormC); + } + /// /// Gets the M d5. /// diff --git a/MediaBrowser.Common/Plugins/BasePlugin.cs b/MediaBrowser.Common/Plugins/BasePlugin.cs index 1a536b4ff..ce068463e 100644 --- a/MediaBrowser.Common/Plugins/BasePlugin.cs +++ b/MediaBrowser.Common/Plugins/BasePlugin.cs @@ -204,6 +204,10 @@ namespace MediaBrowser.Common.Plugins { return (TConfigurationType)XmlSerializer.DeserializeFromFile(typeof(TConfigurationType), path); } + catch (DirectoryNotFoundException) + { + return (TConfigurationType)Activator.CreateInstance(typeof(TConfigurationType)); + } catch (FileNotFoundException) { return (TConfigurationType)Activator.CreateInstance(typeof(TConfigurationType)); diff --git a/MediaBrowser.Controller/Entities/TV/Episode.cs b/MediaBrowser.Controller/Entities/TV/Episode.cs index 6b6f07d4c..6b67cebc8 100644 --- a/MediaBrowser.Controller/Entities/TV/Episode.cs +++ b/MediaBrowser.Controller/Entities/TV/Episode.cs @@ -1,11 +1,11 @@ using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Users; using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; -using MediaBrowser.Model.Users; namespace MediaBrowser.Controller.Entities.TV { @@ -178,6 +178,15 @@ namespace MediaBrowser.Controller.Entities.TV } } + [IgnoreDataMember] + public bool IsInSeasonFolder + { + get + { + return FindParent() != null; + } + } + [IgnoreDataMember] public string SeriesName { diff --git a/MediaBrowser.Controller/Entities/TV/Season.cs b/MediaBrowser.Controller/Entities/TV/Season.cs index ceddbbc3b..54db12b6f 100644 --- a/MediaBrowser.Controller/Entities/TV/Season.cs +++ b/MediaBrowser.Controller/Entities/TV/Season.cs @@ -1,13 +1,12 @@ -using MediaBrowser.Controller.Library; -using MediaBrowser.Controller.Localization; +using MediaBrowser.Controller.Localization; using MediaBrowser.Controller.Providers; -using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Querying; +using MediaBrowser.Model.Users; +using MoreLinq; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; -using MediaBrowser.Model.Users; namespace MediaBrowser.Controller.Entities.TV { @@ -156,24 +155,6 @@ namespace MediaBrowser.Controller.Entities.TV return IndexNumber != null ? IndexNumber.Value.ToString("0000") : Name; } - private IEnumerable GetEpisodes() - { - var series = Series; - - if (series != null && series.ContainsEpisodesWithoutSeasonFolders) - { - var seasonNumber = IndexNumber; - - if (seasonNumber.HasValue) - { - return series.RecursiveChildren.OfType() - .Where(i => i.ParentIndexNumber.HasValue && i.ParentIndexNumber.Value == seasonNumber.Value); - } - } - - return Children.OfType(); - } - [IgnoreDataMember] public bool IsMissingSeason { @@ -221,16 +202,32 @@ namespace MediaBrowser.Controller.Entities.TV var episodes = GetRecursiveChildren(user) .OfType(); - if (IndexNumber.HasValue) + var series = Series; + + if (IndexNumber.HasValue && series != null) { - var series = Series; + return series.GetEpisodes(user, IndexNumber.Value, includeMissingEpisodes, includeVirtualUnairedEpisodes, episodes); + } - if (series != null) + if (series != null && series.ContainsEpisodesWithoutSeasonFolders) + { + var seasonNumber = IndexNumber; + var list = episodes.ToList(); + + if (seasonNumber.HasValue) { - return series.GetEpisodes(user, IndexNumber.Value, includeMissingEpisodes, includeVirtualUnairedEpisodes, episodes); + list.AddRange(series.GetRecursiveChildren(user).OfType() + .Where(i => i.ParentIndexNumber.HasValue && i.ParentIndexNumber.Value == seasonNumber.Value)); + } + else + { + list.AddRange(series.GetRecursiveChildren(user).OfType() + .Where(i => !i.ParentIndexNumber.HasValue)); } - } + episodes = list.DistinctBy(i => i.Id); + } + if (!includeMissingEpisodes) { episodes = episodes.Where(i => !i.IsMissingEpisode); @@ -245,6 +242,33 @@ namespace MediaBrowser.Controller.Entities.TV .Cast(); } + private IEnumerable GetEpisodes() + { + var episodes = RecursiveChildren.OfType(); + var series = Series; + + if (series != null && series.ContainsEpisodesWithoutSeasonFolders) + { + var seasonNumber = IndexNumber; + var list = episodes.ToList(); + + if (seasonNumber.HasValue) + { + list.AddRange(series.RecursiveChildren.OfType() + .Where(i => i.ParentIndexNumber.HasValue && i.ParentIndexNumber.Value == seasonNumber.Value)); + } + else + { + list.AddRange(series.RecursiveChildren.OfType() + .Where(i => !i.ParentIndexNumber.HasValue)); + } + + episodes = list.DistinctBy(i => i.Id); + } + + return episodes; + } + public override IEnumerable GetChildren(User user, bool includeLinkedChildren) { return GetEpisodes(user); diff --git a/MediaBrowser.Controller/Library/IUserManager.cs b/MediaBrowser.Controller/Library/IUserManager.cs index f7fbc9c20..f5846973e 100644 --- a/MediaBrowser.Controller/Library/IUserManager.cs +++ b/MediaBrowser.Controller/Library/IUserManager.cs @@ -186,5 +186,12 @@ namespace MediaBrowser.Controller.Library /// The user identifier. /// The user policy. Task UpdateUserPolicy(string userId, UserPolicy userPolicy); + + /// + /// Makes the valid username. + /// + /// The username. + /// System.String. + string MakeValidUsername(string username); } } diff --git a/MediaBrowser.LocalMetadata/BaseXmlProvider.cs b/MediaBrowser.LocalMetadata/BaseXmlProvider.cs index 82e7809e8..74e3b61ca 100644 --- a/MediaBrowser.LocalMetadata/BaseXmlProvider.cs +++ b/MediaBrowser.LocalMetadata/BaseXmlProvider.cs @@ -28,8 +28,6 @@ namespace MediaBrowser.LocalMetadata var path = file.FullName; - //await XmlProviderUtils.XmlParsingResourcePool.WaitAsync(cancellationToken).ConfigureAwait(false); - try { result.Item = new T(); @@ -45,10 +43,6 @@ namespace MediaBrowser.LocalMetadata { result.HasMetadata = false; } - finally - { - //XmlProviderUtils.XmlParsingResourcePool.Release(); - } return result; } diff --git a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs index 7c512840b..67c9123f5 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs @@ -612,6 +612,10 @@ namespace MediaBrowser.MediaEncoding.Subtitles catch (FileNotFoundException) { + } + catch (DirectoryNotFoundException) + { + } catch (IOException ex) { diff --git a/MediaBrowser.Model/ApiClient/IApiClient.cs b/MediaBrowser.Model/ApiClient/IApiClient.cs index dde6ca0b1..0181325fe 100644 --- a/MediaBrowser.Model/ApiClient/IApiClient.cs +++ b/MediaBrowser.Model/ApiClient/IApiClient.cs @@ -505,15 +505,6 @@ namespace MediaBrowser.Model.ApiClient /// The cancellation token. /// Task<PublicSystemInfo>. Task GetPublicSystemInfoAsync(CancellationToken cancellationToken = default(CancellationToken)); - - /// - /// Gets a person - /// - /// The name. - /// The user id. - /// Task{BaseItemDto}. - /// userId - Task GetPersonAsync(string name, string userId); /// /// Gets a list of plugins installed on the server @@ -967,15 +958,6 @@ namespace MediaBrowser.Model.ApiClient /// item string GetPersonImageUrl(BaseItemPerson item, ImageOptions options); - /// - /// Gets an image url that can be used to download an image from the api - /// - /// The name of the person - /// The options. - /// System.String. - /// name - string GetPersonImageUrl(string name, ImageOptions options); - /// /// Gets an image url that can be used to download an image from the api /// diff --git a/MediaBrowser.Providers/Movies/FanartMovieImageProvider.cs b/MediaBrowser.Providers/Movies/FanartMovieImageProvider.cs index a7ccf3f6e..6813f2ff5 100644 --- a/MediaBrowser.Providers/Movies/FanartMovieImageProvider.cs +++ b/MediaBrowser.Providers/Movies/FanartMovieImageProvider.cs @@ -106,6 +106,10 @@ namespace MediaBrowser.Providers.Movies { // No biggie. Don't blow up } + catch (DirectoryNotFoundException) + { + // No biggie. Don't blow up + } } var language = item.GetPreferredMetadataLanguage(); diff --git a/MediaBrowser.Providers/Music/FanArtAlbumProvider.cs b/MediaBrowser.Providers/Music/FanArtAlbumProvider.cs index 94d682f44..123ff9e29 100644 --- a/MediaBrowser.Providers/Music/FanArtAlbumProvider.cs +++ b/MediaBrowser.Providers/Music/FanArtAlbumProvider.cs @@ -82,6 +82,10 @@ namespace MediaBrowser.Providers.Music catch (FileNotFoundException) { + } + catch (DirectoryNotFoundException) + { + } } diff --git a/MediaBrowser.Providers/Music/FanArtArtistProvider.cs b/MediaBrowser.Providers/Music/FanArtArtistProvider.cs index a8df95fd1..6f633cfc8 100644 --- a/MediaBrowser.Providers/Music/FanArtArtistProvider.cs +++ b/MediaBrowser.Providers/Music/FanArtArtistProvider.cs @@ -90,6 +90,10 @@ namespace MediaBrowser.Providers.Music catch (FileNotFoundException) { + } + catch (DirectoryNotFoundException) + { + } } diff --git a/MediaBrowser.Providers/People/TvdbPersonImageProvider.cs b/MediaBrowser.Providers/People/TvdbPersonImageProvider.cs index 63d054664..253acc13f 100644 --- a/MediaBrowser.Providers/People/TvdbPersonImageProvider.cs +++ b/MediaBrowser.Providers/People/TvdbPersonImageProvider.cs @@ -83,6 +83,10 @@ namespace MediaBrowser.Providers.People { return null; } + catch (DirectoryNotFoundException) + { + return null; + } } private RemoteImageInfo GetImageInfo(string xmlFile, string personName, CancellationToken cancellationToken) diff --git a/MediaBrowser.Providers/TV/FanArtSeasonProvider.cs b/MediaBrowser.Providers/TV/FanArtSeasonProvider.cs index 05244af74..9f0cd4ff1 100644 --- a/MediaBrowser.Providers/TV/FanArtSeasonProvider.cs +++ b/MediaBrowser.Providers/TV/FanArtSeasonProvider.cs @@ -98,6 +98,10 @@ namespace MediaBrowser.Providers.TV { // No biggie. Don't blow up } + catch (DirectoryNotFoundException) + { + // No biggie. Don't blow up + } } } diff --git a/MediaBrowser.Providers/TV/FanartSeriesProvider.cs b/MediaBrowser.Providers/TV/FanartSeriesProvider.cs index afc71698b..8ba25e9f1 100644 --- a/MediaBrowser.Providers/TV/FanartSeriesProvider.cs +++ b/MediaBrowser.Providers/TV/FanartSeriesProvider.cs @@ -106,6 +106,10 @@ namespace MediaBrowser.Providers.TV { // No biggie. Don't blow up } + catch (DirectoryNotFoundException) + { + // No biggie. Don't blow up + } } var language = item.GetPreferredMetadataLanguage(); diff --git a/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs b/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs index 21d41ca00..0b52956de 100644 --- a/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs +++ b/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs @@ -2,6 +2,7 @@ using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Localization; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; @@ -22,14 +23,16 @@ namespace MediaBrowser.Providers.TV private readonly IServerConfigurationManager _config; private readonly ILogger _logger; private readonly ILibraryManager _libraryManager; + private readonly ILocalizationManager _localization; private static readonly CultureInfo UsCulture = new CultureInfo("en-US"); - public MissingEpisodeProvider(ILogger logger, IServerConfigurationManager config, ILibraryManager libraryManager) + public MissingEpisodeProvider(ILogger logger, IServerConfigurationManager config, ILibraryManager libraryManager, ILocalizationManager localization) { _logger = logger; _config = config; _libraryManager = libraryManager; + _localization = localization; } public async Task Run(IEnumerable> series, CancellationToken cancellationToken) @@ -93,16 +96,16 @@ namespace MediaBrowser.Providers.TV var hasBadData = HasInvalidContent(group); - var anySeasonsRemoved = await RemoveObsoleteOrMissingSeasons(group, episodeLookup, false) + var anySeasonsRemoved = await RemoveObsoleteOrMissingSeasons(group, episodeLookup) .ConfigureAwait(false); - var anyEpisodesRemoved = await RemoveObsoleteOrMissingEpisodes(group, episodeLookup, false) + var anyEpisodesRemoved = await RemoveObsoleteOrMissingEpisodes(group, episodeLookup) .ConfigureAwait(false); var hasNewEpisodes = false; var hasNewSeasons = false; - foreach (var series in group.Where(s => s.ContainsEpisodesWithoutSeasonFolders)) + foreach (var series in group) { hasNewSeasons = await AddDummySeasonFolders(series, cancellationToken).ConfigureAwait(false); } @@ -165,14 +168,15 @@ namespace MediaBrowser.Providers.TV /// private async Task AddDummySeasonFolders(Series series, CancellationToken cancellationToken) { - var existingEpisodes = series.RecursiveChildren + var episodesInSeriesFolder = series.RecursiveChildren .OfType() + .Where(i => !i.IsInSeasonFolder) .ToList(); var hasChanges = false; // Loop through the unique season numbers - foreach (var seasonNumber in existingEpisodes.Select(i => i.ParentIndexNumber ?? -1) + foreach (var seasonNumber in episodesInSeriesFolder.Select(i => i.ParentIndexNumber ?? -1) .Where(i => i >= 0) .Distinct() .ToList()) @@ -188,6 +192,20 @@ namespace MediaBrowser.Providers.TV } } + // Unknown season - create a dummy season to put these under + if (episodesInSeriesFolder.Any(i => !i.ParentIndexNumber.HasValue)) + { + var hasSeason = series.Children.OfType() + .Any(i => !i.IndexNumber.HasValue); + + if (!hasSeason) + { + await AddSeason(series, null, cancellationToken).ConfigureAwait(false); + + hasChanges = true; + } + } + return hasChanges; } @@ -292,8 +310,7 @@ namespace MediaBrowser.Providers.TV /// Removes the virtual entry after a corresponding physical version has been added /// private async Task RemoveObsoleteOrMissingEpisodes(IEnumerable series, - IEnumerable> episodeLookup, - bool forceRemoveAll) + IEnumerable> episodeLookup) { var existingEpisodes = (from s in series let seasonOffset = TvdbSeriesProvider.GetSeriesOffset(s.ProviderIds) ?? ((s.AnimeSeriesIndex ?? 1) - 1) @@ -312,11 +329,6 @@ namespace MediaBrowser.Providers.TV var episodesToRemove = virtualEpisodes .Where(i => { - if (forceRemoveAll) - { - return true; - } - if (i.Episode.IndexNumber.HasValue && i.Episode.ParentIndexNumber.HasValue) { var seasonNumber = i.Episode.ParentIndexNumber.Value + i.SeasonOffset; @@ -362,11 +374,9 @@ namespace MediaBrowser.Providers.TV /// /// The series. /// The episode lookup. - /// if set to true [force remove all]. /// Task{System.Boolean}. private async Task RemoveObsoleteOrMissingSeasons(IEnumerable series, - IEnumerable> episodeLookup, - bool forceRemoveAll) + IEnumerable> episodeLookup) { var existingSeasons = (from s in series let seasonOffset = TvdbSeriesProvider.GetSeriesOffset(s.ProviderIds) ?? ((s.AnimeSeriesIndex ?? 1) - 1) @@ -385,11 +395,6 @@ namespace MediaBrowser.Providers.TV var seasonsToRemove = virtualSeasons .Where(i => { - if (forceRemoveAll) - { - return true; - } - if (i.Season.IndexNumber.HasValue) { var seasonNumber = i.Season.IndexNumber.Value + i.SeasonOffset; @@ -409,7 +414,9 @@ namespace MediaBrowser.Providers.TV return false; } - return true; + // Season does not have a number + // Remove if there are no episodes directly in series without a season number + return i.Season.Series.RecursiveChildren.OfType().All(s => s.ParentIndexNumber.HasValue || s.IsInSeasonFolder); }) .ToList(); @@ -472,20 +479,22 @@ namespace MediaBrowser.Providers.TV /// The cancellation token. /// Task{Season}. private async Task AddSeason(Series series, - int seasonNumber, + int? seasonNumber, CancellationToken cancellationToken) { - _logger.Info("Creating Season {0} entry for {1}", seasonNumber, series.Name); + var seasonName = seasonNumber == 0 ? + _config.Configuration.SeasonZeroDisplayName : + (seasonNumber.HasValue ? string.Format(_localization.GetLocalizedString("NameSeasonNumber"), seasonNumber.Value.ToString(UsCulture)) : _localization.GetLocalizedString("NameSeasonUnknown")); - var name = seasonNumber == 0 ? _config.Configuration.SeasonZeroDisplayName : string.Format("Season {0}", seasonNumber.ToString(UsCulture)); + _logger.Info("Creating Season {0} entry for {1}", seasonName, series.Name); var season = new Season { - Name = name, + Name = seasonName, IndexNumber = seasonNumber, Parent = series, DisplayMediaType = typeof(Season).Name, - Id = (series.Id + seasonNumber.ToString(UsCulture) + name).GetMBId(typeof(Season)) + Id = (series.Id + (seasonNumber ?? -1).ToString(UsCulture) + seasonName).GetMBId(typeof(Season)) }; await series.AddChild(season, cancellationToken).ConfigureAwait(false); diff --git a/MediaBrowser.Providers/TV/SeriesPostScanTask.cs b/MediaBrowser.Providers/TV/SeriesPostScanTask.cs index d350d2fe4..e1986a7c1 100644 --- a/MediaBrowser.Providers/TV/SeriesPostScanTask.cs +++ b/MediaBrowser.Providers/TV/SeriesPostScanTask.cs @@ -1,11 +1,12 @@ -using System.Collections.Generic; -using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Localization; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; using System; +using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -25,12 +26,14 @@ namespace MediaBrowser.Providers.TV private readonly ILibraryManager _libraryManager; private readonly IServerConfigurationManager _config; private readonly ILogger _logger; + private readonly ILocalizationManager _localization; - public SeriesPostScanTask(ILibraryManager libraryManager, ILogger logger, IServerConfigurationManager config) + public SeriesPostScanTask(ILibraryManager libraryManager, ILogger logger, IServerConfigurationManager config, ILocalizationManager localization) { _libraryManager = libraryManager; _logger = logger; _config = config; + _localization = localization; } public Task Run(IProgress progress, CancellationToken cancellationToken) @@ -47,7 +50,7 @@ namespace MediaBrowser.Providers.TV var seriesGroups = FindSeriesGroups(seriesList).Where(g => !string.IsNullOrEmpty(g.Key)).ToList(); - await new MissingEpisodeProvider(_logger, _config, _libraryManager).Run(seriesGroups, cancellationToken).ConfigureAwait(false); + await new MissingEpisodeProvider(_logger, _config, _libraryManager, _localization).Run(seriesGroups, cancellationToken).ConfigureAwait(false); var numComplete = 0; diff --git a/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs b/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs index ef9f5427c..52c1ab7dd 100644 --- a/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs +++ b/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs @@ -72,6 +72,10 @@ namespace MediaBrowser.Providers.TV { // Don't fail the provider because this will just keep on going and going. } + catch (DirectoryNotFoundException) + { + // Don't fail the provider because this will just keep on going and going. + } } return list; @@ -101,6 +105,10 @@ namespace MediaBrowser.Providers.TV { // Don't fail the provider because this will just keep on going and going. } + catch (DirectoryNotFoundException) + { + // Don't fail the provider because this will just keep on going and going. + } } return result; @@ -208,8 +216,9 @@ namespace MediaBrowser.Providers.TV /// Fetches the episode data. /// /// The identifier. + /// The identity. /// The series data path. - /// + /// The series provider ids. /// The cancellation token. /// Task{System.Boolean}. private Episode FetchEpisodeData(EpisodeInfo id, EpisodeIdentity identity, string seriesDataPath, Dictionary seriesProviderIds, CancellationToken cancellationToken) @@ -279,6 +288,10 @@ namespace MediaBrowser.Providers.TV { break; } + catch (DirectoryNotFoundException) + { + break; + } episodeNumber++; } diff --git a/MediaBrowser.Providers/TV/TvdbSeasonImageProvider.cs b/MediaBrowser.Providers/TV/TvdbSeasonImageProvider.cs index efafeae96..1ebd7bed5 100644 --- a/MediaBrowser.Providers/TV/TvdbSeasonImageProvider.cs +++ b/MediaBrowser.Providers/TV/TvdbSeasonImageProvider.cs @@ -94,6 +94,10 @@ namespace MediaBrowser.Providers.TV { // No tvdb data yet. Don't blow up } + catch (DirectoryNotFoundException) + { + // No tvdb data yet. Don't blow up + } } return new RemoteImageInfo[] { }; diff --git a/MediaBrowser.Providers/TV/TvdbSeriesImageProvider.cs b/MediaBrowser.Providers/TV/TvdbSeriesImageProvider.cs index 9cc09c40c..08913d3b4 100644 --- a/MediaBrowser.Providers/TV/TvdbSeriesImageProvider.cs +++ b/MediaBrowser.Providers/TV/TvdbSeriesImageProvider.cs @@ -87,6 +87,10 @@ namespace MediaBrowser.Providers.TV { // No tvdb data yet. Don't blow up } + catch (DirectoryNotFoundException) + { + // No tvdb data yet. Don't blow up + } } return new RemoteImageInfo[] { }; diff --git a/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs b/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs index 376dc3548..67d844543 100644 --- a/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs +++ b/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs @@ -1,4 +1,5 @@ using MediaBrowser.Common.Configuration; +using MediaBrowser.Common.Extensions; using MediaBrowser.Common.Net; using MediaBrowser.Controller; using MediaBrowser.Controller.Configuration; @@ -789,7 +790,7 @@ namespace MediaBrowser.Server.Implementations.Connect if (user == null) { // Add user - user = await _userManager.CreateUser(connectEntry.UserName).ConfigureAwait(false); + user = await _userManager.CreateUser(_userManager.MakeValidUsername(connectEntry.UserName)).ConfigureAwait(false); user.ConnectUserName = connectEntry.UserName; user.ConnectUserId = connectEntry.UserId; diff --git a/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs b/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs index b141fea1e..967c78c50 100644 --- a/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs +++ b/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs @@ -78,6 +78,11 @@ namespace MediaBrowser.Server.Implementations.Drawing // No biggie sizeDictionary = new Dictionary(); } + catch (DirectoryNotFoundException) + { + // No biggie + sizeDictionary = new Dictionary(); + } catch (Exception ex) { logger.ErrorException("Error parsing image size cache file", ex); diff --git a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs index 3b5e34520..432ea1f69 100644 --- a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs +++ b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs @@ -459,11 +459,11 @@ namespace MediaBrowser.Server.Implementations.FileOrganization private bool IsSameEpisode(string sourcePath, string newPath) { - var sourceFileInfo = new FileInfo(sourcePath); - var destinationFileInfo = new FileInfo(newPath); - try { + var sourceFileInfo = new FileInfo(sourcePath); + var destinationFileInfo = new FileInfo(newPath); + if (sourceFileInfo.Length == destinationFileInfo.Length) { return true; @@ -473,6 +473,10 @@ namespace MediaBrowser.Server.Implementations.FileOrganization { return false; } + catch (DirectoryNotFoundException) + { + return false; + } return false; } diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index d52288f87..66125784c 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -1755,9 +1755,12 @@ namespace MediaBrowser.Server.Implementations.Library var resolver = new EpisodeResolver(new ExtendedNamingOptions(), new Naming.Logging.NullLogger()); + var fileType = episode.VideoType == VideoType.BluRay || episode.VideoType == VideoType.Dvd || episode.VideoType == VideoType.HdDvd ? + FileInfoType.Directory : + FileInfoType.File; + var locationType = episode.LocationType; - var fileType = /*args.IsDirectory ? FileInfoType.Directory :*/ FileInfoType.File; var episodeInfo = locationType == LocationType.FileSystem || locationType == LocationType.Offline ? resolver.Resolve(episode.Path, fileType) : new Naming.TV.EpisodeInfo(); @@ -1769,29 +1772,42 @@ namespace MediaBrowser.Server.Implementations.Library var changed = false; - if (!episode.IndexNumber.HasValue) + if (episodeInfo.IsByDate) { - episode.IndexNumber = episodeInfo.EpisodeNumber; - if (episode.IndexNumber.HasValue) { + episode.IndexNumber = null; changed = true; } - } - - if (!episode.IndexNumberEnd.HasValue) - { - episode.IndexNumberEnd = episodeInfo.EndingEpsiodeNumber; if (episode.IndexNumberEnd.HasValue) { + episode.IndexNumberEnd = null; changed = true; } - } - if (!episode.ParentIndexNumber.HasValue) - { - episode.ParentIndexNumber = episodeInfo.SeasonNumber; + if (!episode.PremiereDate.HasValue) + { + if (episodeInfo.Year.HasValue && episodeInfo.Month.HasValue && episodeInfo.Day.HasValue) + { + episode.PremiereDate = new DateTime(episodeInfo.Year.Value, episodeInfo.Month.Value, episodeInfo.Day.Value).ToUniversalTime(); + } + + if (episode.PremiereDate.HasValue) + { + changed = true; + } + } + + if (!episode.ProductionYear.HasValue) + { + episode.ProductionYear = episodeInfo.Year; + + if (episode.ProductionYear.HasValue) + { + changed = true; + } + } if (!episode.ParentIndexNumber.HasValue) { @@ -1801,11 +1817,53 @@ namespace MediaBrowser.Server.Implementations.Library { episode.ParentIndexNumber = season.IndexNumber; } + + if (episode.ParentIndexNumber.HasValue) + { + changed = true; + } + } + } + else + { + if (!episode.IndexNumber.HasValue) + { + episode.IndexNumber = episodeInfo.EpisodeNumber; + + if (episode.IndexNumber.HasValue) + { + changed = true; + } } - if (episode.ParentIndexNumber.HasValue) + if (!episode.IndexNumberEnd.HasValue) { - changed = true; + episode.IndexNumberEnd = episodeInfo.EndingEpsiodeNumber; + + if (episode.IndexNumberEnd.HasValue) + { + changed = true; + } + } + + if (!episode.ParentIndexNumber.HasValue) + { + episode.ParentIndexNumber = episodeInfo.SeasonNumber; + + if (!episode.ParentIndexNumber.HasValue) + { + var season = episode.Season; + + if (season != null) + { + episode.ParentIndexNumber = season.IndexNumber; + } + } + + if (episode.ParentIndexNumber.HasValue) + { + changed = true; + } } } diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs index 39b0a93cc..1a873f01e 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs @@ -1,7 +1,5 @@ using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; -using MediaBrowser.Naming.Common; -using MediaBrowser.Naming.IO; using System.Linq; namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV diff --git a/MediaBrowser.Server.Implementations/Library/UserManager.cs b/MediaBrowser.Server.Implementations/Library/UserManager.cs index 1d58ad074..02d7c1be1 100644 --- a/MediaBrowser.Server.Implementations/Library/UserManager.cs +++ b/MediaBrowser.Server.Implementations/Library/UserManager.cs @@ -171,6 +171,38 @@ namespace MediaBrowser.Server.Implementations.Library return AuthenticateUser(username, passwordSha1, null, remoteEndPoint); } + public bool IsValidUsername(string username) + { + // Usernames can contain letters (a-z), numbers (0-9), dashes (-), underscores (_), apostrophes ('), and periods (.) + return username.All(IsValidCharacter); + } + + private bool IsValidCharacter(char i) + { + return char.IsLetterOrDigit(i) || char.Equals(i, '-') || char.Equals(i, '_') || char.Equals(i, '\'') || + char.Equals(i, '.'); + } + + public string MakeValidUsername(string username) + { + if (IsValidUsername(username)) + { + return username; + } + + // Usernames can contain letters (a-z), numbers (0-9), dashes (-), underscores (_), apostrophes ('), and periods (.) + var builder = new StringBuilder(); + + foreach (var c in username) + { + if (IsValidCharacter(c)) + { + builder.Append(c); + } + } + return builder.ToString(); + } + public async Task AuthenticateUser(string username, string passwordSha1, string passwordMd5, string remoteEndPoint) { if (string.IsNullOrWhiteSpace(username)) @@ -178,7 +210,8 @@ namespace MediaBrowser.Server.Implementations.Library throw new ArgumentNullException("username"); } - var user = Users.FirstOrDefault(i => string.Equals(username, i.Name, StringComparison.OrdinalIgnoreCase)); + var user = Users + .FirstOrDefault(i => string.Equals(username, i.Name, StringComparison.OrdinalIgnoreCase)); if (user == null) { @@ -203,20 +236,6 @@ namespace MediaBrowser.Server.Implementations.Library } } - // Maybe user accidently entered connect credentials. let's be flexible - if (!success && user.ConnectLinkType.HasValue && !string.IsNullOrWhiteSpace(passwordMd5)) - { - try - { - await _connectFactory().Authenticate(user.ConnectUserName, passwordMd5).ConfigureAwait(false); - success = true; - } - catch - { - - } - } - // Update LastActivityDate and LastLoginDate, then save if (success) { @@ -273,7 +292,7 @@ namespace MediaBrowser.Server.Implementations.Library // There always has to be at least one user. if (users.Count == 0) { - var name = Environment.UserName; + var name = MakeValidUsername(Environment.UserName); var user = InstantiateNewUser(name, false); @@ -477,6 +496,11 @@ namespace MediaBrowser.Server.Implementations.Library throw new ArgumentNullException("name"); } + if (!IsValidUsername(name)) + { + throw new ArgumentException("Only alphanumeric characters are allowed."); + } + if (Users.Any(u => u.Name.Equals(name, StringComparison.OrdinalIgnoreCase))) { throw new ArgumentException(string.Format("A user with the name '{0}' already exists.", name)); @@ -803,6 +827,10 @@ namespace MediaBrowser.Server.Implementations.Library return (UserPolicy)_xmlSerializer.DeserializeFromFile(typeof(UserPolicy), path); } } + catch (DirectoryNotFoundException) + { + return GetDefaultPolicy(user); + } catch (FileNotFoundException) { return GetDefaultPolicy(user); @@ -840,6 +868,8 @@ namespace MediaBrowser.Server.Implementations.Library var path = GetPolifyFilePath(user); + Directory.CreateDirectory(Path.GetDirectoryName(path)); + lock (_policySyncLock) { _xmlSerializer.SerializeToFile(userPolicy, path); @@ -900,6 +930,10 @@ namespace MediaBrowser.Server.Implementations.Library return (UserConfiguration)_xmlSerializer.DeserializeFromFile(typeof(UserConfiguration), path); } } + catch (DirectoryNotFoundException) + { + return new UserConfiguration(); + } catch (FileNotFoundException) { return new UserConfiguration(); @@ -930,6 +964,8 @@ namespace MediaBrowser.Server.Implementations.Library config = _jsonSerializer.DeserializeFromString(json); } + Directory.CreateDirectory(Path.GetDirectoryName(path)); + lock (_configSyncLock) { _xmlSerializer.SerializeToFile(config, path); diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json index 695200239..827a2388d 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json @@ -419,7 +419,7 @@ "HeaderMediaLocations": "Media Locations", "LabelFolderTypeValue": "Folder type: {0}", "LabelPathSubstitutionHelp": "Optional: Path substitution can map server paths to network shares that clients can access for direct playback.", - "FolderTypeMixed": "Mixed videos", + "FolderTypeMixed": "Mixed content", "FolderTypeMovies": "Movies", "FolderTypeMusic": "Music", "FolderTypeAdultVideos": "Adult videos", @@ -658,5 +658,5 @@ "LabelItemLimitHelp": "Optional. Set a limit to the number of items that will be synced.", "MessageBookPluginRequired": "Requires installation of the Bookshelf plugin", "MessageGamePluginRequired": "Requires installation of the GameBrowser plugin", - "MessageMixedContentHelp": "Content will be displayed with as a plain folder structure" + "MessageMixedContentHelp": "Content will be displayed as a plain folder structure" } diff --git a/MediaBrowser.Server.Implementations/Localization/Server/server.json b/MediaBrowser.Server.Implementations/Localization/Server/server.json index 9a515d492..c0af13950 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/server.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/server.json @@ -37,7 +37,7 @@ "ButtonOk": "Ok", "ButtonCancel": "Cancel", "ButtonNew": "New", - "FolderTypeMixed": "Mixed videos", + "FolderTypeMixed": "Mixed content", "FolderTypeMovies": "Movies", "FolderTypeMusic": "Music", "FolderTypeAdultVideos": "Adult videos", @@ -48,7 +48,7 @@ "FolderTypeBooks": "Books", "FolderTypeTvShows": "TV", "FolderTypeInherit": "Inherit", - "LabelContentType": "Content type:", + "LabelContentType": "Content type:", "HeaderSetupLibrary": "Setup your media library", "ButtonAddMediaFolder": "Add media folder", "LabelFolderType": "Folder type:", @@ -1307,5 +1307,8 @@ "LabelEnableSingleImageInDidlLimitHelp": "Some devices will not render properly if multiple images are embedded within Didl.", "TabActivity": "Activity", "TitleSync": "Sync", - "OptionAllowSyncContent": "Allow syncing media to devices" + "OptionAllowSyncContent": "Allow syncing media to devices", + "NameSeasonUnknown": "Season Unknown", + "NameSeasonNumber": "Season {0}", + "LabelNewUserNameHelp": "Usernames can contain letters (a-z), numbers (0-9), dashes (-), underscores (_), apostrophes ('), and periods (.)" } diff --git a/MediaBrowser.Server.Implementations/News/NewsService.cs b/MediaBrowser.Server.Implementations/News/NewsService.cs index 9eeadfab7..684363d01 100644 --- a/MediaBrowser.Server.Implementations/News/NewsService.cs +++ b/MediaBrowser.Server.Implementations/News/NewsService.cs @@ -26,6 +26,14 @@ namespace MediaBrowser.Server.Implementations.News { return GetProductNewsInternal(query); } + catch (DirectoryNotFoundException) + { + // No biggie + return new QueryResult + { + Items = new NewsItem[] { } + }; + } catch (FileNotFoundException) { // No biggie diff --git a/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs b/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs index 86e92530f..0f1d53ea6 100644 --- a/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs +++ b/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs @@ -256,6 +256,10 @@ namespace MediaBrowser.XbmcMetadata.Savers catch (FileNotFoundException) { + } + catch (DirectoryNotFoundException) + { + } writer.WriteEndElement(); -- cgit v1.2.3 From 55b9bffabcd2322d398d405eadf848a84744121d Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 27 Dec 2014 00:08:39 -0500 Subject: added optional SeasonUserData --- MediaBrowser.Api/IHasDtoOptions.cs | 12 +----- MediaBrowser.Api/Library/LibraryService.cs | 41 +++++++------------- MediaBrowser.Api/Movies/CollectionService.cs | 5 ++- MediaBrowser.Api/Movies/MoviesService.cs | 28 ++++++++------ MediaBrowser.Api/Sync/SyncService.cs | 16 ++++---- MediaBrowser.Api/UserLibrary/ArtistsService.cs | 9 ++--- MediaBrowser.Api/UserLibrary/GameGenresService.cs | 7 ++-- MediaBrowser.Api/UserLibrary/GenresService.cs | 7 ++-- MediaBrowser.Api/UserLibrary/MusicGenresService.cs | 7 ++-- MediaBrowser.Api/UserLibrary/PersonsService.cs | 7 ++-- MediaBrowser.Api/UserLibrary/StudiosService.cs | 7 ++-- MediaBrowser.Api/UserLibrary/UserLibraryService.cs | 45 ++++++++++------------ MediaBrowser.Api/UserLibrary/YearsService.cs | 7 ++-- MediaBrowser.Api/VideosService.cs | 8 ++-- MediaBrowser.Controller/Entities/TV/Series.cs | 14 ++++++- MediaBrowser.Model/Dto/BaseItemDto.cs | 5 +++ MediaBrowser.Model/Dto/DtoOptions.cs | 17 +++++++- MediaBrowser.Model/Querying/ItemFields.cs | 7 +++- MediaBrowser.Providers/TV/SeriesMetadataService.cs | 25 ------------ MediaBrowser.Providers/TV/SeriesPostScanTask.cs | 4 -- .../Channels/ChannelManager.cs | 35 +++++------------ .../Dto/DtoService.cs | 20 +++++++--- .../LiveTv/LiveTvManager.cs | 5 +-- .../Localization/JavaScript/javascript.json | 1 + .../Localization/Server/server.json | 2 +- .../Sync/SyncManager.cs | 8 +--- 26 files changed, 157 insertions(+), 192 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Localization/Server/server.json') diff --git a/MediaBrowser.Api/IHasDtoOptions.cs b/MediaBrowser.Api/IHasDtoOptions.cs index f7fb57f01..2e677e816 100644 --- a/MediaBrowser.Api/IHasDtoOptions.cs +++ b/MediaBrowser.Api/IHasDtoOptions.cs @@ -28,17 +28,7 @@ namespace MediaBrowser.Api options.ImageTypeLimit = request.ImageTypeLimit.Value; } - if (string.IsNullOrWhiteSpace(request.EnableImageTypes)) - { - if (options.EnableImages) - { - // Get everything - options.ImageTypes = Enum.GetNames(typeof(ImageType)) - .Select(i => (ImageType)Enum.Parse(typeof(ImageType), i, true)) - .ToList(); - } - } - else + if (!string.IsNullOrWhiteSpace(request.EnableImageTypes)) { options.ImageTypes = (request.EnableImageTypes ?? string.Empty).Split(',').Where(i => !string.IsNullOrWhiteSpace(i)).Select(v => (ImageType)Enum.Parse(typeof(ImageType), v, true)).ToList(); } diff --git a/MediaBrowser.Api/Library/LibraryService.cs b/MediaBrowser.Api/Library/LibraryService.cs index e85f2cbf9..37d00b937 100644 --- a/MediaBrowser.Api/Library/LibraryService.cs +++ b/MediaBrowser.Api/Library/LibraryService.cs @@ -272,16 +272,13 @@ namespace MediaBrowser.Api.Library items = items.Where(i => i.IsHidden == val).ToList(); } - // Get everything - var fields = Enum.GetNames(typeof(ItemFields)) - .Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true)) - .ToList(); + var dtoOptions = new DtoOptions(); var result = new ItemsResult { TotalRecordCount = items.Count, - Items = items.Select(i => _dtoService.GetBaseItemDto(i, fields)).ToArray() + Items = items.Select(i => _dtoService.GetBaseItemDto(i, dtoOptions)).ToArray() }; return ToOptimizedResult(result); @@ -347,10 +344,7 @@ namespace MediaBrowser.Api.Library var user = request.UserId.HasValue ? _userManager.GetUserById(request.UserId.Value) : null; - // Get everything - var fields = Enum.GetNames(typeof(ItemFields)) - .Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true)) - .ToList(); + var dtoOptions = new DtoOptions(); BaseItem parent = item.Parent; @@ -361,7 +355,7 @@ namespace MediaBrowser.Api.Library parent = TranslateParentItem(parent, user); } - baseItemDtos.Add(_dtoService.GetBaseItemDto(parent, fields, user)); + baseItemDtos.Add(_dtoService.GetBaseItemDto(parent, dtoOptions, user)); parent = parent.Parent; } @@ -583,11 +577,6 @@ namespace MediaBrowser.Api.Library item = item.Parent; } - // Get everything - var fields = Enum.GetNames(typeof(ItemFields)) - .Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true)) - .ToList(); - var themeSongIds = GetThemeSongIds(item); if (themeSongIds.Count == 0 && request.InheritFromParent) @@ -607,10 +596,12 @@ namespace MediaBrowser.Api.Library } } } - + + var dtoOptions = new DtoOptions(); + var dtos = themeSongIds.Select(_libraryManager.GetItemById) .OrderBy(i => i.SortName) - .Select(i => _dtoService.GetBaseItemDto(i, fields, user, item)); + .Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user, item)); var items = dtos.ToArray(); @@ -651,11 +642,6 @@ namespace MediaBrowser.Api.Library item = item.Parent; } - // Get everything - var fields = Enum.GetNames(typeof(ItemFields)) - .Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true)) - .ToList(); - var themeVideoIds = GetThemeVideoIds(item); if (themeVideoIds.Count == 0 && request.InheritFromParent) @@ -681,9 +667,11 @@ namespace MediaBrowser.Api.Library } } + var dtoOptions = new DtoOptions(); + var dtos = themeVideoIds.Select(_libraryManager.GetItemById) .OrderBy(i => i.SortName) - .Select(i => _dtoService.GetBaseItemDto(i, fields, user, item)); + .Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user, item)); var items = dtos.ToArray(); @@ -754,10 +742,7 @@ namespace MediaBrowser.Api.Library : (Folder)_libraryManager.RootFolder) : _libraryManager.GetItemById(id); - // Get everything - var fields = Enum.GetNames(typeof(ItemFields)) - .Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true)) - .ToList(); + var dtoOptions = new DtoOptions(); var dtos = GetSoundtrackSongIds(item, inheritFromParent) .Select(_libraryManager.GetItemById) @@ -765,7 +750,7 @@ namespace MediaBrowser.Api.Library .SelectMany(i => i.RecursiveChildren) .OfType