Browse Source

move user image into profile settings

Luke Pulverenti 10 năm trước cách đây
mục cha
commit
6ca771cc79
81 tập tin đã thay đổi với 886 bổ sung219 xóa
  1. 3 0
      MediaBrowser.Api/LiveTv/LiveTvService.cs
  2. 22 31
      MediaBrowser.Api/Playback/BaseStreamingService.cs
  3. 1 18
      MediaBrowser.Api/Playback/Hls/BaseHlsService.cs
  4. 15 13
      MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
  5. 309 14
      MediaBrowser.Api/Playback/Hls/MpegDashService.cs
  6. 10 2
      MediaBrowser.Api/Playback/StreamState.cs
  7. 15 5
      MediaBrowser.Api/UserService.cs
  8. 71 0
      MediaBrowser.Controller/Entities/DayOfWeekHelper.cs
  9. 21 20
      MediaBrowser.Controller/Entities/TV/Episode.cs
  10. 2 1
      MediaBrowser.Controller/Entities/User.cs
  11. 1 0
      MediaBrowser.Controller/MediaBrowser.Controller.csproj
  12. 6 0
      MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj
  13. 6 0
      MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj
  14. 2 3
      MediaBrowser.Model/Configuration/AccessSchedule.cs
  15. 17 0
      MediaBrowser.Model/Configuration/DynamicDayOfWeek.cs
  16. 12 0
      MediaBrowser.Model/Connect/ConnectUserServer.cs
  17. 2 0
      MediaBrowser.Model/MediaBrowser.Model.csproj
  18. 5 2
      MediaBrowser.Providers/Movies/MovieMetadataService.cs
  19. 11 4
      MediaBrowser.Server.Implementations/Connect/ConnectManager.cs
  20. 17 5
      MediaBrowser.Server.Implementations/Library/UserManager.cs
  21. 2 1
      MediaBrowser.Server.Implementations/Localization/JavaScript/ar.json
  22. 2 1
      MediaBrowser.Server.Implementations/Localization/JavaScript/ca.json
  23. 2 1
      MediaBrowser.Server.Implementations/Localization/JavaScript/cs.json
  24. 2 1
      MediaBrowser.Server.Implementations/Localization/JavaScript/da.json
  25. 2 1
      MediaBrowser.Server.Implementations/Localization/JavaScript/de.json
  26. 2 1
      MediaBrowser.Server.Implementations/Localization/JavaScript/el.json
  27. 2 1
      MediaBrowser.Server.Implementations/Localization/JavaScript/en_GB.json
  28. 2 1
      MediaBrowser.Server.Implementations/Localization/JavaScript/en_US.json
  29. 2 1
      MediaBrowser.Server.Implementations/Localization/JavaScript/es.json
  30. 2 1
      MediaBrowser.Server.Implementations/Localization/JavaScript/es_MX.json
  31. 2 1
      MediaBrowser.Server.Implementations/Localization/JavaScript/fr.json
  32. 2 1
      MediaBrowser.Server.Implementations/Localization/JavaScript/he.json
  33. 2 1
      MediaBrowser.Server.Implementations/Localization/JavaScript/hr.json
  34. 2 1
      MediaBrowser.Server.Implementations/Localization/JavaScript/it.json
  35. 2 1
      MediaBrowser.Server.Implementations/Localization/JavaScript/kk.json
  36. 2 1
      MediaBrowser.Server.Implementations/Localization/JavaScript/ms.json
  37. 2 1
      MediaBrowser.Server.Implementations/Localization/JavaScript/nb.json
  38. 5 4
      MediaBrowser.Server.Implementations/Localization/JavaScript/nl.json
  39. 2 1
      MediaBrowser.Server.Implementations/Localization/JavaScript/pl.json
  40. 9 8
      MediaBrowser.Server.Implementations/Localization/JavaScript/pt_BR.json
  41. 2 1
      MediaBrowser.Server.Implementations/Localization/JavaScript/pt_PT.json
  42. 2 1
      MediaBrowser.Server.Implementations/Localization/JavaScript/ru.json
  43. 2 1
      MediaBrowser.Server.Implementations/Localization/JavaScript/sv.json
  44. 2 1
      MediaBrowser.Server.Implementations/Localization/JavaScript/tr.json
  45. 2 1
      MediaBrowser.Server.Implementations/Localization/JavaScript/vi.json
  46. 2 1
      MediaBrowser.Server.Implementations/Localization/JavaScript/zh_TW.json
  47. 7 0
      MediaBrowser.Server.Implementations/Localization/Server/ar.json
  48. 7 0
      MediaBrowser.Server.Implementations/Localization/Server/ca.json
  49. 7 0
      MediaBrowser.Server.Implementations/Localization/Server/cs.json
  50. 7 0
      MediaBrowser.Server.Implementations/Localization/Server/da.json
  51. 7 0
      MediaBrowser.Server.Implementations/Localization/Server/de.json
  52. 7 0
      MediaBrowser.Server.Implementations/Localization/Server/el.json
  53. 7 0
      MediaBrowser.Server.Implementations/Localization/Server/en_GB.json
  54. 7 0
      MediaBrowser.Server.Implementations/Localization/Server/en_US.json
  55. 7 0
      MediaBrowser.Server.Implementations/Localization/Server/es.json
  56. 8 1
      MediaBrowser.Server.Implementations/Localization/Server/es_MX.json
  57. 7 0
      MediaBrowser.Server.Implementations/Localization/Server/fr.json
  58. 7 0
      MediaBrowser.Server.Implementations/Localization/Server/he.json
  59. 7 0
      MediaBrowser.Server.Implementations/Localization/Server/hr.json
  60. 7 0
      MediaBrowser.Server.Implementations/Localization/Server/it.json
  61. 7 0
      MediaBrowser.Server.Implementations/Localization/Server/kk.json
  62. 7 0
      MediaBrowser.Server.Implementations/Localization/Server/ko.json
  63. 7 0
      MediaBrowser.Server.Implementations/Localization/Server/ms.json
  64. 7 0
      MediaBrowser.Server.Implementations/Localization/Server/nb.json
  65. 19 12
      MediaBrowser.Server.Implementations/Localization/Server/nl.json
  66. 7 0
      MediaBrowser.Server.Implementations/Localization/Server/pl.json
  67. 38 31
      MediaBrowser.Server.Implementations/Localization/Server/pt_BR.json
  68. 7 0
      MediaBrowser.Server.Implementations/Localization/Server/pt_PT.json
  69. 7 0
      MediaBrowser.Server.Implementations/Localization/Server/ru.json
  70. 5 2
      MediaBrowser.Server.Implementations/Localization/Server/server.json
  71. 7 0
      MediaBrowser.Server.Implementations/Localization/Server/sv.json
  72. 7 0
      MediaBrowser.Server.Implementations/Localization/Server/tr.json
  73. 7 0
      MediaBrowser.Server.Implementations/Localization/Server/vi.json
  74. 7 0
      MediaBrowser.Server.Implementations/Localization/Server/zh_TW.json
  75. 9 4
      MediaBrowser.Server.Implementations/Session/SessionManager.cs
  76. 14 6
      MediaBrowser.WebDashboard/Api/DashboardService.cs
  77. 9 3
      MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj
  78. 2 2
      Nuget/MediaBrowser.Common.Internal.nuspec
  79. 1 1
      Nuget/MediaBrowser.Common.nuspec
  80. 1 1
      Nuget/MediaBrowser.Model.Signed.nuspec
  81. 2 2
      Nuget/MediaBrowser.Server.Core.nuspec

+ 3 - 0
MediaBrowser.Api/LiveTv/LiveTvService.cs

@@ -14,6 +14,9 @@ using System.Threading.Tasks;
 
 namespace MediaBrowser.Api.LiveTv
 {
+    /// <summary>
+    /// This is insecure right now to avoid windows phone refactoring
+    /// </summary>
     [Route("/LiveTv/Info", "GET", Summary = "Gets available live tv services.")]
     public class GetLiveTvInfo : IReturn<LiveTvInfo>
     {

+ 22 - 31
MediaBrowser.Api/Playback/BaseStreamingService.cs

@@ -267,9 +267,14 @@ namespace MediaBrowser.Api.Playback
         /// Gets the number of threads.
         /// </summary>
         /// <returns>System.Int32.</returns>
-        /// <exception cref="System.Exception">Unrecognized MediaEncodingQuality value.</exception>
         protected int GetNumberOfThreads(StreamState state, bool isWebm)
         {
+            if (isWebm)
+            {
+                // 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)
             {
@@ -907,9 +912,12 @@ namespace MediaBrowser.Api.Playback
         /// <param name="state">The state.</param>
         /// <param name="outputPath">The output path.</param>
         /// <param name="cancellationTokenSource">The cancellation token source.</param>
+        /// <param name="workingDirectory">The working directory.</param>
         /// <returns>Task.</returns>
-        /// <exception cref="System.InvalidOperationException">ffmpeg was not found at  + MediaEncoder.EncoderPath</exception>
-        protected async Task<TranscodingJob> StartFfMpeg(StreamState state, string outputPath, CancellationTokenSource cancellationTokenSource)
+        protected async Task<TranscodingJob> StartFfMpeg(StreamState state, 
+            string outputPath, 
+            CancellationTokenSource cancellationTokenSource,
+            string workingDirectory = null)
         {
             Directory.CreateDirectory(Path.GetDirectoryName(outputPath));
 
@@ -945,6 +953,11 @@ namespace MediaBrowser.Api.Playback
                 EnableRaisingEvents = true
             };
 
+            if (!string.IsNullOrWhiteSpace(workingDirectory))
+            {
+                process.StartInfo.WorkingDirectory = workingDirectory;
+            }
+
             var transcodingJob = ApiEntryPoint.Instance.OnTranscodeBeginning(outputPath,
                 transcodingId,
                 TranscodingJobType,
@@ -1540,19 +1553,9 @@ namespace MediaBrowser.Api.Playback
                     state.MediaPath = mediaUrl;
                     state.InputProtocol = MediaProtocol.Http;
                 }
-                else
-                {
-                    // No media info, so this is probably needed
-                    state.DeInterlace = true;
-                }
-
-                if (recording.RecordingInfo.Status == RecordingStatus.InProgress)
-                {
-                    state.ReadInputAtNativeFramerate = true;
-                }
 
                 state.RunTimeTicks = recording.RunTimeTicks;
-
+                state.DeInterlace = true;
                 state.OutputAudioSync = "1000";
                 state.InputVideoSync = "-1";
                 state.InputAudioSync = "1";
@@ -1566,9 +1569,8 @@ namespace MediaBrowser.Api.Playback
                 state.IsInputVideo = string.Equals(channel.MediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase);
                 mediaStreams = new List<MediaStream>();
 
-                state.ReadInputAtNativeFramerate = true;
-                state.OutputAudioSync = "1000";
                 state.DeInterlace = true;
+                state.OutputAudioSync = "1000";
                 state.InputVideoSync = "-1";
                 state.InputAudioSync = "1";
 
@@ -1626,30 +1628,19 @@ namespace MediaBrowser.Api.Playback
                 state.RunTimeTicks = mediaSource.RunTimeTicks;
             }
 
-            // If it's a wtv and we don't have media info, we will probably need to deinterlace
-            if (string.Equals(state.InputContainer, "wtv", StringComparison.OrdinalIgnoreCase) &&
-                mediaStreams.Count == 0)
-            {
-                state.DeInterlace = true;
-            }
-
-            if (state.InputProtocol == MediaProtocol.Rtmp)
-            {
-                state.ReadInputAtNativeFramerate = true;
-            }
-
             var videoRequest = request as VideoStreamRequest;
 
             AttachMediaStreamInfo(state, mediaStreams, videoRequest, url);
 
-            state.SegmentLength = state.ReadInputAtNativeFramerate ? 5 : 6;
-            state.HlsListSize = state.ReadInputAtNativeFramerate ? 100 : 1440;
+            state.SegmentLength = 6;
 
             var container = Path.GetExtension(state.RequestedUrl);
 
             if (string.IsNullOrEmpty(container))
             {
-                container = request.Static ? state.InputContainer : Path.GetExtension(GetOutputFilePath(state));
+                container = request.Static ? 
+                    state.InputContainer :
+                    (Path.GetExtension(GetOutputFilePath(state)) ?? string.Empty).TrimStart('.');
             }
 
             state.OutputContainer = (container ?? string.Empty).TrimStart('.');

+ 1 - 18
MediaBrowser.Api/Playback/Hls/BaseHlsService.cs

@@ -107,7 +107,7 @@ namespace MediaBrowser.Api.Playback.Hls
                             throw;
                         }
 
-                        var waitCount = isLive ? 1 : GetSegmentWait();
+                        var waitCount = isLive ? 3 : 2;
                         await WaitForMinimumSegmentCount(playlist, waitCount, cancellationTokenSource.Token).ConfigureAwait(false);
                     }
                 }
@@ -144,23 +144,6 @@ namespace MediaBrowser.Api.Playback.Hls
             return ResultFactory.GetResult(playlistText, MimeTypes.GetMimeType("playlist.m3u8"), new Dictionary<string, string>());
         }
 
