瀏覽代碼

update translations

Luke Pulverenti 10 年之前
父節點
當前提交
9c5cceb4ec
共有 100 個文件被更改,包括 1085 次插入387 次删除
  1. 10 1
      MediaBrowser.Api/System/ActivityLogService.cs
  2. 6 5
      MediaBrowser.Api/UserLibrary/UserLibraryService.cs
  3. 1 1
      MediaBrowser.Controller/Activity/IActivityManager.cs
  4. 2 1
      MediaBrowser.Controller/Activity/IActivityRepository.cs
  5. 0 1
      MediaBrowser.Controller/Channels/ChannelFolderItem.cs
  6. 11 0
      MediaBrowser.Controller/Entities/BaseItem.cs
  7. 26 1
      MediaBrowser.Controller/Entities/Folder.cs
  8. 6 0
      MediaBrowser.Controller/Entities/IHasImages.cs
  9. 6 0
      MediaBrowser.Controller/Entities/IHasMediaSources.cs
  10. 0 1
      MediaBrowser.Controller/Entities/LinkedChild.cs
  11. 18 1
      MediaBrowser.Controller/Entities/Movies/BoxSet.cs
  12. 14 0
      MediaBrowser.Controller/Entities/TV/Episode.cs
  13. 32 0
      MediaBrowser.Controller/Entities/UserView.cs
  14. 2 0
      MediaBrowser.Controller/Library/IUserViewManager.cs
  15. 17 0
      MediaBrowser.Controller/LiveTv/ILiveTvManager.cs
  16. 22 0
      MediaBrowser.Controller/LiveTv/RecordingGroup.cs
  17. 1 0
      MediaBrowser.Controller/MediaBrowser.Controller.csproj
  18. 39 1
      MediaBrowser.Controller/Playlists/Playlist.cs
  19. 16 4
      MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs
  20. 18 13
      MediaBrowser.Dlna/Didl/DidlBuilder.cs
  21. 2 0
      MediaBrowser.Dlna/Profiles/DefaultProfile.cs
  22. 2 0
      MediaBrowser.Dlna/Profiles/Xml/Android.xml
  23. 2 0
      MediaBrowser.Dlna/Profiles/Xml/Default.xml
  24. 2 0
      MediaBrowser.Dlna/Profiles/Xml/Denon AVR.xml
  25. 2 0
      MediaBrowser.Dlna/Profiles/Xml/LG Smart TV.xml
  26. 2 0
      MediaBrowser.Dlna/Profiles/Xml/Linksys DMA2100.xml
  27. 2 0
      MediaBrowser.Dlna/Profiles/Xml/MediaMonkey.xml
  28. 2 0
      MediaBrowser.Dlna/Profiles/Xml/Panasonic Viera.xml
  29. 2 0
      MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml
  30. 2 0
      MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2013.xml
  31. 2 0
      MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player.xml
  32. 3 0
      MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2010).xml
  33. 2 0
      MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2011).xml
  34. 2 0
      MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2012).xml
  35. 2 0
      MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2013).xml
  36. 2 0
      MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 3.xml
  37. 2 0
      MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml
  38. 2 0
      MediaBrowser.Dlna/Profiles/Xml/Windows 8 RT.xml
  39. 2 0
      MediaBrowser.Dlna/Profiles/Xml/Windows Phone.xml
  40. 2 0
      MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml
  41. 2 0
      MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml
  42. 2 0
      MediaBrowser.Dlna/Profiles/Xml/foobar2000.xml
  43. 1 1
      MediaBrowser.Dlna/Ssdp/SsdpHandler.cs
  44. 3 0
      MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj
  45. 3 0
      MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj
  46. 7 0
      MediaBrowser.Model/ApiClient/IApiClient.cs
  47. 3 0
      MediaBrowser.Model/Configuration/ChannelOptions.cs
  48. 20 0
      MediaBrowser.Model/Configuration/ServerConfiguration.cs
  49. 1 0
      MediaBrowser.Model/Configuration/UserConfiguration.cs
  50. 6 0
      MediaBrowser.Model/Dlna/AudioOptions.cs
  51. 3 0
      MediaBrowser.Model/Dlna/DeviceProfile.cs
  52. 5 4
      MediaBrowser.Model/Dlna/StreamBuilder.cs
  53. 4 0
      MediaBrowser.Model/Entities/CollectionType.cs
  54. 1 0
      MediaBrowser.Model/MediaBrowser.Model.csproj
  55. 54 0
      MediaBrowser.Model/Querying/LatestItemsQuery.cs
  56. 5 0
      MediaBrowser.Providers/Manager/ItemImageProvider.cs
  57. 8 2
      MediaBrowser.Providers/Playlists/PlaylistMetadataService.cs
  58. 4 3
      MediaBrowser.Providers/TV/TvdbEpisodeImageProvider.cs
  59. 2 2
      MediaBrowser.Server.Implementations/Activity/ActivityManager.cs
  60. 23 7
      MediaBrowser.Server.Implementations/Activity/ActivityRepository.cs
  61. 30 1
      MediaBrowser.Server.Implementations/Channels/ChannelDownloadScheduledTask.cs
  62. 18 10
      MediaBrowser.Server.Implementations/EntryPoints/ActivityLogEntryPoint.cs
  63. 2 3
      MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs
  64. 102 13
      MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs
  65. 1 1
      MediaBrowser.Server.Implementations/Library/LibraryManager.cs
  66. 7 2
      MediaBrowser.Server.Implementations/Library/UserViewManager.cs
  67. 95 8
      MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs
  68. 60 14
      MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
  69. 2 2
      MediaBrowser.Server.Implementations/Localization/JavaScript/ar.json
  70. 2 2
      MediaBrowser.Server.Implementations/Localization/JavaScript/ca.json
  71. 1 1
      MediaBrowser.Server.Implementations/Localization/JavaScript/cs.json
  72. 2 2
      MediaBrowser.Server.Implementations/Localization/JavaScript/da.json
  73. 2 2
      MediaBrowser.Server.Implementations/Localization/JavaScript/el.json
  74. 2 2
      MediaBrowser.Server.Implementations/Localization/JavaScript/en_GB.json
  75. 2 2
      MediaBrowser.Server.Implementations/Localization/JavaScript/en_US.json
  76. 17 17
      MediaBrowser.Server.Implementations/Localization/JavaScript/es_MX.json
  77. 22 22
      MediaBrowser.Server.Implementations/Localization/JavaScript/fr.json
  78. 2 2
      MediaBrowser.Server.Implementations/Localization/JavaScript/he.json
  79. 11 11
      MediaBrowser.Server.Implementations/Localization/JavaScript/it.json
  80. 20 20
      MediaBrowser.Server.Implementations/Localization/JavaScript/kk.json
  81. 2 2
      MediaBrowser.Server.Implementations/Localization/JavaScript/ms.json
  82. 14 14
      MediaBrowser.Server.Implementations/Localization/JavaScript/nl.json
  83. 2 2
      MediaBrowser.Server.Implementations/Localization/JavaScript/pl.json
  84. 19 19
      MediaBrowser.Server.Implementations/Localization/JavaScript/pt_BR.json
  85. 26 26
      MediaBrowser.Server.Implementations/Localization/JavaScript/ru.json
  86. 2 2
      MediaBrowser.Server.Implementations/Localization/JavaScript/vi.json
  87. 2 2
      MediaBrowser.Server.Implementations/Localization/JavaScript/zh_TW.json
  88. 4 1
      MediaBrowser.Server.Implementations/Localization/Server/ar.json
  89. 4 1
      MediaBrowser.Server.Implementations/Localization/Server/ca.json
  90. 7 4
      MediaBrowser.Server.Implementations/Localization/Server/cs.json
  91. 6 3
      MediaBrowser.Server.Implementations/Localization/Server/da.json
  92. 10 7
      MediaBrowser.Server.Implementations/Localization/Server/de.json
  93. 4 1
      MediaBrowser.Server.Implementations/Localization/Server/el.json
  94. 4 1
      MediaBrowser.Server.Implementations/Localization/Server/en_GB.json
  95. 4 1
      MediaBrowser.Server.Implementations/Localization/Server/en_US.json
  96. 8 5
      MediaBrowser.Server.Implementations/Localization/Server/es.json
  97. 38 35
      MediaBrowser.Server.Implementations/Localization/Server/es_MX.json
  98. 35 32
      MediaBrowser.Server.Implementations/Localization/Server/fr.json
  99. 7 4
      MediaBrowser.Server.Implementations/Localization/Server/he.json
  100. 42 39
      MediaBrowser.Server.Implementations/Localization/Server/it.json

+ 10 - 1
MediaBrowser.Api/System/ActivityLogService.cs

@@ -3,6 +3,8 @@ using MediaBrowser.Controller.Net;
 using MediaBrowser.Model.Activity;
 using MediaBrowser.Model.Querying;
 using ServiceStack;
