diff --git a/MediaBrowser.Api/Library/LibraryService.cs b/MediaBrowser.Api/Library/LibraryService.cs index 9027685b17..85cc879f4f 100644 --- a/MediaBrowser.Api/Library/LibraryService.cs +++ b/MediaBrowser.Api/Library/LibraryService.cs @@ -1,15 +1,19 @@ -using MediaBrowser.Controller.Channels; +using MediaBrowser.Controller.Activity; +using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Localization; using MediaBrowser.Controller.Net; using MediaBrowser.Controller.Persistence; using MediaBrowser.Controller.Session; +using MediaBrowser.Model.Activity; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Logging; using MediaBrowser.Model.Querying; using ServiceStack; using System; @@ -251,24 +255,24 @@ namespace MediaBrowser.Api.Library private readonly IUserDataManager _userDataManager; private readonly IDtoService _dtoService; - private readonly IChannelManager _channelManager; - private readonly ISessionManager _sessionManager; private readonly IAuthorizationContext _authContext; + private readonly IActivityManager _activityManager; + private readonly ILocalizationManager _localization; /// /// Initializes a new instance of the class. /// public LibraryService(IItemRepository itemRepo, ILibraryManager libraryManager, IUserManager userManager, - IDtoService dtoService, IUserDataManager userDataManager, IChannelManager channelManager, ISessionManager sessionManager, IAuthorizationContext authContext) + IDtoService dtoService, IUserDataManager userDataManager, IAuthorizationContext authContext, IActivityManager activityManager, ILocalizationManager localization) { _itemRepo = itemRepo; _libraryManager = libraryManager; _userManager = userManager; _dtoService = dtoService; _userDataManager = userDataManager; - _channelManager = channelManager; - _sessionManager = sessionManager; _authContext = authContext; + _activityManager = activityManager; + _localization = localization; } public object Get(GetMediaFolders request) @@ -302,10 +306,23 @@ namespace MediaBrowser.Api.Library public object Get(GetDownload request) { var item = _libraryManager.GetItemById(request.Id); + var auth = _authContext.GetAuthorizationInfo(Request); - if (!item.CanDelete()) + var user = _userManager.GetUserById(auth.UserId); + + if (user != null) { - throw new ArgumentException("Item does not support downloading"); + if (!item.CanDownload(user)) + { + throw new ArgumentException("Item does not support downloading"); + } + } + else + { + if (!item.CanDownload()) + { + throw new ArgumentException("Item does not support downloading"); + } } var headers = new Dictionary(); @@ -314,6 +331,11 @@ namespace MediaBrowser.Api.Library var filename = Path.GetFileName(item.Path).Replace("\"", string.Empty); headers["Content-Disposition"] = string.Format("attachment; filename=\"{0}\"", filename); + if (user != null) + { + LogDownload(item, user, auth); + } + return ResultFactory.GetStaticFileResult(Request, new StaticFileResultOptions { Path = item.Path, @@ -321,6 +343,25 @@ namespace MediaBrowser.Api.Library }); } + private async void LogDownload(BaseItem item, User user, AuthorizationInfo auth) + { + try + { + await _activityManager.Create(new ActivityLogEntry + { + Name = string.Format(_localization.GetLocalizedString("UserDownloadingItemWithValues"), user.Name, item.Name), + Type = "UserDownloadingContent", + ShortOverview = string.Format(_localization.GetLocalizedString("AppDeviceValues"), auth.Client, auth.Device), + UserId = auth.UserId + + }).ConfigureAwait(false); + } + catch + { + // Logged at lower levels + } + } + public object Get(GetFile request) { var item = _libraryManager.GetItemById(request.Id); diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index d26ca27216..49d5f1c8d8 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -323,13 +323,13 @@ namespace MediaBrowser.Api.Playback switch (qualitySetting) { case EncodingQuality.HighSpeed: - param += " -subq 0 -crf 23"; + param += " -crf 23"; break; case EncodingQuality.HighQuality: - param += " -subq 3 -crf 20"; + param += " -crf 20"; break; case EncodingQuality.MaxQuality: - param += " -subq 6 -crf 18"; + param += " -crf 18"; break; } } diff --git a/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs index 5a00c3d3fe..ffae8612ed 100644 --- a/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs @@ -631,13 +631,13 @@ namespace MediaBrowser.MediaEncoding.Encoder switch (qualitySetting) { case EncodingQuality.HighSpeed: - param += " -subq 0 -crf 23"; + param += " -crf 28"; break; case EncodingQuality.HighQuality: - param += " -subq 3 -crf 20"; + param += " -crf 25"; break; case EncodingQuality.MaxQuality: - param += " -subq 6 -crf 18"; + param += " -crf 21"; break; } } diff --git a/MediaBrowser.Server.Implementations/HttpServer/Security/AuthorizationContext.cs b/MediaBrowser.Server.Implementations/HttpServer/Security/AuthorizationContext.cs index 4e98993014..cd4d23f5cf 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/Security/AuthorizationContext.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/Security/AuthorizationContext.cs @@ -129,6 +129,20 @@ namespace MediaBrowser.Server.Implementations.HttpServer.Security if (tokenInfo != null) { info.UserId = tokenInfo.UserId; + + // TODO: Remove these checks for IsNullOrWhiteSpace + if (string.IsNullOrWhiteSpace(info.Client)) + { + info.Client = tokenInfo.AppName; + } + if (string.IsNullOrWhiteSpace(info.Device)) + { + info.Device = tokenInfo.DeviceName; + } + if (string.IsNullOrWhiteSpace(info.DeviceId)) + { + info.DeviceId = tokenInfo.DeviceId; + } } httpReq.Items["OriginalAuthenticationInfo"] = tokenInfo; } diff --git a/MediaBrowser.Server.Implementations/Library/UserManager.cs b/MediaBrowser.Server.Implementations/Library/UserManager.cs index 88ba3b7bf7..8858abc102 100644 --- a/MediaBrowser.Server.Implementations/Library/UserManager.cs +++ b/MediaBrowser.Server.Implementations/Library/UserManager.cs @@ -410,7 +410,7 @@ namespace MediaBrowser.Server.Implementations.Library dto.HasPassword = !IsPasswordEmpty(offlinePasswordHash); // Hash the pin with the device Id to create a unique result for this device - dto.OfflinePassword = GetSha1String(offlinePasswordHash + deviceId); + dto.OfflinePassword = GetSha1String((offlinePasswordHash + deviceId).ToLower()); dto.ServerName = _appHost.FriendlyName; diff --git a/MediaBrowser.Server.Implementations/Localization/Server/server.json b/MediaBrowser.Server.Implementations/Localization/Server/server.json index c7ebbb48c9..dc80778da9 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/server.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/server.json @@ -1114,6 +1114,7 @@ "MessageApplicationUpdated": "Media Browser Server has been updated", "AuthenticationSucceededWithUserName": "{0} successfully authenticated", "FailedLoginAttemptWithUserName": "Failed login attempt from {0}", + "UserDownloadingItemWithValues": "{0} is downloading {1}", "UserStartedPlayingItemWithValues": "{0} has started playing {1}", "UserStoppedPlayingItemWithValues": "{0} has stopped playing {1}", "AppDeviceValues": "App: {0}, Device: {1}", diff --git a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs index 78821f950b..00b28ad8a0 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs @@ -439,6 +439,16 @@ namespace MediaBrowser.Server.Implementations.Sync return true; } + if (item is Person) + { + return false; + } + + if (item is Year) + { + return false; + } + if (string.Equals(item.MediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase) || string.Equals(item.MediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase) || string.Equals(item.MediaType, MediaType.Photo, StringComparison.OrdinalIgnoreCase) ||