-        /// <summary>
-        /// Gets the segment wait.
-        /// </summary>
-        /// <returns>System.Int32.</returns>
-        protected int GetSegmentWait()
-        {
-            var minimumSegmentCount = 2;
-            var quality = GetQualitySetting();
-
-            if (quality == EncodingQuality.HighSpeed || quality == EncodingQuality.HighQuality)
-            {
-                minimumSegmentCount = 2;
-            }
-
-            return minimumSegmentCount;
-        }
-
         private string GetMasterPlaylistFileText(string firstPlaylist, int bitrate, bool includeBaselineStream, int baselineStreamBitrate)
         {
             var builder = new StringBuilder();

+ 15 - 13
MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs

@@ -114,11 +114,13 @@ namespace MediaBrowser.Api.Playback.Hls
             var segmentPath = GetSegmentPath(playlistPath, index);
             var segmentLength = state.SegmentLength;
 
+            var segmentExtension = GetSegmentFileExtension(state);
+
             TranscodingJob job = null;
 
             if (File.Exists(segmentPath))
             {
-                job = ApiEntryPoint.Instance.OnTranscodeBeginRequest(playlistPath, TranscodingJobType.Hls);
+                job = ApiEntryPoint.Instance.OnTranscodeBeginRequest(playlistPath, TranscodingJobType);
                 return await GetSegmentResult(playlistPath, segmentPath, index, segmentLength, job, cancellationToken).ConfigureAwait(false);
             }
 
@@ -127,23 +129,23 @@ namespace MediaBrowser.Api.Playback.Hls
             {
                 if (File.Exists(segmentPath))
                 {
-                    job = ApiEntryPoint.Instance.OnTranscodeBeginRequest(playlistPath, TranscodingJobType.Hls);
+                    job = ApiEntryPoint.Instance.OnTranscodeBeginRequest(playlistPath, TranscodingJobType);
                     return await GetSegmentResult(playlistPath, segmentPath, index, segmentLength, job, cancellationToken).ConfigureAwait(false);
                 }
                 else
                 {
-                    var currentTranscodingIndex = GetCurrentTranscodingIndex(playlistPath);
+                    var currentTranscodingIndex = GetCurrentTranscodingIndex(playlistPath, segmentExtension);
 
                     if (currentTranscodingIndex == null || index < currentTranscodingIndex.Value || (index - currentTranscodingIndex.Value) > 4)
                     {
                         // If the playlist doesn't already exist, startup ffmpeg
                         try
                         {
-                            ApiEntryPoint.Instance.KillTranscodingJobs(j => j.Type == TranscodingJobType.Hls && string.Equals(j.DeviceId, request.DeviceId, StringComparison.OrdinalIgnoreCase), p => !string.Equals(p, playlistPath, StringComparison.OrdinalIgnoreCase));
+                            ApiEntryPoint.Instance.KillTranscodingJobs(j => j.Type == TranscodingJobType && string.Equals(j.DeviceId, request.DeviceId, StringComparison.OrdinalIgnoreCase), p => !string.Equals(p, playlistPath, StringComparison.OrdinalIgnoreCase));
 
                             if (currentTranscodingIndex.HasValue)
                             {
-                                DeleteLastFile(playlistPath, 0);
+                                DeleteLastFile(playlistPath, segmentExtension, 0);
                             }
 
                             var startSeconds = index * state.SegmentLength;
@@ -173,13 +175,13 @@ namespace MediaBrowser.Api.Playback.Hls
             }
 
             Logger.Info("returning {0}", segmentPath);
-            job = job ?? ApiEntryPoint.Instance.GetTranscodingJob(playlistPath, TranscodingJobType.Hls);
+            job = job ?? ApiEntryPoint.Instance.GetTranscodingJob(playlistPath, TranscodingJobType);
             return await GetSegmentResult(playlistPath, segmentPath, index, segmentLength, job, cancellationToken).ConfigureAwait(false);
         }
 
-        public int? GetCurrentTranscodingIndex(string playlist)
+        public int? GetCurrentTranscodingIndex(string playlist, string segmentExtension)
         {
-            var file = GetLastTranscodingFile(playlist, FileSystem);
+            var file = GetLastTranscodingFile(playlist, segmentExtension, FileSystem);
 
             if (file == null)
             {
@@ -193,14 +195,14 @@ namespace MediaBrowser.Api.Playback.Hls
             return int.Parse(indexString, NumberStyles.Integer, UsCulture);
         }
 
-        private void DeleteLastFile(string path, int retryCount)
+        private void DeleteLastFile(string path, string segmentExtension, int retryCount)
         {
             if (retryCount >= 5)
             {
                 return;
             }
 
-            var file = GetLastTranscodingFile(path, FileSystem);
+            var file = GetLastTranscodingFile(path, segmentExtension, FileSystem);
 
             if (file != null)
             {
@@ -213,7 +215,7 @@ namespace MediaBrowser.Api.Playback.Hls
                     Logger.ErrorException("Error deleting partial stream file(s) {0}", ex, file.FullName);
 
                     Thread.Sleep(100);
-                    DeleteLastFile(path, retryCount + 1);
+                    DeleteLastFile(path, segmentExtension, retryCount + 1);
                 }
                 catch (Exception ex)
                 {
@@ -222,7 +224,7 @@ namespace MediaBrowser.Api.Playback.Hls
             }
         }
 
-        private static FileInfo GetLastTranscodingFile(string playlist, IFileSystem fileSystem)
+        private static FileInfo GetLastTranscodingFile(string playlist, string segmentExtension, IFileSystem fileSystem)
         {
             var folder = Path.GetDirectoryName(playlist);
 
@@ -230,7 +232,7 @@ namespace MediaBrowser.Api.Playback.Hls
             {
                 return new DirectoryInfo(folder)
                     .EnumerateFiles("*", SearchOption.TopDirectoryOnly)
-                    .Where(i => string.Equals(i.Extension, ".ts", StringComparison.OrdinalIgnoreCase))
+                    .Where(i => string.Equals(i.Extension, segmentExtension, StringComparison.OrdinalIgnoreCase))
                     .OrderByDescending(fileSystem.GetLastWriteTimeUtc)
                     .FirstOrDefault();
             }

+ 309 - 14
MediaBrowser.Api/Playback/Hls/MpegDashService.cs

@@ -1,5 +1,4 @@
-using System.Security;
-using MediaBrowser.Common.IO;
+using MediaBrowser.Common.IO;
 using MediaBrowser.Common.Net;
 using MediaBrowser.Controller.Channels;
 using MediaBrowser.Controller.Configuration;
@@ -7,11 +6,15 @@ using MediaBrowser.Controller.Dlna;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.LiveTv;
 using MediaBrowser.Controller.MediaEncoding;
+using MediaBrowser.Controller.Net;
 using MediaBrowser.Model.IO;
 using ServiceStack;
 using System;
 using System.Collections.Generic;
 using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Security;
 using System.Text;
 using System.Threading;
 using System.Threading.Tasks;
@@ -34,6 +37,7 @@ namespace MediaBrowser.Api.Playback.Hls
     }
 
     [Route("/Videos/{Id}/dash/{SegmentId}.ts", "GET")]
+    [Route("/Videos/{Id}/dash/{SegmentId}.mp4", "GET")]
     public class GetDashSegment : VideoStreamRequest
     {
         /// <summary>
@@ -98,9 +102,6 @@ namespace MediaBrowser.Api.Playback.Hls
 
         private string GetManifestText(StreamState state)
         {
-            var audioBitrate = state.OutputAudioBitrate ?? 0;
-            var videoBitrate = state.OutputVideoBitrate ?? 0;
-
             var builder = new StringBuilder();
 
             var time = TimeSpan.FromTicks(state.RunTimeTicks.Value);
@@ -108,8 +109,13 @@ namespace MediaBrowser.Api.Playback.Hls
             var duration = "PT" + time.Hours.ToString("00", UsCulture) + "H" + time.Minutes.ToString("00", UsCulture) + "M" + time.Seconds.ToString("00", UsCulture) + ".00S";
 
             builder.Append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+
+            var profile = string.Equals(GetSegmentFileExtension(state), ".ts", StringComparison.OrdinalIgnoreCase)
+                ? "urn:mpeg:dash:profile:mp2t-simple:2011"
+                : "urn:mpeg:dash:profile:mp2t-simple:2011";
+
             builder.AppendFormat(
-                "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:mpeg:dash:schema:mpd:2011 http://standards.iso.org/ittf/PubliclyAvailableStandards/MPEG-DASH_schema_files/DASH-MPD.xsd\" minBufferTime=\"PT2.00S\" mediaPresentationDuration=\"{0}\" maxSegmentDuration=\"PT{1}S\" type=\"static\" profiles=\"urn:mpeg:dash:profile:mp2t-simple:2011\">",
+                "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:mpeg:dash:schema:mpd:2011 http://standards.iso.org/ittf/PubliclyAvailableStandards/MPEG-DASH_schema_files/DASH-MPD.xsd\" minBufferTime=\"PT2.00S\" mediaPresentationDuration=\"{0}\" maxSegmentDuration=\"PT{1}S\" type=\"static\" profiles=\""+profile+"\">",
                 duration,
                 state.SegmentLength.ToString(CultureInfo.InvariantCulture));
 
@@ -143,7 +149,11 @@ namespace MediaBrowser.Api.Playback.Hls
         {
             var codecs = GetVideoCodecDescriptor(state) + "," + GetAudioCodecDescriptor(state);
 
-            var xml = "<Representation id=\"1\" mimeType=\"video/mp2t\" startWithSAP=\"1\" codecs=\"" + codecs + "\"";
+            var mime = string.Equals(GetSegmentFileExtension(state), ".ts", StringComparison.OrdinalIgnoreCase)
+                ? "video/mp2t"
+                : "video/mp4";
+
+            var xml = "<Representation id=\"1\" mimeType=\"" + mime + "\" startWithSAP=\"1\" codecs=\"" + codecs + "\"";
 
             if (state.OutputWidth.HasValue)
             {
@@ -171,6 +181,7 @@ namespace MediaBrowser.Api.Playback.Hls
         private string GetVideoCodecDescriptor(StreamState state)
         {
             // https://developer.apple.com/library/ios/documentation/networkinginternet/conceptual/streamingmediaguide/FrequentlyAskedQuestions/FrequentlyAskedQuestions.html
+            // http://www.chipwreck.de/blog/2010/02/25/html-5-video-tag-and-attributes/
 
             var level = state.TargetVideoLevel ?? 0;
             var profile = state.TargetVideoProfile ?? string.Empty;
@@ -210,7 +221,7 @@ namespace MediaBrowser.Api.Playback.Hls
                 return "avc1.42001f";
             }
 
-            return "avc1.42001e";
+            return "avc1.42E01E";
         }
 
         private string GetAudioCodecDescriptor(StreamState state)
@@ -234,11 +245,13 @@ namespace MediaBrowser.Api.Playback.Hls
 
         public object Get(GetDashSegment request)
         {
-            return null;
+            return GetDynamicSegment(request, request.SegmentId).Result;
         }
 
         private void AppendSegmentList(StreamState state, StringBuilder builder)
         {
+            var extension = GetSegmentFileExtension(state);
+
             var seconds = TimeSpan.FromTicks(state.RunTimeTicks ?? 0).TotalSeconds;
 
             var queryStringIndex = Request.RawUrl.IndexOf('?');
@@ -247,11 +260,22 @@ namespace MediaBrowser.Api.Playback.Hls
             var index = 0;
             builder.Append("<SegmentList timescale=\"1000\" duration=\"10000\">");
 
+
             while (seconds > 0)
             {
-                var segmentUrl = string.Format("{0}.ts{1}", index.ToString(UsCulture), SecurityElement.Escape(queryString));
+                var segmentUrl = string.Format("dash/{0}{1}{2}",
+                    index.ToString(UsCulture),
+                    extension,
+                    SecurityElement.Escape(queryString));
 
-                builder.AppendFormat("<SegmentURL media=\"{0}\"/>", segmentUrl);
+                if (index == 0)
+                {
+                    builder.AppendFormat("<Initialization sourceURL=\"{0}\"/>", segmentUrl);
+                }
+                else
+                {
+                    builder.AppendFormat("<SegmentURL media=\"{0}\"/>", segmentUrl);
+                }
 
                 seconds -= state.SegmentLength;
                 index++;
@@ -259,6 +283,274 @@ namespace MediaBrowser.Api.Playback.Hls
             builder.Append("</SegmentList>");
         }
 
+        private async Task<object> GetDynamicSegment(VideoStreamRequest request, string segmentId)
+        {
+            if ((request.StartTimeTicks ?? 0) > 0)
+            {
+                throw new ArgumentException("StartTimeTicks is not allowed.");
+            }
+
+            var cancellationTokenSource = new CancellationTokenSource();
+            var cancellationToken = cancellationTokenSource.Token;
+
+            var index = int.Parse(segmentId, NumberStyles.Integer, UsCulture);
+
+            var state = await GetState(request, cancellationToken).ConfigureAwait(false);
+
+            var playlistPath = Path.ChangeExtension(state.OutputFilePath, ".m3u8");
+
+            var segmentExtension = GetSegmentFileExtension(state);
+
+            var segmentPath = GetSegmentPath(playlistPath, segmentExtension, index);
+            var segmentLength = state.SegmentLength;
+
+            TranscodingJob job = null;
+
+            if (File.Exists(segmentPath))
+            {
+                job = ApiEntryPoint.Instance.OnTranscodeBeginRequest(playlistPath, TranscodingJobType);
+                return await GetSegmentResult(playlistPath, segmentPath, index, segmentLength, job, cancellationToken).ConfigureAwait(false);
+            }
+
+            await ApiEntryPoint.Instance.TranscodingStartLock.WaitAsync(cancellationTokenSource.Token).ConfigureAwait(false);
+            try
+            {
+                if (File.Exists(segmentPath))
+                {
+                    job = ApiEntryPoint.Instance.OnTranscodeBeginRequest(playlistPath, TranscodingJobType);
+                    return await GetSegmentResult(playlistPath, segmentPath, index, segmentLength, job, cancellationToken).ConfigureAwait(false);
+                }
+                else
+                {
+                    var currentTranscodingIndex = GetCurrentTranscodingIndex(playlistPath, segmentExtension);
+
+                    if (currentTranscodingIndex == null || index < currentTranscodingIndex.Value || (index - currentTranscodingIndex.Value) > 4)
+                    {
+                        // If the playlist doesn't already exist, startup ffmpeg
+                        try
+                        {
+                            ApiEntryPoint.Instance.KillTranscodingJobs(j => j.Type == TranscodingJobType && string.Equals(j.DeviceId, request.DeviceId, StringComparison.OrdinalIgnoreCase), p => !string.Equals(p, playlistPath, StringComparison.OrdinalIgnoreCase));
+
+                            if (currentTranscodingIndex.HasValue)
+                            {
+                                DeleteLastFile(playlistPath, segmentExtension, 0);
+                            }
+
+                            var startSeconds = index * state.SegmentLength;
+                            request.StartTimeTicks = TimeSpan.FromSeconds(startSeconds).Ticks;
+
+                            job = await StartFfMpeg(state, playlistPath, cancellationTokenSource, Path.GetDirectoryName(playlistPath)).ConfigureAwait(false);
+                        }
+                        catch
+                        {
+                            state.Dispose();
+                            throw;
+                        }
+
+                        await WaitForMinimumSegmentCount(playlistPath, 2, cancellationTokenSource.Token).ConfigureAwait(false);
+                    }
+                }
+            }
+            finally
+            {
+                ApiEntryPoint.Instance.TranscodingStartLock.Release();
+            }
+
+            Logger.Info("waiting for {0}", segmentPath);
+            while (!File.Exists(segmentPath))
+            {
+                await Task.Delay(50, cancellationToken).ConfigureAwait(false);
+            }
+
+            Logger.Info("returning {0}", segmentPath);
+            job = job ?? ApiEntryPoint.Instance.GetTranscodingJob(playlistPath, TranscodingJobType);
+            return await GetSegmentResult(playlistPath, segmentPath, index, segmentLength, job, cancellationToken).ConfigureAwait(false);
+        }
+
+        private async Task<object> GetSegmentResult(string playlistPath,
+            string segmentPath,
+            int segmentIndex,
+            int segmentLength,
+            TranscodingJob transcodingJob,
+            CancellationToken cancellationToken)
+        {
+            // If all transcoding has completed, just return immediately
+            if (!IsTranscoding(playlistPath))
+            {
+                return GetSegmentResult(segmentPath, segmentIndex, segmentLength, transcodingJob);
+            }
+
+            var segmentFilename = Path.GetFileName(segmentPath);
+
+            using (var fileStream = FileSystem.GetFileStream(playlistPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, true))
+            {
+                using (var reader = new StreamReader(fileStream))
+                {
+                    var text = await reader.ReadToEndAsync().ConfigureAwait(false);
+
+                    // If it appears in the playlist, it's done
+                    if (text.IndexOf(segmentFilename, StringComparison.OrdinalIgnoreCase) != -1)
+                    {
+                        return GetSegmentResult(segmentPath, segmentIndex, segmentLength, transcodingJob);
+                    }
+                }
+            }
+
+            // if a different file is encoding, it's done
+            //var currentTranscodingIndex = GetCurrentTranscodingIndex(playlistPath);
+            //if (currentTranscodingIndex > segmentIndex)
+            //{
+            //return GetSegmentResult(segmentPath, segmentIndex);
+            //}
+
+            // Wait for the file to stop being written to, then stream it
+            var length = new FileInfo(segmentPath).Length;
+            var eofCount = 0;
+
+            while (eofCount < 10)
+            {
+                var info = new FileInfo(segmentPath);
+
+                if (!info.Exists)
+                {
+                    break;
+                }
+
+                var newLength = info.Length;
+
+                if (newLength == length)
+                {
+                    eofCount++;
+                }
+                else
+                {
+                    eofCount = 0;
+                }
+
+                length = newLength;
+                await Task.Delay(100, cancellationToken).ConfigureAwait(false);
+            }
+
+            return GetSegmentResult(segmentPath, segmentIndex, segmentLength, transcodingJob);
+        }
+
+        private object GetSegmentResult(string segmentPath, int index, int segmentLength, TranscodingJob transcodingJob)
+        {
+            var segmentEndingSeconds = (1 + index) * segmentLength;
+            var segmentEndingPositionTicks = TimeSpan.FromSeconds(segmentEndingSeconds).Ticks;
+
+            return ResultFactory.GetStaticFileResult(Request, new StaticFileResultOptions
+            {
+                Path = segmentPath,
+                FileShare = FileShare.ReadWrite,
+                OnComplete = () =>
+                {
+                    if (transcodingJob != null)
+                    {
+                        transcodingJob.DownloadPositionTicks = Math.Max(transcodingJob.DownloadPositionTicks ?? segmentEndingPositionTicks, segmentEndingPositionTicks);
+                    }
+
+                }
+            });
+        }
+
+        private bool IsTranscoding(string playlistPath)
+        {
+            var job = ApiEntryPoint.Instance.GetTranscodingJob(playlistPath, TranscodingJobType);
+
+            return job != null && !job.HasExited;
+        }
+        
+        public int? GetCurrentTranscodingIndex(string playlist, string segmentExtension)
+        {
+            var file = GetLastTranscodingFile(playlist, segmentExtension, FileSystem);
+
+            if (file == null)
+            {
+                return null;
+            }
+
+            var playlistFilename = Path.GetFileNameWithoutExtension(playlist);
+
+            var indexString = Path.GetFileNameWithoutExtension(file.Name).Substring(playlistFilename.Length);
+
+            return int.Parse(indexString, NumberStyles.Integer, UsCulture);
+        }
+
+        private void DeleteLastFile(string path, string segmentExtension, int retryCount)
+        {
+            if (retryCount >= 5)
+            {
+                return;
+            }
+
+            var file = GetLastTranscodingFile(path, segmentExtension, FileSystem);
+
+            if (file != null)
+            {
+                try
+                {
+                    File.Delete(file.FullName);
+                }
+                catch (IOException ex)
+                {
+                    Logger.ErrorException("Error deleting partial stream file(s) {0}", ex, file.FullName);
+
+                    Thread.Sleep(100);
+                    DeleteLastFile(path, segmentExtension, retryCount + 1);
+                }
+                catch (Exception ex)
+                {
+                    Logger.ErrorException("Error deleting partial stream file(s) {0}", ex, file.FullName);
+                }
+            }
+        }
+
+        private static FileInfo GetLastTranscodingFile(string playlist, string segmentExtension, IFileSystem fileSystem)
+        {
+            var folder = Path.GetDirectoryName(playlist);
+
+            try
+            {
+                return new DirectoryInfo(folder)
+                    .EnumerateFiles("*", SearchOption.TopDirectoryOnly)
+                    .Where(i => string.Equals(i.Extension, segmentExtension, StringComparison.OrdinalIgnoreCase))
+                    .OrderByDescending(fileSystem.GetLastWriteTimeUtc)
+                    .FirstOrDefault();
+            }
+            catch (DirectoryNotFoundException)
+            {
+                return null;
+            }
+        }
+
+        protected override int GetStartNumber(StreamState state)
+        {
+            return GetStartNumber(state.VideoRequest);
+        }
+
+        private int GetStartNumber(VideoStreamRequest request)
+        {
+            var segmentId = "0";
+
+            var segmentRequest = request as GetDynamicHlsVideoSegment;
+            if (segmentRequest != null)
+            {
+                segmentId = segmentRequest.SegmentId;
+            }
+
+            return int.Parse(segmentId, NumberStyles.Integer, UsCulture);
+        }
+
+        private string GetSegmentPath(string playlist, string segmentExtension, int index)
+        {
+            var folder = Path.GetDirectoryName(playlist);
+
+            var filename = Path.GetFileNameWithoutExtension(playlist);
+
+            return Path.Combine(folder, filename + index.ToString("000", UsCulture) + segmentExtension);
+        }
+        
         protected override string GetAudioArguments(StreamState state)
         {
             var codec = state.OutputAudioCodec;
@@ -330,7 +622,9 @@ 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 segmentFilename = Path.GetFileNameWithoutExtension(outputPath) + "%03d" + GetSegmentFileExtension(state);
+
+            var args = string.Format("{0} -i {1} -map_metadata -1 -threads {2} {3} {4} -copyts -flags -global_header {5} -f ssegment -segment_time {6} -segment_format_options movflags=+faststart -segment_list_size {8} -segment_list \"{9}\" {10}",
                 inputModifier,
                 GetInputArgument(transcodingJobId, state),
                 threads,
@@ -340,7 +634,8 @@ namespace MediaBrowser.Api.Playback.Hls
                 state.SegmentLength.ToString(UsCulture),
                 startNumberParam,
                 state.HlsListSize.ToString(UsCulture),
-                outputPath
+                outputPath,
+                segmentFilename
                 ).Trim();
 
             return args;
@@ -353,7 +648,7 @@ namespace MediaBrowser.Api.Playback.Hls
         /// <returns>System.String.</returns>
         protected override string GetSegmentFileExtension(StreamState state)
         {
-            return ".ts";
+            return ".mp4";
         }
 
         protected override TranscodingJobType TranscodingJobType

+ 10 - 2
MediaBrowser.Api/Playback/StreamState.cs

@@ -64,7 +64,11 @@ namespace MediaBrowser.Api.Playback
         public string LiveTvStreamId { get; set; }
 
         public int SegmentLength = 10;
-        public int HlsListSize;
+
+        public int HlsListSize
+        {
+            get { return ReadInputAtNativeFramerate ? 100 : 1440; }
+        }
 
         public long? RunTimeTicks;
 
@@ -90,7 +94,11 @@ namespace MediaBrowser.Api.Playback
         public string InputVideoSync { get; set; }
 
         public bool DeInterlace { get; set; }
-        public bool ReadInputAtNativeFramerate { get; set; }
+
+        public bool ReadInputAtNativeFramerate
+        {
+            get { return InputProtocol == MediaProtocol.Rtmp || string.Equals(InputContainer, "wtv", StringComparison.OrdinalIgnoreCase); }
+        }
 
         public TransportStreamTimestamp InputTimestamp { get; set; }
 

+ 15 - 5
MediaBrowser.Api/UserService.cs

@@ -5,6 +5,7 @@ using MediaBrowser.Controller.Dto;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Net;
 using MediaBrowser.Controller.Session;
+using MediaBrowser.Model.Connect;
 using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Users;
 using ServiceStack;
@@ -190,11 +191,8 @@ namespace MediaBrowser.Api
 
         public object Get(GetPublicUsers request)
         {
-            var authInfo = AuthorizationContext.GetAuthorizationInfo(Request);
-            var isDashboard = string.Equals(authInfo.Client, "Dashboard", StringComparison.OrdinalIgnoreCase);
-
-            if ((Request.IsLocal && isDashboard) ||
-                !_config.Configuration.IsStartupWizardCompleted)
+            // If the startup wizard hasn't been completed then just return all users
+            if (!_config.Configuration.IsStartupWizardCompleted)
             {
                 return Get(new GetUsers
                 {
@@ -202,6 +200,18 @@ namespace MediaBrowser.Api
                 });
             }
 
+            var authInfo = AuthorizationContext.GetAuthorizationInfo(Request);
+            var isDashboard = string.Equals(authInfo.Client, "Dashboard", StringComparison.OrdinalIgnoreCase);
+
+            if (Request.IsLocal && isDashboard)
+            {
+                var users = _userManager.Users
+                    .Where(i => !i.Configuration.IsDisabled && !(i.ConnectLinkType.HasValue && i.ConnectLinkType.Value == UserLinkType.Guest))
+                    .ToList();
+
+                return ToOptimizedResult(users);
+            }
+
             // TODO: Uncomment this once all clients can handle an empty user list.
             return Get(new GetUsers
             {

+ 71 - 0
MediaBrowser.Controller/Entities/DayOfWeekHelper.cs

@@ -0,0 +1,71 @@
+using MediaBrowser.Model.Configuration;
+using System;
+using System.Collections.Generic;
+
+namespace MediaBrowser.Controller.Entities
+{
+    public static class DayOfWeekHelper
+    {
+        public static List<DayOfWeek> GetDaysOfWeek(DynamicDayOfWeek day)
+        {
+            return GetDaysOfWeek(new List<DynamicDayOfWeek> { day });
+        }
+
+        public static List<DayOfWeek> GetDaysOfWeek(List<DynamicDayOfWeek> days)
+        {
+            var list = new List<DayOfWeek>();
+
+            if (days.Contains(DynamicDayOfWeek.Sunday) ||
+                days.Contains(DynamicDayOfWeek.Weekend) ||
+                days.Contains(DynamicDayOfWeek.Everyday))
+            {
+                list.Add(DayOfWeek.Sunday);
+            }
+
+            if (days.Contains(DynamicDayOfWeek.Saturday) ||
+                days.Contains(DynamicDayOfWeek.Weekend) ||
+                days.Contains(DynamicDayOfWeek.Everyday))
+            {
+                list.Add(DayOfWeek.Saturday);
+            }
+
+            if (days.Contains(DynamicDayOfWeek.Monday) ||
+                days.Contains(DynamicDayOfWeek.Weekday) ||
+                days.Contains(DynamicDayOfWeek.Everyday))
+            {
+                list.Add(DayOfWeek.Monday);
+            }
+
+            if (days.Contains(DynamicDayOfWeek.Monday) ||
+                days.Contains(DynamicDayOfWeek.Weekday) ||
+                days.Contains(DynamicDayOfWeek.Everyday))
+            {
+                list.Add(DayOfWeek.Tuesday
+                    );
+            }
+
+            if (days.Contains(DynamicDayOfWeek.Wednesday) ||
+                days.Contains(DynamicDayOfWeek.Weekday) ||
+                days.Contains(DynamicDayOfWeek.Everyday))
+            {
+                list.Add(DayOfWeek.Wednesday);
+            }
+
+            if (days.Contains(DynamicDayOfWeek.Thursday) ||
+                days.Contains(DynamicDayOfWeek.Weekday) ||
+                days.Contains(DynamicDayOfWeek.Everyday))
+            {
+                list.Add(DayOfWeek.Thursday);
+            }
+
+            if (days.Contains(DynamicDayOfWeek.Friday) ||
+                days.Contains(DynamicDayOfWeek.Weekday) ||
+                days.Contains(DynamicDayOfWeek.Everyday))
+            {
+                list.Add(DayOfWeek.Friday);
+            }
+
+            return list;
+        }
+    }
+}

+ 21 - 20
MediaBrowser.Controller/Entities/TV/Episode.cs

@@ -146,7 +146,27 @@ namespace MediaBrowser.Controller.Entities.TV
         [IgnoreDataMember]
         public Season Season
         {
-            get { return FindParent<Season>(); }
+            get
+            {
+                var season = FindParent<Season>();
+
+                // Episodes directly in series folder
+                if (season == null)
+                {
+                    var series = FindParent<Series>();
+
+                    if (ParentIndexNumber.HasValue)
+                    {
+                        var findNumber = ParentIndexNumber.Value;
+
+                        season = series.Children
+                            .OfType<Season>()
+                            .FirstOrDefault(i => i.IndexNumber.HasValue && i.IndexNumber.Value == findNumber);
+                    }
+                }
+
+                return season;
+            }
         }
 
         [IgnoreDataMember]
@@ -237,25 +257,6 @@ namespace MediaBrowser.Controller.Entities.TV
                     return season.Id;
                 }
 
-                var seasonNumber = ParentIndexNumber;
-
-                // Parent is a Series
-                if (seasonNumber.HasValue)
-                {
-                    var series = Series;
-
-                    if (series != null)
-                    {
-                        season = series.Children.OfType<Season>()
-                            .FirstOrDefault(i => i.IndexNumber.HasValue && i.IndexNumber.Value == seasonNumber.Value);
-
-                        if (season != null)
-                        {
-                            return season.Id;
-                        }
-                    }
-                }
-
                 return null;
             }
         }

+ 2 - 1
MediaBrowser.Controller/Entities/User.cs

@@ -287,7 +287,8 @@ namespace MediaBrowser.Controller.Entities
 
             var localTime = date.ToLocalTime();
 
-            return localTime.DayOfWeek == schedule.DayOfWeek && IsWithinTime(schedule, localTime);
+            return DayOfWeekHelper.GetDaysOfWeek(schedule.DayOfWeek).Contains(localTime.DayOfWeek) && 
+                IsWithinTime(schedule, localTime);
         }
 
         private bool IsWithinTime(AccessSchedule schedule, DateTime localTime)

+ 1 - 0
MediaBrowser.Controller/MediaBrowser.Controller.csproj

@@ -123,6 +123,7 @@
     <Compile Include="Entities\Book.cs" />
     <Compile Include="Configuration\IServerConfigurationManager.cs" />
     <Compile Include="Entities\Audio\MusicGenre.cs" />
+    <Compile Include="Entities\DayOfWeekHelper.cs" />
     <Compile Include="Entities\Extensions.cs" />
     <Compile Include="Entities\Game.cs" />
     <Compile Include="Entities\GameGenre.cs" />

+ 6 - 0
MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj

@@ -173,6 +173,9 @@
     <Compile Include="..\MediaBrowser.Model\Configuration\DlnaOptions.cs">
       <Link>Configuration\DlnaOptions.cs</Link>
     </Compile>
+    <Compile Include="..\MediaBrowser.Model\Configuration\DynamicDayOfWeek.cs">
+      <Link>Configuration\DynamicDayOfWeek.cs</Link>
+    </Compile>
     <Compile Include="..\MediaBrowser.Model\Configuration\EncodingQuality.cs">
       <Link>Configuration\EncodingQuality.cs</Link>
     </Compile>
@@ -230,6 +233,9 @@
     <Compile Include="..\MediaBrowser.Model\Connect\ConnectUserQuery.cs">
       <Link>Connect\ConnectUserQuery.cs</Link>
     </Compile>
+    <Compile Include="..\MediaBrowser.Model\Connect\ConnectUserServer.cs">
+      <Link>Connect\ConnectUserServer.cs</Link>
+    </Compile>
     <Compile Include="..\MediaBrowser.Model\Connect\PinCreationResult.cs">
       <Link>Connect\PinCreationResult.cs</Link>
     </Compile>

+ 6 - 0
MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj

@@ -139,6 +139,9 @@
     <Compile Include="..\MediaBrowser.Model\Configuration\DlnaOptions.cs">
       <Link>Configuration\DlnaOptions.cs</Link>
     </Compile>
+    <Compile Include="..\MediaBrowser.Model\Configuration\DynamicDayOfWeek.cs">
+      <Link>Configuration\DynamicDayOfWeek.cs</Link>
+    </Compile>
     <Compile Include="..\MediaBrowser.Model\Configuration\EncodingQuality.cs">
       <Link>Configuration\EncodingQuality.cs</Link>
     </Compile>
@@ -196,6 +199,9 @@
     <Compile Include="..\MediaBrowser.Model\Connect\ConnectUserQuery.cs">
       <Link>Connect\ConnectUserQuery.cs</Link>
     </Compile>
+    <Compile Include="..\MediaBrowser.Model\Connect\ConnectUserServer.cs">
+      <Link>Connect\ConnectUserServer.cs</Link>
+    </Compile>
     <Compile Include="..\MediaBrowser.Model\Connect\PinCreationResult.cs">
       <Link>Connect\PinCreationResult.cs</Link>
     </Compile>

+ 2 - 3
MediaBrowser.Model/Configuration/AccessSchedule.cs

@@ -1,5 +1,4 @@
-using System;
-
+
 namespace MediaBrowser.Model.Configuration
 {
     public class AccessSchedule
@@ -8,7 +7,7 @@ namespace MediaBrowser.Model.Configuration
         /// Gets or sets the day of week.
         /// </summary>
         /// <value>The day of week.</value>
-        public DayOfWeek DayOfWeek { get; set; }
+        public DynamicDayOfWeek DayOfWeek { get; set; }
         /// <summary>
         /// Gets or sets the start hour.
         /// </summary>

+ 17 - 0
MediaBrowser.Model/Configuration/DynamicDayOfWeek.cs

@@ -0,0 +1,17 @@
+
+namespace MediaBrowser.Model.Configuration
+{
+    public enum DynamicDayOfWeek
+    {
+        Sunday = 0,
+        Monday = 1,
+        Tuesday = 2,
+        Wednesday = 3,
+        Thursday = 4,
+        Friday = 5,
+        Saturday = 6,
+        Everyday = 7,
+        Weekday = 8,
+        Weekend = 9
+    }
+}

+ 12 - 0
MediaBrowser.Model/Connect/ConnectUserServer.cs

@@ -0,0 +1,12 @@
+
+namespace MediaBrowser.Model.Connect
+{
+    public class ConnectUserServer
+    {
+        public string Id { get; set; }
+        public string Url { get; set; }
+        public string Name { get; set; }
+        public string AccessKey { get; set; }
+        public string SystemId { get; set; }
+    }
+}

+ 2 - 0
MediaBrowser.Model/MediaBrowser.Model.csproj

@@ -101,6 +101,7 @@
     <Compile Include="Connect\ConnectAuthorization.cs" />
     <Compile Include="Connect\ConnectUser.cs" />
     <Compile Include="Connect\ConnectUserQuery.cs" />
+    <Compile Include="Connect\ConnectUserServer.cs" />
     <Compile Include="Connect\PinCreationResult.cs" />
     <Compile Include="Connect\PinExchangeResult.cs" />
     <Compile Include="Connect\PinStatusResult.cs" />
@@ -121,6 +122,7 @@
     <Compile Include="Dto\MediaSourceType.cs" />
     <Compile Include="Dto\StreamOptions.cs" />
     <Compile Include="Dto\VideoStreamOptions.cs" />
+    <Compile Include="Configuration\DynamicDayOfWeek.cs" />
     <Compile Include="Entities\ExtraType.cs" />
     <Compile Include="Entities\SupporterInfo.cs" />
     <Compile Include="Entities\TrailerType.cs" />

+ 5 - 2
MediaBrowser.Providers/Movies/MovieMetadataService.cs

@@ -7,8 +7,6 @@ using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Logging;
 using MediaBrowser.Providers.Manager;
 using System.Collections.Generic;
-using System.Threading;
-using System.Threading.Tasks;
 
 namespace MediaBrowser.Providers.Movies
 {
@@ -29,6 +27,11 @@ namespace MediaBrowser.Providers.Movies
         protected override void MergeData(Movie source, Movie target, List<MetadataFields> lockedFields, bool replaceData, bool mergeMetadataSettings)
         {
             ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
+
+            if (replaceData || string.IsNullOrEmpty(target.TmdbCollectionName))
+            {
+                target.TmdbCollectionName = source.TmdbCollectionName;
+            }
         }
     }
 }

+ 11 - 4
MediaBrowser.Server.Implementations/Connect/ConnectManager.cs

@@ -427,13 +427,19 @@ namespace MediaBrowser.Server.Implementations.Connect
             var accessToken = Guid.NewGuid().ToString("N");
             var sendingUser = GetUser(sendingUserId);
 
+            var requesterUserName = sendingUser.ConnectUserName;
+            if (string.IsNullOrWhiteSpace(requesterUserName))
+            {
+                requesterUserName = sendingUser.Name;
+            }
+
             var postData = new Dictionary<string, string>
             {
                 {"serverId", ConnectServerId},
                 {"userId", connectUser.Id},
                 {"userType", "Guest"},
                 {"accessToken", accessToken},
-                {"requesterUserName", sendingUser.ConnectUserName}
+                {"requesterUserName", requesterUserName}
             };
 
             options.SetPostData(postData);
@@ -608,8 +614,6 @@ namespace MediaBrowser.Server.Implementations.Connect
                 }
             }
 
-            users = _userManager.Users.ToList();
-
             var pending = new List<ConnectAuthorization>();
 
             foreach (var connectEntry in list)
@@ -618,7 +622,8 @@ namespace MediaBrowser.Server.Implementations.Connect
                 {
                     if (string.Equals(connectEntry.AcceptStatus, "accepted", StringComparison.OrdinalIgnoreCase))
                     {
-                        var user = users.FirstOrDefault(i => string.Equals(i.ConnectUserId, connectEntry.UserId, StringComparison.OrdinalIgnoreCase));
+                        var user = _userManager.Users
+                            .FirstOrDefault(i => string.Equals(i.ConnectUserId, connectEntry.UserId, StringComparison.OrdinalIgnoreCase));
 
                         if (user == null)
                         {
@@ -635,6 +640,8 @@ namespace MediaBrowser.Server.Implementations.Connect
                             user.Configuration.SyncConnectImage = true;
                             user.Configuration.SyncConnectName = true;
                             user.Configuration.IsHidden = true;
+                            user.Configuration.EnableLiveTvManagement = false;
+                            user.Configuration.IsAdministrator = false;
 
                             _userManager.UpdateConfiguration(user, user.Configuration);
                         }

+ 17 - 5
MediaBrowser.Server.Implementations/Library/UserManager.cs

@@ -10,6 +10,7 @@ using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Persistence;
 using MediaBrowser.Controller.Providers;
 using MediaBrowser.Model.Configuration;
+using MediaBrowser.Model.Connect;
 using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Events;
@@ -225,7 +226,7 @@ namespace MediaBrowser.Server.Implementations.Library
             {
                 var name = Environment.UserName;
 
-                var user = InstantiateNewUser(name);
+                var user = InstantiateNewUser(name, false);
 
                 user.DateLastSaved = DateTime.UtcNow;
 
@@ -403,7 +404,7 @@ namespace MediaBrowser.Server.Implementations.Library
 
             try
             {
-                var user = InstantiateNewUser(name);
+                var user = InstantiateNewUser(name, true);
 
                 var list = Users.ToList();
                 list.Add(user);
@@ -509,6 +510,11 @@ namespace MediaBrowser.Server.Implementations.Library
                 throw new ArgumentNullException("user");
             }
 
+            if (user.ConnectLinkType.HasValue && user.ConnectLinkType.Value == UserLinkType.Guest)
+            {
+                throw new ArgumentException("Passwords for guests cannot be changed.");
+            }
+
             user.Password = string.IsNullOrEmpty(newPassword) ? GetSha1String(string.Empty) : GetSha1String(newPassword);
 
             await UpdateUser(user).ConfigureAwait(false);
@@ -520,15 +526,21 @@ namespace MediaBrowser.Server.Implementations.Library
         /// Instantiates the new user.
         /// </summary>
         /// <param name="name">The name.</param>
+        /// <param name="checkId">if set to <c>true</c> [check identifier].</param>
         /// <returns>User.</returns>
-        private User InstantiateNewUser(string name)
+        private User InstantiateNewUser(string name, bool checkId)
         {
-            var idSalt = ("MBUser" + name);
+            var id = ("MBUser" + name).GetMD5();
+
+            if (checkId && Users.Select(i => i.Id).Contains(id))
+            {
+                id = Guid.NewGuid();
+            }
 
             return new User
             {
                 Name = name,
-                Id = idSalt.GetMD5(),
+                Id = id,
                 DateCreated = DateTime.UtcNow,
                 DateModified = DateTime.UtcNow,
                 UsesIdForConfigurationPath = true

+ 2 - 1
MediaBrowser.Server.Implementations/Localization/JavaScript/ar.json

@@ -601,5 +601,6 @@
     "DeleteDeviceConfirmation": "Are you sure you wish to delete this device? It will reappear the next time a user signs in with it.",
     "LabelEnableCameraUploadFor": "Enable camera upload for:",
     "HeaderSelectUploadPath": "Select Upload Path",
-    "LabelEnableCameraUploadForHelp": "Uploads will occur automatically in the background when signed into Media Browser."
+    "LabelEnableCameraUploadForHelp": "Uploads will occur automatically in the background when signed into Media Browser.",
+    "ErrorMessageStartHourGreaterThanEnd": "End time must be greater than the start time."
 }

+ 2 - 1
MediaBrowser.Server.Implementations/Localization/JavaScript/ca.json

@@ -601,5 +601,6 @@
     "DeleteDeviceConfirmation": "Are you sure you wish to delete this device? It will reappear the next time a user signs in with it.",
     "LabelEnableCameraUploadFor": "Enable camera upload for:",
     "HeaderSelectUploadPath": "Select Upload Path",
-    "LabelEnableCameraUploadForHelp": "Uploads will occur automatically in the background when signed into Media Browser."
+    "LabelEnableCameraUploadForHelp": "Uploads will occur automatically in the background when signed into Media Browser.",
+    "ErrorMessageStartHourGreaterThanEnd": "End time must be greater than the start time."
 }

+ 2 - 1
MediaBrowser.Server.Implementations/Localization/JavaScript/cs.json

@@ -601,5 +601,6 @@
     "DeleteDeviceConfirmation": "Are you sure you wish to delete this device? It will reappear the next time a user signs in with it.",
     "LabelEnableCameraUploadFor": "Enable camera upload for:",
     "HeaderSelectUploadPath": "Select Upload Path",
-    "LabelEnableCameraUploadForHelp": "Uploads will occur automatically in the background when signed into Media Browser."
+    "LabelEnableCameraUploadForHelp": "Uploads will occur automatically in the background when signed into Media Browser.",
+    "ErrorMessageStartHourGreaterThanEnd": "End time must be greater than the start time."
 }

+ 2 - 1
MediaBrowser.Server.Implementations/Localization/JavaScript/da.json

@@ -601,5 +601,6 @@
     "DeleteDeviceConfirmation": "Are you sure you wish to delete this device? It will reappear the next time a user signs in with it.",
     "LabelEnableCameraUploadFor": "Enable camera upload for:",
     "HeaderSelectUploadPath": "Select Upload Path",
-    "LabelEnableCameraUploadForHelp": "Uploads will occur automatically in the background when signed into Media Browser."
+    "LabelEnableCameraUploadForHelp": "Uploads will occur automatically in the background when signed into Media Browser.",
+    "ErrorMessageStartHourGreaterThanEnd": "End time must be greater than the start time."
 }

+ 2 - 1
MediaBrowser.Server.Implementations/Localization/JavaScript/de.json

@@ -601,5 +601,6 @@
     "DeleteDeviceConfirmation": "Are you sure you wish to delete this device? It will reappear the next time a user signs in with it.",
     "LabelEnableCameraUploadFor": "Enable camera upload for:",
     "HeaderSelectUploadPath": "Select Upload Path",
-    "LabelEnableCameraUploadForHelp": "Uploads will occur automatically in the background when signed into Media Browser."
+    "LabelEnableCameraUploadForHelp": "Uploads will occur automatically in the background when signed into Media Browser.",
+    "ErrorMessageStartHourGreaterThanEnd": "End time must be greater than the start time."
 }

+ 2 - 1
MediaBrowser.Server.Implementations/Localization/JavaScript/el.json

@@ -601,5 +601,6 @@
     "DeleteDeviceConfirmation": "Are you sure you wish to delete this device? It will reappear the next time a user signs in with it.",
     "LabelEnableCameraUploadFor": "Enable camera upload for:",
     "HeaderSelectUploadPath": "Select Upload Path",
-    "LabelEnableCameraUploadForHelp": "Uploads will occur automatically in the background when signed into Media Browser."
+    "LabelEnableCameraUploadForHelp": "Uploads will occur automatically in the background when signed into Media Browser.",
+    "ErrorMessageStartHourGreaterThanEnd": "End time must be greater than the start time."
 }

+ 2 - 1
MediaBrowser.Server.Implementations/Localization/JavaScript/en_GB.json

@@ -601,5 +601,6 @@
     "DeleteDeviceConfirmation": "Are you sure you wish to delete this device? It will reappear the next time a user signs in with it.",
     "LabelEnableCameraUploadFor": "Enable camera upload for:",
     "HeaderSelectUploadPath": "Select Upload Path",
-    "LabelEnableCameraUploadForHelp": "Uploads will occur automatically in the background when signed into Media Browser."
+    "LabelEnableCameraUploadForHelp": "Uploads will occur automatically in the background when signed into Media Browser.",
+    "ErrorMessageStartHourGreaterThanEnd": "End time must be greater than the start time."
 }

+ 2 - 1
MediaBrowser.Server.Implementations/Localization/JavaScript/en_US.json

@@ -601,5 +601,6 @@
     "DeleteDeviceConfirmation": "Are you sure you wish to delete this device? It will reappear the next time a user signs in with it.",
     "LabelEnableCameraUploadFor": "Enable camera upload for:",
     "HeaderSelectUploadPath": "Select Upload Path",
-    "LabelEnableCameraUploadForHelp": "Uploads will occur automatically in the background when signed into Media Browser."
+    "LabelEnableCameraUploadForHelp": "Uploads will occur automatically in the background when signed into Media Browser.",
+    "ErrorMessageStartHourGreaterThanEnd": "End time must be greater than the start time."
 }

+ 2 - 1
MediaBrowser.Server.Implementations/Localization/JavaScript/es.json

@@ -601,5 +601,6 @@
     "DeleteDeviceConfirmation": "Are you sure you wish to delete this device? It will reappear the next time a user signs in with it.",
     "LabelEnableCameraUploadFor": "Enable camera upload for:",
     "HeaderSelectUploadPath": "Select Upload Path",
-    "LabelEnableCameraUploadForHelp": "Uploads will occur automatically in the background when signed into Media Browser."
+    "LabelEnableCameraUploadForHelp": "Uploads will occur automatically in the background when signed into Media Browser.",
+    "ErrorMessageStartHourGreaterThanEnd": "End time must be greater than the start time."
 }

+ 2 - 1
MediaBrowser.Server.Implementations/Localization/JavaScript/es_MX.json

@@ -601,5 +601,6 @@
     "DeleteDeviceConfirmation": "\u00bfEsta seguro de querer eliminar este dispositivo? Volver\u00e1 a aparecer la siguiente vez que un usuario inicie sesi\u00f3n en \u00e9l.",
     "LabelEnableCameraUploadFor": "Habilitar subida desde la c\u00e1mara para:",
     "HeaderSelectUploadPath": "Seleccionar trayectoria de subida",
-    "LabelEnableCameraUploadForHelp": "La subida ocurrir\u00e1 autom\u00e1ticamente en segundo plano al iniciar sesi\u00f3n en Media Browser."
+    "LabelEnableCameraUploadForHelp": "La subida ocurrir\u00e1 autom\u00e1ticamente en segundo plano al iniciar sesi\u00f3n en Media Browser.",
+    "ErrorMessageStartHourGreaterThanEnd": "El tiempo de fin debe ser mayor al tiempo de inicio"
 }

+ 2 - 1
MediaBrowser.Server.Implementations/Localization/JavaScript/fr.json

@@ -601,5 +601,6 @@
     "DeleteDeviceConfirmation": "\u00cates-vous s\u00fbr de vouloir supprimer ce p\u00e9riph\u00e9rique? La prochaine fois qu'un utilisateur se connecte au p\u00e9riph\u00e9rique, il sera ajout\u00e9 de nouveau.",
     "LabelEnableCameraUploadFor": "Autoriser l'upload de la cam\u00e9ra pour:",
     "HeaderSelectUploadPath": "S\u00e9lectionner le r\u00e9pertoire d'upload",
-    "LabelEnableCameraUploadForHelp": "Les uploads se lanceront automatiquement en arri\u00e8re plan apr\u00e8s l'authentification dans Media Browser."
+    "LabelEnableCameraUploadForHelp": "Les uploads se lanceront automatiquement en arri\u00e8re plan apr\u00e8s l'authentification dans Media Browser.",
+    "ErrorMessageStartHourGreaterThanEnd": "End time must be greater than the start time."
 }