+using System;
+using System.Globalization;
 
 namespace MediaBrowser.Api.System
 {
@@ -22,6 +24,9 @@ namespace MediaBrowser.Api.System
         /// <value>The limit.</value>
         [ApiMember(Name = "Limit", Description = "Optional. The maximum number of records to return", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
         public int? Limit { get; set; }
+
+        [ApiMember(Name = "MinDate", Description = "Optional. The minimum date. Format = ISO", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")]
+        public string MinDate { get; set; }
     }
 
     [Authenticated]
@@ -36,7 +41,11 @@ namespace MediaBrowser.Api.System
 
         public object Get(GetActivityLogs request)
         {
-            var result = _activityManager.GetActivityLogEntries(request.StartIndex, request.Limit);
+            DateTime? minDate = string.IsNullOrWhiteSpace(request.MinDate) ?
+                (DateTime?)null :
+                DateTime.Parse(request.MinDate, null, DateTimeStyles.RoundtripKind).ToUniversalTime();
+
+            var result = _activityManager.GetActivityLogEntries(minDate, request.StartIndex, request.Limit);
 
             return ToOptimizedResult(result);
         }

+ 6 - 5
MediaBrowser.Api/UserLibrary/UserLibraryService.cs

@@ -318,11 +318,12 @@ namespace MediaBrowser.Api.UserLibrary
                 .OrderByDescending(i => i.DateCreated)
                 .Where(i => i.LocationType != LocationType.Virtual);
 
-            if (request.IsFolder.HasValue)
-            {
-                var val = request.IsFolder.Value;
-                libraryItems = libraryItems.Where(f => f.IsFolder == val);
-            }
+
+            //if (request.IsFolder.HasValue)
+            //{
+                //var val = request.IsFolder.Value;
+                libraryItems = libraryItems.Where(f => f.IsFolder == false);
+            //}
             
             if (!string.IsNullOrEmpty(request.IncludeItemTypes))
             {

+ 1 - 1
MediaBrowser.Controller/Activity/IActivityManager.cs

@@ -12,6 +12,6 @@ namespace MediaBrowser.Controller.Activity
 
         Task Create(ActivityLogEntry entry);
 
-        QueryResult<ActivityLogEntry> GetActivityLogEntries(int? startIndex, int? limit);
+        QueryResult<ActivityLogEntry> GetActivityLogEntries(DateTime? minDate, int? startIndex, int? limit);
     }
 }

+ 2 - 1
MediaBrowser.Controller/Activity/IActivityRepository.cs

@@ -1,5 +1,6 @@
 using MediaBrowser.Model.Activity;
 using MediaBrowser.Model.Querying;
+using System;
 using System.Threading.Tasks;
 
 namespace MediaBrowser.Controller.Activity
@@ -8,6 +9,6 @@ namespace MediaBrowser.Controller.Activity
     {
         Task Create(ActivityLogEntry entry);
 
-        QueryResult<ActivityLogEntry> GetActivityLogEntries(int? startIndex, int? limit);
+        QueryResult<ActivityLogEntry> GetActivityLogEntries(DateTime? minDate, int? startIndex, int? limit);
     }
 }

+ 0 - 1
MediaBrowser.Controller/Channels/ChannelFolderItem.cs

@@ -1,7 +1,6 @@
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Model.Channels;
 using MediaBrowser.Model.Configuration;
-using System.Collections.Generic;
 
 namespace MediaBrowser.Controller.Channels
 {

+ 11 - 0
MediaBrowser.Controller/Entities/BaseItem.cs

@@ -2,6 +2,7 @@
 using MediaBrowser.Common.IO;
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.LiveTv;
 using MediaBrowser.Controller.Localization;
 using MediaBrowser.Controller.Persistence;
 using MediaBrowser.Controller.Providers;
@@ -66,6 +67,15 @@ namespace MediaBrowser.Controller.Entities
         /// <value><c>true</c> if this instance is in mixed folder; otherwise, <c>false</c>.</value>
         public bool IsInMixedFolder { get; set; }
 
+        [IgnoreDataMember]
+        public virtual bool SupportsRemoteImageDownloading
+        {
+            get
+            {
+                return true;
+            }
+        }
+
         private string _name;
         /// <summary>
         /// Gets or sets the name.
@@ -227,6 +237,7 @@ namespace MediaBrowser.Controller.Entities
         public static IItemRepository ItemRepository { get; set; }
         public static IFileSystem FileSystem { get; set; }
         public static IUserDataManager UserDataManager { get; set; }
+        public static ILiveTvManager LiveTvManager { get; set; }
 
         /// <summary>
         /// Returns a <see cref="System.String" /> that represents this instance.

+ 26 - 1
MediaBrowser.Controller/Entities/Folder.cs

@@ -840,7 +840,7 @@ namespace MediaBrowser.Controller.Entities
 
             if (includeLinkedChildren)
             {
-                foreach (var child in GetLinkedChildren())
+                foreach (var child in GetLinkedChildren(user))
                 {
                     if (child.IsVisible(user))
                     {
@@ -924,6 +924,31 @@ namespace MediaBrowser.Controller.Entities
                 .Where(i => i != null);
         }
 
+        protected virtual bool FilterLinkedChildrenPerUser
+        {
+            get
+            {
+                return false;
+            }
+        }
+
+        public IEnumerable<BaseItem> GetLinkedChildren(User user)
+        {
+            if (!FilterLinkedChildrenPerUser)
+            {
+                return GetLinkedChildren();
+            }
+
+            var locations = user.RootFolder
+                .Children
+                .OfType<CollectionFolder>()
+                .SelectMany(i => i.PhysicalLocations)
+                .ToList();
+            
+            return LinkedChildren.Where(i => string.IsNullOrWhiteSpace(i.Path) || locations.Any(l => FileSystem.ContainsSubPath(l, i.Path)))
+                .Select(GetLinkedChild)
+                .Where(i => i != null);
+        }
 
         /// <summary>
         /// Gets the linked children.

+ 6 - 0
MediaBrowser.Controller/Entities/IHasImages.cs

@@ -154,6 +154,12 @@ namespace MediaBrowser.Controller.Entities
         /// </summary>
         /// <value><c>true</c> if this instance is locked; otherwise, <c>false</c>.</value>
         bool IsLocked { get; }
+
+        /// <summary>
+        /// Gets a value indicating whether [supports remote image downloading].
+        /// </summary>
+        /// <value><c>true</c> if [supports remote image downloading]; otherwise, <c>false</c>.</value>
+        bool SupportsRemoteImageDownloading { get; }
     }
 
     public static class HasImagesExtensions

+ 6 - 0
MediaBrowser.Controller/Entities/IHasMediaSources.cs

@@ -9,6 +9,12 @@ namespace MediaBrowser.Controller.Entities
 {
     public interface IHasMediaSources
     {
+        /// <summary>
+        /// Gets the identifier.
+        /// </summary>
+        /// <value>The identifier.</value>
+        Guid Id { get; }
+
         /// <summary>
         /// Gets the media sources.
         /// </summary>

+ 0 - 1
MediaBrowser.Controller/Entities/LinkedChild.cs

@@ -19,7 +19,6 @@ namespace MediaBrowser.Controller.Entities
         /// <summary>
         /// Serves as a cache
         /// </summary>
-        [IgnoreDataMember]
         public Guid? ItemId { get; set; }
 
         public static LinkedChild Create(BaseItem item)

+ 18 - 1
MediaBrowser.Controller/Entities/Movies/BoxSet.cs

@@ -1,5 +1,6 @@
 using System.Runtime.Serialization;
 using MediaBrowser.Common.Progress;
+using MediaBrowser.Controller.Playlists;
 using MediaBrowser.Controller.Providers;
 using MediaBrowser.Model.Configuration;
 using MediaBrowser.Model.Entities;
@@ -26,6 +27,14 @@ namespace MediaBrowser.Controller.Entities.Movies
             Keywords = new List<string>();
         }
 
+        protected override bool FilterLinkedChildrenPerUser
+        {
+            get
+            {
+                return true;
+            }
+        }
+
         public List<Guid> LocalTrailerIds { get; set; }
 
         /// <summary>
@@ -72,6 +81,8 @@ namespace MediaBrowser.Controller.Entities.Movies
         {
             var children = base.GetChildren(user, includeLinkedChildren);
 
+            children = Playlist.FilterInaccessibleItems(children, user);
+
             if (string.Equals(DisplayOrder, ItemSortBy.SortName, StringComparison.OrdinalIgnoreCase))
             {
                 // Sort by name
@@ -83,11 +94,17 @@ namespace MediaBrowser.Controller.Entities.Movies
                 // Sort by release date
                 return LibraryManager.Sort(children, user, new[] { ItemSortBy.ProductionYear, ItemSortBy.PremiereDate, ItemSortBy.SortName }, SortOrder.Ascending);
             }
-            
+
             // Default sorting
             return LibraryManager.Sort(children, user, new[] { ItemSortBy.ProductionYear, ItemSortBy.PremiereDate, ItemSortBy.SortName }, SortOrder.Ascending);
         }
 
+        public override IEnumerable<BaseItem> GetRecursiveChildren(User user, bool includeLinkedChildren = true)
+        {
+            var children = base.GetRecursiveChildren(user, includeLinkedChildren);
+            return Playlist.FilterInaccessibleItems(children, user);
+        }
+
         public BoxSetInfo GetLookupInfo()
         {
             return GetItemLookupInfo<BoxSetInfo>();

+ 14 - 0
MediaBrowser.Controller/Entities/TV/Episode.cs

@@ -188,6 +188,20 @@ namespace MediaBrowser.Controller.Entities.TV
             return false;
         }
 
+        [IgnoreDataMember]
+        public override bool SupportsRemoteImageDownloading
+        {
+            get
+            {
+                if (IsMissingEpisode)
+                {
+                    return false;
+                }
+
+                return true;
+            }
+        }
+
         [IgnoreDataMember]
         public bool IsMissingEpisode
         {

+ 32 - 0
MediaBrowser.Controller/Entities/UserView.cs

@@ -1,15 +1,20 @@
 using MediaBrowser.Controller.Entities.Movies;
 using MediaBrowser.Controller.Entities.TV;
+using MediaBrowser.Controller.Library;
 using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.LiveTv;
 using System;
 using System.Collections.Generic;
 using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
 
 namespace MediaBrowser.Controller.Entities
 {
     public class UserView : Folder
     {
         public string ViewType { get; set; }
+        public static IUserViewManager UserViewManager { get; set; }
 
         public override IEnumerable<BaseItem> GetChildren(User user, bool includeLinkedChildren)
         {
@@ -17,6 +22,23 @@ namespace MediaBrowser.Controller.Entities
 
             switch (ViewType)
             {
+                case CollectionType.LiveTvChannels:
+                    return LiveTvManager.GetInternalChannels(new LiveTvChannelQuery
+                    {
+                        UserId = user.Id.ToString("N")
+
+                    }, CancellationToken.None).Result.Items;
+                case CollectionType.LiveTvRecordingGroups:
+                    return LiveTvManager.GetInternalRecordings(new RecordingQuery
+                    {
+                        UserId = user.Id.ToString("N"),
+                        Status = RecordingStatus.Completed
+
+                    }, CancellationToken.None).Result.Items;
+                case CollectionType.LiveTv:
+                    return GetLiveTvFolders(user).Result;
+                case CollectionType.Folders:
+                    return user.RootFolder.GetChildren(user, includeLinkedChildren);
                 case CollectionType.Games:
                     return mediaFolders.SelectMany(i => i.GetRecursiveChildren(user, includeLinkedChildren))
                         .OfType<GameSystem>();
@@ -34,6 +56,16 @@ namespace MediaBrowser.Controller.Entities
             }
         }
 
+        private async Task<IEnumerable<BaseItem>> GetLiveTvFolders(User user)
+        {
+            var list = new List<BaseItem>();
+
+            list.Add(await UserViewManager.GetUserView(CollectionType.LiveTvChannels, user, string.Empty, CancellationToken.None).ConfigureAwait(false));
+            list.Add(await UserViewManager.GetUserView(CollectionType.LiveTvRecordingGroups, user, string.Empty, CancellationToken.None).ConfigureAwait(false));
+
+            return list;
+        }
+
         protected override IEnumerable<BaseItem> GetEligibleChildrenForRecursiveChildren(User user)
         {
             return GetChildren(user, false);

+ 2 - 0
MediaBrowser.Controller/Library/IUserViewManager.cs

@@ -9,5 +9,7 @@ namespace MediaBrowser.Controller.Library
     public interface IUserViewManager
     {
         Task<IEnumerable<Folder>> GetUserViews(UserViewQuery query, CancellationToken cancellationToken);
+
+        Task<UserView> GetUserView(string type, User user, string sortName, CancellationToken cancellationToken);
     }
 }

+ 17 - 0
MediaBrowser.Controller/LiveTv/ILiveTvManager.cs

@@ -280,5 +280,22 @@ namespace MediaBrowser.Controller.LiveTv
         /// </summary>
         /// <returns>IEnumerable{User}.</returns>
         IEnumerable<User> GetEnabledUsers();
+
+        /// <summary>
+        /// Gets the internal channels.
+        /// </summary>
+        /// <param name="query">The query.</param>
+        /// <param name="cancellationToken">The cancellation token.</param>
+        /// <returns>Task&lt;QueryResult&lt;LiveTvChannel&gt;&gt;.</returns>
+        Task<QueryResult<LiveTvChannel>> GetInternalChannels(LiveTvChannelQuery query,
+            CancellationToken cancellationToken);
+
+        /// <summary>
+        /// Gets the internal recordings.
+        /// </summary>
+        /// <param name="query">The query.</param>
+        /// <param name="cancellationToken">The cancellation token.</param>
+        /// <returns>Task&lt;QueryResult&lt;BaseItem&gt;&gt;.</returns>
+        Task<QueryResult<BaseItem>> GetInternalRecordings(RecordingQuery query, CancellationToken cancellationToken);
     }
 }

+ 22 - 0
MediaBrowser.Controller/LiveTv/RecordingGroup.cs

@@ -0,0 +1,22 @@
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Model.Configuration;
+
+namespace MediaBrowser.Controller.LiveTv
+{
+    public class RecordingGroup : Folder
+    {
+        protected override bool GetBlockUnratedValue(UserConfiguration config)
+        {
+            // Don't block. 
+            return false;
+        }
+
+        public override bool SupportsLocalMetadata
+        {
+            get
+            {
+                return false;
+            }
+        }
+    }
+}

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

@@ -168,6 +168,7 @@
     <Compile Include="Library\LibraryManagerExtensions.cs" />
     <Compile Include="Library\PlaybackStopEventArgs.cs" />
     <Compile Include="Library\UserDataSaveEventArgs.cs" />
+    <Compile Include="LiveTv\RecordingGroup.cs" />
     <Compile Include="LiveTv\RecordingStatusChangedEventArgs.cs" />
     <Compile Include="LiveTv\ILiveTvRecording.cs" />
     <Compile Include="LiveTv\LiveStreamInfo.cs" />

+ 39 - 1
MediaBrowser.Controller/Playlists/Playlist.cs

@@ -12,6 +12,14 @@ namespace MediaBrowser.Controller.Playlists
     {
         public string OwnerUserId { get; set; }
 
+        protected override bool FilterLinkedChildrenPerUser
+        {
+            get
+            {
+                return true;
+            }
+        }
+
         public override IEnumerable<BaseItem> GetChildren(User user, bool includeLinkedChildren)
         {
             return GetPlayableItems(user);
@@ -34,7 +42,12 @@ namespace MediaBrowser.Controller.Playlists
 
         public static IEnumerable<BaseItem> GetPlaylistItems(string playlistMediaType, IEnumerable<BaseItem> inputItems, User user)
         {
-            return inputItems.SelectMany(i =>
+            if (user != null)
+            {
+                inputItems = inputItems.Where(i => i.IsVisible(user));
+            }
+
+            inputItems = inputItems.SelectMany(i =>
             {
                 var folder = i as Folder;
 
@@ -58,6 +71,31 @@ namespace MediaBrowser.Controller.Playlists
                 return new[] { i };
 
             }).Where(m =>  string.Equals(m.MediaType, playlistMediaType, StringComparison.OrdinalIgnoreCase));
+
+            return FilterInaccessibleItems(inputItems, user);
+        }
+
+        public static IEnumerable<BaseItem> FilterInaccessibleItems(IEnumerable<BaseItem> items, User user)
+        {
+            return items;
+            //var locations = user.RootFolder.Children.OfType<CollectionFolder>().SelectMany(i => i.PhysicalLocations).ToList();
+
+            //return items.Where(i =>
+            //{
+            //    var parent = i.Parent;
+
+            //    while (parent != null)
+            //    {
+            //        parent = parent.Parent;
+
+            //        if (parent != null && parent.Parent is AggregateFolder)
+            //        {
+            //            break;
+            //        }
+            //    }
+
+            //    return parent == null || locations.Contains(parent.Path, StringComparer.OrdinalIgnoreCase);
+            //});
         }
 
         [IgnoreDataMember]

+ 16 - 4
MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs

@@ -442,10 +442,6 @@ namespace MediaBrowser.Dlna.ContentDirectory
 
         private async Task<IEnumerable<BaseItem>> GetUserViewChildren(UserView folder, User user, SortCriteria sort)
         {
-            if (string.Equals(folder.ViewType, CollectionType.LiveTv, StringComparison.OrdinalIgnoreCase))
-            {
-                return new List<BaseItem>();
-            }
             if (string.Equals(folder.ViewType, CollectionType.Channels, StringComparison.OrdinalIgnoreCase))
             {
                 var result = await _channelManager.GetChannelsInternal(new ChannelQuery()
@@ -468,6 +464,22 @@ namespace MediaBrowser.Dlna.ContentDirectory
             {
                 return SortItems(folder.GetChildren(user, true).OfType<MusicArtist>(), user, sort);
             }
+            if (string.Equals(folder.ViewType, CollectionType.Folders, StringComparison.OrdinalIgnoreCase))
+            {
+                return SortItems(folder.GetChildren(user, true), user, sort);
+            }
+            if (string.Equals(folder.ViewType, CollectionType.LiveTv, StringComparison.OrdinalIgnoreCase))
+            {
+                return SortItems(folder.GetChildren(user, true), user, sort);
+            }
+            if (string.Equals(folder.ViewType, CollectionType.LiveTvRecordingGroups, StringComparison.OrdinalIgnoreCase))
+            {
+                return SortItems(folder.GetChildren(user, true), user, sort);
+            }
+            if (string.Equals(folder.ViewType, CollectionType.LiveTvChannels, StringComparison.OrdinalIgnoreCase))
+            {
+                return SortItems(folder.GetChildren(user, true), user, sort);
+            }
 
             return GetPlainFolderChildrenSorted(folder, user, sort);
         }

+ 18 - 13
MediaBrowser.Dlna/Didl/DidlBuilder.cs

@@ -80,16 +80,18 @@ namespace MediaBrowser.Dlna.Didl
             // refID?
             // storeAttribute(itemNode, object, ClassProperties.REF_ID, false);
 
-            var audio = item as Audio;
-            if (audio != null)
-            {
-                AddAudioResource(element, audio, deviceId, filter, streamInfo);
-            }
+            var hasMediaSources = item as IHasMediaSources;
 
-            var video = item as Video;
-            if (video != null)
+            if (hasMediaSources != null)
             {
-                AddVideoResource(element, video, deviceId, filter, streamInfo);
+                if (string.Equals(item.MediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase))
+                {
+                    AddAudioResource(element, hasMediaSources, deviceId, filter, streamInfo);
+                }
+                else if (string.Equals(item.MediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase))
+                {
+                    AddVideoResource(element, hasMediaSources, deviceId, filter, streamInfo);
+                }
             }
 
             AddCover(item, element);
@@ -97,7 +99,7 @@ namespace MediaBrowser.Dlna.Didl
             return element;
         }
 
-        private void AddVideoResource(XmlElement container, Video video, string deviceId, Filter filter, StreamInfo streamInfo = null)
+        private void AddVideoResource(XmlElement container, IHasMediaSources video, string deviceId, Filter filter, StreamInfo streamInfo = null)
         {
             if (streamInfo == null)
             {
@@ -181,7 +183,7 @@ namespace MediaBrowser.Dlna.Didl
             }
         }
 
-        private void AddVideoResource(XmlElement container, Video video, string deviceId, Filter filter, string contentFeatures, StreamInfo streamInfo)
+        private void AddVideoResource(XmlElement container, IHasMediaSources video, string deviceId, Filter filter, string contentFeatures, StreamInfo streamInfo)
         {
             var res = container.OwnerDocument.CreateElement(string.Empty, "res", NS_DIDL);
 
@@ -270,7 +272,7 @@ namespace MediaBrowser.Dlna.Didl
             container.AppendChild(res);
         }
         
-        private void AddAudioResource(XmlElement container, Audio audio, string deviceId, Filter filter, StreamInfo streamInfo = null)
+        private void AddAudioResource(XmlElement container, IHasMediaSources audio, string deviceId, Filter filter, StreamInfo streamInfo = null)
         {
             var res = container.OwnerDocument.CreateElement(string.Empty, "res", NS_DIDL);
 
@@ -636,9 +638,12 @@ namespace MediaBrowser.Dlna.Didl
 
             if (!_profile.EnableAlbumArtInDidl)
             {
-                if (!(item is Photo) && !(item is Video))
+                if (!string.Equals(item.MediaType, MediaType.Photo, StringComparison.OrdinalIgnoreCase) && !string.Equals(item.MediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase))
                 {
-                    return;
+                    if (!item.IsFolder)
+                    {
+                        return;
+                    }
                 }
             }
 

+ 2 - 0
MediaBrowser.Dlna/Profiles/DefaultProfile.cs

@@ -32,6 +32,8 @@ namespace MediaBrowser.Dlna.Profiles
 
             MaxStreamingBitrate = 8000000;
             MaxStaticBitrate = 8000000;
+            MusicStreamingTranscodingBitrate = 128000;
+            MusicSyncBitrate = 128000;
 
             EnableAlbumArtInDidl = false;
 

File diff suppressed because it is too large
+ 2 - 0
MediaBrowser.Dlna/Profiles/Xml/Android.xml


File diff suppressed because it is too large
+ 2 - 0
MediaBrowser.Dlna/Profiles/Xml/Default.xml


File diff suppressed because it is too large
+ 2 - 0
MediaBrowser.Dlna/Profiles/Xml/Denon AVR.xml


File diff suppressed because it is too large
+ 2 - 0
MediaBrowser.Dlna/Profiles/Xml/LG Smart TV.xml


File diff suppressed because it is too large
+ 2 - 0
MediaBrowser.Dlna/Profiles/Xml/Linksys DMA2100.xml


File diff suppressed because it is too large
+ 2 - 0
MediaBrowser.Dlna/Profiles/Xml/MediaMonkey.xml


File diff suppressed because it is too large
+ 2 - 0
MediaBrowser.Dlna/Profiles/Xml/Panasonic Viera.xml


File diff suppressed because it is too large
+ 2 - 0
MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml


File diff suppressed because it is too large
+ 2 - 0
MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2013.xml


File diff suppressed because it is too large
+ 2 - 0
MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player.xml


+ 3 - 0
MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2010).xml

@@ -25,6 +25,8 @@
   <MaxIconHeight>48</MaxIconHeight>
   <MaxStreamingBitrate>8000000</MaxStreamingBitrate>
   <MaxStaticBitrate>8000000</MaxStaticBitrate>
+  <MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
+  <MusicSyncBitrate>128000</MusicSyncBitrate>
   <XDlnaDoc>DMS-1.50</XDlnaDoc>
   <SonyAggregationFlags>10</SonyAggregationFlags>
   <ProtocolInfo>http-get:*:audio/mpeg:DLNA.ORG_PN=MP3;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_SM;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_PS_PAL;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000</ProtocolInfo>
@@ -107,4 +109,5 @@
       <Conditions />
     </ResponseProfile>
   </ResponseProfiles>
+  <SubtitleProfiles />
 </Profile>

File diff suppressed because it is too large
+ 2 - 0
MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2011).xml


File diff suppressed because it is too large
+ 2 - 0
MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2012).xml


File diff suppressed because it is too large
+ 2 - 0
MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2013).xml


File diff suppressed because it is too large
+ 2 - 0
MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 3.xml


File diff suppressed because it is too large
+ 2 - 0
MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml


File diff suppressed because it is too large
+ 2 - 0
MediaBrowser.Dlna/Profiles/Xml/Windows 8 RT.xml


File diff suppressed because it is too large
+ 2 - 0
MediaBrowser.Dlna/Profiles/Xml/Windows Phone.xml


File diff suppressed because it is too large
+ 2 - 0
MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml


File diff suppressed because it is too large
+ 2 - 0
MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml


File diff suppressed because it is too large
+ 2 - 0
MediaBrowser.Dlna/Profiles/Xml/foobar2000.xml


+ 1 - 1
MediaBrowser.Dlna/Ssdp/SsdpHandler.cs

@@ -184,7 +184,7 @@ namespace MediaBrowser.Dlna.Ssdp
                     values["ST"] = d.Type;
                     values["USN"] = d.USN;
 
-                    SendDatagram(header, values, endpoint);
+                    SendDatagram(header, values, endpoint, null);
 
                     if (_config.GetDlnaConfiguration().EnableDebugLogging)
                     {

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

@@ -761,6 +761,9 @@
     <Compile Include="..\MediaBrowser.Model\Querying\ItemsResult.cs">
       <Link>Querying\ItemsResult.cs</Link>
     </Compile>
+    <Compile Include="..\MediaBrowser.Model\Querying\LatestItemsQuery.cs">
+      <Link>Querying\LatestItemsQuery.cs</Link>
+    </Compile>
     <Compile Include="..\MediaBrowser.Model\Querying\NextUpQuery.cs">
       <Link>Querying\NextUpQuery.cs</Link>
     </Compile>

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

@@ -718,6 +718,9 @@
     <Compile Include="..\MediaBrowser.Model\Querying\ItemsResult.cs">
       <Link>Querying\ItemsResult.cs</Link>
     </Compile>
+    <Compile Include="..\MediaBrowser.Model\Querying\LatestItemsQuery.cs">
+      <Link>Querying\LatestItemsQuery.cs</Link>
+    </Compile>
     <Compile Include="..\MediaBrowser.Model\Querying\NextUpQuery.cs">
       <Link>Querying\NextUpQuery.cs</Link>
     </Compile>

+ 7 - 0
MediaBrowser.Model/ApiClient/IApiClient.cs

@@ -203,6 +203,13 @@ namespace MediaBrowser.Model.ApiClient
         /// <exception cref="ArgumentNullException">id</exception>
         Task<BaseItemDto> GetItemAsync(string id, string userId);
 
+        /// <summary>
+        /// Gets the latest items.
+        /// </summary>
+        /// <param name="query">The query.</param>
+        /// <returns>Task&lt;QueryResult&lt;BaseItemDto&gt;&gt;.</returns>
+        Task<QueryResult<BaseItemDto>> GetLatestItems(LatestItemsQuery query);
+        
         /// <summary>
         /// Gets the intros async.
         /// </summary>

+ 3 - 0
MediaBrowser.Model/Configuration/ChannelOptions.cs

@@ -9,9 +9,12 @@
 
         public string[] DownloadingChannels { get; set; }
 
+        public double? DownloadSizeLimit { get; set; }
+
         public ChannelOptions()
         {
             DownloadingChannels = new string[] { };
+            DownloadSizeLimit = 1;
             MaxDownloadAge = 30;
         }
     }

+ 20 - 0
MediaBrowser.Model/Configuration/ServerConfiguration.cs

@@ -186,6 +186,7 @@ namespace MediaBrowser.Model.Configuration
         public bool DefaultMetadataSettingsApplied { get; set; }
 
         public bool EnableTokenAuthentication { get; set; }
+        public PeopleMetadataOptions PeopleMetadataOptions { get; set; }
 
         /// <summary>
         /// Initializes a new instance of the <see cref="ServerConfiguration" /> class.
@@ -229,6 +230,8 @@ namespace MediaBrowser.Model.Configuration
 
             UICulture = "en-us";
 
+            PeopleMetadataOptions = new PeopleMetadataOptions();
+
             MetadataOptions = new[]
             {
                 new MetadataOptions(1, 1280) {ItemType = "Book"},
@@ -288,4 +291,21 @@ namespace MediaBrowser.Model.Configuration
             };
         }
     }
+
+    public class PeopleMetadataOptions
+    {
+        public bool DownloadActorMetadata { get; set; }
+        public bool DownloadDirectorMetadata { get; set; }
+        public bool DownloadProducerMetadata { get; set; }
+        public bool DownloadWriterMetadata { get; set; }
+        public bool DownloadComposerMetadata { get; set; }
+        public bool DownloadOtherPeopleMetadata { get; set; }
+        public bool DownloadGuestStarMetadata { get; set; }
+
+        public PeopleMetadataOptions()
+        {
+            DownloadActorMetadata = true;
+            DownloadDirectorMetadata = true;
+        }
+    }
 }

+ 1 - 0
MediaBrowser.Model/Configuration/UserConfiguration.cs

@@ -73,6 +73,7 @@ namespace MediaBrowser.Model.Configuration
 
         public SubtitlePlaybackMode SubtitleMode { get; set; }
         public bool DisplayCollectionsView { get; set; }
+        public bool DisplayFoldersView { get; set; }
 
         /// <summary>
         /// Initializes a new instance of the <see cref="UserConfiguration" /> class.

+ 6 - 0
MediaBrowser.Model/Dlna/AudioOptions.cs

@@ -36,6 +36,12 @@ namespace MediaBrowser.Model.Dlna
         /// <value>The context.</value>
         public EncodingContext Context { get; set; }
 
+        /// <summary>
+        /// Gets or sets the audio transcoding bitrate.
+        /// </summary>
+        /// <value>The audio transcoding bitrate.</value>
+        public int? AudioTranscodingBitrate { get; set; }
+
         /// <summary>
         /// Gets the maximum bitrate.
         /// </summary>

+ 3 - 0
MediaBrowser.Model/Dlna/DeviceProfile.cs

@@ -52,6 +52,9 @@ namespace MediaBrowser.Model.Dlna
         public int? MaxStreamingBitrate { get; set; }
         public int? MaxStaticBitrate { get; set; }
 
+        public int? MusicStreamingTranscodingBitrate { get; set; }
+        public int? MusicSyncBitrate { get; set; }
+
         /// <summary>
         /// Controls the content of the X_DLNADOC element in the urn:schemas-dlna-org:device-1-0 namespace.
         /// </summary>

+ 5 - 4
MediaBrowser.Model/Dlna/StreamBuilder.cs

@@ -217,10 +217,11 @@ namespace MediaBrowser.Model.Dlna
                     playlistItem.MaxAudioChannels = Math.Min(options.MaxAudioChannels.Value, currentValue);
                 }
 
-                if (!playlistItem.AudioBitrate.HasValue)
-                {
-                    playlistItem.AudioBitrate = 128000;
-                }
+                var configuredBitrate = options.AudioTranscodingBitrate ??
+                    (options.Context == EncodingContext.Static ? options.Profile.MusicSyncBitrate : options.Profile.MusicStreamingTranscodingBitrate) ??
+                    128000;
+
+                playlistItem.AudioBitrate = Math.Min(configuredBitrate, playlistItem.AudioBitrate ?? configuredBitrate);
             }
 
             return playlistItem;

+ 4 - 0
MediaBrowser.Model/Entities/CollectionType.cs

@@ -24,5 +24,9 @@
         public const string Channels = "channels";
         public const string LiveTv = "livetv";
         public const string Playlists = "playlists";
+        public const string Folders = "folders";
+
+        public const string LiveTvChannels = "LiveTvChannels";
+        public const string LiveTvRecordingGroups = "LiveTvRecordingGroups";
     }
 }

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

