Luke Pulverenti 10 gadi atpakaļ
vecāks
revīzija
3c48def0d7
32 mainītis faili ar 298 papildinājumiem un 89 dzēšanām
  1. 2 2
      MediaBrowser.Api/Sync/SyncService.cs
  2. 24 1
      MediaBrowser.Controller/Entities/User.cs
  3. 2 2
      MediaBrowser.Controller/Library/IUserManager.cs
  4. 6 0
      MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj
  5. 6 0
      MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj
  6. 23 0
      MediaBrowser.Model/ApiClient/ConnectionOptions.cs
  7. 9 0
      MediaBrowser.Model/ApiClient/IConnectionManager.cs
  8. 12 0
      MediaBrowser.Model/Dto/UserDto.cs
  9. 2 0
      MediaBrowser.Model/MediaBrowser.Model.csproj
  10. 19 0
      MediaBrowser.Model/Sync/SyncCategory.cs
  11. 13 0
      MediaBrowser.Model/Sync/SyncHelper.cs
  12. 10 0
      MediaBrowser.Model/Sync/SyncJob.cs
  13. 10 0
      MediaBrowser.Model/Sync/SyncJobRequest.cs
  14. 2 1
      MediaBrowser.Model/Sync/SyncOptions.cs
  15. 2 5
      MediaBrowser.Model/Users/UserPolicy.cs
  16. 16 2
      MediaBrowser.Server.Implementations/Channels/ChannelDownloadScheduledTask.cs
  17. 4 1
      MediaBrowser.Server.Implementations/Channels/ChannelManager.cs
  18. 2 0
      MediaBrowser.Server.Implementations/Channels/ChannelPostScanTask.cs
  19. 62 7
      MediaBrowser.Server.Implementations/Library/UserManager.cs
  20. 0 35
      MediaBrowser.Server.Implementations/Library/Validators/UserViewPostScanTask.cs
  21. 3 3
      MediaBrowser.Server.Implementations/Localization/Server/server.json
  22. 0 1
      MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
  23. 19 3
      MediaBrowser.Server.Implementations/Session/HttpSessionController.cs
  24. 4 2
      MediaBrowser.Server.Implementations/Sync/SyncManager.cs
  25. 24 10
      MediaBrowser.Server.Implementations/Sync/SyncRepository.cs
  26. 14 6
      MediaBrowser.Server.Startup.Common/ApplicationHost.cs
  27. 1 1
      MediaBrowser.Server.Startup.Common/Migrations/RenameXbmcOptions.cs
  28. 1 1
      MediaBrowser.Server.Startup.Common/Migrations/RenameXmlOptions.cs
  29. 2 2
      Nuget/MediaBrowser.Common.Internal.nuspec
  30. 1 1
      Nuget/MediaBrowser.Common.nuspec
  31. 1 1
      Nuget/MediaBrowser.Model.Signed.nuspec
  32. 2 2
      Nuget/MediaBrowser.Server.Core.nuspec

+ 2 - 2
MediaBrowser.Api/Sync/SyncService.cs

@@ -46,7 +46,7 @@ namespace MediaBrowser.Api.Sync
     }
     }
 
 
     [Route("/Sync/Targets", "GET", Summary = "Gets a list of available sync targets.")]
     [Route("/Sync/Targets", "GET", Summary = "Gets a list of available sync targets.")]