+ 2 - 1
MediaBrowser.Server.Implementations/Localization/JavaScript/he.json

@@ -601,5 +601,6 @@
     "DeleteDeviceConfirmation": "Are you sure you wish to delete this device? It will reappear the next time a user signs in with it.",
     "LabelEnableCameraUploadFor": "Enable camera upload for:",
     "HeaderSelectUploadPath": "Select Upload Path",
-    "LabelEnableCameraUploadForHelp": "Uploads will occur automatically in the background when signed into Media Browser."
+    "LabelEnableCameraUploadForHelp": "Uploads will occur automatically in the background when signed into Media Browser.",
+    "ErrorMessageStartHourGreaterThanEnd": "End time must be greater than the start time."
 }

+ 2 - 1
MediaBrowser.Server.Implementations/Localization/JavaScript/hr.json

@@ -601,5 +601,6 @@
     "DeleteDeviceConfirmation": "Are you sure you wish to delete this device? It will reappear the next time a user signs in with it.",
     "LabelEnableCameraUploadFor": "Enable camera upload for:",
     "HeaderSelectUploadPath": "Select Upload Path",
-    "LabelEnableCameraUploadForHelp": "Uploads will occur automatically in the background when signed into Media Browser."
+    "LabelEnableCameraUploadForHelp": "Uploads will occur automatically in the background when signed into Media Browser.",
+    "ErrorMessageStartHourGreaterThanEnd": "End time must be greater than the start time."
 }