@@ -243,6 +243,7 @@
     <Compile Include="Querying\ItemCountsQuery.cs" />
     <Compile Include="Querying\ItemsByNameQuery.cs" />
     <Compile Include="Entities\BaseItemInfo.cs" />
+    <Compile Include="Querying\LatestItemsQuery.cs" />
     <Compile Include="Querying\NextUpQuery.cs" />
     <Compile Include="Querying\QueryResult.cs" />
     <Compile Include="Querying\SeasonQuery.cs" />

+ 54 - 0
MediaBrowser.Model/Querying/LatestItemsQuery.cs

@@ -0,0 +1,54 @@
+
+namespace MediaBrowser.Model.Querying
+{
+    public class LatestItemsQuery
+    {
+        /// <summary>
+        /// The user to localize search results for
+        /// </summary>
+        /// <value>The user id.</value>
+        public string UserId { get; set; }
+
+        /// <summary>
+        /// Specify this to localize the search to a specific item or folder. Omit to use the root.
+        /// </summary>
+        /// <value>The parent id.</value>
+        public string ParentId { get; set; }
+
+        /// <summary>
+        /// Skips over a given number of items within the results. Use for paging.
+        /// </summary>
+        /// <value>The start index.</value>
+        public int? StartIndex { get; set; }
+
+        /// <summary>
+        /// The maximum number of items to return
+        /// </summary>
+        /// <value>The limit.</value>
+        public int? Limit { get; set; }
+
+        /// <summary>
+        /// Fields to return within the items, in addition to basic information
+        /// </summary>
+        /// <value>The fields.</value>
+        public ItemFields[] Fields { get; set; }
+
+        /// <summary>
+        /// Gets or sets the include item types.
+        /// </summary>
+        /// <value>The include item types.</value>
+        public string[] IncludeItemTypes { get; set; }
+
+        /// <summary>
+        /// Gets or sets a value indicating whether this instance is played.
+        /// </summary>
+        /// <value><c>null</c> if [is played] contains no value, <c>true</c> if [is played]; otherwise, <c>false</c>.</value>
+        public bool? IsPlayed { get; set; }
+
+        /// <summary>
+        /// Gets or sets a value indicating whether [group items].
+        /// </summary>
+        /// <value><c>true</c> if [group items]; otherwise, <c>false</c>.</value>
+        public bool GroupItems { get; set; }
+    }
+}

+ 5 - 0
MediaBrowser.Providers/Manager/ItemImageProvider.cs

@@ -236,6 +236,11 @@ namespace MediaBrowser.Providers.Manager
         {
             try
             {
+                if (!item.SupportsRemoteImageDownloading)
+                {
+                    return;
+                }
+
                 if (!refreshOptions.ReplaceAllImages && 
                     refreshOptions.ReplaceImages.Count == 0 && 
                     ContainsImages(item, provider.GetSupportedImages(item).ToList(), savedOptions, backdropLimit, screenshotLimit))

+ 8 - 2
MediaBrowser.Providers/Playlists/PlaylistMetadataService.cs

@@ -1,5 +1,7 @@
-using MediaBrowser.Common.IO;
+using System.Linq;
+using MediaBrowser.Common.IO;
 using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Playlists;
 using MediaBrowser.Controller.Providers;
 using MediaBrowser.Model.Entities;
@@ -40,7 +42,11 @@ namespace MediaBrowser.Providers.Playlists
 
             if (mergeMetadataSettings)
             {
-                target.LinkedChildren = source.LinkedChildren;
+                var list = source.LinkedChildren.ToList();
+
+                list.AddRange(target.LinkedChildren);
+
+                target.LinkedChildren = list;
             }
         }
     }

+ 4 - 3
MediaBrowser.Providers/TV/TvdbEpisodeImageProvider.cs

@@ -188,9 +188,11 @@ namespace MediaBrowser.Providers.TV
 
         public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date)
         {
-            if (item.LocationType != LocationType.Virtual)
+            var episode = (Episode)item;
+            
+            if (!episode.IsVirtualUnaired)
             {
-                // For non-virtual items, only enable if configured
+                // For non-unaired items, only enable if configured
                 if (!_config.Configuration.EnableTvDbUpdates)
                 {
                     return false;
@@ -199,7 +201,6 @@ namespace MediaBrowser.Providers.TV
 
             if (!item.HasImage(ImageType.Primary))
             {
-                var episode = (Episode)item;
                 var series = episode.Series;
 
                 var seriesId = series != null ? series.GetProviderId(MetadataProviders.Tvdb) : null;

+ 2 - 2
MediaBrowser.Server.Implementations/Activity/ActivityManager.cs

@@ -32,9 +32,9 @@ namespace MediaBrowser.Server.Implementations.Activity
             EventHelper.FireEventIfNotNull(EntryCreated, this, new GenericEventArgs<ActivityLogEntry>(entry), _logger);
         }
 
-        public QueryResult<ActivityLogEntry> GetActivityLogEntries(int? startIndex, int? limit)
+        public QueryResult<ActivityLogEntry> GetActivityLogEntries(DateTime? minDate, int? startIndex, int? limit)
         {
-            return _repo.GetActivityLogEntries(startIndex, limit);
+            return _repo.GetActivityLogEntries(minDate, startIndex, limit);
         }
     }
 }

+ 23 - 7
MediaBrowser.Server.Implementations/Activity/ActivityRepository.cs

@@ -139,7 +139,7 @@ namespace MediaBrowser.Server.Implementations.Activity
             }
         }
 