-    public class GetSyncTarget : IReturn<List<SyncTarget>>
+    public class GetSyncTargets : IReturn<List<SyncTarget>>
     {
     {
         [ApiMember(Name = "UserId", Description = "UserId", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
         [ApiMember(Name = "UserId", Description = "UserId", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
         public string UserId { get; set; }
         public string UserId { get; set; }
@@ -62,7 +62,7 @@ namespace MediaBrowser.Api.Sync
             _syncManager = syncManager;
             _syncManager = syncManager;
         }
         }
 
 
-        public object Get(GetSyncTarget request)
+        public object Get(GetSyncTargets request)
         {
         {
             var result = _syncManager.GetSyncTargets(request.UserId);
             var result = _syncManager.GetSyncTargets(request.UserId);
 
 

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

@@ -140,6 +140,29 @@ namespace MediaBrowser.Controller.Entities
             }
             }
         }
         }
 
 
+        private UserPolicy _policy;
+        private readonly object _policySyncLock = new object();
+        [IgnoreDataMember]
+        public UserPolicy Policy
+        {
+            get
+            {
+                if (_policy == null)
+                {
+                    lock (_policySyncLock)
+                    {
+                        if (_policy == null)
+                        {
+                            _policy = UserManager.GetUserPolicy(this);
+                        }
+                    }
+                }
+                
+                return _policy;
+            }
+            set { _policy = value; }
+        }
+
         /// <summary>
         /// <summary>
         /// Renames the user.
         /// Renames the user.
         /// </summary>
         /// </summary>
@@ -200,7 +223,7 @@ namespace MediaBrowser.Controller.Entities
         /// </summary>
         /// </summary>
         /// <value>The configuration directory path.</value>
         /// <value>The configuration directory path.</value>
         [IgnoreDataMember]
         [IgnoreDataMember]
-        private string ConfigurationDirectoryPath
+        public string ConfigurationDirectoryPath
         {
         {
             get
             get
             {
             {

+ 2 - 2
MediaBrowser.Controller/Library/IUserManager.cs

@@ -168,9 +168,9 @@ namespace MediaBrowser.Controller.Library
         /// <summary>
         /// <summary>
         /// Gets the user policy.
         /// Gets the user policy.
         /// </summary>
         /// </summary>
-        /// <param name="userId">The user identifier.</param>
+        /// <param name="user">The user.</param>
         /// <returns>UserPolicy.</returns>
         /// <returns>UserPolicy.</returns>
-        UserPolicy GetUserPolicy(string userId);
+        UserPolicy GetUserPolicy(User user);
 
 
         /// <summary>
         /// <summary>
         /// Updates the user policy.
         /// Updates the user policy.

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

@@ -80,6 +80,9 @@
     <Compile Include="..\MediaBrowser.Model\ApiClient\ConnectionMode.cs">
     <Compile Include="..\MediaBrowser.Model\ApiClient\ConnectionMode.cs">
       <Link>ApiClient\ConnectionMode.cs</Link>
       <Link>ApiClient\ConnectionMode.cs</Link>
     </Compile>
     </Compile>
+    <Compile Include="..\MediaBrowser.Model\ApiClient\ConnectionOptions.cs">
+      <Link>ApiClient\ConnectionOptions.cs</Link>
+    </Compile>
     <Compile Include="..\MediaBrowser.Model\ApiClient\ConnectionResult.cs">
     <Compile Include="..\MediaBrowser.Model\ApiClient\ConnectionResult.cs">
       <Link>ApiClient\ConnectionResult.cs</Link>
       <Link>ApiClient\ConnectionResult.cs</Link>
     </Compile>
     </Compile>
@@ -1025,6 +1028,9 @@
     <Compile Include="..\MediaBrowser.Model\Session\UserDataChangeInfo.cs">
     <Compile Include="..\MediaBrowser.Model\Session\UserDataChangeInfo.cs">
       <Link>Session\UserDataChangeInfo.cs</Link>
       <Link>Session\UserDataChangeInfo.cs</Link>
     </Compile>
     </Compile>
+    <Compile Include="..\MediaBrowser.Model\Sync\SyncCategory.cs">
+      <Link>Sync\SyncCategory.cs</Link>
+    </Compile>
     <Compile Include="..\MediaBrowser.Model\Sync\SyncJob.cs">
     <Compile Include="..\MediaBrowser.Model\Sync\SyncJob.cs">
       <Link>Sync\SyncJob.cs</Link>
       <Link>Sync\SyncJob.cs</Link>
     </Compile>
     </Compile>

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

@@ -60,6 +60,9 @@
     <Compile Include="..\MediaBrowser.Model\ApiClient\ConnectionMode.cs">
     <Compile Include="..\MediaBrowser.Model\ApiClient\ConnectionMode.cs">
       <Link>ApiClient\ConnectionMode.cs</Link>
       <Link>ApiClient\ConnectionMode.cs</Link>
     </Compile>
     </Compile>
+    <Compile Include="..\MediaBrowser.Model\ApiClient\ConnectionOptions.cs">
+      <Link>ApiClient\ConnectionOptions.cs</Link>
+    </Compile>
     <Compile Include="..\MediaBrowser.Model\ApiClient\ConnectionState.cs">
     <Compile Include="..\MediaBrowser.Model\ApiClient\ConnectionState.cs">
       <Link>ApiClient\ConnectionState.cs</Link>
       <Link>ApiClient\ConnectionState.cs</Link>
     </Compile>
     </Compile>
@@ -984,6 +987,9 @@
     <Compile Include="..\MediaBrowser.Model\Session\UserDataChangeInfo.cs">
     <Compile Include="..\MediaBrowser.Model\Session\UserDataChangeInfo.cs">
       <Link>Session\UserDataChangeInfo.cs</Link>
       <Link>Session\UserDataChangeInfo.cs</Link>
     </Compile>
     </Compile>
+    <Compile Include="..\MediaBrowser.Model\Sync\SyncCategory.cs">
+      <Link>Sync\SyncCategory.cs</Link>
+    </Compile>
     <Compile Include="..\MediaBrowser.Model\Sync\SyncJob.cs">
     <Compile Include="..\MediaBrowser.Model\Sync\SyncJob.cs">
       <Link>Sync\SyncJob.cs</Link>
       <Link>Sync\SyncJob.cs</Link>
     </Compile>
     </Compile>

+ 23 - 0
MediaBrowser.Model/ApiClient/ConnectionOptions.cs

@@ -0,0 +1,23 @@
+
+namespace MediaBrowser.Model.ApiClient
+{
+    public class ConnectionOptions
+    {
+        /// <summary>
+        /// Gets or sets a value indicating whether [enable web socket].
+        /// </summary>
+        /// <value><c>true</c> if [enable web socket]; otherwise, <c>false</c>.</value>
+        public bool EnableWebSocket { get; set; }
+        /// <summary>
+        /// Gets or sets a value indicating whether [report capabilities].
+        /// </summary>
+        /// <value><c>true</c> if [report capabilities]; otherwise, <c>false</c>.</value>
+        public bool ReportCapabilities { get; set; }
+
+        public ConnectionOptions()
+        {
+            EnableWebSocket = true;
+            ReportCapabilities = true;
+        }
+    }
+}

+ 9 - 0
MediaBrowser.Model/ApiClient/IConnectionManager.cs

@@ -77,6 +77,15 @@ namespace MediaBrowser.Model.ApiClient
         /// <returns>Task&lt;ConnectionResult&gt;.</returns>
         /// <returns>Task&lt;ConnectionResult&gt;.</returns>
         Task<ConnectionResult> Connect(ServerInfo server, CancellationToken cancellationToken);
         Task<ConnectionResult> Connect(ServerInfo server, CancellationToken cancellationToken);
 
 
+        /// <summary>
+        /// Connects the specified server.
+        /// </summary>
+        /// <param name="server">The server.</param>
+        /// <param name="options">The options.</param>
+        /// <param name="cancellationToken">The cancellation token.</param>
+        /// <returns>Task&lt;ConnectionResult&gt;.</returns>
+        Task<ConnectionResult> Connect(ServerInfo server, ConnectionOptions options, CancellationToken cancellationToken);
+
         /// <summary>
         /// <summary>
         /// Connects the specified server.
         /// Connects the specified server.
         /// </summary>
         /// </summary>

+ 12 - 0
MediaBrowser.Model/Dto/UserDto.cs

@@ -1,6 +1,7 @@
 using MediaBrowser.Model.Configuration;
 using MediaBrowser.Model.Configuration;
 using MediaBrowser.Model.Connect;
 using MediaBrowser.Model.Connect;
 using MediaBrowser.Model.Extensions;
 using MediaBrowser.Model.Extensions;
+using MediaBrowser.Model.Users;
 using System;
 using System;
 using System.ComponentModel;
 using System.ComponentModel;
 using System.Diagnostics;
 using System.Diagnostics;
@@ -60,6 +61,10 @@ namespace MediaBrowser.Model.Dto
         /// <value><c>true</c> if this instance has password; otherwise, <c>false</c>.</value>
         /// <value><c>true</c> if this instance has password; otherwise, <c>false</c>.</value>
         public bool HasPassword { get; set; }
         public bool HasPassword { get; set; }
 
 
+        /// <summary>
+        /// Gets or sets a value indicating whether this instance has configured password.
+        /// </summary>
+        /// <value><c>true</c> if this instance has configured password; otherwise, <c>false</c>.</value>
         public bool HasConfiguredPassword { get; set; }
         public bool HasConfiguredPassword { get; set; }
         
         
         /// <summary>
         /// <summary>
@@ -80,6 +85,12 @@ namespace MediaBrowser.Model.Dto
         /// <value>The configuration.</value>
         /// <value>The configuration.</value>
         public UserConfiguration Configuration { get; set; }
         public UserConfiguration Configuration { get; set; }
 
 
+        /// <summary>
+        /// Gets or sets the policy.
+        /// </summary>
+        /// <value>The policy.</value>
+        public UserPolicy Policy { get; set; }
+
         /// <summary>
         /// <summary>
         /// Gets or sets the primary image aspect ratio.
         /// Gets or sets the primary image aspect ratio.
         /// </summary>
         /// </summary>
@@ -108,6 +119,7 @@ namespace MediaBrowser.Model.Dto
         public UserDto()
         public UserDto()
         {
         {
             Configuration = new UserConfiguration();
             Configuration = new UserConfiguration();
+            Policy = new UserPolicy();
         }
         }
 
 
         /// <summary>
         /// <summary>

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

@@ -104,6 +104,7 @@
     <Compile Include="Connect\ConnectAuthenticationResult.cs" />
     <Compile Include="Connect\ConnectAuthenticationResult.cs" />
     <Compile Include="Connect\ConnectAuthorization.cs" />
     <Compile Include="Connect\ConnectAuthorization.cs" />
     <Compile Include="Connect\ConnectAuthorizationRequest.cs" />
     <Compile Include="Connect\ConnectAuthorizationRequest.cs" />
+    <Compile Include="ApiClient\ConnectionOptions.cs" />
     <Compile Include="Connect\ConnectPassword.cs" />
     <Compile Include="Connect\ConnectPassword.cs" />
     <Compile Include="Connect\ConnectUser.cs" />
     <Compile Include="Connect\ConnectUser.cs" />
     <Compile Include="Connect\ConnectUserQuery.cs" />
     <Compile Include="Connect\ConnectUserQuery.cs" />
@@ -362,6 +363,7 @@
     <Compile Include="Session\TranscodingInfo.cs" />
     <Compile Include="Session\TranscodingInfo.cs" />
     <Compile Include="Session\UserDataChangeInfo.cs" />
     <Compile Include="Session\UserDataChangeInfo.cs" />
     <Compile Include="Devices\ContentUploadHistory.cs" />
     <Compile Include="Devices\ContentUploadHistory.cs" />
+    <Compile Include="Sync\SyncCategory.cs" />
     <Compile Include="Sync\SyncHelper.cs" />
     <Compile Include="Sync\SyncHelper.cs" />
     <Compile Include="Sync\SyncJob.cs" />
     <Compile Include="Sync\SyncJob.cs" />
     <Compile Include="Sync\SyncJobCreationResult.cs" />
     <Compile Include="Sync\SyncJobCreationResult.cs" />

+ 19 - 0
MediaBrowser.Model/Sync/SyncCategory.cs

@@ -0,0 +1,19 @@
+
+namespace MediaBrowser.Model.Sync
+{
+    public enum SyncCategory
+    {
+        /// <summary>
+        /// The latest
+        /// </summary>
+        Latest = 0,
+        /// <summary>
+        /// The next up
+        /// </summary>
+        NextUp = 1,
+        /// <summary>
+        /// The resume
+        /// </summary>
+        Resume = 2
+    }
+}

+ 13 - 0
MediaBrowser.Model/Sync/SyncHelper.cs

@@ -40,6 +40,7 @@ namespace MediaBrowser.Model.Sync
                     if (item.IsFolder || item.IsGameGenre || item.IsMusicGenre || item.IsGenre || item.IsArtist || item.IsStudio || item.IsPerson)
                     if (item.IsFolder || item.IsGameGenre || item.IsMusicGenre || item.IsGenre || item.IsArtist || item.IsStudio || item.IsPerson)
                     {
                     {
                         options.Add(SyncOptions.SyncNewContent);
                         options.Add(SyncOptions.SyncNewContent);
+                        options.Add(SyncOptions.ItemLimit);
                         break;
                         break;
                     }
                     }
                 }
                 }
@@ -47,5 +48,17 @@ namespace MediaBrowser.Model.Sync
 
 
             return options;
             return options;
         }
         }
+
+        public static List<SyncOptions> GetSyncOptions(SyncCategory category)
+        {
+            List<SyncOptions> options = new List<SyncOptions>();
+
+            options.Add(SyncOptions.Quality);
+            options.Add(SyncOptions.UnwatchedOnly);
+            options.Add(SyncOptions.SyncNewContent);
+            options.Add(SyncOptions.ItemLimit);
+
+            return options;
+        }
     }
     }
 }
 }