+ 2 - 1
MediaBrowser.Server.Implementations/Localization/JavaScript/it.json

@@ -601,5 +601,6 @@
     "DeleteDeviceConfirmation": "Are you sure you wish to delete this device? It will reappear the next time a user signs in with it.",
     "LabelEnableCameraUploadFor": "Enable camera upload for:",
     "HeaderSelectUploadPath": "Select Upload Path",
-    "LabelEnableCameraUploadForHelp": "Uploads will occur automatically in the background when signed into Media Browser."
+    "LabelEnableCameraUploadForHelp": "Uploads will occur automatically in the background when signed into Media Browser.",
+    "ErrorMessageStartHourGreaterThanEnd": "End time must be greater than the start time."
 }

+ 2 - 1
MediaBrowser.Server.Implementations/Localization/JavaScript/kk.json

@@ -601,5 +601,6 @@
     "DeleteDeviceConfirmation": "Are you sure you wish to delete this device? It will reappear the next time a user signs in with it.",
     "LabelEnableCameraUploadFor": "Enable camera upload for:",
     "HeaderSelectUploadPath": "Select Upload Path",
-    "LabelEnableCameraUploadForHelp": "Uploads will occur automatically in the background when signed into Media Browser."
+    "LabelEnableCameraUploadForHelp": "Uploads will occur automatically in the background when signed into Media Browser.",
+    "ErrorMessageStartHourGreaterThanEnd": "End time must be greater than the start time."
 }

+ 2 - 1
MediaBrowser.Server.Implementations/Localization/JavaScript/ms.json

@@ -601,5 +601,6 @@
     "DeleteDeviceConfirmation": "Are you sure you wish to delete this device? It will reappear the next time a user signs in with it.",
     "LabelEnableCameraUploadFor": "Enable camera upload for:",
     "HeaderSelectUploadPath": "Select Upload Path",
-    "LabelEnableCameraUploadForHelp": "Uploads will occur automatically in the background when signed into Media Browser."
+    "LabelEnableCameraUploadForHelp": "Uploads will occur automatically in the background when signed into Media Browser.",
+    "ErrorMessageStartHourGreaterThanEnd": "End time must be greater than the start time."
 }

+ 2 - 1
MediaBrowser.Server.Implementations/Localization/JavaScript/nb.json

@@ -601,5 +601,6 @@
     "DeleteDeviceConfirmation": "Are you sure you wish to delete this device? It will reappear the next time a user signs in with it.",
     "LabelEnableCameraUploadFor": "Enable camera upload for:",
     "HeaderSelectUploadPath": "Select Upload Path",
-    "LabelEnableCameraUploadForHelp": "Uploads will occur automatically in the background when signed into Media Browser."
+    "LabelEnableCameraUploadForHelp": "Uploads will occur automatically in the background when signed into Media Browser.",
+    "ErrorMessageStartHourGreaterThanEnd": "End time must be greater than the start time."
 }

+ 5 - 4
MediaBrowser.Server.Implementations/Localization/JavaScript/nl.json

@@ -595,11 +595,12 @@
     "DashboardTourScheduledTasks": "Beheer eenvoudig langlopende transacties met geplande taken. Beslis zelf wanneer ze worden uitgevoerd en hoe vaak.",
     "DashboardTourMobile": "Het dashboard van Media Browser werkt geweldig op smartphones en tablets. Uw server beheren vanuit de palm van uw hand, overal en altijd.",
     "MessageRefreshQueued": "Vernieuwen wachtrij",
-    "TabDevices": "Devices",
-    "DeviceLastUsedByUserName": "Last used by {0}",
-    "HeaderDeleteDevice": "Delete Device",
+    "TabDevices": "Apparaten",
+    "DeviceLastUsedByUserName": "Het laatste gebruikt door {0}",
+    "HeaderDeleteDevice": "Verwijder apparaat",
     "DeleteDeviceConfirmation": "Are you sure you wish to delete this device? It will reappear the next time a user signs in with it.",
     "LabelEnableCameraUploadFor": "Enable camera upload for:",
     "HeaderSelectUploadPath": "Select Upload Path",
-    "LabelEnableCameraUploadForHelp": "Uploads will occur automatically in the background when signed into Media Browser."
+    "LabelEnableCameraUploadForHelp": "Uploads will occur automatically in the background when signed into Media Browser.",
+    "ErrorMessageStartHourGreaterThanEnd": "End time must be greater than the start time."
 }

+ 2 - 1
MediaBrowser.Server.Implementations/Localization/JavaScript/pl.json

@@ -601,5 +601,6 @@
     "DeleteDeviceConfirmation": "Are you sure you wish to delete this device? It will reappear the next time a user signs in with it.",
     "LabelEnableCameraUploadFor": "Enable camera upload for:",
     "HeaderSelectUploadPath": "Select Upload Path",
-    "LabelEnableCameraUploadForHelp": "Uploads will occur automatically in the background when signed into Media Browser."
+    "LabelEnableCameraUploadForHelp": "Uploads will occur automatically in the background when signed into Media Browser.",
+    "ErrorMessageStartHourGreaterThanEnd": "End time must be greater than the start time."
 }

+ 9 - 8
MediaBrowser.Server.Implementations/Localization/JavaScript/pt_BR.json

@@ -594,12 +594,13 @@
     "DashboardTourNotifications": "Envie, automaticamente, notifica\u00e7\u00f5es de eventos do servidor para seus dispositivos m\u00f3veis, email e mais.",
     "DashboardTourScheduledTasks": "Gerencie facilmente opera\u00e7\u00f5es longas com tarefas agendadas. Decida quando executar e com que frequ\u00eancia.",
     "DashboardTourMobile": "O painel do M\u00e9dia Browser funciona perfeitamente em smartphones e tablets. Gerencie seu servidor da palma de sua m\u00e3o, a qualquer hora e em qualquer lugar.",
-    "MessageRefreshQueued": "Refresh queued",
-    "TabDevices": "Devices",
-    "DeviceLastUsedByUserName": "Last used by {0}",
-    "HeaderDeleteDevice": "Delete Device",
-    "DeleteDeviceConfirmation": "Are you sure you wish to delete this device? It will reappear the next time a user signs in with it.",
-    "LabelEnableCameraUploadFor": "Enable camera upload for:",
-    "HeaderSelectUploadPath": "Select Upload Path",
-    "LabelEnableCameraUploadForHelp": "Uploads will occur automatically in the background when signed into Media Browser."
+    "MessageRefreshQueued": "Atualiza\u00e7\u00e3o iniciada",
+    "TabDevices": "Dispositivos",
+    "DeviceLastUsedByUserName": "Utilizado por \u00faltimo por {0}",
+    "HeaderDeleteDevice": "Excluir Dispositivo",
+    "DeleteDeviceConfirmation": "Tem certeza de que deseja excluir este dispositivo? Ele reaparecer\u00e1 a pr\u00f3xima vez que um usu\u00e1rio utiliz\u00e1-lo.",
+    "LabelEnableCameraUploadFor": "Habilitar envio atrav\u00e9s de c\u00e2mera para:",
+    "HeaderSelectUploadPath": "Selecione o caminho para carga",
+    "LabelEnableCameraUploadForHelp": "Cargas ser\u00e3o executadas automaticamente em retaguarda quando logar no Media Browser.",
+    "ErrorMessageStartHourGreaterThanEnd": "End time must be greater than the start time."
 }

+ 2 - 1
MediaBrowser.Server.Implementations/Localization/JavaScript/pt_PT.json

@@ -601,5 +601,6 @@
     "DeleteDeviceConfirmation": "Are you sure you wish to delete this device? It will reappear the next time a user signs in with it.",
     "LabelEnableCameraUploadFor": "Enable camera upload for:",
     "HeaderSelectUploadPath": "Select Upload Path",
-    "LabelEnableCameraUploadForHelp": "Uploads will occur automatically in the background when signed into Media Browser."
+    "LabelEnableCameraUploadForHelp": "Uploads will occur automatically in the background when signed into Media Browser.",
+    "ErrorMessageStartHourGreaterThanEnd": "End time must be greater than the start time."
 }

+ 2 - 1
MediaBrowser.Server.Implementations/Localization/JavaScript/ru.json

@@ -601,5 +601,6 @@
     "DeleteDeviceConfirmation": "Are you sure you wish to delete this device? It will reappear the next time a user signs in with it.",
     "LabelEnableCameraUploadFor": "Enable camera upload for:",
     "HeaderSelectUploadPath": "Select Upload Path",
-    "LabelEnableCameraUploadForHelp": "Uploads will occur automatically in the background when signed into Media Browser."
+    "LabelEnableCameraUploadForHelp": "Uploads will occur automatically in the background when signed into Media Browser.",
+    "ErrorMessageStartHourGreaterThanEnd": "End time must be greater than the start time."
 }

+ 2 - 1
MediaBrowser.Server.Implementations/Localization/JavaScript/sv.json

@@ -601,5 +601,6 @@
     "DeleteDeviceConfirmation": "Are you sure you wish to delete this device? It will reappear the next time a user signs in with it.",
     "LabelEnableCameraUploadFor": "Enable camera upload for:",
     "HeaderSelectUploadPath": "Select Upload Path",
-    "LabelEnableCameraUploadForHelp": "Uploads will occur automatically in the background when signed into Media Browser."
+    "LabelEnableCameraUploadForHelp": "Uploads will occur automatically in the background when signed into Media Browser.",
+    "ErrorMessageStartHourGreaterThanEnd": "End time must be greater than the start time."
 }

+ 2 - 1
MediaBrowser.Server.Implementations/Localization/JavaScript/tr.json

@@ -601,5 +601,6 @@
     "DeleteDeviceConfirmation": "Are you sure you wish to delete this device? It will reappear the next time a user signs in with it.",
     "LabelEnableCameraUploadFor": "Enable camera upload for:",
     "HeaderSelectUploadPath": "Select Upload Path",
-    "LabelEnableCameraUploadForHelp": "Uploads will occur automatically in the background when signed into Media Browser."
+    "LabelEnableCameraUploadForHelp": "Uploads will occur automatically in the background when signed into Media Browser.",
+    "ErrorMessageStartHourGreaterThanEnd": "End time must be greater than the start time."
 }