-        public QueryResult<ActivityLogEntry> GetActivityLogEntries(int? startIndex, int? limit)
+        public QueryResult<ActivityLogEntry> GetActivityLogEntries(DateTime? minDate, int? startIndex, int? limit)
         {
             using (var cmd = _connection.CreateCommand())
             {
@@ -147,17 +147,33 @@ namespace MediaBrowser.Server.Implementations.Activity
 
                 var whereClauses = new List<string>();
 
-                if (startIndex.HasValue && startIndex.Value > 0)
+                if (minDate.HasValue)
                 {
-                    whereClauses.Add(string.Format("Id NOT IN (SELECT Id FROM ActivityLogEntries ORDER BY DateCreated DESC LIMIT {0})",
-                        startIndex.Value.ToString(_usCulture)));
+                    whereClauses.Add("DateCreated>=@DateCreated");
+                    cmd.Parameters.Add(cmd, "@DateCreated", DbType.Date).Value = minDate.Value;
                 }
 
-                if (whereClauses.Count > 0)
+                var whereTextWithoutPaging = whereClauses.Count == 0 ?
+                    string.Empty :
+                    " where " + string.Join(" AND ", whereClauses.ToArray());
+
+                if (startIndex.HasValue && startIndex.Value > 0)
                 {
-                    cmd.CommandText += " where " + string.Join(" AND ", whereClauses.ToArray());
+                    var pagingWhereText = whereClauses.Count == 0 ?
+                        string.Empty :
+                        " where " + string.Join(" AND ", whereClauses.ToArray());
+                    
+                    whereClauses.Add(string.Format("Id NOT IN (SELECT Id FROM ActivityLogEntries {0} ORDER BY DateCreated DESC LIMIT {1})",
+                        pagingWhereText,
+                        startIndex.Value.ToString(_usCulture)));
                 }
 
+                var whereText = whereClauses.Count == 0 ? 
+                    string.Empty :
+                    " where " + string.Join(" AND ", whereClauses.ToArray());
+
+                cmd.CommandText += whereText;
+
                 cmd.CommandText += " ORDER BY DateCreated DESC";
 
                 if (limit.HasValue)
@@ -165,7 +181,7 @@ namespace MediaBrowser.Server.Implementations.Activity
                     cmd.CommandText += " LIMIT " + limit.Value.ToString(_usCulture);
                 }
 
-                cmd.CommandText += "; select count (Id) from ActivityLogEntries";
+                cmd.CommandText += "; select count (Id) from ActivityLogEntries" + whereTextWithoutPaging;
 
                 var list = new List<ActivityLogEntry>();
                 var count = 0;

+ 30 - 1
MediaBrowser.Server.Implementations/Channels/ChannelDownloadScheduledTask.cs

@@ -7,6 +7,7 @@ using MediaBrowser.Controller.Channels;
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Model.Channels;
+using MediaBrowser.Model.Configuration;
 using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Logging;
 using MediaBrowser.Model.MediaInfo;
@@ -154,7 +155,7 @@ namespace MediaBrowser.Server.Implementations.Channels
                 {
                     try
                     {
-                        await DownloadChannelItem(item, cancellationToken, path);
+                        await DownloadChannelItem(item, options, cancellationToken, path);
                     }
                     catch (OperationCanceledException)
                     {
@@ -176,9 +177,18 @@ namespace MediaBrowser.Server.Implementations.Channels
         }
 
         private async Task DownloadChannelItem(BaseItemDto item,
+            ChannelOptions channelOptions,
             CancellationToken cancellationToken,
             string path)
         {
+            if (channelOptions.DownloadSizeLimit.HasValue)
+            {
+                if (IsSizeLimitReached(path, channelOptions.DownloadSizeLimit.Value))
+                {
+                    return;
+                }    
+            }
+
             var sources = await _manager.GetChannelItemMediaSources(item.Id, cancellationToken)
                 .ConfigureAwait(false);
 
@@ -253,6 +263,25 @@ namespace MediaBrowser.Server.Implementations.Channels
             }
         }
 
+        private bool IsSizeLimitReached(string path, double gbLimit)
+        {
+            var byteLimit = gbLimit*1000000000;
+
+            long total = 0;
+
+            foreach (var file in new DirectoryInfo(path).EnumerateFiles("*", SearchOption.AllDirectories))
+            {
+                total += file.Length;
+
+                if (total >= byteLimit)
+                {
+                    return true;
+                }
+            }
+
+            return false;
+        }
+
         private async Task RefreshMediaSourceItems(IEnumerable<MediaSourceInfo> items, CancellationToken cancellationToken)
         {
             foreach (var item in items)

+ 18 - 10
MediaBrowser.Server.Implementations/EntryPoints/ActivityLogEntryPoint.cs

@@ -61,15 +61,15 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
 
         public void Run()
         {
-            _taskManager.TaskExecuting += _taskManager_TaskExecuting;
-            _taskManager.TaskCompleted += _taskManager_TaskCompleted;
+            //_taskManager.TaskExecuting += _taskManager_TaskExecuting;
+            //_taskManager.TaskCompleted += _taskManager_TaskCompleted;
 
-            _installationManager.PluginInstalled += _installationManager_PluginInstalled;
-            _installationManager.PluginUninstalled += _installationManager_PluginUninstalled;
-            _installationManager.PluginUpdated += _installationManager_PluginUpdated;
+            //_installationManager.PluginInstalled += _installationManager_PluginInstalled;
+            //_installationManager.PluginUninstalled += _installationManager_PluginUninstalled;
+            //_installationManager.PluginUpdated += _installationManager_PluginUpdated;
 
-            _libraryManager.ItemAdded += _libraryManager_ItemAdded;
-            _libraryManager.ItemRemoved += _libraryManager_ItemRemoved;
+            //_libraryManager.ItemAdded += _libraryManager_ItemAdded;
+            //_libraryManager.ItemRemoved += _libraryManager_ItemRemoved;
 
             _sessionManager.SessionStarted += _sessionManager_SessionStarted;
             _sessionManager.AuthenticationFailed += _sessionManager_AuthenticationFailed;
@@ -79,7 +79,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
             _sessionManager.PlaybackStart += _sessionManager_PlaybackStart;
             _sessionManager.PlaybackStopped += _sessionManager_PlaybackStopped;
 
-            _subManager.SubtitlesDownloaded += _subManager_SubtitlesDownloaded;
+            //_subManager.SubtitlesDownloaded += _subManager_SubtitlesDownloaded;
             _subManager.SubtitleDownloadFailure += _subManager_SubtitleDownloadFailure;
 
             _userManager.UserCreated += _userManager_UserCreated;
@@ -87,8 +87,8 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
             _userManager.UserDeleted += _userManager_UserDeleted;
             _userManager.UserConfigurationUpdated += _userManager_UserConfigurationUpdated;
 
-            _config.ConfigurationUpdated += _config_ConfigurationUpdated;
-            _config.NamedConfigurationUpdated += _config_NamedConfigurationUpdated;
+            //_config.ConfigurationUpdated += _config_ConfigurationUpdated;
+            //_config.NamedConfigurationUpdated += _config_NamedConfigurationUpdated;
 
             //_logManager.LoggerLoaded += _logManager_LoggerLoaded;
 
@@ -165,6 +165,9 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
             if (string.IsNullOrWhiteSpace(session.UserName))
             {
                 name = string.Format(_localization.GetLocalizedString("DeviceOfflineWithName"), session.DeviceName);
+
+                // Causing too much spam for now
+                return;
             }
             else
             {
@@ -288,6 +291,9 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
             if (string.IsNullOrWhiteSpace(session.UserName))
             {
                 name = string.Format(_localization.GetLocalizedString("DeviceOnlineWithName"), session.DeviceName);
+
+                // Causing too much spam for now
+                return;
             }
             else
             {
@@ -394,6 +400,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
 
             if (result.Status == TaskCompletionStatus.Cancelled)
             {
+                return;
                 CreateLogEntry(new ActivityLogEntry
                 {
                     Name = string.Format(_localization.GetLocalizedString("ScheduledTaskCancelledWithName"), task.Name),
@@ -403,6 +410,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
             }
             else if (result.Status == TaskCompletionStatus.Completed)
             {
+                return;
                 CreateLogEntry(new ActivityLogEntry
                 {
                     Name = string.Format(_localization.GetLocalizedString("ScheduledTaskCompletedWithName"), task.Name),

+ 2 - 3
MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs

@@ -35,8 +35,6 @@ namespace MediaBrowser.Server.Implementations.HttpServer
 
         private IHttpListener _listener;
 
-        private const int IdleTimeout = 300;
-
         private readonly ContainerAdapter _containerAdapter;
 
         public event EventHandler<WebSocketConnectEventArgs> WebSocketConnected;
@@ -152,7 +150,8 @@ namespace MediaBrowser.Server.Implementations.HttpServer
             HostContext.Config.HandlerFactoryPath = ListenerRequest.GetHandlerPathIfAny(UrlPrefixes.First());
 
             _listener = NativeWebSocket.IsSupported
-                ? _listener = new WebSocketSharpListener(_logger)
+                ? _listener = new HttpListenerServer(_logger)
+                //? _listener = new WebSocketSharpListener(_logger)
                 : _listener = new WebSocketSharpListener(_logger);
 
             _listener.WebSocketHandler = WebSocketHandler;

+ 102 - 13
MediaBrowser.Server.Implementations/HttpServer/SocketSharp/WebSocketSharpListener.cs

@@ -7,16 +7,17 @@ using System.Collections.Concurrent;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
+using System.Threading;
 using System.Threading.Tasks;
 using WebSocketSharp.Net;
-using WebSocketSharp.Server;
 
 namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
 {
     public class WebSocketSharpListener : IHttpListener
     {
         private readonly ConcurrentDictionary<string, string> _localEndPoints = new ConcurrentDictionary<string, string>(StringComparer.OrdinalIgnoreCase);
-        private WebSocketSharp.Server.HttpServer _httpsv;
+        private WebSocketSharp.Net.HttpListener _listener;
+        private readonly AutoResetEvent _listenForNextRequest = new AutoResetEvent(false);
 
         private readonly ILogger _logger;
 
@@ -38,16 +39,85 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
 
         public void Start(IEnumerable<string> urlPrefixes)
         {
-            _httpsv = new WebSocketSharp.Server.HttpServer(8096, false, urlPrefixes.First());
+            if (_listener == null)
+                _listener = new WebSocketSharp.Net.HttpListener();
 
-            _httpsv.OnRequest += _httpsv_OnRequest;
+            foreach (var prefix in urlPrefixes)
+            {
+                _logger.Info("Adding HttpListener prefix " + prefix);
+                _listener.Prefixes.Add(prefix);
+            }
+
+            _listener.Start();
 
-            _httpsv.Start();
+            Task.Factory.StartNew(Listen, TaskCreationOptions.LongRunning);
+        }
+
+        private bool IsListening
+        {
+            get { return _listener != null && _listener.IsListening; }
         }
 
-        void _httpsv_OnRequest(object sender, HttpRequestEventArgs e)
+        // Loop here to begin processing of new requests.
+        private void Listen()
         {
-            Task.Factory.StartNew(() => InitTask(e.Context));
+            while (IsListening)
+            {
+                if (_listener == null) return;
+
+                try
+                {
+                    _listener.BeginGetContext(ListenerCallback, _listener);
+                    _listenForNextRequest.WaitOne();
+                }
+                catch (Exception ex)
+                {
+                    _logger.Error("Listen()", ex);
+                    return;
+                }
+                if (_listener == null) return;
+            }
+        }
+
+        // Handle the processing of a request in here.
+        private void ListenerCallback(IAsyncResult asyncResult)
+        {
+            var listener = asyncResult.AsyncState as HttpListener;
+            HttpListenerContext context;
+
+            if (listener == null) return;
+            var isListening = listener.IsListening;
+
+            try
+            {
+                if (!isListening)
+                {
+                    _logger.Debug("Ignoring ListenerCallback() as HttpListener is no longer listening"); return;
+                }
+                // The EndGetContext() method, as with all Begin/End asynchronous methods in the .NET Framework,
+                // blocks until there is a request to be processed or some type of data is available.
+                context = listener.EndGetContext(asyncResult);
+            }
+            catch (Exception ex)
+            {
+                // You will get an exception when httpListener.Stop() is called
+                // because there will be a thread stopped waiting on the .EndGetContext()
+                // method, and again, that is just the way most Begin/End asynchronous
+                // methods of the .NET Framework work.
+                var errMsg = ex + ": " + IsListening;
+                _logger.Warn(errMsg);
+                return;
+            }
+            finally
+            {
+                // Once we know we have a request (or exception), we signal the other thread
+                // so that it calls the BeginGetContext() (or possibly exits if we're not
+                // listening any more) method to start handling the next incoming request
+                // while we continue to process this request on a different thread.
+                _listenForNextRequest.Set();
+            }
+
+            Task.Factory.StartNew(() => InitTask(context));
         }
 
         private void InitTask(HttpListenerContext context)
@@ -169,20 +239,39 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
 
         public void Stop()
         {
-            _httpsv.Stop();
+            if (_listener != null)
+            {
+                foreach (var prefix in _listener.Prefixes.ToList())
+                {
+                    _listener.Prefixes.Remove(prefix);
+                }
+
+                _listener.Close();
+            }
         }
 
-        private readonly object _disposeLock = new object();
         public void Dispose()
         {
+            Dispose(true);
+        }
+
+        private bool _disposed;
+        private readonly object _disposeLock = new object();
+        protected virtual void Dispose(bool disposing)
+        {
+            if (_disposed) return;
+
             lock (_disposeLock)
             {
-                if (_httpsv != null)
+                if (_disposed) return;
+
+                if (disposing)
                 {
-                    _httpsv.OnRequest -= _httpsv_OnRequest;
-                    _httpsv.Stop();
-                    _httpsv = null;
+                    Stop();
                 }
+
+                //release unmanaged resources here...
+                _disposed = true;
             }
         }
     }

+ 1 - 1
MediaBrowser.Server.Implementations/Library/LibraryManager.cs

@@ -906,7 +906,7 @@ namespace MediaBrowser.Server.Implementations.Library
             // Ensure the location is available.
             Directory.CreateDirectory(ConfigurationManager.ApplicationPaths.PeoplePath);
 
-            return new PeopleValidator(this, _logger).ValidatePeople(cancellationToken, new MetadataRefreshOptions(), progress);
+            return new PeopleValidator(this, _logger, ConfigurationManager).ValidatePeople(cancellationToken, progress);
         }
 
         /// <summary>

+ 7 - 2
MediaBrowser.Server.Implementations/Library/UserViewManager.cs

@@ -93,7 +93,7 @@ namespace MediaBrowser.Server.Implementations.Library
             if (user.Configuration.DisplayCollectionsView &&
                 recursiveChildren.OfType<BoxSet>().Any())
             {
-                list.Add(await GetUserView(CollectionType.BoxSets, user, CollectionType.BoxSets, cancellationToken).ConfigureAwait(false));
+                list.Add(await GetUserView(CollectionType.BoxSets, user, string.Empty, cancellationToken).ConfigureAwait(false));
             }
 
             if (recursiveChildren.OfType<Playlist>().Any())
@@ -101,6 +101,11 @@ namespace MediaBrowser.Server.Implementations.Library
                 list.Add(_playlists.GetPlaylistsFolder(user.Id.ToString("N")));
             }
 
+            if (user.Configuration.DisplayFoldersView)
+            {
+                list.Add(await GetUserView(CollectionType.Folders, user, "zz_" + CollectionType.Folders, cancellationToken).ConfigureAwait(false));
+            }
+
             if (query.IncludeExternalContent)
             {
                 var channelResult = await _channelManager.GetChannels(new ChannelQuery
@@ -131,7 +136,7 @@ namespace MediaBrowser.Server.Implementations.Library
             return _libraryManager.Sort(list, user, new[] { ItemSortBy.SortName }, SortOrder.Ascending).Cast<Folder>();
         }
 
-        private Task<UserView> GetUserView(string type, User user, string sortName, CancellationToken cancellationToken)
+        public Task<UserView> GetUserView(string type, User user, string sortName, CancellationToken cancellationToken)
         {
             var name = _localizationManager.GetLocalizedString("ViewType" + type);
 

+ 95 - 8
MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs

@@ -1,8 +1,13 @@
 using MediaBrowser.Common.Progress;
+using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Providers;
+using MediaBrowser.Model.Configuration;
+using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Logging;
 using System;
+using System.Collections.Generic;
 using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
@@ -23,46 +28,128 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
         /// </summary>
         private readonly ILogger _logger;
 
+        private readonly IServerConfigurationManager _config;
+
         /// <summary>
         /// Initializes a new instance of the <see cref="PeopleValidator" /> class.
         /// </summary>
         /// <param name="libraryManager">The library manager.</param>
         /// <param name="logger">The logger.</param>
-        public PeopleValidator(ILibraryManager libraryManager, ILogger logger)
+        public PeopleValidator(ILibraryManager libraryManager, ILogger logger, IServerConfigurationManager config)
         {
             _libraryManager = libraryManager;
             _logger = logger;
+            _config = config;
+        }
+
+        private bool DownloadMetadata(PersonInfo i, PeopleMetadataOptions options)
+        {
+            if (i.IsType(PersonType.Actor))
+            {
+                return options.DownloadActorMetadata;
+            }
+            if (i.IsType(PersonType.Director))
+            {
+                return options.DownloadDirectorMetadata;
+            }
+            if (i.IsType(PersonType.Composer))
+            {
+                return options.DownloadComposerMetadata;
+            }
+            if (i.IsType(PersonType.Writer))
+            {
+                return options.DownloadWriterMetadata;
+            }
+            if (i.IsType(PersonType.Producer))
+            {
+                return options.DownloadProducerMetadata;
+            }
+            if (i.IsType(PersonType.GuestStar))
+            {
+                return options.DownloadGuestStarMetadata;
+            }
+
+            return options.DownloadOtherPeopleMetadata;
+        }
+
+        private IEnumerable<PersonInfo> GetPeopleToValidate(BaseItem item, PeopleMetadataOptions options)
+        {
+            return item.People.Where(i =>
+            {
+                if (i.IsType(PersonType.Actor))
+                {
+                    return options.DownloadActorMetadata;
+                }
+                if (i.IsType(PersonType.Director))
+                {
+                    return options.DownloadDirectorMetadata;
+                }
+                if (i.IsType(PersonType.Composer))
+                {
+                    return options.DownloadComposerMetadata;
+                }
+                if (i.IsType(PersonType.Writer))
+                {
+                    return options.DownloadWriterMetadata;
+                }
+                if (i.IsType(PersonType.Producer))
+                {
+                    return options.DownloadProducerMetadata;
+                }
+                if (i.IsType(PersonType.GuestStar))
+                {
+                    return options.DownloadGuestStarMetadata;
+                }
+
+                return options.DownloadOtherPeopleMetadata;
+            });
         }
 
         /// <summary>
         /// Validates the people.
         /// </summary>
         /// <param name="cancellationToken">The cancellation token.</param>
-        /// <param name="options">The options.</param>
         /// <param name="progress">The progress.</param>
         /// <returns>Task.</returns>
-        public async Task ValidatePeople(CancellationToken cancellationToken, MetadataRefreshOptions options, IProgress<double> progress)
+        public async Task ValidatePeople(CancellationToken cancellationToken, IProgress<double> progress)
         {
             var innerProgress = new ActionableProgress<double>();
 
             innerProgress.RegisterAction(pct => progress.Report(pct * .15));
 
+            var peopleOptions = _config.Configuration.PeopleMetadataOptions;
+
             var people = _libraryManager.RootFolder.GetRecursiveChildren()
-                .SelectMany(c => c.People)
+                .SelectMany(i => i.People)
                 .Where(i => !string.IsNullOrWhiteSpace(i.Name))
-                .Select(i => i.Name)
-                .Distinct(StringComparer.OrdinalIgnoreCase)
                 .ToList();
 
-            var numComplete = 0;
+            var dict = new Dictionary<string, bool>(StringComparer.OrdinalIgnoreCase);
 
             foreach (var person in people)
+            {
+                bool current;
+                if (!dict.TryGetValue(person.Name, out current) || !current)
+                {
+                    dict[person.Name] = DownloadMetadata(person, peopleOptions);
+                }
+            }
+
+            var numComplete = 0;
+
+            foreach (var person in dict)
             {
                 cancellationToken.ThrowIfCancellationRequested();
 
                 try
                 {
-                    var item = _libraryManager.GetPerson(person);
+                    var item = _libraryManager.GetPerson(person.Key);
+
+                    var options = new MetadataRefreshOptions
+                    {
+                         MetadataRefreshMode = person.Value ? MetadataRefreshMode.Default : MetadataRefreshMode.ValidationOnly,
+                         ImageRefreshMode = person.Value ? ImageRefreshMode.Default : ImageRefreshMode.ValidationOnly
+                    };
 
                     await item.RefreshMetadata(options, cancellationToken).ConfigureAwait(false);
                 }

+ 60 - 14
MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs

@@ -128,7 +128,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
             _taskManager.CancelIfRunningAndQueue<RefreshChannelsScheduledTask>();
         }
 
-        public async Task<QueryResult<ChannelInfoDto>> GetChannels(LiveTvChannelQuery query, CancellationToken cancellationToken)
+        public async Task<QueryResult<LiveTvChannel>> GetInternalChannels(LiveTvChannelQuery query, CancellationToken cancellationToken)
         {
             var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(new Guid(query.UserId));
 
@@ -217,9 +217,24 @@ namespace MediaBrowser.Server.Implementations.LiveTv
                 allEnumerable = allEnumerable.Take(query.Limit.Value);
             }
 
+            var result = new QueryResult<LiveTvChannel>
+            {
+                Items = allEnumerable.ToArray(),
+                TotalRecordCount = allChannels.Count
+            };
+
+            return result;
+        }
+
+        public async Task<QueryResult<ChannelInfoDto>> GetChannels(LiveTvChannelQuery query, CancellationToken cancellationToken)
+        {
+            var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(new Guid(query.UserId));
+
+            var internalResult = await GetInternalChannels(query, cancellationToken).ConfigureAwait(false);
+
             var returnList = new List<ChannelInfoDto>();
 
-            foreach (var channel in allEnumerable)
+            foreach (var channel in internalResult.Items)
             {
                 var currentProgram = await GetCurrentProgram(channel.ExternalId, cancellationToken).ConfigureAwait(false);
 
@@ -229,7 +244,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
             var result = new QueryResult<ChannelInfoDto>
             {
                 Items = returnList.ToArray(),
-                TotalRecordCount = allChannels.Count
+                TotalRecordCount = internalResult.TotalRecordCount
             };
 
             return result;
@@ -260,12 +275,20 @@ namespace MediaBrowser.Server.Implementations.LiveTv
             return obj;
         }
 
-        private async Task RefreshIfNeeded(IEnumerable<LiveTvProgram> programs, CancellationToken cancellationToken)
+        private Task RefreshIfNeeded(IEnumerable<LiveTvProgram> programs, CancellationToken cancellationToken)
         {
-            foreach (var program in programs)
+            var list = programs.ToList();
+
+            Task.Run(async () =>
             {
-                await RefreshIfNeeded(program, cancellationToken).ConfigureAwait(false);
-            }
+                foreach (var program in list)
+                {
+                    await RefreshIfNeeded(program, CancellationToken.None).ConfigureAwait(false);
+                }
+
+            }, cancellationToken);
+
+            return Task.FromResult(true);
         }
 
         private async Task RefreshIfNeeded(LiveTvProgram program, CancellationToken cancellationToken)
@@ -275,9 +298,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv
                 return;
             }
 
-            await program.RefreshMetadata(cancellationToken).ConfigureAwait(false);
-
             _refreshedPrograms.TryAdd(program.Id, true);
+            
+            await program.RefreshMetadata(cancellationToken).ConfigureAwait(false);
         }
 
         public async Task<ILiveTvRecording> GetInternalRecording(string id, CancellationToken cancellationToken)
@@ -1028,15 +1051,15 @@ namespace MediaBrowser.Server.Implementations.LiveTv
             return channels.Select(i => new Tuple<string, ChannelInfo>(service.Name, i));
         }
 
-        public async Task<QueryResult<RecordingInfoDto>> GetRecordings(RecordingQuery query, CancellationToken cancellationToken)
+        public async Task<QueryResult<BaseItem>> GetInternalRecordings(RecordingQuery query, CancellationToken cancellationToken)
         {
             var service = ActiveService;
 
             if (service == null)
             {
-                return new QueryResult<RecordingInfoDto>
+                return new QueryResult<BaseItem>
                 {
-                    Items = new RecordingInfoDto[] { }
+                    Items = new BaseItem[] { }
                 };
             }
 
@@ -1121,7 +1144,30 @@ namespace MediaBrowser.Server.Implementations.LiveTv
                 entities = entities.Take(query.Limit.Value);
             }
 
-            var returnArray = entities
+            return new QueryResult<BaseItem>
+            {
+                Items = entities.Cast<BaseItem>().ToArray(),
+                TotalRecordCount = entityList.Count
+            };
+        }
+
+        public async Task<QueryResult<RecordingInfoDto>> GetRecordings(RecordingQuery query, CancellationToken cancellationToken)
+        {
+            var service = ActiveService;
+
+            if (service == null)
+            {
+                return new QueryResult<RecordingInfoDto>
+                {
+                    Items = new RecordingInfoDto[] { }
+                };
+            }
+
+            var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(new Guid(query.UserId));
+
+            var internalResult = await GetInternalRecordings(query, cancellationToken).ConfigureAwait(false);
+
+            var returnArray = internalResult.Items.Cast<ILiveTvRecording>()
                 .Select(i =>
                 {
                     var channel = string.IsNullOrEmpty(i.RecordingInfo.ChannelId) ? null : GetInternalChannel(_tvDtoService.GetInternalChannelId(service.Name, i.RecordingInfo.ChannelId));
@@ -1132,7 +1178,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
             return new QueryResult<RecordingInfoDto>
             {
                 Items = returnArray,
-                TotalRecordCount = entityList.Count
+                TotalRecordCount = internalResult.TotalRecordCount
             };
         }
 

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

@@ -58,14 +58,14 @@
     "ButtonMute": "Mute",
     "ButtonUnmute": "Unmute",
     "ButtonStop": "Stop",
-    "ButtonNextTrack": "Next Track",
+    "ButtonNextTrack": "Next track",
     "ButtonPause": "Pause",
     "ButtonPlay": "Play",
     "ButtonEdit": "Edit",
     "ButtonQueue": "Queue",
     "ButtonPlayTrailer": "Play trailer",
     "ButtonPlaylist": "Playlist",
-    "ButtonPreviousTrack": "Previous Track",
+    "ButtonPreviousTrack": "Previous track",
     "LabelEnabled": "Enabled",
     "LabelDisabled": "Disabled",
     "ButtonMoreInformation": "More Information",

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

@@ -58,14 +58,14 @@
     "ButtonMute": "Mute",
     "ButtonUnmute": "Unmute",
     "ButtonStop": "Stop",
-    "ButtonNextTrack": "Next Track",
+    "ButtonNextTrack": "Next track",
     "ButtonPause": "Pause",
     "ButtonPlay": "Play",
     "ButtonEdit": "Edit",
     "ButtonQueue": "Queue",
     "ButtonPlayTrailer": "Play trailer",
     "ButtonPlaylist": "Playlist",
-    "ButtonPreviousTrack": "Previous Track",
+    "ButtonPreviousTrack": "Previous track",
     "LabelEnabled": "Enabled",
     "LabelDisabled": "Disabled",
     "ButtonMoreInformation": "More Information",

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

@@ -58,7 +58,7 @@
     "ButtonMute": "Mute",
     "ButtonUnmute": "Unmute",
     "ButtonStop": "Stop",
-    "ButtonNextTrack": "Next Track",
+    "ButtonNextTrack": "Next track",
     "ButtonPause": "Pause",
     "ButtonPlay": "P\u0159ehr\u00e1t",
     "ButtonEdit": "Upravit",

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

@@ -58,14 +58,14 @@
     "ButtonMute": "Mute",
     "ButtonUnmute": "Unmute",
     "ButtonStop": "Stop",
-    "ButtonNextTrack": "Next Track",
+    "ButtonNextTrack": "Next track",
     "ButtonPause": "Pause",
     "ButtonPlay": "Afspil",
     "ButtonEdit": "Rediger",
     "ButtonQueue": "Queue",
     "ButtonPlayTrailer": "Play trailer",
     "ButtonPlaylist": "Playlist",
-    "ButtonPreviousTrack": "Previous Track",
+    "ButtonPreviousTrack": "Previous track",
     "LabelEnabled": "Enabled",
     "LabelDisabled": "Disabled",
     "ButtonMoreInformation": "More Information",

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

@@ -58,14 +58,14 @@
     "ButtonMute": "Mute",
     "ButtonUnmute": "Unmute",
     "ButtonStop": "Stop",
-    "ButtonNextTrack": "Next Track",
+    "ButtonNextTrack": "Next track",
     "ButtonPause": "Pause",
     "ButtonPlay": "Play",
     "ButtonEdit": "Edit",
     "ButtonQueue": "Queue",
     "ButtonPlayTrailer": "Play trailer",
     "ButtonPlaylist": "Playlist",
-    "ButtonPreviousTrack": "Previous Track",
+    "ButtonPreviousTrack": "Previous track",
     "LabelEnabled": "Enabled",
     "LabelDisabled": "Disabled",
     "ButtonMoreInformation": "More Information",

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

@@ -58,14 +58,14 @@
     "ButtonMute": "Mute",
     "ButtonUnmute": "Unmute",
     "ButtonStop": "Stop",
-    "ButtonNextTrack": "Next Track",
+    "ButtonNextTrack": "Next track",
     "ButtonPause": "Pause",
     "ButtonPlay": "Play",
     "ButtonEdit": "Edit",
     "ButtonQueue": "Queue",
     "ButtonPlayTrailer": "Play trailer",
     "ButtonPlaylist": "Playlist",
-    "ButtonPreviousTrack": "Previous Track",
+    "ButtonPreviousTrack": "Previous track",
     "LabelEnabled": "Enabled",
     "LabelDisabled": "Disabled",
     "ButtonMoreInformation": "More Information",

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

@@ -58,14 +58,14 @@
     "ButtonMute": "Mute",
     "ButtonUnmute": "Unmute",
     "ButtonStop": "Stop",
-    "ButtonNextTrack": "Next Track",
+    "ButtonNextTrack": "Next track",
     "ButtonPause": "Pause",
     "ButtonPlay": "Play",
     "ButtonEdit": "Edit",
     "ButtonQueue": "Queue",
     "ButtonPlayTrailer": "Play trailer",
     "ButtonPlaylist": "Playlist",
-    "ButtonPreviousTrack": "Previous Track",
+    "ButtonPreviousTrack": "Previous track",
     "LabelEnabled": "Enabled",
     "LabelDisabled": "Disabled",
     "ButtonMoreInformation": "More Information",

+ 17 - 17
MediaBrowser.Server.Implementations/Localization/JavaScript/es_MX.json

@@ -331,24 +331,24 @@
     "ButtonViewSeriesRecording": "Ver grabaciones de series",
     "ValueOriginalAirDate": "Fecha de transmisi\u00f3n original: {0}",
     "ButtonRemoveFromPlaylist": "Eliminar de la lista de reproducci\u00f3n",
-    "HeaderSpecials": "Specials",
-    "HeaderTrailers": "Trailers",
+    "HeaderSpecials": "Especiales",
+    "HeaderTrailers": "Avances",
     "HeaderAudio": "Audio",
-    "HeaderResolution": "Resolution",
+    "HeaderResolution": "Resoluci\u00f3n",
     "HeaderVideo": "Video",
-    "HeaderRuntime": "Runtime",
-    "HeaderCommunityRating": "Community rating",
-    "HeaderParentalRating": "Parental rating",
-    "HeaderReleaseDate": "Release date",
-    "HeaderDateAdded": "Date added",
+    "HeaderRuntime": "Duraci\u00f3n",
+    "HeaderCommunityRating": "Calificaci\u00f3n de la comunidad",
+    "HeaderParentalRating": "Calificaci\u00f3n parental",
+    "HeaderReleaseDate": "Fecha de estreno",
+    "HeaderDateAdded": "Fecha de adici\u00f3n",
     "HeaderSeries": "Series",
-    "HeaderSeason": "Season",
-    "HeaderSeasonNumber": "Season number",
-    "HeaderNetwork": "Network",
-    "HeaderYear": "Year",
-    "HeaderGameSystem": "Game system",
-    "HeaderPlayers": "Players",
-    "HeaderEmbeddedImage": "Embedded image",
-    "HeaderTrack": "Track",
-    "HeaderDisc": "Disc"
+    "HeaderSeason": "Temporada",
+    "HeaderSeasonNumber": "N\u00famero de temporada",
+    "HeaderNetwork": "Cadena",
+    "HeaderYear": "A\u00f1o",
+    "HeaderGameSystem": "Sistema de Juegos",
+    "HeaderPlayers": "Jugadores",
+    "HeaderEmbeddedImage": "Im\u00e1gen embebida",
+    "HeaderTrack": "Pista",
+    "HeaderDisc": "Disco"
 }

+ 22 - 22
MediaBrowser.Server.Implementations/Localization/JavaScript/fr.json

@@ -321,34 +321,34 @@
     "ButtonNew": "Nouveau",
     "MessageInternetExplorerWebm": "Pour de meilleurs r\u00e9sultats avec Internet Explorer, merci d'installer le plugin WebM pour IE.",
     "HeaderVideoError": "Erreur vid\u00e9o",
-    "ButtonAddToPlaylist": "Add to playlist",
-    "HeaderAddToPlaylist": "Add to Playlist",
+    "ButtonAddToPlaylist": "Ajouter \u00e0 la liste de lecture",
+    "HeaderAddToPlaylist": "Ajouter \u00e0 la liste de lecture",
     "LabelName": "Nom:",
     "ButtonSubmit": "Soumettre",
-    "LabelSelectPlaylist": "Playlist:",
-    "OptionNewPlaylist": "New playlist...",
-    "MessageAddedToPlaylistSuccess": "Ok",
-    "ButtonViewSeriesRecording": "View series recording",
-    "ValueOriginalAirDate": "Original air date: {0}",
+    "LabelSelectPlaylist": "Liste de lecture:",
+    "OptionNewPlaylist": "Nouvelle liste de lecture...",
+    "MessageAddedToPlaylistSuccess": "OK",
+    "ButtonViewSeriesRecording": "Voir enregistrements de s\u00e9ries",
+    "ValueOriginalAirDate": "Date de diffusion originale: {0}",
     "ButtonRemoveFromPlaylist": "Remove from playlist",
     "HeaderSpecials": "Specials",
-    "HeaderTrailers": "Trailers",
+    "HeaderTrailers": "Bande-Annonces",
     "HeaderAudio": "Audio",
-    "HeaderResolution": "Resolution",
-    "HeaderVideo": "Video",
+    "HeaderResolution": "R\u00e9solution",
+    "HeaderVideo": "Vid\u00e9o",
     "HeaderRuntime": "Runtime",
-    "HeaderCommunityRating": "Community rating",
-    "HeaderParentalRating": "Parental rating",
-    "HeaderReleaseDate": "Release date",
-    "HeaderDateAdded": "Date added",
-    "HeaderSeries": "Series",
-    "HeaderSeason": "Season",
-    "HeaderSeasonNumber": "Season number",
-    "HeaderNetwork": "Network",
-    "HeaderYear": "Year",
-    "HeaderGameSystem": "Game system",
-    "HeaderPlayers": "Players",
+    "HeaderCommunityRating": "Note de communaut\u00e9",
+    "HeaderParentalRating": "Note parentale",
+    "HeaderReleaseDate": "Date de lancement",
+    "HeaderDateAdded": "Date ajout\u00e9e",
+    "HeaderSeries": "S\u00e9ries",
+    "HeaderSeason": "Saison",
+    "HeaderSeasonNumber": "Num\u00e9ro de saison",
+    "HeaderNetwork": "R\u00e9seau",
+    "HeaderYear": "Ann\u00e9e",
+    "HeaderGameSystem": "Plateforme de jeu",
+    "HeaderPlayers": "Lecteurs",
     "HeaderEmbeddedImage": "Embedded image",
     "HeaderTrack": "Track",
-    "HeaderDisc": "Disc"
+    "HeaderDisc": "Disque"
 }

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

@@ -58,14 +58,14 @@
     "ButtonMute": "Mute",
     "ButtonUnmute": "Unmute",
     "ButtonStop": "Stop",
-    "ButtonNextTrack": "Next Track",
+    "ButtonNextTrack": "Next track",
     "ButtonPause": "Pause",
     "ButtonPlay": "\u05e0\u05d2\u05df",
     "ButtonEdit": "\u05e2\u05e8\u05d5\u05da",
     "ButtonQueue": "Queue",
     "ButtonPlayTrailer": "Play trailer",
     "ButtonPlaylist": "Playlist",
-    "ButtonPreviousTrack": "Previous Track",
+    "ButtonPreviousTrack": "Previous track",
     "LabelEnabled": "Enabled",
     "LabelDisabled": "Disabled",
     "ButtonMoreInformation": "More Information",

+ 11 - 11
MediaBrowser.Server.Implementations/Localization/JavaScript/it.json

@@ -321,15 +321,15 @@
     "ButtonNew": "Nuovo",
     "MessageInternetExplorerWebm": "Se utilizzi internet explorer installa WebM plugin",
     "HeaderVideoError": "Video Error",
-    "ButtonAddToPlaylist": "Add to playlist",
-    "HeaderAddToPlaylist": "Add to Playlist",
+    "ButtonAddToPlaylist": "Aggiungi alla playlist",
+    "HeaderAddToPlaylist": "Aggiungi alla playlist",
     "LabelName": "Nome:",
     "ButtonSubmit": "Invia",
     "LabelSelectPlaylist": "Playlist:",
-    "OptionNewPlaylist": "New playlist...",
+    "OptionNewPlaylist": "Nuova  playlist...",
     "MessageAddedToPlaylistSuccess": "Ok",
-    "ButtonViewSeriesRecording": "View series recording",
-    "ValueOriginalAirDate": "Original air date: {0}",
+    "ButtonViewSeriesRecording": "Vista delle serie in registrazione",
+    "ValueOriginalAirDate": "Prima messa in onda (originale): {0}",
     "ButtonRemoveFromPlaylist": "Remove from playlist",
     "HeaderSpecials": "Specials",
     "HeaderTrailers": "Trailers",
@@ -345,10 +345,10 @@
     "HeaderSeason": "Season",
     "HeaderSeasonNumber": "Season number",
     "HeaderNetwork": "Network",
-    "HeaderYear": "Year",
-    "HeaderGameSystem": "Game system",
-    "HeaderPlayers": "Players",
-    "HeaderEmbeddedImage": "Embedded image",
-    "HeaderTrack": "Track",
-    "HeaderDisc": "Disc"
+    "HeaderYear": "Anno",
+    "HeaderGameSystem": "Gioco Sistema",
+    "HeaderPlayers": "Giocatori",
+    "HeaderEmbeddedImage": "Immagine incorporata",
+    "HeaderTrack": "Traccia",
+    "HeaderDisc": "Disco"
 }

+ 20 - 20
MediaBrowser.Server.Implementations/Localization/JavaScript/kk.json

@@ -331,24 +331,24 @@
     "ButtonViewSeriesRecording": "\u0421\u0435\u0440\u0438\u0430\u043b \u0436\u0430\u0437\u0431\u0430\u0441\u044b\u043d \u049b\u0430\u0440\u0430\u0443",
     "ValueOriginalAirDate": "\u0411\u0430\u0441\u0442\u0430\u043f\u049b\u044b \u044d\u0444\u0438\u0440: {0}",
     "ButtonRemoveFromPlaylist": "\u041e\u0439\u043d\u0430\u0442\u0443 \u0442\u0456\u0437\u0456\u043c\u0456\u043d\u0435\u043d \u0430\u043b\u0430\u0441\u0442\u0430\u0443",
-    "HeaderSpecials": "Specials",
-    "HeaderTrailers": "Trailers",
-    "HeaderAudio": "Audio",
-    "HeaderResolution": "Resolution",
-    "HeaderVideo": "Video",
-    "HeaderRuntime": "Runtime",
-    "HeaderCommunityRating": "Community rating",
-    "HeaderParentalRating": "Parental rating",
-    "HeaderReleaseDate": "Release date",
-    "HeaderDateAdded": "Date added",
-    "HeaderSeries": "Series",
-    "HeaderSeason": "Season",
-    "HeaderSeasonNumber": "Season number",
-    "HeaderNetwork": "Network",
-    "HeaderYear": "Year",
-    "HeaderGameSystem": "Game system",
-    "HeaderPlayers": "Players",
-    "HeaderEmbeddedImage": "Embedded image",
-    "HeaderTrack": "Track",
-    "HeaderDisc": "Disc"
+    "HeaderSpecials": "\u0410\u0440\u043d\u0430\u0439\u044b\u043b\u0430\u0440",
+    "HeaderTrailers": "\u0422\u0440\u0435\u0439\u043b\u0435\u0440\u043b\u0435\u0440",
+    "HeaderAudio": "\u0414\u044b\u0431\u044b\u0441",
+    "HeaderResolution": "\u0410\u0436\u044b\u0440\u0430\u0442\u044b\u043c\u0434\u044b\u043b\u044b\u0493\u044b",
+    "HeaderVideo": "\u0411\u0435\u0439\u043d\u0435",
+    "HeaderRuntime": "\u04b0\u0437\u0430\u049b\u0442\u044b\u0493\u044b",
+    "HeaderCommunityRating": "\u049a\u0430\u0443\u044b\u043c\u0434\u0430\u0441\u0442\u044b\u049b \u0431\u0430\u0493\u0430\u043b\u0430\u0443\u044b",
+    "HeaderParentalRating": "\u0416\u0430\u0441\u0442\u0430\u0441 \u0441\u0430\u043d\u0430\u0442\u044b",
+    "HeaderReleaseDate": "\u0428\u044b\u0493\u0430\u0440\u0443 \u043a\u04af\u043d-\u0430\u0439\u044b",
+    "HeaderDateAdded": "\u04ae\u0441\u0442\u0435\u0443 \u043a\u04af\u043d-\u0430\u0439\u044b",
+    "HeaderSeries": "\u0421\u0435\u0440\u0438\u0430\u043b",
+    "HeaderSeason": "\u041c\u0430\u0443\u0441\u044b\u043c",
+    "HeaderSeasonNumber": "\u041c\u0430\u0443\u0441\u044b\u043c \u043d\u04e9\u043c\u0456\u0440\u0456",
+    "HeaderNetwork": "\u0422\u0435\u043b\u0435\u0436\u0435\u043b\u0456",
+    "HeaderYear": "\u0416\u044b\u043b\u044b",
+    "HeaderGameSystem": "\u041e\u0439\u044b\u043d \u0436\u04af\u0439\u0435\u0441\u0456",
+    "HeaderPlayers": "\u041e\u0439\u044b\u043d\u0448\u044b\u043b\u0430\u0440",
+    "HeaderEmbeddedImage": "\u0415\u043d\u0434\u0456\u0440\u0456\u043b\u0433\u0435\u043d \u0441\u0443\u0440\u0435\u0442",
+    "HeaderTrack": "\u0416\u043e\u043b\u0448\u044b\u049b",
+    "HeaderDisc": "\u0414\u0438\u0441\u043a\u0456"
 }

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

@@ -58,14 +58,14 @@
     "ButtonMute": "Mute",
     "ButtonUnmute": "Unmute",
     "ButtonStop": "Stop",
-    "ButtonNextTrack": "Next Track",
+    "ButtonNextTrack": "Next track",
     "ButtonPause": "Pause",
     "ButtonPlay": "Play",
     "ButtonEdit": "Edit",
     "ButtonQueue": "Queue",
     "ButtonPlayTrailer": "Play trailer",
     "ButtonPlaylist": "Playlist",
-    "ButtonPreviousTrack": "Previous Track",
+    "ButtonPreviousTrack": "Previous track",
     "LabelEnabled": "Enabled",
     "LabelDisabled": "Disabled",
     "ButtonMoreInformation": "More Information",

+ 14 - 14
MediaBrowser.Server.Implementations/Localization/JavaScript/nl.json

@@ -334,21 +334,21 @@
     "HeaderSpecials": "Specials",
     "HeaderTrailers": "Trailers",
     "HeaderAudio": "Audio",
-    "HeaderResolution": "Resolution",
+    "HeaderResolution": "Resolutie",
     "HeaderVideo": "Video",
-    "HeaderRuntime": "Runtime",
-    "HeaderCommunityRating": "Community rating",
-    "HeaderParentalRating": "Parental rating",
-    "HeaderReleaseDate": "Release date",
-    "HeaderDateAdded": "Date added",
+    "HeaderRuntime": "Speelduur",
+    "HeaderCommunityRating": "Gemeenschap cijfer",
+    "HeaderParentalRating": "Kijkwijzer classificering",
+    "HeaderReleaseDate": "Releasedatum ",
+    "HeaderDateAdded": "Datum toegevoegd",
     "HeaderSeries": "Series",
-    "HeaderSeason": "Season",
-    "HeaderSeasonNumber": "Season number",
-    "HeaderNetwork": "Network",
-    "HeaderYear": "Year",
-    "HeaderGameSystem": "Game system",
-    "HeaderPlayers": "Players",
-    "HeaderEmbeddedImage": "Embedded image",
+    "HeaderSeason": "Seizoen",
+    "HeaderSeasonNumber": "Seizoen nummer",
+    "HeaderNetwork": "Zender",
+    "HeaderYear": "Jaar",
+    "HeaderGameSystem": "Spelsysteem",
+    "HeaderPlayers": "Spelers",
+    "HeaderEmbeddedImage": "Ingesloten afbeelding",
     "HeaderTrack": "Track",
-    "HeaderDisc": "Disc"
+    "HeaderDisc": "Schijf"
 }

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

@@ -58,14 +58,14 @@
     "ButtonMute": "Mute",
     "ButtonUnmute": "Unmute",
     "ButtonStop": "Stop",
-    "ButtonNextTrack": "Next Track",
+    "ButtonNextTrack": "Next track",
     "ButtonPause": "Pause",
     "ButtonPlay": "Play",
     "ButtonEdit": "Edit",
     "ButtonQueue": "Queue",
     "ButtonPlayTrailer": "Play trailer",
     "ButtonPlaylist": "Playlist",
-    "ButtonPreviousTrack": "Previous Track",
+    "ButtonPreviousTrack": "Previous track",
     "LabelEnabled": "Enabled",
     "LabelDisabled": "Disabled",
     "ButtonMoreInformation": "More Information",

+ 19 - 19
MediaBrowser.Server.Implementations/Localization/JavaScript/pt_BR.json

@@ -331,24 +331,24 @@
     "ButtonViewSeriesRecording": "Visualizar grava\u00e7\u00e3o de s\u00e9ries",
     "ValueOriginalAirDate": "Data original de exibi\u00e7\u00e3o: {0}",
     "ButtonRemoveFromPlaylist": "Remover da lista de reprodu\u00e7\u00e3o",
-    "HeaderSpecials": "Specials",
+    "HeaderSpecials": "Especiais",
     "HeaderTrailers": "Trailers",
-    "HeaderAudio": "Audio",
-    "HeaderResolution": "Resolution",
-    "HeaderVideo": "Video",
-    "HeaderRuntime": "Runtime",
-    "HeaderCommunityRating": "Community rating",
-    "HeaderParentalRating": "Parental rating",
-    "HeaderReleaseDate": "Release date",
-    "HeaderDateAdded": "Date added",
-    "HeaderSeries": "Series",
-    "HeaderSeason": "Season",
-    "HeaderSeasonNumber": "Season number",
-    "HeaderNetwork": "Network",
-    "HeaderYear": "Year",
-    "HeaderGameSystem": "Game system",
-    "HeaderPlayers": "Players",
-    "HeaderEmbeddedImage": "Embedded image",
-    "HeaderTrack": "Track",
-    "HeaderDisc": "Disc"
+    "HeaderAudio": "\u00c1udio",
+    "HeaderResolution": "Resolu\u00e7\u00e3o",
+    "HeaderVideo": "V\u00eddeo",
+    "HeaderRuntime": "Dura\u00e7\u00e3o",
+    "HeaderCommunityRating": "Classifica\u00e7\u00e3o da Comunidade",
+    "HeaderParentalRating": "Classifica\u00e7\u00e3o parental",
+    "HeaderReleaseDate": "Data de lan\u00e7amento",
+    "HeaderDateAdded": "Data de adi\u00e7\u00e3o",
+    "HeaderSeries": "S\u00e9rie",
+    "HeaderSeason": "Temporada",
+    "HeaderSeasonNumber": "N\u00famero da temporada",
+    "HeaderNetwork": "Rede de TV",
+    "HeaderYear": "Ano",
+    "HeaderGameSystem": "Sistema do jogo",
+    "HeaderPlayers": "Jogadores",
+    "HeaderEmbeddedImage": "Imagem incorporada",
+    "HeaderTrack": "Faixa",
+    "HeaderDisc": "Disco"
 }

+ 26 - 26
MediaBrowser.Server.Implementations/Localization/JavaScript/ru.json

@@ -29,7 +29,7 @@
     "MessageKeysLinked": "\u041a\u043b\u044e\u0447\u0438 \u0431\u044b\u043b\u0438 \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u043d\u044b.",
     "HeaderConfirmation": "\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435",
     "MessageKeyUpdated": "\u041a\u043b\u044e\u0447 \u0441\u043f\u043e\u043d\u0441\u043e\u0440\u0430 \u0431\u044b\u043b \u043e\u0431\u043d\u043e\u0432\u043b\u0451\u043d.",
-    "MessageKeyRemoved": "\u041a\u043b\u044e\u0447 \u0441\u043f\u043e\u043d\u0441\u043e\u0440\u0430 \u0431\u044b\u043b \u0443\u0431\u0440\u0430\u043d.",
+    "MessageKeyRemoved": "\u041a\u043b\u044e\u0447 \u0441\u043f\u043e\u043d\u0441\u043e\u0440\u0430 \u0431\u044b\u043b \u0443\u0434\u0430\u043b\u0451\u043d.",
     "ErrorLaunchingChromecast": "\u041f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 Chromecast. \u0423\u0431\u0435\u0434\u0438\u0442\u0435\u0441\u044c, \u0447\u0442\u043e \u0432\u0430\u0448\u0435 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u043e \u043a \u0431\u0435\u0441\u043f\u0440\u043e\u0432\u043e\u0434\u043d\u043e\u0439 \u0441\u0435\u0442\u0438.",
     "HeaderSearch": "\u041f\u043e\u0438\u0441\u043a",
     "LabelArtist": "\u0418\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c",
@@ -63,7 +63,7 @@
     "ButtonPlay": "\u0412\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438",
     "ButtonEdit": "\u041f\u0440\u0430\u0432\u0438\u0442\u044c",
     "ButtonQueue": "\u041e\u0447\u0435\u0440\u0435\u0434\u044c",
-    "ButtonPlayTrailer": "\u0412\u043e\u0441\u043f\u0440 \u0442\u0440\u0435\u0439\u043b\u0435\u0440",
+    "ButtonPlayTrailer": "\u0412\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438 \u0442\u0440\u0435\u0439\u043b\u0435\u0440",
     "ButtonPlaylist": "\u0421\u043f\u0438\u0441\u043e\u043a \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u044f",
     "ButtonPreviousTrack": "\u041f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0430\u044f \u0434\u043e\u0440\u043e\u0436\u043a\u0430",
     "LabelEnabled": "\u0412\u043a\u043b\u044e\u0447\u0435\u043d\u043e",
@@ -77,7 +77,7 @@
     "MessageInvalidUser": "\u041d\u0435\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u043e\u0435 \u0438\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0438\u043b\u0438 \u043f\u0430\u0440\u043e\u043b\u044c.",
     "HeaderAllRecordings": "\u0412\u0441\u0435 \u0437\u0430\u043f\u0438\u0441\u0438",
     "RecommendationBecauseYouLike": "\u0418\u0431\u043e \u0432\u0430\u043c \u043d\u0440\u0430\u0432\u0438\u0442\u0441\u044f {0}",
-    "RecommendationBecauseYouWatched": "\u0422\u0430\u043a \u043a\u0430\u043a \u0432\u044b \u0441\u043c\u043e\u0442\u0440\u0435\u043b\u0438 {0}",
+    "RecommendationBecauseYouWatched": "\u0418\u0431\u043e \u0432\u044b \u0441\u043c\u043e\u0442\u0440\u0435\u043b\u0438 {0}",
     "RecommendationDirectedBy": "\u041f\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0449\u0438\u043a {0}",
     "RecommendationStarring": "\u0412 \u0433\u043b\u0430\u0432\u043d\u043e\u0439 \u0440\u043e\u043b\u0438 {0}",
     "HeaderConfirmRecordingCancellation": "\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u043e\u0442\u043c\u0435\u043d\u044b \u0437\u0430\u043f\u0438\u0441\u0438",
@@ -144,7 +144,7 @@
     "HeaderSelectChannelDownloadPathHelp": "\u041f\u0435\u0440\u0435\u0439\u0434\u0438\u0442\u0435 \u043a \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0443 \u0438\u043b\u0438 \u0432\u0432\u0435\u0434\u0438\u0442\u0435 \u043f\u0443\u0442\u044c, \u0447\u0442\u043e\u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0444\u0430\u0439\u043b\u043e\u0432 \u043a\u0435\u0448\u0430 \u043a\u0430\u043d\u0430\u043b\u043e\u0432. \u041f\u0430\u043f\u043a\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430 \u0434\u043b\u044f \u0437\u0430\u043f\u0438\u0441\u0438.",
     "OptionNewCollection": "\u041d\u043e\u0432\u0430\u044f...",
     "ButtonAdd": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c",
-    "ButtonRemove": "\u0423\u0431\u0440\u0430\u0442\u044c",
+    "ButtonRemove": "\u0418\u0437\u044a\u044f\u0442\u044c",
     "LabelChapterDownloaders": "\u0417\u0430\u0433\u0440\u0443\u0437\u0447\u0438\u043a\u0438 \u0441\u0446\u0435\u043d:",
     "LabelChapterDownloadersHelp": "\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u0435 \u0438 \u0440\u0430\u043d\u0436\u0438\u0440\u0443\u0439\u0442\u0435 \u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0438\u0442\u0430\u0435\u043c\u044b\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u0447\u0438\u043a\u0438 \u0441\u0446\u0435\u043d \u0432 \u043f\u043e\u0440\u044f\u0434\u043a\u0435 \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442\u0430. \u0417\u0430\u0433\u0440\u0443\u0437\u0447\u0438\u043a\u0438 \u043d\u0438\u0437\u043a\u043e\u0433\u043e \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442\u0430 \u0431\u0443\u0434\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u0441\u0432\u0435\u0434\u0435\u043d\u0438\u0439.",
     "HeaderFavoriteAlbums": "\u0418\u0437\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u0430\u043b\u044c\u0431\u043e\u043c\u044b",
@@ -284,7 +284,7 @@
     "LabelPremiereProgram": "\u041f\u0420\u0415\u041c\u042c\u0415\u0420\u0410",
     "LabelHDProgram": "HD",
     "HeaderChangeFolderType": "\u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0442\u0438\u043f\u0430 \u043f\u0430\u043f\u043a\u0438",
-    "HeaderChangeFolderTypeHelp": "\u0427\u0442\u043e\u0431\u044b \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0442\u0438\u043f \u043f\u0430\u043f\u043a\u0438, \u0443\u0434\u0430\u043b\u0438\u0442\u0435 \u0438 \u043f\u0435\u0440\u0435\u0441\u0442\u0440\u043e\u0439\u0442\u0435 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044e \u0441 \u043d\u043e\u0432\u044b\u043c \u0442\u0438\u043f\u043e\u043c.",
+    "HeaderChangeFolderTypeHelp": "\u0414\u043b\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0442\u0438\u043f\u0430 \u043f\u0430\u043f\u043a\u0438, \u0443\u0434\u0430\u043b\u0438\u0442\u0435 \u043c\u0435\u0434\u0438\u0430\u043f\u0430\u043f\u043a\u0443 \u0438 \u043f\u0435\u0440\u0435\u0441\u0442\u0440\u043e\u0439\u0442\u0435 \u0435\u0451 \u0441 \u043d\u043e\u0432\u044b\u043c \u0442\u0438\u043f\u043e\u043c.",
     "HeaderAlert": "\u041e\u043f\u043e\u0432\u0435\u0449\u0435\u043d\u0438\u0435",
     "MessagePleaseRestart": "\u041f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u0435, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u044c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435.",
     "ButtonRestart": "\u041f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c",
@@ -330,25 +330,25 @@
     "MessageAddedToPlaylistSuccess": "\u041e\u041a",
     "ButtonViewSeriesRecording": "\u041f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0437\u0430\u043f\u0438\u0441\u044c \u0441\u0435\u0440\u0438\u0430\u043b\u0430",
     "ValueOriginalAirDate": "\u041f\u0435\u0440\u0432\u043e\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0439 \u044d\u0444\u0438\u0440: {0}",
-    "ButtonRemoveFromPlaylist": "\u0423\u0431\u0440\u0430\u0442\u044c \u0438\u0437 \u0441\u043f\u0438\u0441\u043a\u0430 \u0432\u043e\u0441\u043f\u0440-\u0438\u044f",
-    "HeaderSpecials": "Specials",
-    "HeaderTrailers": "Trailers",
-    "HeaderAudio": "Audio",
-    "HeaderResolution": "Resolution",
-    "HeaderVideo": "Video",
-    "HeaderRuntime": "Runtime",
-    "HeaderCommunityRating": "Community rating",
-    "HeaderParentalRating": "Parental rating",
-    "HeaderReleaseDate": "Release date",
-    "HeaderDateAdded": "Date added",
-    "HeaderSeries": "Series",
-    "HeaderSeason": "Season",
-    "HeaderSeasonNumber": "Season number",
-    "HeaderNetwork": "Network",
-    "HeaderYear": "Year",
-    "HeaderGameSystem": "Game system",
-    "HeaderPlayers": "Players",
-    "HeaderEmbeddedImage": "Embedded image",
-    "HeaderTrack": "Track",
-    "HeaderDisc": "Disc"
+    "ButtonRemoveFromPlaylist": "\u0418\u0437\u044a\u044f\u0442\u044c \u0438\u0437 \u0441\u043f\u0438\u0441\u043a\u0430 \u0432\u043e\u0441\u043f\u0440-\u0438\u044f",
+    "HeaderSpecials": "\u0421\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0435",
+    "HeaderTrailers": "\u0422\u0440\u0435\u0439\u043b\u0435\u0440\u044b",
+    "HeaderAudio": "\u0410\u0443\u0434\u0438\u043e",
+    "HeaderResolution": "\u0420\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u0435",
+    "HeaderVideo": "\u0412\u0438\u0434\u0435\u043e",
+    "HeaderRuntime": "\u0414\u043b\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c",
+    "HeaderCommunityRating": "\u041e\u0431\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u0430\u044f \u043e\u0446\u0435\u043d\u043a\u0430",
+    "HeaderParentalRating": "\u0412\u043e\u0437\u0440\u0430\u0441\u0442\u043d\u0430\u044f \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f",
+    "HeaderReleaseDate": "\u0414\u0430\u0442\u0430 \u0432\u044b\u043f\u0443\u0441\u043a\u0430",
+    "HeaderDateAdded": "\u0414\u0430\u0442\u0430 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f",
+    "HeaderSeries": "\u0421\u0435\u0440\u0438\u0430\u043b",
+    "HeaderSeason": "\u0421\u0435\u0437\u043e\u043d",
+    "HeaderSeasonNumber": "\u041d\u043e\u043c\u0435\u0440 \u0441\u0435\u0437\u043e\u043d\u0430",
+    "HeaderNetwork": "\u0422\u0435\u043b\u0435\u0441\u0435\u0442\u044c",
+    "HeaderYear": "\u0413\u043e\u0434",
+    "HeaderGameSystem": "\u0418\u0433\u0440\u043e\u0432\u0430\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430",
+    "HeaderPlayers": "\u0418\u0433\u0440\u043e\u043a\u0438",
+    "HeaderEmbeddedImage": "\u0412\u043d\u0435\u0434\u0440\u0451\u043d\u043d\u044b\u0439 \u0440\u0438\u0441\u0443\u043d\u043e\u043a",
+    "HeaderTrack": "\u0414\u043e\u0440\u043e\u0436\u043a\u0430",
+    "HeaderDisc": "\u0414\u0438\u0441\u043a"
 }

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

@@ -58,14 +58,14 @@
     "ButtonMute": "Mute",
     "ButtonUnmute": "Unmute",
     "ButtonStop": "Stop",
-    "ButtonNextTrack": "Next Track",
+    "ButtonNextTrack": "Next track",
     "ButtonPause": "Pause",
     "ButtonPlay": "Play",
     "ButtonEdit": "Edit",
     "ButtonQueue": "Queue",
     "ButtonPlayTrailer": "Play trailer",
     "ButtonPlaylist": "Playlist",
-    "ButtonPreviousTrack": "Previous Track",
+    "ButtonPreviousTrack": "Previous track",
     "LabelEnabled": "Enabled",
     "LabelDisabled": "Disabled",
     "ButtonMoreInformation": "More Information",

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

@@ -58,14 +58,14 @@
     "ButtonMute": "Mute",
     "ButtonUnmute": "Unmute",
     "ButtonStop": "Stop",
-    "ButtonNextTrack": "Next Track",
+    "ButtonNextTrack": "Next track",
     "ButtonPause": "Pause",
     "ButtonPlay": "\u64ad\u653e",
     "ButtonEdit": "\u7de8\u8f2f",
     "ButtonQueue": "Queue",
     "ButtonPlayTrailer": "Play trailer",
     "ButtonPlaylist": "Playlist",
-    "ButtonPreviousTrack": "Previous Track",
+    "ButtonPreviousTrack": "Previous track",
     "LabelEnabled": "Enabled",
     "LabelDisabled": "Disabled",
     "ButtonMoreInformation": "More Information",

+ 4 - 1
MediaBrowser.Server.Implementations/Localization/Server/ar.json

@@ -788,6 +788,7 @@
     "HeaderMetadataManager": "Metadata Manager",
     "HeaderPreferences": "Preferences",
     "MessageLoadingChannels": "Loading channel content...",
+    "MessageLoadingContent": "Loading content...",
     "ButtonMarkRead": "Mark Read",
     "OptionDefaultSort": "Default",
     "OptionCommunityMostWatchedSort": "Most Watched",
@@ -979,5 +980,7 @@
     "UserStartedPlayingItemWithValues": "{0} has started playing {1}",
     "UserStoppedPlayingItemWithValues": "{0} has stopped playing {1}",
     "AppDeviceValues": "App: {0}, Device: {1}",
-    "ProviderValue": "Provider: {0}"
+    "ProviderValue": "Provider: {0}",
+    "LabelChannelDownloadSizeLimit": "Download size limit (GB):",
+    "LabelChannelDownloadSizeLimitHelp": "Limit the size of the channel download folder"
 }

+ 4 - 1
MediaBrowser.Server.Implementations/Localization/Server/ca.json

@@ -788,6 +788,7 @@
     "HeaderMetadataManager": "Metadata Manager",
     "HeaderPreferences": "Preferences",
     "MessageLoadingChannels": "Loading channel content...",
+    "MessageLoadingContent": "Loading content...",
     "ButtonMarkRead": "Mark Read",
     "OptionDefaultSort": "Default",
     "OptionCommunityMostWatchedSort": "Most Watched",
@@ -979,5 +980,7 @@
     "UserStartedPlayingItemWithValues": "{0} has started playing {1}",
     "UserStoppedPlayingItemWithValues": "{0} has stopped playing {1}",
     "AppDeviceValues": "App: {0}, Device: {1}",
-    "ProviderValue": "Provider: {0}"
+    "ProviderValue": "Provider: {0}",
+    "LabelChannelDownloadSizeLimit": "Download size limit (GB):",
+    "LabelChannelDownloadSizeLimitHelp": "Limit the size of the channel download folder"
 }

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