+ 10 - 0
MediaBrowser.Model/Sync/SyncJob.cs

@@ -21,6 +21,16 @@ namespace MediaBrowser.Model.Sync
         /// <value>The quality.</value>
         /// <value>The quality.</value>
         public SyncQuality Quality { get; set; }
         public SyncQuality Quality { get; set; }
         /// <summary>
         /// <summary>
+        /// Gets or sets the category.
+        /// </summary>
+        /// <value>The category.</value>
+        public SyncCategory? Category { get; set; }
+        /// <summary>
+        /// Gets or sets the parent identifier.
+        /// </summary>
+        /// <value>The parent identifier.</value>
+        public string ParentId { get; set; }
+        /// <summary>
         /// Gets or sets the current progress.
         /// Gets or sets the current progress.
         /// </summary>
         /// </summary>
         /// <value>The current progress.</value>
         /// <value>The current progress.</value>

+ 10 - 0
MediaBrowser.Model/Sync/SyncJobRequest.cs

@@ -15,6 +15,16 @@ namespace MediaBrowser.Model.Sync
         /// <value>The item ids.</value>
         /// <value>The item ids.</value>
         public List<string> ItemIds { get; set; }
         public List<string> ItemIds { get; set; }
         /// <summary>
         /// <summary>
+        /// Gets or sets the category.
+        /// </summary>
+        /// <value>The category.</value>
+        public SyncCategory? Category { get; set; }
+        /// <summary>
+        /// Gets or sets the parent identifier.
+        /// </summary>
+        /// <value>The parent identifier.</value>
+        public string ParentId { get; set; }
+        /// <summary>
         /// Gets or sets the quality.
         /// Gets or sets the quality.
         /// </summary>
         /// </summary>
         /// <value>The quality.</value>
         /// <value>The quality.</value>