+ 2 - 1
MediaBrowser.Server.Implementations/Localization/JavaScript/vi.json

@@ -601,5 +601,6 @@
     "DeleteDeviceConfirmation": "Are you sure you wish to delete this device? It will reappear the next time a user signs in with it.",
     "LabelEnableCameraUploadFor": "Enable camera upload for:",
     "HeaderSelectUploadPath": "Select Upload Path",
-    "LabelEnableCameraUploadForHelp": "Uploads will occur automatically in the background when signed into Media Browser."
+    "LabelEnableCameraUploadForHelp": "Uploads will occur automatically in the background when signed into Media Browser.",
+    "ErrorMessageStartHourGreaterThanEnd": "End time must be greater than the start time."
 }

+ 2 - 1
MediaBrowser.Server.Implementations/Localization/JavaScript/zh_TW.json

@@ -601,5 +601,6 @@
     "DeleteDeviceConfirmation": "Are you sure you wish to delete this device? It will reappear the next time a user signs in with it.",
     "LabelEnableCameraUploadFor": "Enable camera upload for:",
     "HeaderSelectUploadPath": "Select Upload Path",
-    "LabelEnableCameraUploadForHelp": "Uploads will occur automatically in the background when signed into Media Browser."
+    "LabelEnableCameraUploadForHelp": "Uploads will occur automatically in the background when signed into Media Browser.",
+    "ErrorMessageStartHourGreaterThanEnd": "End time must be greater than the start time."
 }

+ 7 - 0
MediaBrowser.Server.Implementations/Localization/Server/ar.json

@@ -440,12 +440,19 @@
     "VisitMediaBrowserWebsite": "Visit the Media Browser Web Site",
     "HeaderPendingInvitations": "Pending Invitations",
     "VisitMediaBrowserWebsiteLong": "Visit the Media Browser Web site to catch the latest news and keep up with the developer blog.",
+    "TabParentalControl": "Parental Control",
     "OptionHideUser": "Hide this user from login screens",
+    "HeaderAccessSchedule": "Access Schedule",
     "OptionDisableUser": "Disable this user",
+    "HeaderAccessScheduleHelp": "Create an access schedule to limit access to certain hours.",
     "OptionDisableUserHelp": "If disabled the server will not allow any connections from this user. Existing connections will be abruptly terminated.",
+    "ButtonAddSchedule": "Add Schedule",
     "HeaderAdvancedControl": "Advanced Control",
+    "LabelAccessDay": "Day of week:",
     "LabelName": "Name:",
+    "LabelAccessStart": "Start hour:",
     "OptionAllowUserToManageServer": "Allow this user to manage the server",
+    "LabelAccessEnd": "End hour:",
     "HeaderFeatureAccess": "Feature Access",
     "OptionAllowMediaPlayback": "Allow media playback",
     "OptionAllowBrowsingLiveTv": "Allow browsing of live tv",

+ 7 - 0
MediaBrowser.Server.Implementations/Localization/Server/ca.json

@@ -440,12 +440,19 @@
     "VisitMediaBrowserWebsite": "Visit the Media Browser Web Site",
     "HeaderPendingInvitations": "Pending Invitations",
     "VisitMediaBrowserWebsiteLong": "Visit the Media Browser Web site to catch the latest news and keep up with the developer blog.",
+    "TabParentalControl": "Parental Control",
     "OptionHideUser": "Hide this user from login screens",
+    "HeaderAccessSchedule": "Access Schedule",
     "OptionDisableUser": "Disable this user",
+    "HeaderAccessScheduleHelp": "Create an access schedule to limit access to certain hours.",
     "OptionDisableUserHelp": "If disabled the server will not allow any connections from this user. Existing connections will be abruptly terminated.",
+    "ButtonAddSchedule": "Add Schedule",
     "HeaderAdvancedControl": "Advanced Control",
+    "LabelAccessDay": "Day of week:",
     "LabelName": "Name:",
+    "LabelAccessStart": "Start hour:",
     "OptionAllowUserToManageServer": "Allow this user to manage the server",
+    "LabelAccessEnd": "End hour:",
     "HeaderFeatureAccess": "Feature Access",
     "OptionAllowMediaPlayback": "Allow media playback",
     "OptionAllowBrowsingLiveTv": "Allow browsing of live tv",

+ 7 - 0
MediaBrowser.Server.Implementations/Localization/Server/cs.json

@@ -440,12 +440,19 @@
     "VisitMediaBrowserWebsite": "Nav\u0161t\u00edvit str\u00e1nku programu Media Browser",
     "HeaderPendingInvitations": "Pending Invitations",
     "VisitMediaBrowserWebsiteLong": "Nav\u0161tivte str\u00e1nku programu Media Browser pro zji\u0161t\u011bn\u00ed posledn\u00edch novinek a informac\u00ed od v\u00fdvoj\u00e1\u0159\u016f.",
+    "TabParentalControl": "Parental Control",
     "OptionHideUser": "Skr\u00fdt tohoto u\u017eivatele z p\u0159ihla\u0161ovac\u00edch obrazovek",
+    "HeaderAccessSchedule": "Access Schedule",
     "OptionDisableUser": "Zablokovat tohoto u\u017eivatele",
+    "HeaderAccessScheduleHelp": "Create an access schedule to limit access to certain hours.",
     "OptionDisableUserHelp": "Pokud je zablokov\u00e1n, server nepovol\u00ed tomuto u\u017eivateli \u017e\u00e1dn\u00e9 p\u0159ipojen\u00ed. Existuj\u00edc\u00ed p\u0159ipojen\u00ed bude okam\u017eit\u011b p\u0159eru\u0161eno.",
+    "ButtonAddSchedule": "Add Schedule",
     "HeaderAdvancedControl": "Pokro\u010dil\u00e9 nastaven\u00ed",
+    "LabelAccessDay": "Day of week:",
     "LabelName": "Jm\u00e9no:",
+    "LabelAccessStart": "Start hour:",
     "OptionAllowUserToManageServer": "Povolit tomuto u\u017eivateli spr\u00e1vu serveru",
+    "LabelAccessEnd": "End hour:",
     "HeaderFeatureAccess": "P\u0159\u00edstup k funkc\u00edm",
     "OptionAllowMediaPlayback": "Povolit p\u0159ehr\u00e1v\u00e1n\u00ed medi\u00ed",
     "OptionAllowBrowsingLiveTv": "Provolit \u017eiv\u00e9 vys\u00edl\u00e1n\u00ed",

+ 7 - 0
MediaBrowser.Server.Implementations/Localization/Server/da.json

@@ -440,12 +440,19 @@
     "VisitMediaBrowserWebsite": "Bes\u00f8g Media Browsers Webside",
     "HeaderPendingInvitations": "Pending Invitations",
     "VisitMediaBrowserWebsiteLong": "Visit the Media Browser Web site to catch the latest news and keep up with the developer blog.",
+    "TabParentalControl": "Parental Control",
     "OptionHideUser": "Vis ikke denne bruger p\u00e5 logind siden",
+    "HeaderAccessSchedule": "Access Schedule",
     "OptionDisableUser": "Deaktiver denne bruger",
+    "HeaderAccessScheduleHelp": "Create an access schedule to limit access to certain hours.",
     "OptionDisableUserHelp": "Hvis deaktiveret vil serveren ikke tillade forbindelser fra denne bruger. Eksisterende forbindelser vil blive afbrudt.",
+    "ButtonAddSchedule": "Add Schedule",
     "HeaderAdvancedControl": "Avanceret Kontrol",
+    "LabelAccessDay": "Day of week:",
     "LabelName": "Navn:",
+    "LabelAccessStart": "Start hour:",
     "OptionAllowUserToManageServer": "Tillad denne bruger at administrere serveren",
+    "LabelAccessEnd": "End hour:",
     "HeaderFeatureAccess": "Funktion Adgang",
     "OptionAllowMediaPlayback": "Tillad medie afspilning",
     "OptionAllowBrowsingLiveTv": "Tillad gennemsyn af direkte tv",

+ 7 - 0
MediaBrowser.Server.Implementations/Localization/Server/de.json

@@ -440,12 +440,19 @@
     "VisitMediaBrowserWebsite": "Besuche die Media Browser Website",
     "HeaderPendingInvitations": "Pending Invitations",
     "VisitMediaBrowserWebsiteLong": "Besuche die Media Browser Website um die aktuellsten Neuigkeiten zu erfahren und halte dich auf dem Laufenden mit dem Entwicklerblog.",
+    "TabParentalControl": "Parental Control",
     "OptionHideUser": "Verberge diesen Benutzer in den Anmeldebildschirmen",
+    "HeaderAccessSchedule": "Access Schedule",
     "OptionDisableUser": "Sperre diesen Benutzer",
+    "HeaderAccessScheduleHelp": "Create an access schedule to limit access to certain hours.",
     "OptionDisableUserHelp": "Wenn deaktiviert,wird der Server keine Verbindung von diesem Benutzer erlauben. Bestehenden Verbindungen werden sofort beendet.",
+    "ButtonAddSchedule": "Add Schedule",
     "HeaderAdvancedControl": "Erweiterte Kontrolle",
+    "LabelAccessDay": "Day of week:",
     "LabelName": "Name:",
+    "LabelAccessStart": "Start hour:",
     "OptionAllowUserToManageServer": "Dieser Benutzer kann den Server managen",
+    "LabelAccessEnd": "End hour:",
     "HeaderFeatureAccess": "Funktionszugriff",
     "OptionAllowMediaPlayback": "Erlaube das Abspielen von Medien",
     "OptionAllowBrowsingLiveTv": "Erlaube das durchsuchen von Live-TV",

+ 7 - 0
MediaBrowser.Server.Implementations/Localization/Server/el.json

@@ -440,12 +440,19 @@
     "VisitMediaBrowserWebsite": "Visit the Media Browser Web Site",
     "HeaderPendingInvitations": "Pending Invitations",
     "VisitMediaBrowserWebsiteLong": "Visit the Media Browser Web site to catch the latest news and keep up with the developer blog.",
+    "TabParentalControl": "Parental Control",
     "OptionHideUser": "Hide this user from login screens",
+    "HeaderAccessSchedule": "Access Schedule",
     "OptionDisableUser": "Disable this user",
+    "HeaderAccessScheduleHelp": "Create an access schedule to limit access to certain hours.",
     "OptionDisableUserHelp": "If disabled the server will not allow any connections from this user. Existing connections will be abruptly terminated.",
+    "ButtonAddSchedule": "Add Schedule",
     "HeaderAdvancedControl": "Advanced Control",
+    "LabelAccessDay": "Day of week:",
     "LabelName": "Name:",
+    "LabelAccessStart": "Start hour:",
     "OptionAllowUserToManageServer": "Allow this user to manage the server",
+    "LabelAccessEnd": "End hour:",
     "HeaderFeatureAccess": "Feature Access",
     "OptionAllowMediaPlayback": "Allow media playback",
     "OptionAllowBrowsingLiveTv": "Allow browsing of live tv",

+ 7 - 0
MediaBrowser.Server.Implementations/Localization/Server/en_GB.json

@@ -440,12 +440,19 @@
     "VisitMediaBrowserWebsite": "Visit the Media Browser Web Site",
     "HeaderPendingInvitations": "Pending Invitations",
     "VisitMediaBrowserWebsiteLong": "Visit the Media Browser Web site to catch the latest news and keep up with the developer blog.",
+    "TabParentalControl": "Parental Control",
     "OptionHideUser": "Hide this user from login screens",
+    "HeaderAccessSchedule": "Access Schedule",
     "OptionDisableUser": "Disable this user",
+    "HeaderAccessScheduleHelp": "Create an access schedule to limit access to certain hours.",
     "OptionDisableUserHelp": "If disabled the server will not allow any connections from this user. Existing connections will be abruptly terminated.",
+    "ButtonAddSchedule": "Add Schedule",
     "HeaderAdvancedControl": "Advanced Control",
+    "LabelAccessDay": "Day of week:",
     "LabelName": "Name:",
+    "LabelAccessStart": "Start hour:",
     "OptionAllowUserToManageServer": "Allow this user to manage the server",
+    "LabelAccessEnd": "End hour:",
     "HeaderFeatureAccess": "Feature Access",
     "OptionAllowMediaPlayback": "Allow media playback",
     "OptionAllowBrowsingLiveTv": "Allow browsing of live tv",

+ 7 - 0
MediaBrowser.Server.Implementations/Localization/Server/en_US.json

@@ -440,12 +440,19 @@
     "VisitMediaBrowserWebsite": "Visit the Media Browser Web Site",
     "HeaderPendingInvitations": "Pending Invitations",
     "VisitMediaBrowserWebsiteLong": "Visit the Media Browser Web site to catch the latest news and keep up with the developer blog.",
+    "TabParentalControl": "Parental Control",
     "OptionHideUser": "Hide this user from login screens",
+    "HeaderAccessSchedule": "Access Schedule",
     "OptionDisableUser": "Disable this user",
+    "HeaderAccessScheduleHelp": "Create an access schedule to limit access to certain hours.",
     "OptionDisableUserHelp": "If disabled the server will not allow any connections from this user. Existing connections will be abruptly terminated.",
+    "ButtonAddSchedule": "Add Schedule",
     "HeaderAdvancedControl": "Advanced Control",
+    "LabelAccessDay": "Day of week:",
     "LabelName": "Name:",
+    "LabelAccessStart": "Start hour:",
     "OptionAllowUserToManageServer": "Allow this user to manage the server",
+    "LabelAccessEnd": "End hour:",
     "HeaderFeatureAccess": "Feature Access",
     "OptionAllowMediaPlayback": "Allow media playback",
     "OptionAllowBrowsingLiveTv": "Allow browsing of live tv",

+ 7 - 0
MediaBrowser.Server.Implementations/Localization/Server/es.json

@@ -440,12 +440,19 @@
     "VisitMediaBrowserWebsite": "Visitar la web de Media Browser",
     "HeaderPendingInvitations": "Pending Invitations",
     "VisitMediaBrowserWebsiteLong": "Visita la web de Media Browser para estar informado de las \u00faltimas not\u00edcias y mantenerte al d\u00eda con el blog de desarrolladores.",
+    "TabParentalControl": "Parental Control",
     "OptionHideUser": "Ocultar este usuario en las pantallas de inicio de sesi\u00f3n",
+    "HeaderAccessSchedule": "Access Schedule",
     "OptionDisableUser": "Deshabilitar este usuario",
+    "HeaderAccessScheduleHelp": "Create an access schedule to limit access to certain hours.",
     "OptionDisableUserHelp": "Si est\u00e1 deshabilitado, el servidor no aceptar\u00e1 conexiones de este usuario. Si existen conexiones de este usuario, finalizar\u00e1n inmediatamente.",
+    "ButtonAddSchedule": "Add Schedule",
     "HeaderAdvancedControl": "Control avanzado",
+    "LabelAccessDay": "Day of week:",
     "LabelName": "Nombre:",
+    "LabelAccessStart": "Start hour:",
     "OptionAllowUserToManageServer": "Permite a este usuario administrar el servidor",
+    "LabelAccessEnd": "End hour:",
     "HeaderFeatureAccess": "Permisos de acceso",
     "OptionAllowMediaPlayback": "Permitir reproducci\u00f3n de medios",
     "OptionAllowBrowsingLiveTv": "Acceso a TV en vivo",

+ 8 - 1
MediaBrowser.Server.Implementations/Localization/Server/es_MX.json

@@ -440,12 +440,19 @@
     "VisitMediaBrowserWebsite": "Visitar el Sitio Web de Media Browser",
     "HeaderPendingInvitations": "Invitaciones Pendientes",
     "VisitMediaBrowserWebsiteLong": "Visite el Sitio Web de Media Browser para estar conocer las \u00faltimas not\u00edcias y mantenerse al d\u00eda con el blog de los desarrolladores.",
+    "TabParentalControl": "Control Parental",
     "OptionHideUser": "Ocultar este usuario en las pantallas de inicio de sesi\u00f3n",
+    "HeaderAccessSchedule": "Acceder Programaci\u00f3n",
     "OptionDisableUser": "Desactivar este usuario",
+    "HeaderAccessScheduleHelp": "Crear programaci\u00f3n de acceso para limitar el acceso a ciertos horarios.",
     "OptionDisableUserHelp": "Si est\u00e1 desactivado, el servidor no aceptar\u00e1 conexiones de este usuario. Las conexiones existentes ser\u00e1n finalizadas abruptamente.",
+    "ButtonAddSchedule": "Agregar Programaci\u00f3n",
     "HeaderAdvancedControl": "Control Avanzado",
+    "LabelAccessDay": "D\u00eda de la semana:",
     "LabelName": "Nombre:",
+    "LabelAccessStart": "Hora de inicio:",
     "OptionAllowUserToManageServer": "Permitir a este usuario administrar el servidor",
+    "LabelAccessEnd": "Hora de fin:",
     "HeaderFeatureAccess": "Permisos de acceso",
     "OptionAllowMediaPlayback": "Permitir reproducci\u00f3n de medios",
     "OptionAllowBrowsingLiveTv": "Permitir acceder a TV en vivo",
@@ -532,7 +539,7 @@
     "OptionPrePaddingRequired": "Prtecci\u00f3n previa es requerida para grabar.",
     "LabelPostPaddingMinutes": "Minutos de protecci\u00f3n posterior:",
     "OptionPostPaddingRequired": "Protecci\u00f3n posterior es requerida para grabar.",
-    "HeaderWhatsOnTV": "\u00bfQu\u00e9 se V\u00e9?",
+    "HeaderWhatsOnTV": "\u00bfQu\u00e9 hay?",
     "HeaderUpcomingTV": "Pr\u00f3ximos Programas",
     "TabStatus": "Estado",
     "TabSettings": "Configuraci\u00f3n",

+ 7 - 0
MediaBrowser.Server.Implementations/Localization/Server/fr.json

@@ -440,12 +440,19 @@
     "VisitMediaBrowserWebsite": "Visiter le site Web de Media Browser",
     "HeaderPendingInvitations": "Pending Invitations",
     "VisitMediaBrowserWebsiteLong": "Visiter le site Web de Media Browser pour lire les derni\u00e8res nouvelles et parcourir le journal des d\u00e9veloppeurs.",
+    "TabParentalControl": "Parental Control",
     "OptionHideUser": "Ne pas afficher cet utilisateur dans les \u00e9crans de connexion",
+    "HeaderAccessSchedule": "Access Schedule",
     "OptionDisableUser": "D\u00e9sactiver cet utilisateur",