@@ -480,7 +480,7 @@
     "HeaderProgram": "Program",
     "HeaderClients": "Klienti",
     "LabelCompleted": "Hotovo",
-    "LabelFailed": "Failed",
+    "LabelFailed": "Chyba",
     "LabelSkipped": "P\u0159esko\u010deno",
     "HeaderEpisodeOrganization": "Organizace epizod",
     "LabelSeries": "Series:",
@@ -630,8 +630,8 @@
     "ButtonFullscreen": "Toggle fullscreen",
     "ButtonScenes": "Sc\u00e9ny",
     "ButtonSubtitles": "Titulky",
-    "ButtonAudioTracks": "Audio tracks",
-    "ButtonPreviousTrack": "Previous track",
+    "ButtonAudioTracks": "Audio stopy",
+    "ButtonPreviousTrack": "P\u0159edchod\u00ed stopa",
     "ButtonNextTrack": "Next track",
     "ButtonStop": "Stop",
     "ButtonPause": "Pause",
@@ -788,6 +788,7 @@
     "HeaderMetadataManager": "Spr\u00e1vce metadat",
     "HeaderPreferences": "Preferences",
     "MessageLoadingChannels": "Loading channel content...",
+    "MessageLoadingContent": "Loading content...",
     "ButtonMarkRead": "Ozna\u010dit jako p\u0159e\u010dten\u00e9",
     "OptionDefaultSort": "Default",
     "OptionCommunityMostWatchedSort": "Nejsledovan\u011bj\u0161\u00ed",