+ 2 - 1
MediaBrowser.Model/Sync/SyncOptions.cs

@@ -6,6 +6,7 @@ namespace MediaBrowser.Model.Sync
         Name = 0,
         Name = 0,
         Quality = 1,
         Quality = 1,
         UnwatchedOnly = 2,
         UnwatchedOnly = 2,
-        SyncNewContent
+        SyncNewContent = 3,
+        ItemLimit = 4
     }
     }
 }
 }

+ 2 - 5
MediaBrowser.Model/Users/UserPolicy.cs

@@ -1,11 +1,8 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
+
 namespace MediaBrowser.Model.Users
 namespace MediaBrowser.Model.Users
 {
 {
     public class UserPolicy
     public class UserPolicy
     {
     {
+        public bool EnableSync { get; set; }
     }
     }
 }
 }

+ 16 - 2
MediaBrowser.Server.Implementations/Channels/ChannelDownloadScheduledTask.cs

@@ -13,8 +13,10 @@ using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Logging;
 using MediaBrowser.Model.Logging;
 using MediaBrowser.Model.MediaInfo;
 using MediaBrowser.Model.MediaInfo;
 using MediaBrowser.Model.Querying;
 using MediaBrowser.Model.Querying;
+using MoreLinq;
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
+using System.Globalization;
 using System.IO;
 using System.IO;
 using System.Linq;
 using System.Linq;
 using System.Threading;
 using System.Threading;
@@ -64,7 +66,10 @@ namespace MediaBrowser.Server.Implementations.Channels
         {
         {
             CleanChannelContent(cancellationToken);
             CleanChannelContent(cancellationToken);
 
 
-            var users = _userManager.Users.Select(i => i.Id.ToString("N")).ToList();
+            var users = _userManager.Users
+                .DistinctBy(GetUserDistinctValue)
+                .Select(i => i.Id.ToString("N"))
+                .ToList();
 
 
             var numComplete = 0;
             var numComplete = 0;
 
 
@@ -88,6 +93,15 @@ namespace MediaBrowser.Server.Implementations.Channels
             progress.Report(100);
             progress.Report(100);
         }
         }
 
 
+        public static string GetUserDistinctValue(User user)
+        {
+            var channels = user.Configuration.BlockedChannels
+                .OrderBy(i => i)
+                .ToList();
+
+            return string.Join("|", channels.ToArray());
+        }
+
         private async Task DownloadContent(string user,
         private async Task DownloadContent(string user,
             CancellationToken cancellationToken,
             CancellationToken cancellationToken,
             IProgress<double> progress)
             IProgress<double> progress)
@@ -201,7 +215,7 @@ namespace MediaBrowser.Server.Implementations.Channels
                 if (IsSizeLimitReached(path, limit.Value))
                 if (IsSizeLimitReached(path, limit.Value))
                 {
                 {
                     return;
                     return;
-                }    
+                }
             }
             }
 
 
             var itemId = item.Id.ToString("N");
             var itemId = item.Id.ToString("N");

+ 4 - 1
MediaBrowser.Server.Implementations/Channels/ChannelManager.cs

@@ -533,10 +533,13 @@ namespace MediaBrowser.Server.Implementations.Channels
                 ? null
                 ? null
                 : _userManager.GetUserById(query.UserId);
                 : _userManager.GetUserById(query.UserId);
 
 
+            var limit = query.Limit;
+
             // See below about parental control
             // See below about parental control
             if (user != null)
             if (user != null)
             {
             {
                 query.StartIndex = null;
                 query.StartIndex = null;
+                query.Limit = null;
             }
             }
 
 
             var internalResult = await GetLatestChannelItemsInternal(query, cancellationToken).ConfigureAwait(false);
             var internalResult = await GetLatestChannelItemsInternal(query, cancellationToken).ConfigureAwait(false);