+    "HeaderAccessScheduleHelp": "Create an access schedule to limit access to certain hours.",
     "OptionDisableUserHelp": "Si d\u00e9sactiv\u00e9, le serveur n'autorisera pas de connexion de cet utilisateur. Les connexions existantes seront interrompues.",
+    "ButtonAddSchedule": "Add Schedule",
     "HeaderAdvancedControl": "Contr\u00f4le avanc\u00e9",
+    "LabelAccessDay": "Day of week:",
     "LabelName": "Nom :",
+    "LabelAccessStart": "Start hour:",
     "OptionAllowUserToManageServer": "Autoriser la gestion du serveur \u00e0 cet utilisateur",
+    "LabelAccessEnd": "End hour:",
     "HeaderFeatureAccess": "Acc\u00e8s aux  caract\u00e9ristiques",
     "OptionAllowMediaPlayback": "Autoriser la lecture du m\u00e9dia",
     "OptionAllowBrowsingLiveTv": "Autoriser la TV en direct",

+ 7 - 0
MediaBrowser.Server.Implementations/Localization/Server/he.json

@@ -440,12 +440,19 @@
     "VisitMediaBrowserWebsite": "\u05d1\u05e7\u05e8 \u05d1\u05d0\u05ea\u05e8 \u05e9\u05dc Media Browser",
     "HeaderPendingInvitations": "Pending Invitations",
     "VisitMediaBrowserWebsiteLong": "\u05d1\u05e7\u05e8 \u05d1\u05d0\u05ea\u05e8 \u05e9\u05dc Media Browser \u05db\u05d3\u05d9 \u05dc\u05d4\u05ea\u05e2\u05d3\u05db\u05df \u05d1\u05d7\u05e9\u05d3\u05d5\u05ea \u05d4\u05d0\u05d7\u05e8\u05d5\u05e0\u05d5\u05ea \u05d5\u05d1\u05d1\u05dc\u05d5\u05d2 \u05d4\u05de\u05e4\u05ea\u05d7\u05d9\u05dd.",
+    "TabParentalControl": "Parental Control",
     "OptionHideUser": "\u05d4\u05e1\u05ea\u05e8 \u05de\u05e9\u05ea\u05de\u05e9 \u05d6\u05d4 \u05d1\u05d7\u05dc\u05d5\u05df \u05d4\u05d4\u05ea\u05d7\u05d1\u05e8\u05d5\u05ea",
+    "HeaderAccessSchedule": "Access Schedule",
     "OptionDisableUser": "\u05d1\u05d8\u05dc \u05de\u05e9\u05ea\u05de\u05e9 \u05d6\u05d4",
+    "HeaderAccessScheduleHelp": "Create an access schedule to limit access to certain hours.",
     "OptionDisableUserHelp": "\u05d0\u05dd \u05de\u05d1\u05d5\u05d8\u05dc, \u05d4\u05e9\u05e8\u05ea \u05e9\u05dc\u05d0 \u05d9\u05d0\u05e4\u05e9\u05e8 \u05d7\u05d9\u05d1\u05d5\u05e8\u05d9\u05dd \u05de\u05de\u05e9\u05ea\u05de\u05e9 \u05d6\u05d4. \u05d7\u05d9\u05d1\u05d5\u05e8\u05d9\u05dd \u05e4\u05e2\u05d9\u05dc\u05d9\u05dd \u05d9\u05d1\u05d5\u05d8\u05dc\u05d5 \u05de\u05d9\u05d9\u05d3.",
+    "ButtonAddSchedule": "Add Schedule",
     "HeaderAdvancedControl": "\u05e9\u05dc\u05d9\u05d8\u05d4 \u05de\u05ea\u05e7\u05d3\u05de\u05d5\u05ea",
+    "LabelAccessDay": "Day of week:",
     "LabelName": "\u05e9\u05dd:",
+    "LabelAccessStart": "Start hour:",
     "OptionAllowUserToManageServer": "\u05d0\u05e4\u05e9\u05e8 \u05dc\u05de\u05e9\u05ea\u05de\u05e9 \u05d6\u05d4 \u05dc\u05e0\u05d4\u05dc \u05d0\u05ea \u05d4\u05e9\u05e8\u05ea",
+    "LabelAccessEnd": "End hour:",
     "HeaderFeatureAccess": "\u05d2\u05d9\u05e9\u05d4 \u05dc\u05de\u05d0\u05e4\u05d9\u05d9\u05e0\u05d9\u05dd",
     "OptionAllowMediaPlayback": "\u05d0\u05e4\u05e9\u05e8 \u05e0\u05d9\u05d2\u05d5\u05df \u05de\u05d3\u05d9\u05d4",
     "OptionAllowBrowsingLiveTv": "\u05d0\u05e4\u05e9\u05e8 \u05d3\u05e4\u05d3\u05d5\u05e3 \u05d1\u05d8\u05dc\u05d5\u05d5\u05d9\u05d6\u05d9\u05d4 \u05d7\u05d9\u05d4",

+ 7 - 0
MediaBrowser.Server.Implementations/Localization/Server/hr.json

@@ -440,12 +440,19 @@
     "VisitMediaBrowserWebsite": "Posjeti Media Browser web stranicu",
     "HeaderPendingInvitations": "Pending Invitations",
     "VisitMediaBrowserWebsiteLong": "Posjeti Media Browser web stranicu kako bi vidjeli najnovije vijesti i bili u toku sa programerskim blogom",
+    "TabParentalControl": "Parental Control",
     "OptionHideUser": "Sakrij korisnika sa prozora prijave",
+    "HeaderAccessSchedule": "Access Schedule",
     "OptionDisableUser": "Onemogu\u0107i ovog korisnika",
+    "HeaderAccessScheduleHelp": "Create an access schedule to limit access to certain hours.",
     "OptionDisableUserHelp": "Ako je onemogu\u0107en server ne\u0107e dopustiti nikakve veze od ovog korisnika. Postoje\u0107e veze \u0107e odmah biti prekinute.",
+    "ButtonAddSchedule": "Add Schedule",
     "HeaderAdvancedControl": "Napredna kontrola",
+    "LabelAccessDay": "Day of week:",
     "LabelName": "Ime:",
+    "LabelAccessStart": "Start hour:",
     "OptionAllowUserToManageServer": "Dopusti ovom korisniku da upravlja serverom",
+    "LabelAccessEnd": "End hour:",
     "HeaderFeatureAccess": "Pristup opcijama",
     "OptionAllowMediaPlayback": "Dopusti reprodukciju medijskog sadr\u017eaja",
     "OptionAllowBrowsingLiveTv": "Omogu\u0107i pregled TV programa",

+ 7 - 0
MediaBrowser.Server.Implementations/Localization/Server/it.json

@@ -440,12 +440,19 @@
     "VisitMediaBrowserWebsite": "Visita il sito di Media Browser",
     "HeaderPendingInvitations": "Pending Invitations",
     "VisitMediaBrowserWebsiteLong": "Vuoi saperne di pi\u00f9 sulle ultime novit\u00e0?",
+    "TabParentalControl": "Parental Control",
     "OptionHideUser": "Nascondi questo utente dalla schermata di Accesso",
+    "HeaderAccessSchedule": "Access Schedule",
     "OptionDisableUser": "Disabilita utente",
+    "HeaderAccessScheduleHelp": "Create an access schedule to limit access to certain hours.",
     "OptionDisableUserHelp": "Se disabilitato, il server non sar\u00e0 disponibile per questo utente.La connessione corrente verr\u00e0 TERMINATA",
+    "ButtonAddSchedule": "Add Schedule",
     "HeaderAdvancedControl": "Controlli avanzati",
+    "LabelAccessDay": "Day of week:",
     "LabelName": "Nome:",
+    "LabelAccessStart": "Start hour:",
     "OptionAllowUserToManageServer": "Consenti a questo utente di accedere alla configurazione del SERVER",
+    "LabelAccessEnd": "End hour:",
     "HeaderFeatureAccess": "Caratteristiche di accesso",
     "OptionAllowMediaPlayback": "Consenti la riproduzione",
     "OptionAllowBrowsingLiveTv": "Consenti la navigazione sulla Tv indiretta",

+ 7 - 0
MediaBrowser.Server.Implementations/Localization/Server/kk.json

@@ -440,12 +440,19 @@
     "VisitMediaBrowserWebsite": "Media Browser \u0441\u0430\u0439\u0442\u044b\u043d\u0430 \u0431\u0430\u0440\u0443",
     "HeaderPendingInvitations": "Pending Invitations",
     "VisitMediaBrowserWebsiteLong": "\u0421\u043e\u04a3\u0493\u044b \u0436\u0430\u04a3\u0430\u043b\u044b\u049b\u0442\u0430\u0440\u0434\u044b \u0431\u0456\u043b\u0456\u043f \u0430\u043b\u0443 \u04af\u0448\u0456\u043d \u0436\u04d9\u043d\u0435 \u0436\u0430\u0441\u0430\u049b\u0442\u0430\u0443\u0448\u044b\u043b\u0430\u0440 \u0431\u043b\u043e\u0433\u0456\u043c\u0435\u043d \u0442\u0430\u043d\u044b\u0441\u044b\u043f \u0442\u04b1\u0440\u0443 \u04af\u0448\u0456\u043d Media Browser \u0441\u0430\u0439\u0442\u044b\u043d\u0430 \u0431\u0430\u0440\u044b\u04a3\u044b\u0437.",
+    "TabParentalControl": "Parental Control",
     "OptionHideUser": "\u0411\u04b1\u043b \u043f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u0443\u0448\u044b\u043d\u044b \u043a\u0456\u0440\u0443 \u044d\u043a\u0440\u0430\u043d\u0434\u0430\u0440\u044b\u043d\u0430\u043d \u0436\u0430\u0441\u044b\u0440\u0443",
+    "HeaderAccessSchedule": "Access Schedule",
     "OptionDisableUser": "\u0411\u04b1\u043b \u043f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u0443\u0448\u044b\u0493\u0430 \u0442\u044b\u0439\u044b\u043c \u0441\u0430\u043b\u0443",
+    "HeaderAccessScheduleHelp": "Create an access schedule to limit access to certain hours.",
     "OptionDisableUserHelp": "\u0415\u0433\u0435\u0440 \u0442\u044b\u0439\u044b\u043c \u0441\u0430\u043b\u044b\u043d\u0441\u0430, \u0441\u0435\u0440\u0432\u0435\u0440 \u0431\u04b1\u043b \u043f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u0443\u0448\u044b\u0434\u0430\u043d \u0435\u0448\u049b\u0430\u043d\u0434\u0430\u0439 \u049b\u043e\u0441\u044b\u043b\u044b\u043c\u0493\u0430 \u0440\u04b1\u049b\u0441\u0430\u0442 \u0435\u0442\u043f\u0435\u0439\u0434\u0456. \u0411\u0430\u0440 \u049b\u043e\u0441\u044b\u043b\u044b\u043c\u0434\u0430\u0440 \u043a\u0435\u043d\u0435\u0442 \u04af\u0437\u0456\u043b\u0435\u0434\u0456.",
+    "ButtonAddSchedule": "Add Schedule",
     "HeaderAdvancedControl": "\u041a\u0435\u04a3\u0435\u0439\u0442\u0456\u043b\u0433\u0435\u043d \u0431\u0430\u0441\u049b\u0430\u0440\u0443",
+    "LabelAccessDay": "Day of week:",
     "LabelName": "\u0410\u0442\u044b:",
+    "LabelAccessStart": "Start hour:",
     "OptionAllowUserToManageServer": "\u0411\u0443\u043b \u043f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u0443\u0448\u044b\u0493\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0434\u0456 \u0431\u0430\u0441\u049b\u0430\u0440\u0443 \u04af\u0448\u0456\u043d \u0440\u04b1\u049b\u0441\u0430\u0442 \u0435\u0442\u0443",
+    "LabelAccessEnd": "End hour:",
     "HeaderFeatureAccess": "\u041c\u04af\u043c\u043a\u0456\u043d\u0434\u0456\u043a\u0442\u0435\u0440\u0433\u0435 \u049b\u0430\u0442\u044b\u043d\u0430\u0441",
     "OptionAllowMediaPlayback": "\u0422\u0430\u0441\u0443\u0448\u044b\u0434\u0435\u0440\u0435\u043a\u0442\u0435\u0440\u0434\u0456 \u043e\u0439\u043d\u0430\u0442\u0443\u044b\u043d\u0430 \u0440\u04b1\u049b\u0441\u0430\u0442 \u0435\u0442\u0443",
     "OptionAllowBrowsingLiveTv": "\u042d\u0444\u0438\u0440\u043b\u0456\u043a \u0422\u0414 \u0448\u043e\u043b\u0443\u044b\u043d\u0430 \u0440\u04b1\u049b\u0441\u0430\u0442 \u0435\u0442\u0443",

+ 7 - 0
MediaBrowser.Server.Implementations/Localization/Server/ko.json

@@ -440,12 +440,19 @@
     "VisitMediaBrowserWebsite": "Visit the Media Browser Web Site",
     "HeaderPendingInvitations": "Pending Invitations",
     "VisitMediaBrowserWebsiteLong": "Visit the Media Browser Web site to catch the latest news and keep up with the developer blog.",
+    "TabParentalControl": "Parental Control",
     "OptionHideUser": "Hide this user from login screens",
+    "HeaderAccessSchedule": "Access Schedule",
     "OptionDisableUser": "Disable this user",
+    "HeaderAccessScheduleHelp": "Create an access schedule to limit access to certain hours.",
     "OptionDisableUserHelp": "If disabled the server will not allow any connections from this user. Existing connections will be abruptly terminated.",
+    "ButtonAddSchedule": "Add Schedule",
     "HeaderAdvancedControl": "Advanced Control",
+    "LabelAccessDay": "Day of week:",
     "LabelName": "Name:",
+    "LabelAccessStart": "Start hour:",
     "OptionAllowUserToManageServer": "Allow this user to manage the server",
+    "LabelAccessEnd": "End hour:",
     "HeaderFeatureAccess": "Feature Access",
     "OptionAllowMediaPlayback": "Allow media playback",
     "OptionAllowBrowsingLiveTv": "Allow browsing of live tv",

+ 7 - 0
MediaBrowser.Server.Implementations/Localization/Server/ms.json

@@ -440,12 +440,19 @@
     "VisitMediaBrowserWebsite": "Visit the Media Browser Web Site",
     "HeaderPendingInvitations": "Pending Invitations",
     "VisitMediaBrowserWebsiteLong": "Visit the Media Browser Web site to catch the latest news and keep up with the developer blog.",
+    "TabParentalControl": "Parental Control",
     "OptionHideUser": "Hide this user from login screens",
+    "HeaderAccessSchedule": "Access Schedule",
     "OptionDisableUser": "Disable this user",
+    "HeaderAccessScheduleHelp": "Create an access schedule to limit access to certain hours.",
     "OptionDisableUserHelp": "If disabled the server will not allow any connections from this user. Existing connections will be abruptly terminated.",
+    "ButtonAddSchedule": "Add Schedule",
     "HeaderAdvancedControl": "Advanced Control",
+    "LabelAccessDay": "Day of week:",
     "LabelName": "Name:",
+    "LabelAccessStart": "Start hour:",
     "OptionAllowUserToManageServer": "Allow this user to manage the server",
+    "LabelAccessEnd": "End hour:",
     "HeaderFeatureAccess": "Feature Access",
     "OptionAllowMediaPlayback": "Allow media playback",
     "OptionAllowBrowsingLiveTv": "Allow browsing of live tv",

+ 7 - 0
MediaBrowser.Server.Implementations/Localization/Server/nb.json

@@ -440,12 +440,19 @@
     "VisitMediaBrowserWebsite": "Bes\u00f8k Media Browsers nettside",
     "HeaderPendingInvitations": "Pending Invitations",
     "VisitMediaBrowserWebsiteLong": "Bes\u00f8k Media Browser sin side for \u00e5 f\u00e5 de siste nyhetene og for \u00e5 f\u00f8lge med p\u00e5 utviklerbloggen.",
+    "TabParentalControl": "Parental Control",
     "OptionHideUser": "Skjul brukere fra logginn-skjermen",
+    "HeaderAccessSchedule": "Access Schedule",
     "OptionDisableUser": "Deaktiver denne brukeren",
+    "HeaderAccessScheduleHelp": "Create an access schedule to limit access to certain hours.",
     "OptionDisableUserHelp": "Hvis avsl\u00e5tt, serveren vil ikke godta noen forbindelser fra denne brukeren. eksisterende forbindelser vil bli br\u00e5tt avsluttet.",
+    "ButtonAddSchedule": "Add Schedule",
     "HeaderAdvancedControl": "Avansert Kontroll",
+    "LabelAccessDay": "Day of week:",
     "LabelName": "Navn",
+    "LabelAccessStart": "Start hour:",
     "OptionAllowUserToManageServer": "TIllatt denne brukeren \u00e5 administrere serveren",
+    "LabelAccessEnd": "End hour:",
     "HeaderFeatureAccess": "Funksjon Tilgang",
     "OptionAllowMediaPlayback": "Tillatt medieavspilling",
     "OptionAllowBrowsingLiveTv": "Tillat surfing av Live TV",

+ 19 - 12
MediaBrowser.Server.Implementations/Localization/Server/nl.json

@@ -394,21 +394,21 @@
     "OptionSunday": "Zondag",
     "HeaderWelcomeToMediaBrowserServerDashboard": "Welkom bij de Media Browser Dashboard",
     "OptionMonday": "Maandag",
-    "LabelDateAddedBehavior": "Date added behavior for new content:",
+    "LabelDateAddedBehavior": "Datum toegevoegd gedrag voor nieuwe content:",
     "OptionTuesday": "Dinsdag",
-    "OptionDateAddedImportTime": "Use date scanned into the library",
+    "OptionDateAddedImportTime": "Gebruik scan datum",
     "OptionWednesday": "Woensdag",
-    "OptionDateAddedFileTime": "Use file creation date",
+    "OptionDateAddedFileTime": "Gebruik aanmaak datum bestand",
     "OptionThursday": "Donderdag",
-    "LabelDateAddedBehaviorHelp": "If a metadata value is present it will always be used before either of these options.",
+    "LabelDateAddedBehaviorHelp": "Als er metadata gegevens zijn hebben deze voorrang op deze opties.",
     "OptionFriday": "Vrijdag",
-    "LabelNumberTrailerToPlay": "Number of trailers to play:",
+    "LabelNumberTrailerToPlay": "Aantal af te spelen trailers:",
     "OptionSaturday": "Zaterdag",
     "TitleDevices": "Devices",
     "HeaderManagement": "Beheer",
     "TabCameraUpload": "Camera Upload",
     "LabelManagement": "Management:",