@@ -979,5 +980,7 @@
     "UserStartedPlayingItemWithValues": "{0} has started playing {1}",
     "UserStoppedPlayingItemWithValues": "{0} has stopped playing {1}",
     "AppDeviceValues": "App: {0}, Device: {1}",
-    "ProviderValue": "Provider: {0}"
+    "ProviderValue": "Provider: {0}",
+    "LabelChannelDownloadSizeLimit": "Download size limit (GB):",
+    "LabelChannelDownloadSizeLimitHelp": "Limit the size of the channel download folder"
 }

+ 6 - 3
MediaBrowser.Server.Implementations/Localization/Server/da.json

@@ -627,10 +627,10 @@
     "TabNowPlaying": "Spiler nu",
     "TabNavigation": "Navigation",
     "TabControls": "Controls",
-    "ButtonFullscreen": "Toggle fullscreen",
+    "ButtonFullscreen": "Skift til fuldsk\u00e6rm",
     "ButtonScenes": "Scener",
     "ButtonSubtitles": "Undertekster",
-    "ButtonAudioTracks": "Audio tracks",
+    "ButtonAudioTracks": "Lyd filer",
     "ButtonPreviousTrack": "Previous track",
     "ButtonNextTrack": "Next track",
     "ButtonStop": "Stop",