@@ -554,7 +557,7 @@ namespace MediaBrowser.Server.Implementations.Channels
             if (user != null)
             if (user != null)
             {
             {
                 items = items.Where(i => i.IsVisible(user))
                 items = items.Where(i => i.IsVisible(user))
-                    .Take(10)
+                    .Take(limit ?? 10)
                     .ToArray();
                     .ToArray();
 
 
                 totalRecordCount = items.Length;
                 totalRecordCount = items.Length;

+ 2 - 0
MediaBrowser.Server.Implementations/Channels/ChannelPostScanTask.cs

@@ -3,6 +3,7 @@ using MediaBrowser.Controller.Channels;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Model.Channels;
 using MediaBrowser.Model.Channels;
 using MediaBrowser.Model.Logging;
 using MediaBrowser.Model.Logging;
+using MoreLinq;
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Linq;
 using System.Linq;
@@ -27,6 +28,7 @@ namespace MediaBrowser.Server.Implementations.Channels
         public async Task Run(IProgress<double> progress, CancellationToken cancellationToken)
         public async Task Run(IProgress<double> progress, CancellationToken cancellationToken)
         {
         {
             var users = _userManager.Users
             var users = _userManager.Users
+                .DistinctBy(ChannelDownloadScheduledTask.GetUserDistinctValue)
                 .Select(i => i.Id.ToString("N"))
                 .Select(i => i.Id.ToString("N"))
                 .ToList();
                 .ToList();
 
 

+ 62 - 7
MediaBrowser.Server.Implementations/Library/UserManager.cs

@@ -1,4 +1,5 @@
-using MediaBrowser.Common.Events;
+using System.Collections.Concurrent;
+using MediaBrowser.Common.Events;
 using MediaBrowser.Common.Extensions;
 using MediaBrowser.Common.Extensions;
 using MediaBrowser.Common.Net;
 using MediaBrowser.Common.Net;
 using MediaBrowser.Controller;
 using MediaBrowser.Controller;
@@ -317,7 +318,8 @@ namespace MediaBrowser.Server.Implementations.Library
                 ConnectLinkType = user.ConnectLinkType,
                 ConnectLinkType = user.ConnectLinkType,
                 ConnectUserId = user.ConnectUserId,
                 ConnectUserId = user.ConnectUserId,
                 ConnectUserName = user.ConnectUserName,
                 ConnectUserName = user.ConnectUserName,
-                ServerId = _appHost.SystemId
+                ServerId = _appHost.SystemId,
+                Policy = user.Policy
             };
             };
 
 
             var image = user.GetImageInfo(ImageType.Primary, 0);
             var image = user.GetImageInfo(ImageType.Primary, 0);
@@ -529,6 +531,8 @@ namespace MediaBrowser.Server.Implementations.Library
                     _logger.ErrorException("Error deleting file {0}", ex, path);
                     _logger.ErrorException("Error deleting file {0}", ex, path);
                 }
                 }
 
 
+                DeleteUserPolicy(user);
+
                 // Force this to be lazy loaded again
                 // Force this to be lazy loaded again
                 Users = await LoadUsers().ConfigureAwait(false);
                 Users = await LoadUsers().ConfigureAwait(false);
 
 
@@ -715,7 +719,7 @@ namespace MediaBrowser.Server.Implementations.Library
 
 
             var usersReset = new List<string>();
             var usersReset = new List<string>();
 
 
-            var valid = !string.IsNullOrWhiteSpace(_lastPin) && 
+            var valid = !string.IsNullOrWhiteSpace(_lastPin) &&
                 string.Equals(_lastPin, pin, StringComparison.OrdinalIgnoreCase) &&
                 string.Equals(_lastPin, pin, StringComparison.OrdinalIgnoreCase) &&
                 _lastPasswordPinCreationResult != null &&
                 _lastPasswordPinCreationResult != null &&
                 _lastPasswordPinCreationResult.ExpirationDate > DateTime.UtcNow;
                 _lastPasswordPinCreationResult.ExpirationDate > DateTime.UtcNow;
@@ -769,14 +773,65 @@ namespace MediaBrowser.Server.Implementations.Library
             public DateTime ExpirationDate { get; set; }
             public DateTime ExpirationDate { get; set; }
         }
         }
 
 
-        public UserPolicy GetUserPolicy(string userId)
+        public UserPolicy GetUserPolicy(User user)
+        {
+            var path = GetPolifyFilePath(user);
+
+            try
+            {
+                lock (_policySyncLock)
+                {
+                    return (UserPolicy)_xmlSerializer.DeserializeFromFile(typeof(UserPolicy), path);
+                }
+            }
+            catch (Exception ex)
+            {
+                _logger.ErrorException("Error reading policy file: {0}", ex, path);
+
+                return new UserPolicy
+                {
+                    EnableSync = !user.ConnectLinkType.HasValue || user.ConnectLinkType.Value != UserLinkType.Guest
+                };
+            }
+        }
+
+        private readonly object _policySyncLock = new object();
+        public async Task UpdateUserPolicy(string userId, UserPolicy userPolicy)
+        {
+            var user = GetUserById(userId);
+            var path = GetPolifyFilePath(user);
+
+            lock (_policySyncLock)
+            {
+                _xmlSerializer.SerializeToFile(userPolicy, path);
+                user.Policy = userPolicy;
+            }
+        }
+
+        private void DeleteUserPolicy(User user)
         {
         {
-            throw new NotImplementedException();
+            var path = GetPolifyFilePath(user);
+
+            try
+            {
+                lock (_policySyncLock)
+                {
+                    File.Delete(path);
+                }
+            }
+            catch (IOException)
+            {
+
+            }
+            catch (Exception ex)
+            {
+                _logger.ErrorException("Error deleting policy file", ex);
+            }
         }
         }
 
 
-        public Task UpdateUserPolicy(string userId, UserPolicy userPolicy)
+        private string GetPolifyFilePath(User user)
         {
         {
-            throw new NotImplementedException();
+            return Path.Combine(user.ConfigurationDirectoryPath, "policy.xml");
         }
         }
     }
     }
 }
 }

+ 0 - 35
MediaBrowser.Server.Implementations/Library/Validators/UserViewPostScanTask.cs

@@ -1,35 +0,0 @@
-using MediaBrowser.Controller.Library;
-using MediaBrowser.Model.Library;
-using System;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace MediaBrowser.Server.Implementations.Library.Validators
-{
-    public class UserViewPostScanTask : ILibraryPostScanTask
-    {
-        private readonly IUserManager _userManager;
-        private readonly IUserViewManager _userViewManager;
-
-        public UserViewPostScanTask(IUserManager userManager, IUserViewManager userViewManager)
-        {
-            _userManager = userManager;
-            _userViewManager = userViewManager;
-        }
-
-        public async Task Run(IProgress<double> progress, CancellationToken cancellationToken)
-        {
-            foreach (var user in _userManager.Users)
-            {
-                foreach (var view in await _userViewManager.GetUserViews(new UserViewQuery
-                {
-                    UserId = user.Id.ToString("N")
-
-                }, cancellationToken).ConfigureAwait(false))
-                {
-                    await view.RefreshMetadata(cancellationToken).ConfigureAwait(false);
-                }
-            }
-        }
-    }
-}

+ 3 - 3
MediaBrowser.Server.Implementations/Localization/Server/server.json