-    "TabDevices": "Devices",
+    "TabDevices": "Apparaten",
     "OptionMissingImdbId": "IMDb Id ontbreekt",
     "HeaderCameraUploadHelp": "Automatically upload photos and videos taken from your mobile devices into Media Browser.",
     "OptionMissingTvdbId": "TheTVDB Id ontbreekt",
@@ -440,12 +440,19 @@
     "VisitMediaBrowserWebsite": "Bezoek de Media Browser Website",
     "HeaderPendingInvitations": "Pending Invitations",
     "VisitMediaBrowserWebsiteLong": "Bezoek de Media Browser-website voor het laatste nieuws en blijf op de hoogte via de ontwikkelaars blog.",
+    "TabParentalControl": "Parental Control",
     "OptionHideUser": "Verberg deze gebruiker op de aanmeldschermen",
+    "HeaderAccessSchedule": "Access Schedule",
     "OptionDisableUser": "Deze account uitschakelen",
+    "HeaderAccessScheduleHelp": "Create an access schedule to limit access to certain hours.",
     "OptionDisableUserHelp": "Indien uitgeschakeld zal de server geen verbindingen van deze gebruiker toe staan. Bestaande verbindingen zullen abrupt worden be\u00ebindigd.",
+    "ButtonAddSchedule": "Add Schedule",
     "HeaderAdvancedControl": "Geavanceerd Beheer",
+    "LabelAccessDay": "Day of week:",
     "LabelName": "Naam:",
+    "LabelAccessStart": "Start hour:",
     "OptionAllowUserToManageServer": "Deze gebruiker kan de server te beheren",
+    "LabelAccessEnd": "End hour:",
     "HeaderFeatureAccess": "Functie toegang",
     "OptionAllowMediaPlayback": "Afspelen van media toestaan",
     "OptionAllowBrowsingLiveTv": "Bladeren door live tv toestaan",
@@ -682,13 +689,13 @@
     "NewCollectionNameExample": "Voorbeeld: Star Wars Collectie",
     "OptionSearchForInternetMetadata": "Zoeken op het internet voor afbeeldingen en metadata",
     "ButtonCreate": "Cre\u00ebren",
-    "LabelLocalHttpServerPortNumber": "Local port number:",
-    "LabelLocalHttpServerPortNumberHelp": "The tcp port number that Media Browser's http server should bind to.",
-    "LabelPublicPort": "Public port number:",
-    "LabelPublicPortHelp": "The public port number that should be mapped to the local port.",
+    "LabelLocalHttpServerPortNumber": "Lokaal poort nummer:",
+    "LabelLocalHttpServerPortNumberHelp": "De TCP poort waarop de Media Browser Server beschikbaar is.",
+    "LabelPublicPort": "Publieke poort nummer:",
+    "LabelPublicPortHelp": "Het poortnummer op het internet waarop Media Browser beschikbaar is.",
     "LabelWebSocketPortNumber": "Web socket poortnummer:",
-    "LabelEnableAutomaticPortMap": "Enable automatic port mapping",
-    "LabelEnableAutomaticPortMapHelp": "Attempt to automatically map the public port to the local port via UPnP. This may not work with some router models.",
+    "LabelEnableAutomaticPortMap": "Schakel automatisch poort vertalen in",
+    "LabelEnableAutomaticPortMapHelp": "Probeer om de publieke poort automatisch te vertalen naar de lokale poort via UPnP. Dit werk niet op alle routers.",
     "LabelExternalDDNS": "Externe DDNS:",
     "LabelExternalDDNSHelp": "Als u een dynamische DNS heeft kun u die hier invoeren. Media Browser apps zullen het gebruiken om op afstand verbinding te maken.",
     "TabResume": "Hervatten",

+ 7 - 0
MediaBrowser.Server.Implementations/Localization/Server/pl.json

@@ -440,12 +440,19 @@
     "VisitMediaBrowserWebsite": "Odwied\u017a stron\u0119 Media Browser",
     "HeaderPendingInvitations": "Pending Invitations",
     "VisitMediaBrowserWebsiteLong": "Visit the Media Browser Web site to catch the latest news and keep up with the developer blog.",
+    "TabParentalControl": "Parental Control",
     "OptionHideUser": "Hide this user from login screens",
+    "HeaderAccessSchedule": "Access Schedule",
     "OptionDisableUser": "Disable this user",
+    "HeaderAccessScheduleHelp": "Create an access schedule to limit access to certain hours.",
     "OptionDisableUserHelp": "If disabled the server will not allow any connections from this user. Existing connections will be abruptly terminated.",
+    "ButtonAddSchedule": "Add Schedule",
     "HeaderAdvancedControl": "Advanced Control",
+    "LabelAccessDay": "Day of week:",
     "LabelName": "Name:",
+    "LabelAccessStart": "Start hour:",
     "OptionAllowUserToManageServer": "Allow this user to manage the server",
+    "LabelAccessEnd": "End hour:",
     "HeaderFeatureAccess": "Feature Access",
     "OptionAllowMediaPlayback": "Allow media playback",
     "OptionAllowBrowsingLiveTv": "Allow browsing of live tv",

+ 38 - 31
MediaBrowser.Server.Implementations/Localization/Server/pt_BR.json

@@ -70,7 +70,7 @@
     "ButtonOk": "Ok",
     "LabelChannelDownloadSizeLimit": "Limite do tamanho para download (GB):",
     "ButtonCancel": "Cancelar",
-    "LabelChannelDownloadSizeLimitHelpText": "Limit the size of the channel download folder.",
+    "LabelChannelDownloadSizeLimitHelpText": "Limitar o tamanho da pasta de download do canal.",
     "HeaderRecentActivity": "Atividade Recente",
     "ButtonNew": "Novo",
     "HeaderPeople": "Pessoas",
@@ -152,7 +152,7 @@
     "LabelWebsite": "Website:",
     "ButtonAddLocalUser": "Adicionar Usu\u00e1rio Local",
     "LabelTagline": "Slogan:",
-    "ButtonInviteUser": "Invite User",
+    "ButtonInviteUser": "Convidar Usu\u00e1rio",
     "ButtonSave": "Salvar",
     "LabelOverview": "Sinopse:",
     "ButtonResetPassword": "Redefinir Senha",
@@ -394,58 +394,65 @@
     "OptionSunday": "Domingo",
     "HeaderWelcomeToMediaBrowserServerDashboard": "Bem Vindo ao Painel do Media Browser",
     "OptionMonday": "Segunda-feira",
-    "LabelDateAddedBehavior": "Date added behavior for new content:",
+    "LabelDateAddedBehavior": "Data de adi\u00e7\u00e3o de comportamento para o novo conte\u00fado:",
     "OptionTuesday": "Ter\u00e7a-feira",
-    "OptionDateAddedImportTime": "Use date scanned into the library",
+    "OptionDateAddedImportTime": "Use a data obtida na biblioteca",
     "OptionWednesday": "Quarta-feira",
-    "OptionDateAddedFileTime": "Use file creation date",
+    "OptionDateAddedFileTime": "Use a data de cria\u00e7\u00e3o do arquivo",
     "OptionThursday": "Quinta-feira",
-    "LabelDateAddedBehaviorHelp": "If a metadata value is present it will always be used before either of these options.",
+    "LabelDateAddedBehaviorHelp": "Se um valor de metadata estiver presente, ele sempre ser\u00e1 utilizado antes destas op\u00e7\u00f5es.",
     "OptionFriday": "Sexta-feira",
-    "LabelNumberTrailerToPlay": "Number of trailers to play:",
+    "LabelNumberTrailerToPlay": "N\u00famero de trailers a serem apresentados:",
     "OptionSaturday": "S\u00e1bado",
-    "TitleDevices": "Devices",
+    "TitleDevices": "Dispositivos",
     "HeaderManagement": "Gerenciamento",
-    "TabCameraUpload": "Camera Upload",
+    "TabCameraUpload": "Carga atrav\u00e9s de c\u00e2mera",
     "LabelManagement": "Administra\u00e7\u00e3o:",
-    "TabDevices": "Devices",
+    "TabDevices": "Dispositivos",
     "OptionMissingImdbId": "Faltando Id IMDb",
-    "HeaderCameraUploadHelp": "Automatically upload photos and videos taken from your mobile devices into Media Browser.",
+    "HeaderCameraUploadHelp": "Carga autom\u00e1tica de fotos e v\u00eddeos de seus dispositivos m\u00f3veis para o Media Browser.",
     "OptionMissingTvdbId": "Faltando Id TheTVDB",
-    "MessageNoDevicesSupportCameraUpload": "You currently don't have any devices that support camera upload.",
+    "MessageNoDevicesSupportCameraUpload": "Atualmente voc\u00ea n\u00e3o tem nenhum dispositivo que suporte carga atrav\u00e9s da c\u00e2mera.",
     "OptionMissingOverview": "Faltando Sinopse",
-    "LabelCameraUploadPath": "Camera upload path:",
+    "LabelCameraUploadPath": "Caminho para carga atrav\u00e9s da c\u00e2mera:",
     "OptionFileMetadataYearMismatch": "Anos do Arquivo e Metadados n\u00e3o conferem",
-    "LabelCameraUploadPathHelp": "Select a custom upload path, if desired. If unspecified a default folder will be used.",
+    "LabelCameraUploadPathHelp": "Selecione o caminho, caso desejado. Se n\u00e3o for especificado um caminho, ser\u00e1 usada uma pasta padr\u00e3o.",
     "TabGeneral": "Geral",
-    "LabelCreateCameraUploadSubfolder": "Create a subfolder for each device",
+    "LabelCreateCameraUploadSubfolder": "Criar uma subpasta para cada dispositivo",
     "TitleSupport": "Suporte",
-    "LabelCreateCameraUploadSubfolderHelp": "Specific folders can be assigned to a device by clicking on it from the Devices page.",
+    "LabelCreateCameraUploadSubfolderHelp": "Pastas espec\u00edficas podem ser atribu\u00eddas a um dispositivo clicando-as na p\u00e1gina de Dispositivos.",
     "TabLog": "Log",
-    "LabelCustomDeviceDisplayName": "Display name:",
+    "LabelCustomDeviceDisplayName": "Nome para exibi\u00e7\u00e3o:",
     "TabAbout": "Sobre",
-    "LabelCustomDeviceDisplayNameHelp": "Supply a custom display name or leave empty to use the name reported by the device.",
+    "LabelCustomDeviceDisplayNameHelp": "Forne\u00e7a um nome para exibi\u00e7\u00e3o ou deixe vazio para usar o nome informado pelo dispositivo.",
     "TabSupporterKey": "Chave de Colaborador",
-    "HeaderInviteUser": "Invite User",
+    "HeaderInviteUser": "Convidar usu\u00e1rio",
     "TabBecomeSupporter": "Torne-se um Colaborador",
-    "LabelConnectInviteUserHelp": "This is the username or email that your friend uses to sign in to the Media Browser website.",
+    "LabelConnectInviteUserHelp": "Este \u00e9 o nome do usu\u00e1rio ou email que seu amigo usa para o website do Media Browser",
     "MediaBrowserHasCommunity": "Media Browser tem uma comunidade que cresce em usu\u00e1rios e colaboradores.",
-    "HeaderInviteUserHelp": "Sharing your media with friends is easier than ever before with Media Browser Connect.",
+    "HeaderInviteUserHelp": "Compartilhar suas m\u00eddias com seus amigos \u00e9 muito mais facil com o Media Browser Connect",
     "CheckoutKnowledgeBase": "Verifique nossa base de conhecimento para ajud\u00e1-lo a obter o m\u00e1ximo do Media Browser.",
-    "ButtonSendInvitation": "Send Invitation",
+    "ButtonSendInvitation": "Enviar convite",
     "SearchKnowledgeBase": "Pesquisar na Base de Conhecimento",
-    "HeaderGuests": "Guests",
+    "HeaderGuests": "Convidados",
     "VisitTheCommunity": "Visitar a Comunidade",
-    "HeaderLocalUsers": "Local Users",
+    "HeaderLocalUsers": "Usu\u00e1rios Locais",
     "VisitMediaBrowserWebsite": "Visitar o Web Site do Media Browser",
-    "HeaderPendingInvitations": "Pending Invitations",
+    "HeaderPendingInvitations": "Convites pendentes",
     "VisitMediaBrowserWebsiteLong": "Visite o Web Site do Media Browser para obter as \u00faltimas novidades e atualizar-se com o blog de desenvolvedores.",
+    "TabParentalControl": "Parental Control",
     "OptionHideUser": "Ocultar este usu\u00e1rio das telas de login",
+    "HeaderAccessSchedule": "Access Schedule",
     "OptionDisableUser": "Desativar este usu\u00e1rio",
+    "HeaderAccessScheduleHelp": "Create an access schedule to limit access to certain hours.",
     "OptionDisableUserHelp": "Se estiver desativado o servidor n\u00e3o permitir\u00e1 nenhuma conex\u00e3o deste usu\u00e1rio. Conex\u00f5es existentes ser\u00e3o abruptamente terminadas.",
+    "ButtonAddSchedule": "Add Schedule",
     "HeaderAdvancedControl": "Controle Avan\u00e7ado",
+    "LabelAccessDay": "Day of week:",
     "LabelName": "Nome:",
+    "LabelAccessStart": "Start hour:",
     "OptionAllowUserToManageServer": "Permitir a este usu\u00e1rio administrar o servidor",
+    "LabelAccessEnd": "End hour:",
     "HeaderFeatureAccess": "Acesso aos Recursos",
     "OptionAllowMediaPlayback": "Permitir reprodu\u00e7\u00e3o de m\u00eddia",
     "OptionAllowBrowsingLiveTv": "Permitir navega\u00e7\u00e3o na tv ao vivo",
@@ -682,13 +689,13 @@
     "NewCollectionNameExample": "Exemplo: Cole\u00e7\u00e3o Star Wars",
     "OptionSearchForInternetMetadata": "Buscar artwork e metadados na internet",
     "ButtonCreate": "Criar",
-    "LabelLocalHttpServerPortNumber": "Local port number:",
-    "LabelLocalHttpServerPortNumberHelp": "The tcp port number that Media Browser's http server should bind to.",
-    "LabelPublicPort": "Public port number:",
-    "LabelPublicPortHelp": "The public port number that should be mapped to the local port.",
+    "LabelLocalHttpServerPortNumber": "N\u00famero da porta local:",
+    "LabelLocalHttpServerPortNumberHelp": "O n\u00famero da porta tcp que o servidor http do Media Browser utilizar\u00e1.",
+    "LabelPublicPort": "N\u00famero da porta p\u00fablica:",
+    "LabelPublicPortHelp": "O n\u00famero da porta p\u00fablica que deve ser mapeado para a porta local.",
     "LabelWebSocketPortNumber": "N\u00famero da porta do web socket:",
-    "LabelEnableAutomaticPortMap": "Enable automatic port mapping",
-    "LabelEnableAutomaticPortMapHelp": "Attempt to automatically map the public port to the local port via UPnP. This may not work with some router models.",
+    "LabelEnableAutomaticPortMap": "Habilitar mapeamento autom\u00e1tico de portas",
+    "LabelEnableAutomaticPortMapHelp": "Tentativa de mapear automaticamente a porta p\u00fablica para a local atrav\u00e9s de uPnP. Isto poder\u00e1 n\u00e3o funcionar em alguns modelos de roteadores.",
     "LabelExternalDDNS": "DDNS Externo:",
     "LabelExternalDDNSHelp": "Se voc\u00ea tem um DNS din\u00e2mico digite aqui. O Media Browser o usar\u00e1 quando conectar remotamente.",
     "TabResume": "Retomar",

+ 7 - 0
MediaBrowser.Server.Implementations/Localization/Server/pt_PT.json

@@ -440,12 +440,19 @@
     "VisitMediaBrowserWebsite": "Visite a p\u00e1gina web do Media Browser",
     "HeaderPendingInvitations": "Pending Invitations",
     "VisitMediaBrowserWebsiteLong": "Visite a p\u00e1gina do Media Browser para ficar a par das \u00faltimas novidades e para acompanhar o blog do programador.",
+    "TabParentalControl": "Parental Control",
     "OptionHideUser": "Ocultar este utilizador dos formul\u00e1rios de in\u00edcio de sess\u00e3o",
+    "HeaderAccessSchedule": "Access Schedule",
     "OptionDisableUser": "Desativar este utilizador",
+    "HeaderAccessScheduleHelp": "Create an access schedule to limit access to certain hours.",
     "OptionDisableUserHelp": "Se desativado, o servidor n\u00e3o permite nenhuma conex\u00e3o deste utilizador. Conex\u00f5es existentes ser\u00e3o terminadas.",
+    "ButtonAddSchedule": "Add Schedule",
     "HeaderAdvancedControl": "Controlo Avan\u00e7ado",
+    "LabelAccessDay": "Day of week:",
     "LabelName": "Nome:",
+    "LabelAccessStart": "Start hour:",
     "OptionAllowUserToManageServer": "Permitir a este utilizador gerir o servidor",
+    "LabelAccessEnd": "End hour:",
     "HeaderFeatureAccess": "Acesso a Caracter\u00edsticas",
     "OptionAllowMediaPlayback": "Permitir reprodu\u00e7\u00e3o de multim\u00e9dia",
     "OptionAllowBrowsingLiveTv": "Permitir navega\u00e7\u00e3o da tv ao vivo",

+ 7 - 0
MediaBrowser.Server.Implementations/Localization/Server/ru.json

@@ -440,12 +440,19 @@
     "VisitMediaBrowserWebsite": "\u041f\u043e\u0441\u0435\u0442\u0438\u0442\u044c \u0441\u0430\u0439\u0442 Media Browser",
     "HeaderPendingInvitations": "Pending Invitations",
     "VisitMediaBrowserWebsiteLong": "\u041f\u043e\u0441\u0435\u0442\u0438\u0442\u0435 \u0441\u0430\u0439\u0442 Media Browser, \u0447\u0442\u043e\u0431\u044b \u0441\u043b\u0435\u0434\u0438\u0442\u044c \u0437\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u043c\u0438 \u043d\u043e\u0432\u043e\u0441\u0442\u044f\u043c\u0438 \u0438 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c \u043e\u0441\u0432\u0435\u0434\u043e\u043c\u043b\u0451\u043d\u043d\u043e\u0441\u0442\u044c \u043f\u043e \u0431\u043b\u043e\u0433\u0443 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432.",