@@ -788,6 +788,7 @@
     "HeaderMetadataManager": "Metadata Manager",
     "HeaderPreferences": "Preferences",
     "MessageLoadingChannels": "Loading channel content...",
+    "MessageLoadingContent": "Loading content...",
     "ButtonMarkRead": "Mark Read",
     "OptionDefaultSort": "Default",
     "OptionCommunityMostWatchedSort": "Most Watched",
@@ -979,5 +980,7 @@
     "UserStartedPlayingItemWithValues": "{0} has started playing {1}",
     "UserStoppedPlayingItemWithValues": "{0} has stopped playing {1}",
     "AppDeviceValues": "App: {0}, Device: {1}",
-    "ProviderValue": "Provider: {0}"
+    "ProviderValue": "Provider: {0}",
+    "LabelChannelDownloadSizeLimit": "Download size limit (GB):",
+    "LabelChannelDownloadSizeLimitHelp": "Limit the size of the channel download folder"
 }

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

@@ -480,10 +480,10 @@
     "HeaderProgram": "Programm",
     "HeaderClients": "Clients",
     "LabelCompleted": "Fertiggestellt",
-    "LabelFailed": "Failed",
+    "LabelFailed": "Gescheitert",
     "LabelSkipped": "\u00dcbersprungen",
     "HeaderEpisodeOrganization": "Episodensortierung",
-    "LabelSeries": "Series:",
+    "LabelSeries": "Serien:",
     "LabelSeasonNumber": "Staffelnummer",
     "LabelEpisodeNumber": "Episodennummer",
     "LabelEndingEpisodeNumber": "Ending episode number",
@@ -627,12 +627,12 @@
     "TabNowPlaying": "Aktuelle Wiedergabe",
     "TabNavigation": "Navigation",
     "TabControls": "Controls",
-    "ButtonFullscreen": "Toggle fullscreen",
+    "ButtonFullscreen": "Schalte Vollbild um",
     "ButtonScenes": "Szenen",
     "ButtonSubtitles": "Untertitel",
-    "ButtonAudioTracks": "Audio tracks",
-    "ButtonPreviousTrack": "Previous track",
-    "ButtonNextTrack": "Next track",
+    "ButtonAudioTracks": "Audiospuren",
+    "ButtonPreviousTrack": "Vorheriger Track",
+    "ButtonNextTrack": "N\u00e4chster Track",
     "ButtonStop": "Stop",
     "ButtonPause": "Pause",
     "LabelGroupMoviesIntoCollections": "Gruppiere Filme in Collections",
@@ -788,6 +788,7 @@
     "HeaderMetadataManager": "Metadaten-Manager",
     "HeaderPreferences": "Einstellungen",
     "MessageLoadingChannels": "Lade Channel Inhalt...",
+    "MessageLoadingContent": "Loading content...",
     "ButtonMarkRead": "Als gelesen markieren",
     "OptionDefaultSort": "Default",
     "OptionCommunityMostWatchedSort": "Meistgesehen",
@@ -979,5 +980,7 @@
     "UserStartedPlayingItemWithValues": "{0} has started playing {1}",
     "UserStoppedPlayingItemWithValues": "{0} has stopped playing {1}",
     "AppDeviceValues": "App: {0}, Device: {1}",
-    "ProviderValue": "Provider: {0}"
+    "ProviderValue": "Provider: {0}",
+    "LabelChannelDownloadSizeLimit": "Download size limit (GB):",
+    "LabelChannelDownloadSizeLimitHelp": "Limit the size of the channel download folder"
 }

+ 4 - 1
MediaBrowser.Server.Implementations/Localization/Server/el.json

@@ -788,6 +788,7 @@
     "HeaderMetadataManager": "Metadata Manager",
     "HeaderPreferences": "Preferences",
     "MessageLoadingChannels": "Loading channel content...",
+    "MessageLoadingContent": "Loading content...",
     "ButtonMarkRead": "Mark Read",
     "OptionDefaultSort": "Default",
     "OptionCommunityMostWatchedSort": "Most Watched",
@@ -979,5 +980,7 @@
     "UserStartedPlayingItemWithValues": "{0} has started playing {1}",
     "UserStoppedPlayingItemWithValues": "{0} has stopped playing {1}",
     "AppDeviceValues": "App: {0}, Device: {1}",
-    "ProviderValue": "Provider: {0}"
+    "ProviderValue": "Provider: {0}",
+    "LabelChannelDownloadSizeLimit": "Download size limit (GB):",
+    "LabelChannelDownloadSizeLimitHelp": "Limit the size of the channel download folder"
 }

+ 4 - 1
MediaBrowser.Server.Implementations/Localization/Server/en_GB.json

@@ -788,6 +788,7 @@
     "HeaderMetadataManager": "Metadata Manager",
     "HeaderPreferences": "Preferences",
     "MessageLoadingChannels": "Loading channel content...",
+    "MessageLoadingContent": "Loading content...",
     "ButtonMarkRead": "Mark Read",
     "OptionDefaultSort": "Default",
     "OptionCommunityMostWatchedSort": "Most Watched",
@@ -979,5 +980,7 @@
     "UserStartedPlayingItemWithValues": "{0} has started playing {1}",
     "UserStoppedPlayingItemWithValues": "{0} has stopped playing {1}",
     "AppDeviceValues": "App: {0}, Device: {1}",
-    "ProviderValue": "Provider: {0}"
+    "ProviderValue": "Provider: {0}",
+    "LabelChannelDownloadSizeLimit": "Download size limit (GB):",
+    "LabelChannelDownloadSizeLimitHelp": "Limit the size of the channel download folder"
 }

+ 4 - 1
MediaBrowser.Server.Implementations/Localization/Server/en_US.json

@@ -788,6 +788,7 @@
     "HeaderMetadataManager": "Metadata Manager",
     "HeaderPreferences": "Preferences",
     "MessageLoadingChannels": "Loading channel content...",
+    "MessageLoadingContent": "Loading content...",
     "ButtonMarkRead": "Mark Read",
     "OptionDefaultSort": "Default",
     "OptionCommunityMostWatchedSort": "Most Watched",
@@ -979,5 +980,7 @@
     "UserStartedPlayingItemWithValues": "{0} has started playing {1}",
     "UserStoppedPlayingItemWithValues": "{0} has stopped playing {1}",
     "AppDeviceValues": "App: {0}, Device: {1}",
-    "ProviderValue": "Provider: {0}"
+    "ProviderValue": "Provider: {0}",
+    "LabelChannelDownloadSizeLimit": "Download size limit (GB):",
+    "LabelChannelDownloadSizeLimitHelp": "Limit the size of the channel download folder"
 }

+ 8 - 5
MediaBrowser.Server.Implementations/Localization/Server/es.json

@@ -480,10 +480,10 @@
     "HeaderProgram": "Programa",
     "HeaderClients": "Clientes",
     "LabelCompleted": "Completado",
-    "LabelFailed": "Error",
+    "LabelFailed": "Err\u00f3neo",
     "LabelSkipped": "Omitido",
     "HeaderEpisodeOrganization": "Organizaci\u00f3n de episodios",
-    "LabelSeries": "Series:",
+    "LabelSeries": "Serie:",
     "LabelSeasonNumber": "Temporada n\u00famero:",
     "LabelEpisodeNumber": "Episodio n\u00famero:",
     "LabelEndingEpisodeNumber": "N\u00famero episodio final:",
@@ -627,10 +627,10 @@
     "TabNowPlaying": "Reproduciendo ahora",
     "TabNavigation": "Navegaci\u00f3n",
     "TabControls": "Controles",
-    "ButtonFullscreen": "Toggle fullscreen",
+    "ButtonFullscreen": "Pantalla completa",
     "ButtonScenes": "Escenas",
     "ButtonSubtitles": "Subt\u00edtulos",
-    "ButtonAudioTracks": "Audio tracks",
+    "ButtonAudioTracks": "Pistas de audio",
     "ButtonPreviousTrack": "Pista anterior",
     "ButtonNextTrack": "Pista siguiente",
     "ButtonStop": "Detener",
@@ -788,6 +788,7 @@
     "HeaderMetadataManager": "Metadata Manager",
     "HeaderPreferences": "Preferencias",
     "MessageLoadingChannels": "Cargando contenidos del canal...",
+    "MessageLoadingContent": "Loading content...",
     "ButtonMarkRead": "Marcar como le\u00eddo",
     "OptionDefaultSort": "Por defecto",
     "OptionCommunityMostWatchedSort": "M\u00e1s visto",
@@ -979,5 +980,7 @@
     "UserStartedPlayingItemWithValues": "{0} has started playing {1}",
     "UserStoppedPlayingItemWithValues": "{0} has stopped playing {1}",
     "AppDeviceValues": "App: {0}, Device: {1}",
-    "ProviderValue": "Provider: {0}"
+    "ProviderValue": "Provider: {0}",
+    "LabelChannelDownloadSizeLimit": "Download size limit (GB):",
+    "LabelChannelDownloadSizeLimitHelp": "Limit the size of the channel download folder"
 }

+ 38 - 35
MediaBrowser.Server.Implementations/Localization/Server/es_MX.json

@@ -627,12 +627,12 @@
     "TabNowPlaying": "Reproduci\u00e9ndo Ahora",
     "TabNavigation": "Navegaci\u00f3n",
     "TabControls": "Controles",
-    "ButtonFullscreen": "Cambiar a pantalla completa",
+    "ButtonFullscreen": "Alternar pantalla completa",
     "ButtonScenes": "Escenas",
     "ButtonSubtitles": "Subt\u00edtulos",
     "ButtonAudioTracks": "Pistas de audio",
-    "ButtonPreviousTrack": "Pista anterior",
-    "ButtonNextTrack": "Pista siguiente",
+    "ButtonPreviousTrack": "Pista Anterior",
+    "ButtonNextTrack": "Pista Siguiente",
     "ButtonStop": "Detener",
     "ButtonPause": "Pausar",
     "LabelGroupMoviesIntoCollections": "Agrupar pel\u00edculas en colecciones",
@@ -788,6 +788,7 @@
     "HeaderMetadataManager": "Administrador de Metadatos",
     "HeaderPreferences": "Preferencias",
     "MessageLoadingChannels": "Cargando contenidos del canal...",
+    "MessageLoadingContent": "Loading content...",
     "ButtonMarkRead": "Marcar como Le\u00eddo",
     "OptionDefaultSort": "Por defecto",
     "OptionCommunityMostWatchedSort": "M\u00e1s Visto",
@@ -948,36 +949,38 @@
     "OptionReportAlbums": "\u00c1lbums",
     "OptionReportAdultVideos": "Videos para Adultos",
     "ButtonMore": "M\u00e1s",
-    "HeaderActivity": "Activity",
-    "ScheduledTaskStartedWithName": "{0} started",
-    "ScheduledTaskCancelledWithName": "{0} was cancelled",
-    "ScheduledTaskCompletedWithName": "{0} completed",
-    "ScheduledTaskFailed": "Scheduled task completed",
-    "PluginInstalledWithName": "{0} was installed",
-    "PluginUpdatedWithName": "{0} was updated",
-    "PluginUninstalledWithName": "{0} was uninstalled",
-    "ScheduledTaskFailedWithName": "{0} failed",
-    "ItemAddedWithName": "{0} was added to the library",
-    "ItemRemovedWithName": "{0} was removed from the library",
-    "DeviceOnlineWithName": "{0} is connected",
-    "UserOnlineFromDevice": "{0} is online from {1}",
-    "DeviceOfflineWithName": "{0} has disconnected",
-    "UserOfflineFromDevice": "{0} has disconnected from {1}",
-    "SubtitlesDownloadedForItem": "Subtitles downloaded for {0}",
-    "SubtitleDownloadFailureForItem": "Subtitles failed to download for {0}",
-    "LabelRunningTimeValue": "Running time: {0}",
-    "LabelIpAddressValue": "Ip address: {0}",
-    "UserConfigurationUpdatedWithName": "User configuration has been updated for {0}",
-    "UserCreatedWithName": "User {0} has been created",
-    "UserPasswordChangedWithName": "Password has been changed for user {0}",
-    "UserDeletedWithName": "User {0} has been deleted",
-    "MessageServerConfigurationUpdated": "Server configuration has been updated",
-    "MessageNamedServerConfigurationUpdatedWithValue": "Server configuration section {0} has been updated",
-    "MessageApplicationUpdated": "Media Browser Server has been updated",
-    "AuthenticationSucceededWithUserName": "{0} successfully authenticated",
-    "FailedLoginAttemptWithUserName": "Failed login attempt from {0}",
-    "UserStartedPlayingItemWithValues": "{0} has started playing {1}",
-    "UserStoppedPlayingItemWithValues": "{0} has stopped playing {1}",
-    "AppDeviceValues": "App: {0}, Device: {1}",
-    "ProviderValue": "Provider: {0}"
+    "HeaderActivity": "Actividad",
+    "ScheduledTaskStartedWithName": "{0} Iniciado",
+    "ScheduledTaskCancelledWithName": "{0} fue cancelado",
+    "ScheduledTaskCompletedWithName": "{0} completado",
+    "ScheduledTaskFailed": "Tarea programada completada",
+    "PluginInstalledWithName": "{0} fue instalado",
+    "PluginUpdatedWithName": "{0} fue actualizado",
+    "PluginUninstalledWithName": "{0} fue desinstalado",
+    "ScheduledTaskFailedWithName": "{0} fall\u00f3",
+    "ItemAddedWithName": "{0} fue agregado a la biblioteca",
+    "ItemRemovedWithName": "{0} fue removido de la biblioteca",
+    "DeviceOnlineWithName": "{0} est\u00e1 conectado",
+    "UserOnlineFromDevice": "{0} est\u00e1 en l\u00ednea desde {1}",
+    "DeviceOfflineWithName": "{0} se ha desconectado",
+    "UserOfflineFromDevice": "{0} se ha desconecatdo desde {1}",
+    "SubtitlesDownloadedForItem": "Subt\u00edtulos descargados para {0}",
+    "SubtitleDownloadFailureForItem": "Fall\u00f3 la descarga de subt\u00edtulos para {0}",
+    "LabelRunningTimeValue": "Duraci\u00f3n: {0}",
+    "LabelIpAddressValue": "Direcci\u00f3n IP: {0}",
+    "UserConfigurationUpdatedWithName": "Se ha actualizado la configuraci\u00f3n del usuario {0}",
+    "UserCreatedWithName": "Se ha creado el usuario {0}",
+    "UserPasswordChangedWithName": "Se ha cambiado la contrase\u00f1a para el usuario {0}",
+    "UserDeletedWithName": "Se ha eliminado al usuario {0}",
+    "MessageServerConfigurationUpdated": "Se ha actualizado la configuraci\u00f3n del servidor",
+    "MessageNamedServerConfigurationUpdatedWithValue": "Se ha actualizado la secci\u00f3n {0} de la configuraci\u00f3n del servidor",
+    "MessageApplicationUpdated": "Se ha actualizado el Servidor de Media Browser",
+    "AuthenticationSucceededWithUserName": "{0} autenticado con \u00e9xito",
+    "FailedLoginAttemptWithUserName": "Intento fallido de inicio de sesi\u00f3n de {0}",
+    "UserStartedPlayingItemWithValues": "{0} ha iniciado la reproducci\u00f3n de {1}",
+    "UserStoppedPlayingItemWithValues": "{0} ha detenido la reproducci\u00f3n de {1}",
+    "AppDeviceValues": "App: {0}, Dispositivo: {1}",
+    "ProviderValue": "Proveedor: {0}",
+    "LabelChannelDownloadSizeLimit": "Download size limit (GB):",
+    "LabelChannelDownloadSizeLimitHelp": "Limit the size of the channel download folder"
 }

+ 35 - 32
MediaBrowser.Server.Implementations/Localization/Server/fr.json

@@ -397,7 +397,7 @@
     "HeaderCastCrew": "\u00c9quipe de tournage",
     "HeaderAdditionalParts": "Parties Additionelles",
     "ButtonSplitVersionsApart": "S\u00e9parer les versions",
-    "ButtonPlayTrailer": "Trailer",
+    "ButtonPlayTrailer": "Bande-annonce",
     "LabelMissing": "Manquant(s)",
     "LabelOffline": "Hors ligne",
     "PathSubstitutionHelp": "Les substitutions de chemins d'acc\u00e8s sont utilis\u00e9es pour faire correspondre un chemin d'acc\u00e8s du serveur \u00e0 un chemin d'acc\u00e8s accessible par les clients. En autorisant un acc\u00e8s direct aux m\u00e9dias du serveur, les clients pourront les lire directement du r\u00e9seau et \u00e9viter l'utilisation inutiles des ressources du serveur en demandant du transcodage.",
@@ -480,10 +480,10 @@
     "HeaderProgram": "Programme",
     "HeaderClients": "Clients",
     "LabelCompleted": "Compl\u00e9t\u00e9",
-    "LabelFailed": "Failed",
+    "LabelFailed": "\u00c9chec",
     "LabelSkipped": "Saut\u00e9",
     "HeaderEpisodeOrganization": "Organisation d'\u00e9pisodes",
-    "LabelSeries": "Series:",
+    "LabelSeries": "S\u00e9ries:",
     "LabelSeasonNumber": "Num\u00e9ro de saison",
     "LabelEpisodeNumber": "Num\u00e9ro d'\u00e9pisode",
     "LabelEndingEpisodeNumber": "Num\u00e9ro d'\u00e9pisode se terminant",
@@ -627,12 +627,12 @@
     "TabNowPlaying": "En cours de lecture",
     "TabNavigation": "Navigation",
     "TabControls": "Contr\u00f4les",
-    "ButtonFullscreen": "Basculer en plein \u00e9cran",
+    "ButtonFullscreen": "Plein \u00e9cran",
     "ButtonScenes": "Sc\u00e8nes",
     "ButtonSubtitles": "Sous-titres",
-    "ButtonAudioTracks": "Pistes audio",
-    "ButtonPreviousTrack": "Previous track",
-    "ButtonNextTrack": "Next track",
+    "ButtonAudioTracks": "Piste audio",
+    "ButtonPreviousTrack": "Piste pr\u00e9c\u00e9dante",
+    "ButtonNextTrack": "Piste suivante",
     "ButtonStop": "Arr\u00eat",
     "ButtonPause": "Pause",
     "LabelGroupMoviesIntoCollections": "Grouper les films en collections",