@@ -232,10 +232,10 @@
     "HeaderFeatureAccess": "Feature Access",
     "HeaderFeatureAccess": "Feature Access",
     "OptionAllowMediaPlayback": "Allow media playback",
     "OptionAllowMediaPlayback": "Allow media playback",
     "OptionAllowBrowsingLiveTv": "Allow browsing of live tv",
     "OptionAllowBrowsingLiveTv": "Allow browsing of live tv",
-    "OptionAllowDeleteLibraryContent": "Allow this user to delete library content",
+    "OptionAllowDeleteLibraryContent": "Allow deletion of library content",
     "OptionAllowManageLiveTv": "Allow management of live tv recordings",
     "OptionAllowManageLiveTv": "Allow management of live tv recordings",
-    "OptionAllowRemoteControlOthers": "Allow this user to remote control other users",
-    "OptionAllowRemoteSharedDevices": "Allow this user to remote control shared devices",
+    "OptionAllowRemoteControlOthers": "Allow remote control of other users",
+    "OptionAllowRemoteSharedDevices": "Allow remote control of shared devices",
     "OptionAllowRemoteSharedDevicesHelp": "Dlna devices are considered shared until a user begins controlling it.",
     "OptionAllowRemoteSharedDevicesHelp": "Dlna devices are considered shared until a user begins controlling it.",
     "HeaderRemoteControl": "Remote Control",
     "HeaderRemoteControl": "Remote Control",
     "OptionMissingTmdbId": "Missing Tmdb Id",
     "OptionMissingTmdbId": "Missing Tmdb Id",

+ 0 - 1
MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj

@@ -215,7 +215,6 @@
     <Compile Include="Library\Validators\PeopleValidator.cs" />
     <Compile Include="Library\Validators\PeopleValidator.cs" />
     <Compile Include="Library\Validators\StudiosPostScanTask.cs" />
     <Compile Include="Library\Validators\StudiosPostScanTask.cs" />
     <Compile Include="Library\Validators\StudiosValidator.cs" />
     <Compile Include="Library\Validators\StudiosValidator.cs" />
-    <Compile Include="Library\Validators\UserViewPostScanTask.cs" />
     <Compile Include="Library\Validators\YearsPostScanTask.cs" />
     <Compile Include="Library\Validators\YearsPostScanTask.cs" />
     <Compile Include="LiveTv\ChannelImageProvider.cs" />
     <Compile Include="LiveTv\ChannelImageProvider.cs" />
     <Compile Include="LiveTv\CleanDatabaseScheduledTask.cs" />
     <Compile Include="LiveTv\CleanDatabaseScheduledTask.cs" />

+ 19 - 3
MediaBrowser.Server.Implementations/Session/HttpSessionController.cs

@@ -25,6 +25,7 @@ namespace MediaBrowser.Server.Implementations.Session
         private readonly string _postUrl;
         private readonly string _postUrl;
 
 
         private Timer _pingTimer;
         private Timer _pingTimer;
+        private DateTime _lastPingTime;
 
 
         public HttpSessionController(IHttpClient httpClient,
         public HttpSessionController(IHttpClient httpClient,
             IJsonSerializer json,
             IJsonSerializer json,
@@ -68,10 +69,23 @@ namespace MediaBrowser.Server.Implementations.Session
             try
             try
             {
             {
                 await SendMessage("Ping", CancellationToken.None).ConfigureAwait(false);
                 await SendMessage("Ping", CancellationToken.None).ConfigureAwait(false);
+
+                _lastPingTime = DateTime.UtcNow;
             }
             }
             catch
             catch
             {
             {
-                ReportSessionEnded();
+                var lastActivityDate = new[] { _lastPingTime, Session.LastActivityDate }
+                    .Max();
+
+                var timeSinceLastPing = DateTime.UtcNow - lastActivityDate;
+
+                // We don't want to stop the session due to one single request failure
+                // At the same time, we don't want the timeout to be too long because it will
+                // be sitting in active sessions available for remote control, when it's not
+                if (timeSinceLastPing >= TimeSpan.FromMinutes(5))
+                {
+                    ReportSessionEnded();
+                }
             }
             }
         }
         }
 
 