+    "TabParentalControl": "Parental Control",
     "OptionHideUser": "\u0421\u043a\u0440\u044b\u0442\u044c \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0441 \u044d\u043a\u0440\u0430\u043d\u043e\u0432 \u0432\u0445\u043e\u0434\u0430",
+    "HeaderAccessSchedule": "Access Schedule",
     "OptionDisableUser": "\u0417\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f",
+    "HeaderAccessScheduleHelp": "Create an access schedule to limit access to certain hours.",
     "OptionDisableUserHelp": "\u041f\u0440\u0438 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438, \u0441\u0435\u0440\u0432\u0435\u0440 \u043d\u0435 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0438\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0434\u043b\u044f \u043b\u044e\u0431\u044b\u0445 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439 \u043e\u0442 \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f. \u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0431\u0443\u0434\u0443\u0442 \u0440\u0435\u0437\u043a\u043e \u043e\u0431\u043e\u0440\u0432\u0430\u043d\u044b.",
+    "ButtonAddSchedule": "Add Schedule",
     "HeaderAdvancedControl": "\u0420\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u043d\u043e\u0435 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435",
+    "LabelAccessDay": "Day of week:",
     "LabelName": "\u0418\u043c\u044f (\u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435):",
+    "LabelAccessStart": "Start hour:",
     "OptionAllowUserToManageServer": "\u042d\u0442\u043e\u043c\u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0434\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u043c",
+    "LabelAccessEnd": "End hour:",
     "HeaderFeatureAccess": "\u0414\u043e\u0441\u0442\u0443\u043f \u043a \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438",
     "OptionAllowMediaPlayback": "\u0420\u0430\u0437\u0440\u0435\u0448\u0438\u0442\u044c \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u043c\u0435\u0434\u0438\u0430\u0434\u0430\u043d\u043d\u044b\u0445",
     "OptionAllowBrowsingLiveTv": "\u0420\u0430\u0437\u0440\u0435\u0448\u0438\u0442\u044c \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440 \u044d\u0444\u0438\u0440\u043d\u043e\u0433\u043e \u0442\u0432",

+ 5 - 2
MediaBrowser.Server.Implementations/Localization/Server/server.json

@@ -830,7 +830,7 @@
     "HeaderWelcomeToMediaBrowserWebClient": "Welcome to the Media Browser Web Client",
     "ButtonDismiss": "Dismiss",
     "ButtonTakeTheTour": "Take the tour",
-    "ButtonEditOtherUserPreferences": "Edit this user's personal preferences.",
+    "ButtonEditOtherUserPreferences": "Edit this user's profile and personal preferences.",
     "LabelChannelStreamQuality": "Preferred internet stream quality:",
     "LabelChannelStreamQualityHelp": "In a low bandwidth environment, limiting quality can help ensure a smooth streaming experience.",
     "OptionBestAvailableStreamQuality": "Best available",
@@ -1242,5 +1242,8 @@
     "LabelAccessDay": "Day of week:",
     "LabelAccessStart": "Start time:",
     "LabelAccessEnd": "End time:",
-    "HeaderSchedule": "Schedule"
+    "HeaderSchedule": "Schedule",
+    "OptionEveryday": "Every day",
+    "OptionWeekdays": "Weekdays",
+    "OptionWeekends": "Weekends"
 }

+ 7 - 0
MediaBrowser.Server.Implementations/Localization/Server/sv.json

@@ -440,12 +440,19 @@
     "VisitMediaBrowserWebsite": "G\u00e5 till Media Browsers hemsida",
     "HeaderPendingInvitations": "Pending Invitations",
     "VisitMediaBrowserWebsiteLong": "G\u00e5 till Media Browsers hemsida och l\u00e4s de senaste nyheterna och utvecklarbloggen",
+    "TabParentalControl": "Parental Control",
     "OptionHideUser": "Visa inte den h\u00e4r anv\u00e4ndaren p\u00e5 inloggningssidorna",
+    "HeaderAccessSchedule": "Access Schedule",
     "OptionDisableUser": "Sp\u00e4rra den h\u00e4r anv\u00e4ndaren",
+    "HeaderAccessScheduleHelp": "Create an access schedule to limit access to certain hours.",
     "OptionDisableUserHelp": "Sp\u00e4rrade anv\u00e4ndare till\u00e5ts ej kontakta servern. Eventuella p\u00e5g\u00e5ende anslutningar avbryts omedelbart.",
+    "ButtonAddSchedule": "Add Schedule",
     "HeaderAdvancedControl": "Avancerade anv\u00e4ndarinst\u00e4llningar",
+    "LabelAccessDay": "Day of week:",
     "LabelName": "Namn:",
+    "LabelAccessStart": "Start hour:",
     "OptionAllowUserToManageServer": "Till\u00e5t denna anv\u00e4ndare att administrera servern",
+    "LabelAccessEnd": "End hour:",
     "HeaderFeatureAccess": "Tillg\u00e5ng till funktioner",
     "OptionAllowMediaPlayback": "Till\u00e5t mediauppspelning",
     "OptionAllowBrowsingLiveTv": "Till\u00e5t bl\u00e4ddring i live-TV",

+ 7 - 0
MediaBrowser.Server.Implementations/Localization/Server/tr.json

@@ -440,12 +440,19 @@
     "VisitMediaBrowserWebsite": "Visit the Media Browser Web Site",
     "HeaderPendingInvitations": "Pending Invitations",
     "VisitMediaBrowserWebsiteLong": "Visit the Media Browser Web site to catch the latest news and keep up with the developer blog.",
+    "TabParentalControl": "Parental Control",
     "OptionHideUser": "Hide this user from login screens",
+    "HeaderAccessSchedule": "Access Schedule",
     "OptionDisableUser": "Kullan\u0131c\u0131 Devre D\u0131\u015f\u0131 B\u0131rak",
+    "HeaderAccessScheduleHelp": "Create an access schedule to limit access to certain hours.",
     "OptionDisableUserHelp": "If disabled the server will not allow any connections from this user. Existing connections will be abruptly terminated.",
+    "ButtonAddSchedule": "Add Schedule",
     "HeaderAdvancedControl": "Geli\u015fmi\u015f Kontrol",
+    "LabelAccessDay": "Day of week:",
     "LabelName": "\u0130sim",
+    "LabelAccessStart": "Start hour:",
     "OptionAllowUserToManageServer": "Allow this user to manage the server",
+    "LabelAccessEnd": "End hour:",
     "HeaderFeatureAccess": "Feature Access",
     "OptionAllowMediaPlayback": "Allow media playback",
     "OptionAllowBrowsingLiveTv": "Allow browsing of live tv",

+ 7 - 0
MediaBrowser.Server.Implementations/Localization/Server/vi.json

@@ -440,12 +440,19 @@
     "VisitMediaBrowserWebsite": "Gh\u00e9 th\u0103m web site Media Browser",
     "HeaderPendingInvitations": "Pending Invitations",
     "VisitMediaBrowserWebsiteLong": "Visit the Media Browser Web site to catch the latest news and keep up with the developer blog.",
+    "TabParentalControl": "Parental Control",
     "OptionHideUser": "\u1ea8n ng\u01b0\u1eddi d\u00f9ng n\u00e0y t\u1eeb m\u00e0n h\u00ecnh \u0111\u0103ng nh\u1eadp",
+    "HeaderAccessSchedule": "Access Schedule",
     "OptionDisableUser": "V\u00f4 hi\u1ec7u h\u00f3a ng\u01b0\u1eddi d\u00f9ng n\u00e0y",
+    "HeaderAccessScheduleHelp": "Create an access schedule to limit access to certain hours.",
     "OptionDisableUserHelp": "If disabled the server will not allow any connections from this user. Existing connections will be abruptly terminated.",
+    "ButtonAddSchedule": "Add Schedule",
     "HeaderAdvancedControl": "Advanced Control",
+    "LabelAccessDay": "Day of week:",
     "LabelName": "T\u00ean:",
+    "LabelAccessStart": "Start hour:",
     "OptionAllowUserToManageServer": "Cho ph\u00e9p ng\u01b0\u1eddi d\u00f9ng n\u00e0y qu\u1ea3n l\u00fd m\u00e1y ch\u1ee7",
+    "LabelAccessEnd": "End hour:",
     "HeaderFeatureAccess": "Truy c\u1eadp t\u00ednh n\u0103ng",
     "OptionAllowMediaPlayback": "Cho ph\u00e9p ch\u1ea1y media",
     "OptionAllowBrowsingLiveTv": "Cho ph\u00e9p duy\u1ec7t ch\u01b0\u01a1ng tr\u00ecnh truy\u1ec1n h\u00ecnh tr\u1ef1c ti\u1ebfp",

+ 7 - 0
MediaBrowser.Server.Implementations/Localization/Server/zh_TW.json

@@ -440,12 +440,19 @@
     "VisitMediaBrowserWebsite": "\u8a2a\u554fMedia Browser\u7db2\u7ad9",
     "HeaderPendingInvitations": "Pending Invitations",
     "VisitMediaBrowserWebsiteLong": "\u8a2a\u554fMedia Browser\u7684\u7db2\u7ad9\uff0c\u4ee5\u7dca\u8cbc\u6700\u65b0\u7684\u6d88\u606f\u548c\u8ddf\u4e0a\u958b\u767c\u8005\u535a\u5ba2\u3002",
+    "TabParentalControl": "Parental Control",
     "OptionHideUser": "\u5f9e\u767b\u9304\u9801\u9762\u96b1\u85cf\u6b64\u7528\u6236",
+    "HeaderAccessSchedule": "Access Schedule",
     "OptionDisableUser": "\u7981\u7528\u6b64\u7528\u6236",
+    "HeaderAccessScheduleHelp": "Create an access schedule to limit access to certain hours.",
     "OptionDisableUserHelp": "\u88ab\u7981\u7528\u7684\u7528\u6236\u5c07\u4e0d\u5141\u8a31\u9023\u63a5\u4f3a\u670d\u5668\u3002\u73fe\u6709\u7684\u9023\u63a5\u5c07\u88ab\u5373\u6642\u7d42\u6b62\u3002",
+    "ButtonAddSchedule": "Add Schedule",
     "HeaderAdvancedControl": "\u9ad8\u7d1a\u63a7\u5236",
+    "LabelAccessDay": "Day of week:",
     "LabelName": "\u540d\u5b57\uff1a",
+    "LabelAccessStart": "Start hour:",
     "OptionAllowUserToManageServer": "\u5141\u8a31\u9019\u7528\u6236\u7ba1\u7406\u4f3a\u670d\u5668",
+    "LabelAccessEnd": "End hour:",
     "HeaderFeatureAccess": "\u53ef\u4ee5\u4f7f\u7528\u7684\u529f\u80fd",
     "OptionAllowMediaPlayback": "\u5141\u8a31\u5a92\u9ad4\u64ad\u653e",
     "OptionAllowBrowsingLiveTv": "\u5141\u8a31\u4f7f\u7528\u96fb\u8996\u529f\u80fd",

+ 9 - 4
MediaBrowser.Server.Implementations/Session/SessionManager.cs

@@ -14,6 +14,7 @@ using MediaBrowser.Controller.LiveTv;
 using MediaBrowser.Controller.Persistence;
 using MediaBrowser.Controller.Security;
 using MediaBrowser.Controller.Session;
+using MediaBrowser.Model.Connect;
 using MediaBrowser.Model.Devices;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Events;
@@ -1243,7 +1244,14 @@ namespace MediaBrowser.Server.Implementations.Session
         public async Task<AuthenticationResult> AuthenticateNewSession(AuthenticationRequest request,
             bool isLocal)
         {
-            var result = (isLocal && string.Equals(request.App, "Dashboard", StringComparison.OrdinalIgnoreCase)) ||
+            var user = _userManager.Users
+                .FirstOrDefault(i => string.Equals(request.Username, i.Name, StringComparison.OrdinalIgnoreCase));
+
+            var allowWithoutPassword = isLocal &&
+                                       string.Equals(request.App, "Dashboard", StringComparison.OrdinalIgnoreCase)
+                                       && !(user != null && user.ConnectLinkType.HasValue && user.ConnectLinkType.Value == UserLinkType.Guest);
+
+            var result = allowWithoutPassword ||
                 await _userManager.AuthenticateUser(request.Username, request.Password, request.RemoteEndPoint).ConfigureAwait(false);
 
             if (!result)
@@ -1253,9 +1261,6 @@ namespace MediaBrowser.Server.Implementations.Session
                 throw new AuthenticationException("Invalid user or password entered.");
             }
 
-            var user = _userManager.Users
-                .First(i => string.Equals(request.Username, i.Name, StringComparison.OrdinalIgnoreCase));
-
             var token = await GetAuthorizationToken(user.Id.ToString("N"), request.DeviceId, request.App, request.DeviceName).ConfigureAwait(false);
 
             EventHelper.FireEventIfNotNull(AuthenticationSucceeded, this, new GenericEventArgs<AuthenticationRequest>(request), _logger);

+ 14 - 6
MediaBrowser.WebDashboard/Api/DashboardService.cs

@@ -483,13 +483,21 @@ namespace MediaBrowser.WebDashboard.Api
 
             var builder = new StringBuilder();
 
-            using (var fs = _fileSystem.GetFileStream(GetDashboardResourcePath("thirdparty/mediabrowser.apiclient.js"), FileMode.Open, FileAccess.Read, FileShare.ReadWrite, true))
+            foreach (var file in new[]
             {
-                using (var streamReader = new StreamReader(fs))
+                "thirdparty/apiclient/sha1.js",
+                "thirdparty/apiclient/mediabrowser.apiclient.js",
+                "thirdparty/apiclient/connectionmanager.js"
+            })
+            {
+                using (var fs = _fileSystem.GetFileStream(GetDashboardResourcePath(file), FileMode.Open, FileAccess.Read, FileShare.ReadWrite, true))
                 {
-                    var text = await streamReader.ReadToEndAsync().ConfigureAwait(false);
-                    builder.Append(text);
-                    builder.Append(Environment.NewLine);
+                    using (var streamReader = new StreamReader(fs))
+                    {
+                        var text = await streamReader.ReadToEndAsync().ConfigureAwait(false);
+                        builder.Append(text);
+                        builder.Append(Environment.NewLine);
+                    }
                 }
             }
 
@@ -668,7 +676,7 @@ namespace MediaBrowser.WebDashboard.Api
                                 "tvupcoming.js",
                                 "useredit.js",
                                 "userpassword.js",
-                                "userimagepage.js",
+                                "myprofile.js",
                                 "userprofilespage.js",
                                 "userparentalcontrol.js",
                                 "userlibraryaccess.js",

+ 9 - 3
MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj

@@ -85,7 +85,7 @@
     </ProjectReference>
   </ItemGroup>
   <ItemGroup>
-    <EmbeddedResource Include="dashboard-ui\thirdparty\mediabrowser.apiclient.js">
+    <EmbeddedResource Include="dashboard-ui\thirdparty\apiclient\mediabrowser.apiclient.js">
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
     </EmbeddedResource>
     <Content Include="dashboard-ui\channelitems.html">
@@ -898,6 +898,12 @@
     <Content Include="dashboard-ui\serversecurity.html">
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
     </Content>
+    <Content Include="dashboard-ui\thirdparty\apiclient\connectionmanager.js">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+    <Content Include="dashboard-ui\thirdparty\apiclient\sha1.js">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
     <Content Include="dashboard-ui\thirdparty\cast_sender.js">
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
     </Content>
@@ -1896,7 +1902,7 @@
     </Content>
   </ItemGroup>
   <ItemGroup>
-    <Content Include="dashboard-ui\userimage.html">
+    <Content Include="dashboard-ui\myprofile.html">
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
     </Content>
   </ItemGroup>
@@ -1952,7 +1958,7 @@
     <Content Include="dashboard-ui\scripts\useredit.js">
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
     </Content>
-    <Content Include="dashboard-ui\scripts\userimagepage.js">
+    <Content Include="dashboard-ui\scripts\myprofile.js">
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
     </Content>
     <Content Include="dashboard-ui\scripts\userprofilespage.js">

+ 2 - 2
Nuget/MediaBrowser.Common.Internal.nuspec

@@ -2,7 +2,7 @@
 <package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
     <metadata>
         <id>MediaBrowser.Common.Internal</id>
-        <version>3.0.486</version>
+        <version>3.0.487</version>
         <title>MediaBrowser.Common.Internal</title>
         <authors>Luke</authors>
         <owners>ebr,Luke,scottisafool</owners>
@@ -12,7 +12,7 @@
         <description>Contains common components shared by Media Browser Theater and Media Browser Server. Not intended for plugin developer consumption.</description>
         <copyright>Copyright © Media Browser 2013</copyright>
         <dependencies>
-            <dependency id="MediaBrowser.Common" version="3.0.486" />
+            <dependency id="MediaBrowser.Common" version="3.0.487" />
             <dependency id="NLog" version="3.1.0.0" />
             <dependency id="SimpleInjector" version="2.5.2" />
             <dependency id="sharpcompress" version="0.10.2" />

+ 1 - 1
Nuget/MediaBrowser.Common.nuspec

@@ -2,7 +2,7 @@
 <package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
     <metadata>
         <id>MediaBrowser.Common</id>
-        <version>3.0.486</version>
+        <version>3.0.487</version>
         <title>MediaBrowser.Common</title>
         <authors>Media Browser Team</authors>
         <owners>ebr,Luke,scottisafool</owners>

+ 1 - 1
Nuget/MediaBrowser.Model.Signed.nuspec

@@ -2,7 +2,7 @@
 <package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
     <metadata>
         <id>MediaBrowser.Model.Signed</id>
-        <version>3.0.486</version>
+        <version>3.0.487</version>
         <title>MediaBrowser.Model - Signed Edition</title>
         <authors>Media Browser Team</authors>
         <owners>ebr,Luke,scottisafool</owners>

+ 2 - 2
Nuget/MediaBrowser.Server.Core.nuspec

@@ -2,7 +2,7 @@
 <package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
     <metadata>
         <id>MediaBrowser.Server.Core</id>
-        <version>3.0.486</version>
+        <version>3.0.487</version>
         <title>Media Browser.Server.Core</title>
         <authors>Media Browser Team</authors>
         <owners>ebr,Luke,scottisafool</owners>
@@ -12,7 +12,7 @@
         <description>Contains core components required to build plugins for Media Browser Server.</description>
         <copyright>Copyright © Media Browser 2013</copyright>
         <dependencies>
-            <dependency id="MediaBrowser.Common" version="3.0.486" />
+            <dependency id="MediaBrowser.Common" version="3.0.487" />
         </dependencies>
     </metadata>
     <files>