@@ -788,6 +788,7 @@
     "HeaderMetadataManager": "Gestionnaire de m\u00e9tadonn\u00e9es",
     "HeaderPreferences": "Pr\u00e9f\u00e9rences",
     "MessageLoadingChannels": "Chargement du contenu de la cha\u00eene...",
+    "MessageLoadingContent": "Loading content...",
     "ButtonMarkRead": "Marquer lu",
     "OptionDefaultSort": "Par d\u00e9faut",
     "OptionCommunityMostWatchedSort": "Les plus \u00e9cout\u00e9s",
@@ -795,7 +796,7 @@
     "MessageNoMovieSuggestionsAvailable": "Aucune suggestion de film n'est actuellement disponible. Commencez \u00e0 regarder et noter vos films pour avoir des suggestions.",
     "MessageNoCollectionsAvailable": "Les Collections permettent le groupement de films, S\u00e9ries, Albums, Livres et Jeux. Cliquer sur \"Nouveau\" pour commencer la cr\u00e9ation des Collections.",
     "MessageNoPlaylistsAvailable": "Playlists allow you to create lists of content to play consecutively at a time. To add items to playlists, right click or tap and hold, then select Add to Playlist.",
-    "MessageNoPlaylistItemsAvailable": "This playlist is currently empty.",
+    "MessageNoPlaylistItemsAvailable": "Cette liste de lecture est pr\u00e9sentement vide.",
     "HeaderWelcomeToMediaBrowserWebClient": "Bienvenue au client Web Media Browser",
     "ButtonDismiss": "Annuler",
     "MessageLearnHowToCustomize": "Apprenez comment personnaliser cette page selon vos propres go\u00fbts. S\u00e9lectionnez votre ic\u00f4ne d'utilisateur dans le coin en haut, \u00e0 droite de l'\u00e9cran pour visionner et mettre \u00e0 jour vos pr\u00e9f\u00e9rences. ",
@@ -896,43 +897,43 @@
     "HeaderChapters": "Chapitres",
     "HeaderResumeSettings": "Reprendre les param\u00e8tres",
     "TabSync": "Sync",
-    "TitleUsers": "Users",
+    "TitleUsers": "Utilisateurs",
     "LabelProtocol": "Protocol:",
     "OptionProtocolHttp": "Http",
     "OptionProtocolHls": "Http Live Streaming",
-    "LabelContext": "Context:",
-    "OptionContextStreaming": "Streaming",
+    "LabelContext": "Contexte:",
+    "OptionContextStreaming": "Diffusion",
     "OptionContextStatic": "Sync",
-    "ButtonAddToPlaylist": "Add to playlist",
-    "TabPlaylists": "Playlists",
+    "ButtonAddToPlaylist": "Ajouter \u00e0 la liste de lecture",
+    "TabPlaylists": "Listes de lecture",
     "ButtonClose": "Fermer",
-    "LabelAllLanguages": "All languages",
-    "HeaderBrowseOnlineImages": "Browse Online Images",
+    "LabelAllLanguages": "Toutes les langues",
+    "HeaderBrowseOnlineImages": "Parcourir les images en ligne",
     "LabelSource": "Source:",
-    "OptionAll": "All",
+    "OptionAll": "Tous",
     "LabelImage": "Image:",
-    "ButtonBrowseImages": "Browse Images",
+    "ButtonBrowseImages": "Parcourir les images:",
     "HeaderImages": "Images",
-    "HeaderBackdrops": "Backdrops",
+    "HeaderBackdrops": "Arri\u00e8re-plans",
     "HeaderScreenshots": "Screenshots",
-    "HeaderAddUpdateImage": "Add\/Update Image",
-    "LabelJpgPngOnly": "JPG\/PNG only",
-    "LabelImageType": "Image type:",
-    "OptionPrimary": "Primary",
+    "HeaderAddUpdateImage": "Ajouter\/mettre \u00e0 jour image",
+    "LabelJpgPngOnly": "JPG\/PNG seulement",
+    "LabelImageType": "Type d'image:",
+    "OptionPrimary": "Principal",
     "OptionArt": "Art",
-    "OptionBox": "Box",
-    "OptionBoxRear": "Box rear",
-    "OptionDisc": "Disc",
+    "OptionBox": "Bo\u00eetier",
+    "OptionBoxRear": "Dos de bo\u00eetier",
+    "OptionDisc": "Disque",
     "OptionLogo": "Logo",
     "OptionMenu": "Menu",
     "OptionScreenshot": "Screenshot",
-    "OptionLocked": "Locked",
-    "OptionUnidentified": "Unidentified",
-    "OptionMissingParentalRating": "Missing parental rating",
+    "OptionLocked": "Verrouill\u00e9",
+    "OptionUnidentified": "Non identifi\u00e9",
+    "OptionMissingParentalRating": "Note de contr\u00f4le parental manquante",
     "OptionStub": "Stub",
-    "HeaderEpisodes": "Episodes:",
-    "OptionSeason0": "Season 0",
-    "LabelReport": "Report:",
+    "HeaderEpisodes": "\u00c9pisodes:",
+    "OptionSeason0": "Saison 0",
+    "LabelReport": "Rapport:",
     "OptionReportSongs": "Songs",
     "OptionReportSeries": "Series",
     "OptionReportSeasons": "Seasons",
@@ -979,5 +980,7 @@
     "UserStartedPlayingItemWithValues": "{0} has started playing {1}",
     "UserStoppedPlayingItemWithValues": "{0} has stopped playing {1}",
     "AppDeviceValues": "App: {0}, Device: {1}",
-    "ProviderValue": "Provider: {0}"
+    "ProviderValue": "Provider: {0}",
+    "LabelChannelDownloadSizeLimit": "Download size limit (GB):",
+    "LabelChannelDownloadSizeLimitHelp": "Limit the size of the channel download folder"
 }

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

@@ -397,7 +397,7 @@
     "HeaderCastCrew": "\u05e9\u05d7\u05e7\u05e0\u05d9\u05dd \u05d5\u05e6\u05d5\u05d5\u05ea",
     "HeaderAdditionalParts": "\u05d7\u05dc\u05e7\u05d9\u05dd \u05e0\u05d5\u05e1\u05e4\u05d9\u05dd",
     "ButtonSplitVersionsApart": "\u05e4\u05e6\u05dc \u05d2\u05e8\u05e1\u05d0\u05d5\u05ea \u05d1\u05e0\u05e4\u05e8\u05d3",
-    "ButtonPlayTrailer": "Trailer",
+    "ButtonPlayTrailer": "\u05d8\u05e8\u05d9\u05d9\u05dc\u05e8\u05d9\u05dd",
     "LabelMissing": "\u05d7\u05e1\u05e8",
     "LabelOffline": "\u05dc\u05d0 \u05de\u05e7\u05d5\u05d5\u05df",
     "PathSubstitutionHelp": "\u05e0\u05ea\u05d9\u05d1\u05d9\u05dd \u05d7\u05dc\u05d5\u05e4\u05d9\u05d9\u05dd \u05d4\u05dd \u05dc\u05e6\u05d5\u05e8\u05da \u05de\u05d9\u05e4\u05d5\u05d9 \u05e0\u05ea\u05d9\u05d1\u05d9\u05dd \u05d1\u05e9\u05e8\u05ea \u05dc\u05e0\u05ea\u05d9\u05d1\u05d9\u05dd \u05e9\u05de\u05e9\u05ea\u05de\u05e9\u05d9\u05dd \u05d9\u05db\u05d5\u05dc\u05d9\u05dd \u05dc\u05d2\u05e9\u05ea \u05d0\u05dc\u05d9\u05d4\u05dd. \u05e2\u05dc \u05d9\u05d3\u05d9 \u05d4\u05e8\u05e9\u05d0\u05d4 \u05dc\u05de\u05e9\u05ea\u05de\u05e9\u05d9\u05dd \u05d2\u05d9\u05e9\u05d4 \u05d9\u05e9\u05d9\u05e8\u05d4 \u05dc\u05de\u05d3\u05d9\u05d4 \u05d1\u05e9\u05e8\u05ea \u05d0\u05dd \u05d9\u05db\u05d5\u05dc\u05d9\u05dd \u05dc\u05e0\u05d2\u05df \u05d0\u05ea \u05d4\u05e7\u05d1\u05e6\u05d9\u05dd \u05d9\u05e9\u05d9\u05e8\u05d5\u05ea \u05e2\u05dc \u05d2\u05d1\u05d9 \u05d4\u05e8\u05e9\u05ea \u05d5\u05dc\u05d4\u05d9\u05de\u05e0\u05e2 \u05de\u05e9\u05d9\u05de\u05d5\u05e9 \u05d1\u05de\u05e9\u05d0\u05d1\u05d9 \u05d4\u05e9\u05e8\u05ea \u05dc\u05e6\u05d5\u05e8\u05da \u05e7\u05d9\u05d3\u05d5\u05d3 \u05d5\u05e9\u05d9\u05d3\u05d5\u05e8.",
@@ -480,10 +480,10 @@
     "HeaderProgram": "\u05ea\u05d5\u05db\u05e0\u05d4",
     "HeaderClients": "\u05de\u05e9\u05ea\u05de\u05e9\u05d9\u05dd",
     "LabelCompleted": "\u05d4\u05d5\u05e9\u05dc\u05dd",
-    "LabelFailed": "Failed",
+    "LabelFailed": "\u05e0\u05db\u05e9\u05dc",
     "LabelSkipped": "\u05d3\u05d5\u05dc\u05d2",
     "HeaderEpisodeOrganization": "\u05d0\u05d9\u05e8\u05d2\u05d5\u05df \u05e4\u05e8\u05e7\u05d9\u05dd",
-    "LabelSeries": "Series:",
+    "LabelSeries": "\u05e1\u05d3\u05e8\u05d4:",
     "LabelSeasonNumber": "\u05de\u05e1\u05e4\u05e8 \u05e2\u05d5\u05e0\u05d4:",
     "LabelEpisodeNumber": "\u05de\u05e1\u05e4\u05e8 \u05e4\u05e8\u05e7:",
     "LabelEndingEpisodeNumber": "\u05de\u05e1\u05e4\u05e8 \u05e1\u05d9\u05d5\u05dd \u05e4\u05e8\u05e7:",
@@ -788,6 +788,7 @@
     "HeaderMetadataManager": "Metadata Manager",
     "HeaderPreferences": "Preferences",
     "MessageLoadingChannels": "Loading channel content...",
+    "MessageLoadingContent": "Loading content...",
     "ButtonMarkRead": "Mark Read",
     "OptionDefaultSort": "Default",
     "OptionCommunityMostWatchedSort": "Most Watched",
@@ -979,5 +980,7 @@
     "UserStartedPlayingItemWithValues": "{0} has started playing {1}",
     "UserStoppedPlayingItemWithValues": "{0} has stopped playing {1}",
     "AppDeviceValues": "App: {0}, Device: {1}",
-    "ProviderValue": "Provider: {0}"
+    "ProviderValue": "Provider: {0}",
+    "LabelChannelDownloadSizeLimit": "Download size limit (GB):",
+    "LabelChannelDownloadSizeLimitHelp": "Limit the size of the channel download folder"
 }

+ 42 - 39
MediaBrowser.Server.Implementations/Localization/Server/it.json

@@ -480,10 +480,10 @@
     "HeaderProgram": "Programma",
     "HeaderClients": "Dispositivi",
     "LabelCompleted": "Completato",
-    "LabelFailed": "Failed",
+    "LabelFailed": "Fallito",
     "LabelSkipped": "Saltato",
     "HeaderEpisodeOrganization": "Organizzazione Episodi",
-    "LabelSeries": "Series:",
+    "LabelSeries": "Serie:",
     "LabelSeasonNumber": "Numero Stagione",
     "LabelEpisodeNumber": "Numero Episodio",
     "LabelEndingEpisodeNumber": "Ultimo Episodio Numero",
@@ -627,12 +627,12 @@
     "TabNowPlaying": "In esecuzione",
     "TabNavigation": "Navigazione",
     "TabControls": "Controlli",
-    "ButtonFullscreen": "Tutto Schermo",
+    "ButtonFullscreen": "Schermo intero",
     "ButtonScenes": "Scene",
     "ButtonSubtitles": "Sottotitoli",
-    "ButtonAudioTracks": "Tracce audio",
-    "ButtonPreviousTrack": "Previous track",
-    "ButtonNextTrack": "Next track",
+    "ButtonAudioTracks": "Traccia Audio",
+    "ButtonPreviousTrack": "Precedente traccia",
+    "ButtonNextTrack": "traccia Prossima",
     "ButtonStop": "Stop",
     "ButtonPause": "Pausa",
     "LabelGroupMoviesIntoCollections": "Raggruppa i film nelle collection",
@@ -788,14 +788,15 @@
     "HeaderMetadataManager": "Metadata Manager",
     "HeaderPreferences": "Preferenze",
     "MessageLoadingChannels": "Sto caricando il contenuto del canale",
+    "MessageLoadingContent": "Loading content...",
     "ButtonMarkRead": "Segna come letto",
     "OptionDefaultSort": "Predefinito",
     "OptionCommunityMostWatchedSort": "Pi\u00f9 visti",
     "TabNextUp": "Da vedere",
     "MessageNoMovieSuggestionsAvailable": "Nessun suggerimento di film sono attualmente disponibili. Iniziare a guardare e valutare i vostri film, e poi tornare per visualizzare le tue segnalazioni.",
     "MessageNoCollectionsAvailable": "Collezioni permettono di godere di raggruppamenti personalizzati di film, serie, album, libri e giochi. Fare clic sul pulsante Nuovo per avviare la creazione di collezioni.",
-    "MessageNoPlaylistsAvailable": "Playlists allow you to create lists of content to play consecutively at a time. To add items to playlists, right click or tap and hold, then select Add to Playlist.",
-    "MessageNoPlaylistItemsAvailable": "This playlist is currently empty.",
+    "MessageNoPlaylistsAvailable": "Playlist ti permettere di mettere in coda gli elementi da riprodurre.Usa il tasto destro o tap e tieni premuto quindi seleziona elemento da aggiungere",
+    "MessageNoPlaylistItemsAvailable": "Questa playlist al momento \u00e8 vuota",
     "HeaderWelcomeToMediaBrowserWebClient": "Benvenuti nel Media Browser Web client",
     "ButtonDismiss": "Dismetti",
     "MessageLearnHowToCustomize": "Ulteriori informazioni su come personalizzare questa pagina ai tuoi gusti personali. Fare clic sull'icona utente in alto a destra dello schermo per visualizzare e aggiornare le vostre preferenze.",
@@ -903,48 +904,48 @@
     "LabelContext": "Contenuto:",
     "OptionContextStreaming": "Streaming",
     "OptionContextStatic": "Sinc",
-    "ButtonAddToPlaylist": "Add to playlist",
+    "ButtonAddToPlaylist": "Aggiungi alla playlist",
     "TabPlaylists": "Playlists",
     "ButtonClose": "Chiudi",
-    "LabelAllLanguages": "All languages",
-    "HeaderBrowseOnlineImages": "Browse Online Images",
-    "LabelSource": "Source:",
-    "OptionAll": "All",
-    "LabelImage": "Image:",
-    "ButtonBrowseImages": "Browse Images",
-    "HeaderImages": "Images",
-    "HeaderBackdrops": "Backdrops",
-    "HeaderScreenshots": "Screenshots",
-    "HeaderAddUpdateImage": "Add\/Update Image",
-    "LabelJpgPngOnly": "JPG\/PNG only",
-    "LabelImageType": "Image type:",
-    "OptionPrimary": "Primary",
+    "LabelAllLanguages": "Tutte le lingue",
+    "HeaderBrowseOnlineImages": "Sfoglia le immagini sul web",
+    "LabelSource": "Origine:",
+    "OptionAll": "Tutto",
+    "LabelImage": "Immagine:",
+    "ButtonBrowseImages": "Sfoglia immagini",
+    "HeaderImages": "Immagini",
+    "HeaderBackdrops": "Sfondi",
+    "HeaderScreenshots": "Immagini",
+    "HeaderAddUpdateImage": "Aggiungi\/aggiorna immagine",
+    "LabelJpgPngOnly": "JPG\/PNG solamente",
+    "LabelImageType": "Tipo immagine",
+    "OptionPrimary": "Primaria",
     "OptionArt": "Art",
     "OptionBox": "Box",
     "OptionBoxRear": "Box rear",
     "OptionDisc": "Disc",
     "OptionLogo": "Logo",
     "OptionMenu": "Menu",
-    "OptionScreenshot": "Screenshot",
-    "OptionLocked": "Locked",
-    "OptionUnidentified": "Unidentified",
-    "OptionMissingParentalRating": "Missing parental rating",
+    "OptionScreenshot": "Immagine",
+    "OptionLocked": "Bloccato",
+    "OptionUnidentified": "Non identificata",
+    "OptionMissingParentalRating": "Voto genitori mancante",
     "OptionStub": "Stub",
-    "HeaderEpisodes": "Episodes:",
-    "OptionSeason0": "Season 0",
+    "HeaderEpisodes": "Episodi:",
+    "OptionSeason0": "Stagione 0",
     "LabelReport": "Report:",
-    "OptionReportSongs": "Songs",
+    "OptionReportSongs": "Canzoni",
     "OptionReportSeries": "Series",
-    "OptionReportSeasons": "Seasons",
+    "OptionReportSeasons": "Stagioni",
     "OptionReportTrailers": "Trailers",
-    "OptionReportMusicVideos": "Music videos",
-    "OptionReportMovies": "Movies",
-    "OptionReportHomeVideos": "Home videos",
-    "OptionReportGames": "Games",
-    "OptionReportEpisodes": "Episodes",
-    "OptionReportCollections": "Collections",
-    "OptionReportBooks": "Books",
-    "OptionReportArtists": "Artists",
+    "OptionReportMusicVideos": "Video musicali",
+    "OptionReportMovies": "Film",
+    "OptionReportHomeVideos": "Video personali",
+    "OptionReportGames": "Giochi",
+    "OptionReportEpisodes": "Episodi",
+    "OptionReportCollections": "Collezioni",
+    "OptionReportBooks": "Libri",
+    "OptionReportArtists": "Cantanti",
     "OptionReportAlbums": "Albums",
     "OptionReportAdultVideos": "Adult videos",
     "ButtonMore": "Pi\u00f9 info...",
@@ -979,5 +980,7 @@
     "UserStartedPlayingItemWithValues": "{0} has started playing {1}",
     "UserStoppedPlayingItemWithValues": "{0} has stopped playing {1}",
     "AppDeviceValues": "App: {0}, Device: {1}",
-    "ProviderValue": "Provider: {0}"
+    "ProviderValue": "Provider: {0}",
+    "LabelChannelDownloadSizeLimit": "Download size limit (GB):",
+    "LabelChannelDownloadSizeLimitHelp": "Limit the size of the channel download folder"
 }

Some files were not shown because too many files changed in this diff