@@ -90,6 +104,8 @@ namespace MediaBrowser.Server.Implementations.Session
         {
         {
             if (_pingTimer != null)
             if (_pingTimer != null)
             {
             {
+                _lastPingTime = DateTime.UtcNow;
+
                 var period = TimeSpan.FromSeconds(60);
                 var period = TimeSpan.FromSeconds(60);
 
 
                 _pingTimer.Change(period, period);
                 _pingTimer.Change(period, period);
@@ -101,8 +117,8 @@ namespace MediaBrowser.Server.Implementations.Session
             return SendMessage(name, new Dictionary<string, string>(), cancellationToken);
             return SendMessage(name, new Dictionary<string, string>(), cancellationToken);
         }
         }
 
 
-        private async Task SendMessage(string name, 
-            Dictionary<string, string> args, 
+        private async Task SendMessage(string name,
+            Dictionary<string, string> args,
             CancellationToken cancellationToken)
             CancellationToken cancellationToken)
         {
         {
             var url = PostUrl + "/" + name + ToQueryString(args);
             var url = PostUrl + "/" + name + ToQueryString(args);

+ 4 - 2
MediaBrowser.Server.Implementations/Sync/SyncManager.cs

@@ -47,7 +47,7 @@ namespace MediaBrowser.Server.Implementations.Sync
             var processor = new SyncJobProcessor(_libraryManager, _repo, this, _logger, _userManager);
             var processor = new SyncJobProcessor(_libraryManager, _repo, this, _logger, _userManager);
 
 
             var user = _userManager.GetUserById(request.UserId);
             var user = _userManager.GetUserById(request.UserId);
-            
+
             var items = processor
             var items = processor
                 .GetItemsForSync(request.ItemIds, user)
                 .GetItemsForSync(request.ItemIds, user)
                 .ToList();
                 .ToList();
@@ -85,7 +85,9 @@ namespace MediaBrowser.Server.Implementations.Sync
                 DateLastModified = DateTime.UtcNow,
                 DateLastModified = DateTime.UtcNow,
                 SyncNewContent = request.SyncNewContent,
                 SyncNewContent = request.SyncNewContent,
                 ItemCount = items.Count,
                 ItemCount = items.Count,
-                Quality = request.Quality
+                Quality = request.Quality,
+                Category = request.Category,
+                ParentId = request.ParentId
             };
             };
 
 
             // It's just a static list
             // It's just a static list

+ 24 - 10
MediaBrowser.Server.Implementations/Sync/SyncRepository.cs

@@ -35,13 +35,13 @@ namespace MediaBrowser.Server.Implementations.Sync
 
 
         public async Task Initialize()
         public async Task Initialize()
         {
         {
-            var dbFile = Path.Combine(_appPaths.DataPath, "sync5.db");
+            var dbFile = Path.Combine(_appPaths.DataPath, "sync6.db");
 
 
             _connection = await SqliteExtensions.ConnectToDb(dbFile, _logger).ConfigureAwait(false);
             _connection = await SqliteExtensions.ConnectToDb(dbFile, _logger).ConfigureAwait(false);
 
 
             string[] queries = {
             string[] queries = {
 
 
-                                "create table if not exists SyncJobs (Id GUID PRIMARY KEY, TargetId TEXT NOT NULL, Name TEXT NOT NULL, Quality TEXT NOT NULL, Status TEXT NOT NULL, Progress FLOAT, UserId TEXT NOT NULL, ItemIds TEXT NOT NULL, UnwatchedOnly BIT, ItemLimit INT, SyncNewContent BIT, DateCreated DateTime, DateLastModified DateTime, ItemCount int)",
+                                "create table if not exists SyncJobs (Id GUID PRIMARY KEY, TargetId TEXT NOT NULL, Name TEXT NOT NULL, Quality TEXT NOT NULL, Status TEXT NOT NULL, Progress FLOAT, UserId TEXT NOT NULL, ItemIds TEXT NOT NULL, Category TEXT, ParentId TEXT, UnwatchedOnly BIT, ItemLimit INT, SyncNewContent BIT, DateCreated DateTime, DateLastModified DateTime, ItemCount int)",
                                 "create index if not exists idx_SyncJobs on SyncJobs(Id)",
                                 "create index if not exists idx_SyncJobs on SyncJobs(Id)",
 
 
                                 "create table if not exists SyncJobItems (Id GUID PRIMARY KEY, ItemId TEXT, JobId TEXT, OutputPath TEXT, Status TEXT, TargetId TEXT, DateCreated DateTime, Progress FLOAT)",
                                 "create table if not exists SyncJobItems (Id GUID PRIMARY KEY, ItemId TEXT, JobId TEXT, OutputPath TEXT, Status TEXT, TargetId TEXT, DateCreated DateTime, Progress FLOAT)",
@@ -65,7 +65,7 @@ namespace MediaBrowser.Server.Implementations.Sync
             _deleteJobCommand.Parameters.Add(_deleteJobCommand, "@Id");
             _deleteJobCommand.Parameters.Add(_deleteJobCommand, "@Id");
 
 
             _saveJobCommand = _connection.CreateCommand();
             _saveJobCommand = _connection.CreateCommand();
-            _saveJobCommand.CommandText = "replace into SyncJobs (Id, TargetId, Name, Quality, Status, Progress, UserId, ItemIds, UnwatchedOnly, ItemLimit, SyncNewContent, DateCreated, DateLastModified, ItemCount) values (@Id, @TargetId, @Name, @Quality, @Status, @Progress, @UserId, @ItemIds, @UnwatchedOnly, @ItemLimit, @SyncNewContent, @DateCreated, @DateLastModified, @ItemCount)";
+            _saveJobCommand.CommandText = "replace into SyncJobs (Id, TargetId, Name, Quality, Status, Progress, UserId, ItemIds, Category, ParentId, UnwatchedOnly, ItemLimit, SyncNewContent, DateCreated, DateLastModified, ItemCount) values (@Id, @TargetId, @Name, @Quality, @Status, @Progress, @UserId, @ItemIds, @Category, @ParentId, @UnwatchedOnly, @ItemLimit, @SyncNewContent, @DateCreated, @DateLastModified, @ItemCount)";
 
 
             _saveJobCommand.Parameters.Add(_saveJobCommand, "@Id");
             _saveJobCommand.Parameters.Add(_saveJobCommand, "@Id");
             _saveJobCommand.Parameters.Add(_saveJobCommand, "@TargetId");
             _saveJobCommand.Parameters.Add(_saveJobCommand, "@TargetId");
@@ -75,6 +75,8 @@ namespace MediaBrowser.Server.Implementations.Sync
             _saveJobCommand.Parameters.Add(_saveJobCommand, "@Progress");
             _saveJobCommand.Parameters.Add(_saveJobCommand, "@Progress");
             _saveJobCommand.Parameters.Add(_saveJobCommand, "@UserId");
             _saveJobCommand.Parameters.Add(_saveJobCommand, "@UserId");
             _saveJobCommand.Parameters.Add(_saveJobCommand, "@ItemIds");
             _saveJobCommand.Parameters.Add(_saveJobCommand, "@ItemIds");
+            _saveJobCommand.Parameters.Add(_saveJobCommand, "@Category");
+            _saveJobCommand.Parameters.Add(_saveJobCommand, "@ParentId");
             _saveJobCommand.Parameters.Add(_saveJobCommand, "@UnwatchedOnly");
             _saveJobCommand.Parameters.Add(_saveJobCommand, "@UnwatchedOnly");
             _saveJobCommand.Parameters.Add(_saveJobCommand, "@ItemLimit");
             _saveJobCommand.Parameters.Add(_saveJobCommand, "@ItemLimit");
             _saveJobCommand.Parameters.Add(_saveJobCommand, "@SyncNewContent");
             _saveJobCommand.Parameters.Add(_saveJobCommand, "@SyncNewContent");
@@ -95,7 +97,7 @@ namespace MediaBrowser.Server.Implementations.Sync
             _saveJobItemCommand.Parameters.Add(_saveJobCommand, "@Progress");
             _saveJobItemCommand.Parameters.Add(_saveJobCommand, "@Progress");
         }
         }
 
 
-        private const string BaseJobSelectText = "select Id, TargetId, Name, Quality, Status, Progress, UserId, ItemIds, UnwatchedOnly, ItemLimit, SyncNewContent, DateCreated, DateLastModified, ItemCount from SyncJobs";
+        private const string BaseJobSelectText = "select Id, TargetId, Name, Quality, Status, Progress, UserId, ItemIds, Category, ParentId, UnwatchedOnly, ItemLimit, SyncNewContent, DateCreated, DateLastModified, ItemCount from SyncJobs";
         private const string BaseJobItemSelectText = "select Id, ItemId, JobId, OutputPath, Status, TargetId, DateCreated, Progress from SyncJobItems";
         private const string BaseJobItemSelectText = "select Id, ItemId, JobId, OutputPath, Status, TargetId, DateCreated, Progress from SyncJobItems";
 
 
         public SyncJob GetJob(string id)
         public SyncJob GetJob(string id)
@@ -166,19 +168,29 @@ namespace MediaBrowser.Server.Implementations.Sync
 
 
             if (!reader.IsDBNull(8))
             if (!reader.IsDBNull(8))
             {
             {
-                info.UnwatchedOnly = reader.GetBoolean(8);
+                info.Category = (SyncCategory)Enum.Parse(typeof(SyncCategory), reader.GetString(8), true);
             }
             }
 
 
             if (!reader.IsDBNull(9))
             if (!reader.IsDBNull(9))
             {
             {
-                info.ItemLimit = reader.GetInt32(9);
+                info.ParentId = reader.GetString(9);
             }
             }
 
 
-            info.SyncNewContent = reader.GetBoolean(10);
+            if (!reader.IsDBNull(10))
+            {
+                info.UnwatchedOnly = reader.GetBoolean(10);
+            }
+
+            if (!reader.IsDBNull(11))
+            {
+                info.ItemLimit = reader.GetInt32(11);
+            }
+
+            info.SyncNewContent = reader.GetBoolean(12);
 
 
-            info.DateCreated = reader.GetDateTime(11).ToUniversalTime();
-            info.DateLastModified = reader.GetDateTime(12).ToUniversalTime();
-            info.ItemCount = reader.GetInt32(13);
+            info.DateCreated = reader.GetDateTime(13).ToUniversalTime();
+            info.DateLastModified = reader.GetDateTime(14).ToUniversalTime();
+            info.ItemCount = reader.GetInt32(15);
 
 
             return info;
             return info;
         }
         }
@@ -213,6 +225,8 @@ namespace MediaBrowser.Server.Implementations.Sync
                 _saveJobCommand.GetParameter(index++).Value = job.Progress;
                 _saveJobCommand.GetParameter(index++).Value = job.Progress;
                 _saveJobCommand.GetParameter(index++).Value = job.UserId;
                 _saveJobCommand.GetParameter(index++).Value = job.UserId;
                 _saveJobCommand.GetParameter(index++).Value = string.Join(",", job.RequestedItemIds.ToArray());
                 _saveJobCommand.GetParameter(index++).Value = string.Join(",", job.RequestedItemIds.ToArray());
+                _saveJobCommand.GetParameter(index++).Value = job.Category;
+                _saveJobCommand.GetParameter(index++).Value = job.ParentId;
                 _saveJobCommand.GetParameter(index++).Value = job.UnwatchedOnly;
                 _saveJobCommand.GetParameter(index++).Value = job.UnwatchedOnly;
                 _saveJobCommand.GetParameter(index++).Value = job.ItemLimit;
                 _saveJobCommand.GetParameter(index++).Value = job.ItemLimit;
                 _saveJobCommand.GetParameter(index++).Value = job.SyncNewContent;
                 _saveJobCommand.GetParameter(index++).Value = job.SyncNewContent;

+ 14 - 6
MediaBrowser.Server.Startup.Common/ApplicationHost.cs

@@ -341,12 +341,20 @@ namespace MediaBrowser.Server.Startup.Common
 
 
         private void PerformVersionMigration()
         private void PerformVersionMigration()
         {
         {
-            new MigrateUserFolders(ApplicationPaths).Run();
-            new PlaylistImages(ServerConfigurationManager).Run();
-            new RenameXbmcOptions(ServerConfigurationManager).Run();
-            new RenameXmlOptions(ServerConfigurationManager).Run();
-            new DeprecatePlugins(ApplicationPaths).Run();
-            new DeleteDlnaProfiles(ApplicationPaths).Run();
+            var migrations = new List<IVersionMigration>
+            {
+                new MigrateUserFolders(ApplicationPaths),
+                new PlaylistImages(ServerConfigurationManager),
+                new RenameXbmcOptions(ServerConfigurationManager),
+                new RenameXmlOptions(ServerConfigurationManager),
+                new DeprecatePlugins(ApplicationPaths),
+                new DeleteDlnaProfiles(ApplicationPaths)
+            };
+
+            foreach (var task in migrations)
+            {
+                task.Run();
+            }
         }
         }
 
 
         /// <summary>
         /// <summary>

+ 1 - 1
MediaBrowser.Server.Startup.Common/Migrations/RenameXbmcOptions.cs

@@ -3,7 +3,7 @@ using System;
 
 
 namespace MediaBrowser.Server.Startup.Common.Migrations
 namespace MediaBrowser.Server.Startup.Common.Migrations
 {
 {
-    public class RenameXbmcOptions
+    public class RenameXbmcOptions : IVersionMigration
     {
     {
         private readonly IServerConfigurationManager _config;
         private readonly IServerConfigurationManager _config;
 
 

+ 1 - 1
MediaBrowser.Server.Startup.Common/Migrations/RenameXmlOptions.cs

@@ -3,7 +3,7 @@ using System;
 
 
 namespace MediaBrowser.Server.Startup.Common.Migrations
 namespace MediaBrowser.Server.Startup.Common.Migrations
 {
 {
-    public class RenameXmlOptions
+    public class RenameXmlOptions : IVersionMigration
     {
     {
         private readonly IServerConfigurationManager _config;
         private readonly IServerConfigurationManager _config;
 
 

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

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

+ 1 - 1
Nuget/MediaBrowser.Common.nuspec

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

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

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

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

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