diff options
| author | Luke Pulverenti <luke.pulverenti@gmail.com> | 2016-11-03 03:14:14 -0400 |
|---|---|---|
| committer | Luke Pulverenti <luke.pulverenti@gmail.com> | 2016-11-03 03:14:14 -0400 |
| commit | b76a1abda578b8ff64bad2997b036b0fc43e264f (patch) | |
| tree | 7b73000abcf71e90c290b6107525969cb904ed2d /MediaBrowser.Server.Implementations | |
| parent | 3eb4091808735858b01855d298226d239be464af (diff) | |
move classes to portable server lib
Diffstat (limited to 'MediaBrowser.Server.Implementations')
14 files changed, 0 insertions, 3964 deletions
diff --git a/MediaBrowser.Server.Implementations/Collections/CollectionImageProvider.cs b/MediaBrowser.Server.Implementations/Collections/CollectionImageProvider.cs deleted file mode 100644 index d70d4b9e6..000000000 --- a/MediaBrowser.Server.Implementations/Collections/CollectionImageProvider.cs +++ /dev/null @@ -1,86 +0,0 @@ -using MediaBrowser.Common.Configuration; -using MediaBrowser.Controller.Drawing; -using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Entities.Audio; -using MediaBrowser.Controller.Entities.Movies; -using MediaBrowser.Controller.Entities.TV; -using MediaBrowser.Controller.Providers; -using MediaBrowser.Model.Entities; -using MediaBrowser.Server.Implementations.Photos; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using MediaBrowser.Common.IO; -using MediaBrowser.Controller.IO; -using MediaBrowser.Model.IO; -using MediaBrowser.Model.Extensions; - -namespace MediaBrowser.Server.Implementations.Collections -{ - public class CollectionImageProvider : BaseDynamicImageProvider<BoxSet> - { - public CollectionImageProvider(IFileSystem fileSystem, IProviderManager providerManager, IApplicationPaths applicationPaths, IImageProcessor imageProcessor) : base(fileSystem, providerManager, applicationPaths, imageProcessor) - { - } - - protected override bool Supports(IHasImages item) - { - // Right now this is the only way to prevent this image from getting created ahead of internet image providers - if (!item.IsLocked) - { - return false; - } - - return base.Supports(item); - } - - protected override Task<List<BaseItem>> GetItemsWithImages(IHasImages item) - { - var playlist = (BoxSet)item; - - var items = playlist.Children.Concat(playlist.GetLinkedChildren()) - .Select(i => - { - var subItem = i; - - var episode = subItem as Episode; - - if (episode != null) - { - var series = episode.Series; - if (series != null && series.HasImage(ImageType.Primary)) - { - return series; - } - } - - if (subItem.HasImage(ImageType.Primary)) - { - return subItem; - } - - var parent = subItem.GetParent(); - - if (parent != null && parent.HasImage(ImageType.Primary)) - { - if (parent is MusicAlbum) - { - return parent; - } - } - - return null; - }) - .Where(i => i != null) - .DistinctBy(i => i.Id) - .ToList(); - - return Task.FromResult(GetFinalItems(items, 2)); - } - - protected override Task<string> CreateImage(IHasImages item, List<BaseItem> itemsWithImages, string outputPathWithoutExtension, ImageType imageType, int imageIndex) - { - return CreateSingleImage(itemsWithImages, outputPathWithoutExtension, ImageType.Primary); - } - } -} diff --git a/MediaBrowser.Server.Implementations/Devices/DeviceManager.cs b/MediaBrowser.Server.Implementations/Devices/DeviceManager.cs deleted file mode 100644 index e2e59df08..000000000 --- a/MediaBrowser.Server.Implementations/Devices/DeviceManager.cs +++ /dev/null @@ -1,306 +0,0 @@ -using MediaBrowser.Common.Configuration; -using MediaBrowser.Common.Events; -using MediaBrowser.Common.Net; -using MediaBrowser.Controller.Devices; -using MediaBrowser.Controller.Library; -using MediaBrowser.Model.Devices; -using MediaBrowser.Model.Events; -using MediaBrowser.Model.Extensions; -using MediaBrowser.Model.Logging; -using MediaBrowser.Model.Net; -using MediaBrowser.Model.Querying; -using MediaBrowser.Model.Session; -using MediaBrowser.Model.Users; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading.Tasks; -using MediaBrowser.Common.IO; -using MediaBrowser.Model.IO; -using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.IO; - -namespace MediaBrowser.Server.Implementations.Devices -{ - public class DeviceManager : IDeviceManager - { - private readonly IDeviceRepository _repo; - private readonly IUserManager _userManager; - private readonly IFileSystem _fileSystem; - private readonly ILibraryMonitor _libraryMonitor; - private readonly IServerConfigurationManager _config; - private readonly ILogger _logger; - private readonly INetworkManager _network; - - public event EventHandler<GenericEventArgs<CameraImageUploadInfo>> CameraImageUploaded; - - /// <summary> - /// Occurs when [device options updated]. - /// </summary> - public event EventHandler<GenericEventArgs<DeviceInfo>> DeviceOptionsUpdated; - - public DeviceManager(IDeviceRepository repo, IUserManager userManager, IFileSystem fileSystem, ILibraryMonitor libraryMonitor, IServerConfigurationManager config, ILogger logger, INetworkManager network) - { - _repo = repo; - _userManager = userManager; - _fileSystem = fileSystem; - _libraryMonitor = libraryMonitor; - _config = config; - _logger = logger; - _network = network; - } - - public async Task<DeviceInfo> RegisterDevice(string reportedId, string name, string appName, string appVersion, string usedByUserId) - { - if (string.IsNullOrWhiteSpace(reportedId)) - { - throw new ArgumentNullException("reportedId"); - } - - var device = GetDevice(reportedId) ?? new DeviceInfo - { - Id = reportedId - }; - - device.ReportedName = name; - device.AppName = appName; - device.AppVersion = appVersion; - - if (!string.IsNullOrWhiteSpace(usedByUserId)) - { - var user = _userManager.GetUserById(usedByUserId); - - device.LastUserId = user.Id.ToString("N"); - device.LastUserName = user.Name; - } - - device.DateLastModified = DateTime.UtcNow; - - await _repo.SaveDevice(device).ConfigureAwait(false); - - return device; - } - - public Task SaveCapabilities(string reportedId, ClientCapabilities capabilities) - { - return _repo.SaveCapabilities(reportedId, capabilities); - } - - public ClientCapabilities GetCapabilities(string reportedId) - { - return _repo.GetCapabilities(reportedId); - } - - public DeviceInfo GetDevice(string id) - { - return _repo.GetDevice(id); - } - - public QueryResult<DeviceInfo> GetDevices(DeviceQuery query) - { - IEnumerable<DeviceInfo> devices = _repo.GetDevices().OrderByDescending(i => i.DateLastModified); - - if (query.SupportsContentUploading.HasValue) - { - var val = query.SupportsContentUploading.Value; - - devices = devices.Where(i => GetCapabilities(i.Id).SupportsContentUploading == val); - } - - if (query.SupportsSync.HasValue) - { - var val = query.SupportsSync.Value; - - devices = devices.Where(i => GetCapabilities(i.Id).SupportsSync == val); - } - - if (query.SupportsPersistentIdentifier.HasValue) - { - var val = query.SupportsPersistentIdentifier.Value; - - devices = devices.Where(i => - { - var caps = GetCapabilities(i.Id); - var deviceVal = caps.SupportsPersistentIdentifier; - return deviceVal == val; - }); - } - - if (!string.IsNullOrWhiteSpace(query.UserId)) - { - devices = devices.Where(i => CanAccessDevice(query.UserId, i.Id)); - } - - var array = devices.ToArray(); - return new QueryResult<DeviceInfo> - { - Items = array, - TotalRecordCount = array.Length - }; - } - - public Task DeleteDevice(string id) - { - return _repo.DeleteDevice(id); - } - - public ContentUploadHistory GetCameraUploadHistory(string deviceId) - { - return _repo.GetCameraUploadHistory(deviceId); - } - - public async Task AcceptCameraUpload(string deviceId, Stream stream, LocalFileInfo file) - { - var device = GetDevice(deviceId); - var path = GetUploadPath(device); - - if (!string.IsNullOrWhiteSpace(file.Album)) - { - path = Path.Combine(path, _fileSystem.GetValidFilename(file.Album)); - } - - path = Path.Combine(path, file.Name); - path = Path.ChangeExtension(path, MimeTypes.ToExtension(file.MimeType) ?? "jpg"); - - _libraryMonitor.ReportFileSystemChangeBeginning(path); - - _fileSystem.CreateDirectory(Path.GetDirectoryName(path)); - - try - { - using (var fs = _fileSystem.GetFileStream(path, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read)) - { - await stream.CopyToAsync(fs).ConfigureAwait(false); - } - - _repo.AddCameraUpload(deviceId, file); - } - finally - { - _libraryMonitor.ReportFileSystemChangeComplete(path, true); - } - - if (CameraImageUploaded != null) - { - EventHelper.FireEventIfNotNull(CameraImageUploaded, this, new GenericEventArgs<CameraImageUploadInfo> - { - Argument = new CameraImageUploadInfo - { - Device = device, - FileInfo = file - } - }, _logger); - } - } - - private string GetUploadPath(DeviceInfo device) - { - if (!string.IsNullOrWhiteSpace(device.CameraUploadPath)) - { - return device.CameraUploadPath; - } - - var config = _config.GetUploadOptions(); - if (!string.IsNullOrWhiteSpace(config.CameraUploadPath)) - { - return config.CameraUploadPath; - } - - var path = DefaultCameraUploadsPath; - - if (config.EnableCameraUploadSubfolders) - { - path = Path.Combine(path, _fileSystem.GetValidFilename(device.Name)); - } - - return path; - } - - private string DefaultCameraUploadsPath - { - get { return Path.Combine(_config.CommonApplicationPaths.DataPath, "camerauploads"); } - } - - public async Task UpdateDeviceInfo(string id, DeviceOptions options) - { - var device = GetDevice(id); - - device.CustomName = options.CustomName; - device.CameraUploadPath = options.CameraUploadPath; - - await _repo.SaveDevice(device).ConfigureAwait(false); - - EventHelper.FireEventIfNotNull(DeviceOptionsUpdated, this, new GenericEventArgs<DeviceInfo>(device), _logger); - } - - public bool CanAccessDevice(string userId, string deviceId) - { - if (string.IsNullOrWhiteSpace(userId)) - { - throw new ArgumentNullException("userId"); - } - if (string.IsNullOrWhiteSpace(deviceId)) - { - throw new ArgumentNullException("deviceId"); - } - - var user = _userManager.GetUserById(userId); - - if (user == null) - { - throw new ArgumentException("user not found"); - } - - if (!CanAccessDevice(user.Policy, deviceId)) - { - var capabilities = GetCapabilities(deviceId); - - if (capabilities != null && capabilities.SupportsPersistentIdentifier) - { - return false; - } - } - - return true; - } - - private bool CanAccessDevice(UserPolicy policy, string id) - { - if (policy.EnableAllDevices) - { - return true; - } - - if (policy.IsAdministrator) - { - return true; - } - - return ListHelper.ContainsIgnoreCase(policy.EnabledDevices, id); - } - } - - public class DevicesConfigStore : IConfigurationFactory - { - public IEnumerable<ConfigurationStore> GetConfigurations() - { - return new List<ConfigurationStore> - { - new ConfigurationStore - { - Key = "devices", - ConfigurationType = typeof(DevicesOptions) - } - }; - } - } - - public static class UploadConfigExtension - { - public static DevicesOptions GetUploadOptions(this IConfigurationManager config) - { - return config.GetConfiguration<DevicesOptions>("devices"); - } - } -}
\ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/EntryPoints/ActivityLogEntryPoint.cs b/MediaBrowser.Server.Implementations/EntryPoints/ActivityLogEntryPoint.cs deleted file mode 100644 index 51f5f57b3..000000000 --- a/MediaBrowser.Server.Implementations/EntryPoints/ActivityLogEntryPoint.cs +++ /dev/null @@ -1,561 +0,0 @@ -using MediaBrowser.Common.Configuration; -using MediaBrowser.Common.Plugins; -using MediaBrowser.Common.Updates; -using MediaBrowser.Controller; -using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Library; -using MediaBrowser.Controller.Plugins; -using MediaBrowser.Controller.Session; -using MediaBrowser.Controller.Subtitles; -using MediaBrowser.Model.Activity; -using MediaBrowser.Model.Events; -using MediaBrowser.Model.Logging; -using MediaBrowser.Model.Tasks; -using MediaBrowser.Model.Updates; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using MediaBrowser.Model.Globalization; - -namespace MediaBrowser.Server.Implementations.EntryPoints -{ - public class ActivityLogEntryPoint : IServerEntryPoint - { - private readonly IInstallationManager _installationManager; - - //private readonly ILogManager _logManager; - //private readonly ILogger _logger; - private readonly ISessionManager _sessionManager; - private readonly ITaskManager _taskManager; - private readonly IActivityManager _activityManager; - private readonly ILocalizationManager _localization; - - private readonly ILibraryManager _libraryManager; - private readonly ISubtitleManager _subManager; - private readonly IUserManager _userManager; - private readonly IServerConfigurationManager _config; - private readonly IServerApplicationHost _appHost; - - public ActivityLogEntryPoint(ISessionManager sessionManager, ITaskManager taskManager, IActivityManager activityManager, ILocalizationManager localization, IInstallationManager installationManager, ILibraryManager libraryManager, ISubtitleManager subManager, IUserManager userManager, IServerConfigurationManager config, IServerApplicationHost appHost) - { - //_logger = _logManager.GetLogger("ActivityLogEntryPoint"); - _sessionManager = sessionManager; - _taskManager = taskManager; - _activityManager = activityManager; - _localization = localization; - _installationManager = installationManager; - _libraryManager = libraryManager; - _subManager = subManager; - _userManager = userManager; - _config = config; - //_logManager = logManager; - _appHost = appHost; - } - - public void Run() - { - //_taskManager.TaskExecuting += _taskManager_TaskExecuting; - //_taskManager.TaskCompleted += _taskManager_TaskCompleted; - - //_installationManager.PluginInstalled += _installationManager_PluginInstalled; - //_installationManager.PluginUninstalled += _installationManager_PluginUninstalled; - //_installationManager.PluginUpdated += _installationManager_PluginUpdated; - - //_libraryManager.ItemAdded += _libraryManager_ItemAdded; - //_libraryManager.ItemRemoved += _libraryManager_ItemRemoved; - - _sessionManager.SessionStarted += _sessionManager_SessionStarted; - _sessionManager.AuthenticationFailed += _sessionManager_AuthenticationFailed; - _sessionManager.AuthenticationSucceeded += _sessionManager_AuthenticationSucceeded; - _sessionManager.SessionEnded += _sessionManager_SessionEnded; - - _sessionManager.PlaybackStart += _sessionManager_PlaybackStart; - _sessionManager.PlaybackStopped += _sessionManager_PlaybackStopped; - - //_subManager.SubtitlesDownloaded += _subManager_SubtitlesDownloaded; - _subManager.SubtitleDownloadFailure += _subManager_SubtitleDownloadFailure; - - _userManager.UserCreated += _userManager_UserCreated; - _userManager.UserPasswordChanged += _userManager_UserPasswordChanged; - _userManager.UserDeleted += _userManager_UserDeleted; - _userManager.UserConfigurationUpdated += _userManager_UserConfigurationUpdated; - _userManager.UserLockedOut += _userManager_UserLockedOut; - - //_config.ConfigurationUpdated += _config_ConfigurationUpdated; - //_config.NamedConfigurationUpdated += _config_NamedConfigurationUpdated; - - //_logManager.LoggerLoaded += _logManager_LoggerLoaded; - - _appHost.ApplicationUpdated += _appHost_ApplicationUpdated; - } - - void _userManager_UserLockedOut(object sender, GenericEventArgs<User> e) - { - CreateLogEntry(new ActivityLogEntry - { - Name = string.Format(_localization.GetLocalizedString("UserLockedOutWithName"), e.Argument.Name), - Type = "UserLockedOut", - UserId = e.Argument.Id.ToString("N") - }); - } - - void _subManager_SubtitleDownloadFailure(object sender, SubtitleDownloadFailureEventArgs e) - { - CreateLogEntry(new ActivityLogEntry - { - Name = string.Format(_localization.GetLocalizedString("SubtitleDownloadFailureForItem"), Notifications.Notifications.GetItemName(e.Item)), - Type = "SubtitleDownloadFailure", - ItemId = e.Item.Id.ToString("N"), - ShortOverview = string.Format(_localization.GetLocalizedString("ProviderValue"), e.Provider), - Overview = LogHelper.GetLogMessage(e.Exception).ToString() - }); - } - - void _sessionManager_PlaybackStopped(object sender, PlaybackStopEventArgs e) - { - var item = e.MediaInfo; - - if (item == null) - { - //_logger.Warn("PlaybackStopped reported with null media info."); - return; - } - - if (item.IsThemeMedia) - { - // Don't report theme song or local trailer playback - return; - } - - if (e.Users.Count == 0) - { - return; - } - - var user = e.Users.First(); - - CreateLogEntry(new ActivityLogEntry - { - Name = string.Format(_localization.GetLocalizedString("UserStoppedPlayingItemWithValues"), user.Name, item.Name), - Type = "PlaybackStopped", - ShortOverview = string.Format(_localization.GetLocalizedString("AppDeviceValues"), e.ClientName, e.DeviceName), - UserId = user.Id.ToString("N") - }); - } - - void _sessionManager_PlaybackStart(object sender, PlaybackProgressEventArgs e) - { - var item = e.MediaInfo; - - if (item == null) - { - //_logger.Warn("PlaybackStart reported with null media info."); - return; - } - - if (item.IsThemeMedia) - { - // Don't report theme song or local trailer playback - return; - } - - if (e.Users.Count == 0) - { - return; - } - - var user = e.Users.First(); - - CreateLogEntry(new ActivityLogEntry - { - Name = string.Format(_localization.GetLocalizedString("UserStartedPlayingItemWithValues"), user.Name, item.Name), - Type = "PlaybackStart", - ShortOverview = string.Format(_localization.GetLocalizedString("AppDeviceValues"), e.ClientName, e.DeviceName), - UserId = user.Id.ToString("N") - }); - } - - void _sessionManager_SessionEnded(object sender, SessionEventArgs e) - { - string name; - var session = e.SessionInfo; - - if (string.IsNullOrWhiteSpace(session.UserName)) - { - name = string.Format(_localization.GetLocalizedString("DeviceOfflineWithName"), session.DeviceName); - - // Causing too much spam for now - return; - } - else - { - name = string.Format(_localization.GetLocalizedString("UserOfflineFromDevice"), session.UserName, session.DeviceName); - } - - CreateLogEntry(new ActivityLogEntry - { - Name = name, - Type = "SessionEnded", - ShortOverview = string.Format(_localization.GetLocalizedString("LabelIpAddressValue"), session.RemoteEndPoint), - UserId = session.UserId.HasValue ? session.UserId.Value.ToString("N") : null - }); - } - - void _sessionManager_AuthenticationSucceeded(object sender, GenericEventArgs<AuthenticationRequest> e) - { - CreateLogEntry(new ActivityLogEntry - { - Name = string.Format(_localization.GetLocalizedString("AuthenticationSucceededWithUserName"), e.Argument.Username), - Type = "AuthenticationSucceeded", - ShortOverview = string.Format(_localization.GetLocalizedString("LabelIpAddressValue"), e.Argument.RemoteEndPoint) - }); - } - - void _sessionManager_AuthenticationFailed(object sender, GenericEventArgs<AuthenticationRequest> e) - { - CreateLogEntry(new ActivityLogEntry - { - Name = string.Format(_localization.GetLocalizedString("FailedLoginAttemptWithUserName"), e.Argument.Username), - Type = "AuthenticationFailed", - ShortOverview = string.Format(_localization.GetLocalizedString("LabelIpAddressValue"), e.Argument.RemoteEndPoint), - Severity = LogSeverity.Error - }); - } - - void _appHost_ApplicationUpdated(object sender, GenericEventArgs<PackageVersionInfo> e) - { - CreateLogEntry(new ActivityLogEntry - { - Name = _localization.GetLocalizedString("MessageApplicationUpdated"), - Type = "ApplicationUpdated", - ShortOverview = string.Format(_localization.GetLocalizedString("VersionNumber"), e.Argument.versionStr), - Overview = e.Argument.description - }); - } - - void _logManager_LoggerLoaded(object sender, EventArgs e) - { - } - - void _config_NamedConfigurationUpdated(object sender, ConfigurationUpdateEventArgs e) - { - CreateLogEntry(new ActivityLogEntry - { - Name = string.Format(_localization.GetLocalizedString("MessageNamedServerConfigurationUpdatedWithValue"), e.Key), - Type = "NamedConfigurationUpdated" - }); - } - - void _config_ConfigurationUpdated(object sender, EventArgs e) - { - CreateLogEntry(new ActivityLogEntry - { - Name = _localization.GetLocalizedString("MessageServerConfigurationUpdated"), - Type = "ServerConfigurationUpdated" - }); - } - - void _userManager_UserConfigurationUpdated(object sender, GenericEventArgs<User> e) - { - CreateLogEntry(new ActivityLogEntry - { - Name = string.Format(_localization.GetLocalizedString("UserConfigurationUpdatedWithName"), e.Argument.Name), - Type = "UserConfigurationUpdated", - UserId = e.Argument.Id.ToString("N") - }); - } - - void _userManager_UserDeleted(object sender, GenericEventArgs<User> e) - { - CreateLogEntry(new ActivityLogEntry - { - Name = string.Format(_localization.GetLocalizedString("UserDeletedWithName"), e.Argument.Name), - Type = "UserDeleted" - }); - } - - void _userManager_UserPasswordChanged(object sender, GenericEventArgs<User> e) - { - CreateLogEntry(new ActivityLogEntry - { - Name = string.Format(_localization.GetLocalizedString("UserPasswordChangedWithName"), e.Argument.Name), - Type = "UserPasswordChanged", - UserId = e.Argument.Id.ToString("N") - }); - } - - void _userManager_UserCreated(object sender, GenericEventArgs<User> e) - { - CreateLogEntry(new ActivityLogEntry - { - Name = string.Format(_localization.GetLocalizedString("UserCreatedWithName"), e.Argument.Name), - Type = "UserCreated", - UserId = e.Argument.Id.ToString("N") - }); - } - - void _subManager_SubtitlesDownloaded(object sender, SubtitleDownloadEventArgs e) - { - CreateLogEntry(new ActivityLogEntry - { - Name = string.Format(_localization.GetLocalizedString("SubtitlesDownloadedForItem"), Notifications.Notifications.GetItemName(e.Item)), - Type = "SubtitlesDownloaded", - ItemId = e.Item.Id.ToString("N"), - ShortOverview = string.Format(_localization.GetLocalizedString("ProviderValue"), e.Provider) - }); - } - - void _sessionManager_SessionStarted(object sender, SessionEventArgs e) - { - string name; - var session = e.SessionInfo; - - if (string.IsNullOrWhiteSpace(session.UserName)) - { - name = string.Format(_localization.GetLocalizedString("DeviceOnlineWithName"), session.DeviceName); - - // Causing too much spam for now - return; - } - else - { - name = string.Format(_localization.GetLocalizedString("UserOnlineFromDevice"), session.UserName, session.DeviceName); - } - - CreateLogEntry(new ActivityLogEntry - { - Name = name, - Type = "SessionStarted", - ShortOverview = string.Format(_localization.GetLocalizedString("LabelIpAddressValue"), session.RemoteEndPoint), - UserId = session.UserId.HasValue ? session.UserId.Value.ToString("N") : null - }); - } - - void _libraryManager_ItemRemoved(object sender, ItemChangeEventArgs e) - { - if (e.Item.SourceType != SourceType.Library) - { - return; - } - - CreateLogEntry(new ActivityLogEntry - { - Name = string.Format(_localization.GetLocalizedString("ItemRemovedWithName"), Notifications.Notifications.GetItemName(e.Item)), - Type = "ItemRemoved" - }); - } - - void _libraryManager_ItemAdded(object sender, ItemChangeEventArgs e) - { - if (e.Item.SourceType != SourceType.Library) - { - return; - } - - CreateLogEntry(new ActivityLogEntry - { - Name = string.Format(_localization.GetLocalizedString("ItemAddedWithName"), Notifications.Notifications.GetItemName(e.Item)), - Type = "ItemAdded", - ItemId = e.Item.Id.ToString("N") - }); - } - - void _installationManager_PluginUpdated(object sender, GenericEventArgs<Tuple<IPlugin, PackageVersionInfo>> e) - { - CreateLogEntry(new ActivityLogEntry - { - Name = string.Format(_localization.GetLocalizedString("PluginUpdatedWithName"), e.Argument.Item1.Name), - Type = "PluginUpdated", - ShortOverview = string.Format(_localization.GetLocalizedString("VersionNumber"), e.Argument.Item2.versionStr), - Overview = e.Argument.Item2.description - }); - } - - void _installationManager_PluginUninstalled(object sender, GenericEventArgs<IPlugin> e) - { - CreateLogEntry(new ActivityLogEntry - { - Name = string.Format(_localization.GetLocalizedString("PluginUninstalledWithName"), e.Argument.Name), - Type = "PluginUninstalled" - }); - } - - void _installationManager_PluginInstalled(object sender, GenericEventArgs<PackageVersionInfo> e) - { - CreateLogEntry(new ActivityLogEntry - { - Name = string.Format(_localization.GetLocalizedString("PluginInstalledWithName"), e.Argument.name), - Type = "PluginInstalled", - ShortOverview = string.Format(_localization.GetLocalizedString("VersionNumber"), e.Argument.versionStr) - }); - } - - void _taskManager_TaskExecuting(object sender, GenericEventArgs<IScheduledTaskWorker> e) - { - var task = e.Argument; - - var activityTask = task.ScheduledTask as IConfigurableScheduledTask; - if (activityTask != null && !activityTask.IsLogged) - { - return; - } - - CreateLogEntry(new ActivityLogEntry - { - Name = string.Format(_localization.GetLocalizedString("ScheduledTaskStartedWithName"), task.Name), - Type = "ScheduledTaskStarted" - }); - } - - void _taskManager_TaskCompleted(object sender, TaskCompletionEventArgs e) - { - var result = e.Result; - var task = e.Task; - - var activityTask = task.ScheduledTask as IConfigurableScheduledTask; - if (activityTask != null && !activityTask.IsLogged) - { - return; - } - - var time = result.EndTimeUtc - result.StartTimeUtc; - var runningTime = string.Format(_localization.GetLocalizedString("LabelRunningTimeValue"), ToUserFriendlyString(time)); - - if (result.Status == TaskCompletionStatus.Failed) - { - var vals = new List<string>(); - - if (!string.IsNullOrWhiteSpace(e.Result.ErrorMessage)) - { - vals.Add(e.Result.ErrorMessage); - } - if (!string.IsNullOrWhiteSpace(e.Result.LongErrorMessage)) - { - vals.Add(e.Result.LongErrorMessage); - } - - CreateLogEntry(new ActivityLogEntry - { - Name = string.Format(_localization.GetLocalizedString("ScheduledTaskFailedWithName"), task.Name), - Type = "ScheduledTaskFailed", - Overview = string.Join(Environment.NewLine, vals.ToArray()), - ShortOverview = runningTime, - Severity = LogSeverity.Error - }); - } - } - - private async void CreateLogEntry(ActivityLogEntry entry) - { - try - { - await _activityManager.Create(entry).ConfigureAwait(false); - } - catch - { - // Logged at lower levels - } - } - - public void Dispose() - { - _taskManager.TaskExecuting -= _taskManager_TaskExecuting; - _taskManager.TaskCompleted -= _taskManager_TaskCompleted; - - _installationManager.PluginInstalled -= _installationManager_PluginInstalled; - _installationManager.PluginUninstalled -= _installationManager_PluginUninstalled; - _installationManager.PluginUpdated -= _installationManager_PluginUpdated; - - _libraryManager.ItemAdded -= _libraryManager_ItemAdded; - _libraryManager.ItemRemoved -= _libraryManager_ItemRemoved; - - _sessionManager.SessionStarted -= _sessionManager_SessionStarted; - _sessionManager.AuthenticationFailed -= _sessionManager_AuthenticationFailed; - _sessionManager.AuthenticationSucceeded -= _sessionManager_AuthenticationSucceeded; - _sessionManager.SessionEnded -= _sessionManager_SessionEnded; - - _sessionManager.PlaybackStart -= _sessionManager_PlaybackStart; - _sessionManager.PlaybackStopped -= _sessionManager_PlaybackStopped; - - _subManager.SubtitlesDownloaded -= _subManager_SubtitlesDownloaded; - _subManager.SubtitleDownloadFailure -= _subManager_SubtitleDownloadFailure; - - _userManager.UserCreated -= _userManager_UserCreated; - _userManager.UserPasswordChanged -= _userManager_UserPasswordChanged; - _userManager.UserDeleted -= _userManager_UserDeleted; - _userManager.UserConfigurationUpdated -= _userManager_UserConfigurationUpdated; - _userManager.UserLockedOut -= _userManager_UserLockedOut; - - _config.ConfigurationUpdated -= _config_ConfigurationUpdated; - _config.NamedConfigurationUpdated -= _config_NamedConfigurationUpdated; - - //_logManager.LoggerLoaded -= _logManager_LoggerLoaded; - - _appHost.ApplicationUpdated -= _appHost_ApplicationUpdated; - } - - /// <summary> - /// Constructs a user-friendly string for this TimeSpan instance. - /// </summary> - public static string ToUserFriendlyString(TimeSpan span) - { - const int DaysInYear = 365; - const int DaysInMonth = 30; - - // Get each non-zero value from TimeSpan component - List<string> values = new List<string>(); - - // Number of years - int days = span.Days; - if (days >= DaysInYear) - { - int years = days / DaysInYear; - values.Add(CreateValueString(years, "year")); - days = days % DaysInYear; - } - // Number of months - if (days >= DaysInMonth) - { - int months = days / DaysInMonth; - values.Add(CreateValueString(months, "month")); - days = days % DaysInMonth; - } - // Number of days - if (days >= 1) - values.Add(CreateValueString(days, "day")); - // Number of hours - if (span.Hours >= 1) - values.Add(CreateValueString(span.Hours, "hour")); - // Number of minutes - if (span.Minutes >= 1) - values.Add(CreateValueString(span.Minutes, "minute")); - // Number of seconds (include when 0 if no other components included) - if (span.Seconds >= 1 || values.Count == 0) - values.Add(CreateValueString(span.Seconds, "second")); - - // Combine values into string - StringBuilder builder = new StringBuilder(); - for (int i = 0; i < values.Count; i++) - { - if (builder.Length > 0) - builder.Append(i == values.Count - 1 ? " and " : ", "); - builder.Append(values[i]); - } - // Return result - return builder.ToString(); - } - - /// <summary> - /// Constructs a string description of a time-span value. - /// </summary> - /// <param name="value">The value of this item</param> - /// <param name="description">The name of this item (singular form)</param> - private static string CreateValueString(int value, string description) - { - return String.Format("{0:#,##0} {1}", - value, value == 1 ? description : String.Format("{0}s", description)); - } - } -} diff --git a/MediaBrowser.Server.Implementations/EntryPoints/Notifications/Notifications.cs b/MediaBrowser.Server.Implementations/EntryPoints/Notifications/Notifications.cs deleted file mode 100644 index f3d1dc8f9..000000000 --- a/MediaBrowser.Server.Implementations/EntryPoints/Notifications/Notifications.cs +++ /dev/null @@ -1,544 +0,0 @@ -using MediaBrowser.Common.Configuration; -using MediaBrowser.Common.Plugins; -using MediaBrowser.Common.Updates; -using MediaBrowser.Controller; -using MediaBrowser.Controller.Devices; -using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Entities.Audio; -using MediaBrowser.Controller.Library; -using MediaBrowser.Controller.Notifications; -using MediaBrowser.Controller.Plugins; -using MediaBrowser.Controller.Session; -using MediaBrowser.Model.Entities; -using MediaBrowser.Model.Events; -using MediaBrowser.Model.Logging; -using MediaBrowser.Model.Notifications; -using MediaBrowser.Model.Tasks; -using MediaBrowser.Model.Updates; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using MediaBrowser.Controller.Entities.TV; - -namespace MediaBrowser.Server.Implementations.EntryPoints.Notifications -{ - /// <summary> - /// Creates notifications for various system events - /// </summary> - public class Notifications : IServerEntryPoint - { - private readonly IInstallationManager _installationManager; - private readonly IUserManager _userManager; - private readonly ILogger _logger; - - private readonly ITaskManager _taskManager; - private readonly INotificationManager _notificationManager; - - private readonly ILibraryManager _libraryManager; - private readonly ISessionManager _sessionManager; - private readonly IServerApplicationHost _appHost; - - private Timer LibraryUpdateTimer { get; set; } - private readonly object _libraryChangedSyncLock = new object(); - - private readonly IConfigurationManager _config; - private readonly IDeviceManager _deviceManager; - - public Notifications(IInstallationManager installationManager, IUserManager userManager, ILogger logger, ITaskManager taskManager, INotificationManager notificationManager, ILibraryManager libraryManager, ISessionManager sessionManager, IServerApplicationHost appHost, IConfigurationManager config, IDeviceManager deviceManager) - { - _installationManager = installationManager; - _userManager = userManager; - _logger = logger; - _taskManager = taskManager; - _notificationManager = notificationManager; - _libraryManager = libraryManager; - _sessionManager = sessionManager; - _appHost = appHost; - _config = config; - _deviceManager = deviceManager; - } - - public void Run() - { - _installationManager.PluginInstalled += _installationManager_PluginInstalled; - _installationManager.PluginUpdated += _installationManager_PluginUpdated; - _installationManager.PackageInstallationFailed += _installationManager_PackageInstallationFailed; - _installationManager.PluginUninstalled += _installationManager_PluginUninstalled; - - _taskManager.TaskCompleted += _taskManager_TaskCompleted; - - _userManager.UserCreated += _userManager_UserCreated; - _libraryManager.ItemAdded += _libraryManager_ItemAdded; - _sessionManager.PlaybackStart += _sessionManager_PlaybackStart; - _sessionManager.PlaybackStopped += _sessionManager_PlaybackStopped; - _appHost.HasPendingRestartChanged += _appHost_HasPendingRestartChanged; - _appHost.HasUpdateAvailableChanged += _appHost_HasUpdateAvailableChanged; - _appHost.ApplicationUpdated += _appHost_ApplicationUpdated; - _deviceManager.CameraImageUploaded += _deviceManager_CameraImageUploaded; - - _userManager.UserLockedOut += _userManager_UserLockedOut; - } - - async void _userManager_UserLockedOut(object sender, GenericEventArgs<User> e) - { - var type = NotificationType.UserLockedOut.ToString(); - - var notification = new NotificationRequest - { - NotificationType = type - }; - - notification.Variables["UserName"] = e.Argument.Name; - - await SendNotification(notification).ConfigureAwait(false); - } - - async void _deviceManager_CameraImageUploaded(object sender, GenericEventArgs<CameraImageUploadInfo> e) - { - var type = NotificationType.CameraImageUploaded.ToString(); - - var notification = new NotificationRequest - { - NotificationType = type - }; - - notification.Variables["DeviceName"] = e.Argument.Device.Name; - - await SendNotification(notification).ConfigureAwait(false); - } - - async void _appHost_ApplicationUpdated(object sender, GenericEventArgs<PackageVersionInfo> e) - { - var type = NotificationType.ApplicationUpdateInstalled.ToString(); - - var notification = new NotificationRequest - { - NotificationType = type, - Url = e.Argument.infoUrl - }; - - notification.Variables["Version"] = e.Argument.versionStr; - notification.Variables["ReleaseNotes"] = e.Argument.description; - - await SendNotification(notification).ConfigureAwait(false); - } - - async void _installationManager_PluginUpdated(object sender, GenericEventArgs<Tuple<IPlugin, PackageVersionInfo>> e) - { - var type = NotificationType.PluginUpdateInstalled.ToString(); - - var installationInfo = e.Argument.Item1; - - var notification = new NotificationRequest - { - Description = e.Argument.Item2.description, - NotificationType = type - }; - - notification.Variables["Name"] = installationInfo.Name; - notification.Variables["Version"] = installationInfo.Version.ToString(); - notification.Variables["ReleaseNotes"] = e.Argument.Item2.description; - - await SendNotification(notification).ConfigureAwait(false); - } - - async void _installationManager_PluginInstalled(object sender, GenericEventArgs<PackageVersionInfo> e) - { - var type = NotificationType.PluginInstalled.ToString(); - - var installationInfo = e.Argument; - - var notification = new NotificationRequest - { - Description = installationInfo.description, - NotificationType = type - }; - - notification.Variables["Name"] = installationInfo.name; - notification.Variables["Version"] = installationInfo.versionStr; - - await SendNotification(notification).ConfigureAwait(false); - } - - async void _appHost_HasUpdateAvailableChanged(object sender, EventArgs e) - { - // This notification is for users who can't auto-update (aka running as service) - if (!_appHost.HasUpdateAvailable || _appHost.CanSelfUpdate) - { - return; - } - - var type = NotificationType.ApplicationUpdateAvailable.ToString(); - - var notification = new NotificationRequest - { - Description = "Please see emby.media for details.", - NotificationType = type - }; - - await SendNotification(notification).ConfigureAwait(false); - } - - async void _appHost_HasPendingRestartChanged(object sender, EventArgs e) - { - if (!_appHost.HasPendingRestart) - { - return; - } - - var type = NotificationType.ServerRestartRequired.ToString(); - - var notification = new NotificationRequest - { - NotificationType = type - }; - - await SendNotification(notification).ConfigureAwait(false); - } - - private NotificationOptions GetOptions() - { - return _config.GetConfiguration<NotificationOptions>("notifications"); - } - - void _sessionManager_PlaybackStart(object sender, PlaybackProgressEventArgs e) - { - var item = e.MediaInfo; - - if (item == null) - { - _logger.Warn("PlaybackStart reported with null media info."); - return; - } - - var video = e.Item as Video; - if (video != null && video.IsThemeMedia) - { - return; - } - - var type = GetPlaybackNotificationType(item.MediaType); - - SendPlaybackNotification(type, e); - } - - void _sessionManager_PlaybackStopped(object sender, PlaybackStopEventArgs e) - { - var item = e.MediaInfo; - - if (item == null) - { - _logger.Warn("PlaybackStopped reported with null media info."); - return; - } - - var video = e.Item as Video; - if (video != null && video.IsThemeMedia) - { - return; - } - - var type = GetPlaybackStoppedNotificationType(item.MediaType); - - SendPlaybackNotification(type, e); - } - - private async void SendPlaybackNotification(string type, PlaybackProgressEventArgs e) - { - var user = e.Users.FirstOrDefault(); - - if (user != null && !GetOptions().IsEnabledToMonitorUser(type, user.Id.ToString("N"))) - { - return; - } - - var item = e.MediaInfo; - - if ( item.IsThemeMedia) - { - // Don't report theme song or local trailer playback - return; - } - - var notification = new NotificationRequest - { - NotificationType = type - }; - - if (e.Item != null) - { - notification.Variables["ItemName"] = GetItemName(e.Item); - } - else - { - notification.Variables["ItemName"] = item.Name; - } - - notification.Variables["UserName"] = user == null ? "Unknown user" : user.Name; - notification.Variables["AppName"] = e.ClientName; - notification.Variables["DeviceName"] = e.DeviceName; - - await SendNotification(notification).ConfigureAwait(false); - } - - private string GetPlaybackNotificationType(string mediaType) - { - if (string.Equals(mediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase)) - { - return NotificationType.AudioPlayback.ToString(); - } - if (string.Equals(mediaType, MediaType.Game, StringComparison.OrdinalIgnoreCase)) - { - return NotificationType.GamePlayback.ToString(); - } - if (string.Equals(mediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase)) - { - return NotificationType.VideoPlayback.ToString(); - } - - return null; - } - - private string GetPlaybackStoppedNotificationType(string mediaType) - { - if (string.Equals(mediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase)) - { - return NotificationType.AudioPlaybackStopped.ToString(); - } - if (string.Equals(mediaType, MediaType.Game, StringComparison.OrdinalIgnoreCase)) - { - return NotificationType.GamePlaybackStopped.ToString(); - } - if (string.Equals(mediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase)) - { - return NotificationType.VideoPlaybackStopped.ToString(); - } - - return null; - } - - private readonly List<BaseItem> _itemsAdded = new List<BaseItem>(); - void _libraryManager_ItemAdded(object sender, ItemChangeEventArgs e) - { - if (!FilterItem(e.Item)) - { - return; - } - - lock (_libraryChangedSyncLock) - { - if (LibraryUpdateTimer == null) - { - LibraryUpdateTimer = new Timer(LibraryUpdateTimerCallback, null, 5000, - Timeout.Infinite); - } - else - { - LibraryUpdateTimer.Change(5000, Timeout.Infinite); - } - - _itemsAdded.Add(e.Item); - } - } - - private bool FilterItem(BaseItem item) - { - if (item.IsFolder) - { - return false; - } - - if (item.LocationType == LocationType.Virtual) - { - return false; - } - - if (item is IItemByName) - { - return false; - } - - return item.SourceType == SourceType.Library; - } - - private async void LibraryUpdateTimerCallback(object state) - { - List<BaseItem> items; - - lock (_libraryChangedSyncLock) - { - items = _itemsAdded.ToList(); - _itemsAdded.Clear(); - DisposeLibraryUpdateTimer(); - } - - items = items.Take(10).ToList(); - - foreach (var item in items) - { - var notification = new NotificationRequest - { - NotificationType = NotificationType.NewLibraryContent.ToString() - }; - - notification.Variables["Name"] = GetItemName(item); - - await SendNotification(notification).ConfigureAwait(false); - } - } - - public static string GetItemName(BaseItem item) - { - var name = item.Name; - var episode = item as Episode; - if (episode != null) - { - if (episode.IndexNumber.HasValue) - { - name = string.Format("Ep{0} - {1}", episode.IndexNumber.Value.ToString(CultureInfo.InvariantCulture), name); - } - if (episode.ParentIndexNumber.HasValue) - { - name = string.Format("S{0}, {1}", episode.ParentIndexNumber.Value.ToString(CultureInfo.InvariantCulture), name); - } - } - - var hasSeries = item as IHasSeries; - - if (hasSeries != null) - { - name = hasSeries.SeriesName + " - " + name; - } - - var hasArtist = item as IHasArtist; - if (hasArtist != null) - { - var artists = hasArtist.AllArtists; - - if (artists.Count > 0) - { - name = hasArtist.AllArtists[0] + " - " + name; - } - } - - return name; - } - - async void _userManager_UserCreated(object sender, GenericEventArgs<User> e) - { - var notification = new NotificationRequest - { - UserIds = new List<string> { e.Argument.Id.ToString("N") }, - Name = "Welcome to Emby!", - Description = "Check back here for more notifications." - }; - - await SendNotification(notification).ConfigureAwait(false); - } - - async void _taskManager_TaskCompleted(object sender, TaskCompletionEventArgs e) - { - var result = e.Result; - - if (result.Status == TaskCompletionStatus.Failed) - { - var type = NotificationType.TaskFailed.ToString(); - - var notification = new NotificationRequest - { - Description = result.ErrorMessage, - Level = NotificationLevel.Error, - NotificationType = type - }; - - notification.Variables["Name"] = result.Name; - notification.Variables["ErrorMessage"] = result.ErrorMessage; - - await SendNotification(notification).ConfigureAwait(false); - } - } - - async void _installationManager_PluginUninstalled(object sender, GenericEventArgs<IPlugin> e) - { - var type = NotificationType.PluginUninstalled.ToString(); - - var plugin = e.Argument; - - var notification = new NotificationRequest - { - NotificationType = type - }; - - notification.Variables["Name"] = plugin.Name; - notification.Variables["Version"] = plugin.Version.ToString(); - - await SendNotification(notification).ConfigureAwait(false); - } - - async void _installationManager_PackageInstallationFailed(object sender, InstallationFailedEventArgs e) - { - var installationInfo = e.InstallationInfo; - - var type = NotificationType.InstallationFailed.ToString(); - - var notification = new NotificationRequest - { - Level = NotificationLevel.Error, - Description = e.Exception.Message, - NotificationType = type - }; - - notification.Variables["Name"] = installationInfo.Name; - notification.Variables["Version"] = installationInfo.Version; - - await SendNotification(notification).ConfigureAwait(false); - } - - private async Task SendNotification(NotificationRequest notification) - { - try - { - await _notificationManager.SendNotification(notification, CancellationToken.None).ConfigureAwait(false); - } - catch (Exception ex) - { - _logger.ErrorException("Error sending notification", ex); - } - } - - public void Dispose() - { - DisposeLibraryUpdateTimer(); - - _installationManager.PluginInstalled -= _installationManager_PluginInstalled; - _installationManager.PluginUpdated -= _installationManager_PluginUpdated; - _installationManager.PackageInstallationFailed -= _installationManager_PackageInstallationFailed; - _installationManager.PluginUninstalled -= _installationManager_PluginUninstalled; - - _taskManager.TaskCompleted -= _taskManager_TaskCompleted; - - _userManager.UserCreated -= _userManager_UserCreated; - _libraryManager.ItemAdded -= _libraryManager_ItemAdded; - _sessionManager.PlaybackStart -= _sessionManager_PlaybackStart; - - _appHost.HasPendingRestartChanged -= _appHost_HasPendingRestartChanged; - _appHost.HasUpdateAvailableChanged -= _appHost_HasUpdateAvailableChanged; - _appHost.ApplicationUpdated -= _appHost_ApplicationUpdated; - - _deviceManager.CameraImageUploaded -= _deviceManager_CameraImageUploaded; - _userManager.UserLockedOut -= _userManager_UserLockedOut; - } - - private void DisposeLibraryUpdateTimer() - { - if (LibraryUpdateTimer != null) - { - LibraryUpdateTimer.Dispose(); - LibraryUpdateTimer = null; - } - } - } -} diff --git a/MediaBrowser.Server.Implementations/EntryPoints/Notifications/WebSocketNotifier.cs b/MediaBrowser.Server.Implementations/EntryPoints/Notifications/WebSocketNotifier.cs deleted file mode 100644 index 916b4a622..000000000 --- a/MediaBrowser.Server.Implementations/EntryPoints/Notifications/WebSocketNotifier.cs +++ /dev/null @@ -1,54 +0,0 @@ -using MediaBrowser.Controller.Net; -using MediaBrowser.Controller.Notifications; -using MediaBrowser.Controller.Plugins; -using System.Linq; - -namespace MediaBrowser.Server.Implementations.EntryPoints.Notifications -{ - /// <summary> - /// Notifies clients anytime a notification is added or udpated - /// </summary> - public class WebSocketNotifier : IServerEntryPoint - { - private readonly INotificationsRepository _notificationsRepo; - - private readonly IServerManager _serverManager; - - public WebSocketNotifier(INotificationsRepository notificationsRepo, IServerManager serverManager) - { - _notificationsRepo = notificationsRepo; - _serverManager = serverManager; - } - - public void Run() - { - _notificationsRepo.NotificationAdded += _notificationsRepo_NotificationAdded; - - _notificationsRepo.NotificationsMarkedRead += _notificationsRepo_NotificationsMarkedRead; - } - - void _notificationsRepo_NotificationsMarkedRead(object sender, NotificationReadEventArgs e) - { - var list = e.IdList.ToList(); - - list.Add(e.UserId); - list.Add(e.IsRead.ToString().ToLower()); - - var msg = string.Join("|", list.ToArray()); - - _serverManager.SendWebSocketMessage("NotificationsMarkedRead", msg); - } - - void _notificationsRepo_NotificationAdded(object sender, NotificationUpdateEventArgs e) - { - var msg = e.Notification.UserId + "|" + e.Notification.Id; - - _serverManager.SendWebSocketMessage("NotificationAdded", msg); - } - - public void Dispose() - { - _notificationsRepo.NotificationAdded -= _notificationsRepo_NotificationAdded; - } - } -} diff --git a/MediaBrowser.Server.Implementations/Library/UserDataManager.cs b/MediaBrowser.Server.Implementations/Library/UserDataManager.cs deleted file mode 100644 index 9ee65a57c..000000000 --- a/MediaBrowser.Server.Implementations/Library/UserDataManager.cs +++ /dev/null @@ -1,287 +0,0 @@ -using MediaBrowser.Common.Events; -using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Entities.Audio; -using MediaBrowser.Controller.Library; -using MediaBrowser.Controller.Persistence; -using MediaBrowser.Model.Dto; -using MediaBrowser.Model.Entities; -using MediaBrowser.Model.Logging; -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; - -namespace MediaBrowser.Server.Implementations.Library -{ - /// <summary> - /// Class UserDataManager - /// </summary> - public class UserDataManager : IUserDataManager - { - public event EventHandler<UserDataSaveEventArgs> UserDataSaved; - - private readonly ConcurrentDictionary<string, UserItemData> _userData = - new ConcurrentDictionary<string, UserItemData>(StringComparer.OrdinalIgnoreCase); - - private readonly ILogger _logger; - private readonly IServerConfigurationManager _config; - - public UserDataManager(ILogManager logManager, IServerConfigurationManager config) - { - _config = config; - _logger = logManager.GetLogger(GetType().Name); - } - - /// <summary> - /// Gets or sets the repository. - /// </summary> - /// <value>The repository.</value> - public IUserDataRepository Repository { get; set; } - - public async Task SaveUserData(Guid userId, IHasUserData item, UserItemData userData, UserDataSaveReason reason, CancellationToken cancellationToken) - { - if (userData == null) - { - throw new ArgumentNullException("userData"); - } - if (item == null) - { - throw new ArgumentNullException("item"); - } - if (userId == Guid.Empty) - { - throw new ArgumentNullException("userId"); - } - - cancellationToken.ThrowIfCancellationRequested(); - - var keys = item.GetUserDataKeys(); - - foreach (var key in keys) - { - await Repository.SaveUserData(userId, key, userData, cancellationToken).ConfigureAwait(false); - } - - var cacheKey = GetCacheKey(userId, item.Id); - _userData.AddOrUpdate(cacheKey, userData, (k, v) => userData); - - EventHelper.FireEventIfNotNull(UserDataSaved, this, new UserDataSaveEventArgs - { - Keys = keys, - UserData = userData, - SaveReason = reason, - UserId = userId, - Item = item - - }, _logger); - } - - /// <summary> - /// Save the provided user data for the given user. Batch operation. Does not fire any events or update the cache. - /// </summary> - /// <param name="userId"></param> - /// <param name="userData"></param> - /// <param name="cancellationToken"></param> - /// <returns></returns> - public async Task SaveAllUserData(Guid userId, IEnumerable<UserItemData> userData, CancellationToken cancellationToken) - { - if (userData == null) - { - throw new ArgumentNullException("userData"); - } - if (userId == Guid.Empty) - { - throw new ArgumentNullException("userId"); - } - - cancellationToken.ThrowIfCancellationRequested(); - - await Repository.SaveAllUserData(userId, userData, cancellationToken).ConfigureAwait(false); - } - - /// <summary> - /// Retrieve all user data for the given user - /// </summary> - /// <param name="userId"></param> - /// <returns></returns> - public IEnumerable<UserItemData> GetAllUserData(Guid userId) - { - if (userId == Guid.Empty) - { - throw new ArgumentNullException("userId"); - } - - return Repository.GetAllUserData(userId); - } - - public UserItemData GetUserData(Guid userId, Guid itemId, List<string> keys) - { - if (userId == Guid.Empty) - { - throw new ArgumentNullException("userId"); - } - if (keys == null) - { - throw new ArgumentNullException("keys"); - } - if (keys.Count == 0) - { - throw new ArgumentException("UserData keys cannot be empty."); - } - - var cacheKey = GetCacheKey(userId, itemId); - - return _userData.GetOrAdd(cacheKey, k => GetUserDataInternal(userId, keys)); - } - - private UserItemData GetUserDataInternal(Guid userId, List<string> keys) - { - var userData = Repository.GetUserData(userId, keys); - - if (userData != null) - { - return userData; - } - - if (keys.Count > 0) - { - return new UserItemData - { - UserId = userId, - Key = keys[0] - }; - } - - return null; - } - - /// <summary> - /// Gets the internal key. - /// </summary> - /// <returns>System.String.</returns> - private string GetCacheKey(Guid userId, Guid itemId) - { - return userId.ToString("N") + itemId.ToString("N"); - } - - public UserItemData GetUserData(IHasUserData user, IHasUserData item) - { - return GetUserData(user.Id, item); - } - - public UserItemData GetUserData(string userId, IHasUserData item) - { - return GetUserData(new Guid(userId), item); - } - - public UserItemData GetUserData(Guid userId, IHasUserData item) - { - return GetUserData(userId, item.Id, item.GetUserDataKeys()); - } - - public async Task<UserItemDataDto> GetUserDataDto(IHasUserData item, User user) - { - var userData = GetUserData(user.Id, item); - var dto = GetUserItemDataDto(userData); - - await item.FillUserDataDtoValues(dto, userData, null, user).ConfigureAwait(false); - return dto; - } - - public async Task<UserItemDataDto> GetUserDataDto(IHasUserData item, BaseItemDto itemDto, User user) - { - var userData = GetUserData(user.Id, item); - var dto = GetUserItemDataDto(userData); - - await item.FillUserDataDtoValues(dto, userData, itemDto, user).ConfigureAwait(false); - return dto; - } - - /// <summary> - /// Converts a UserItemData to a DTOUserItemData - /// </summary> - /// <param name="data">The data.</param> - /// <returns>DtoUserItemData.</returns> - /// <exception cref="System.ArgumentNullException"></exception> - private UserItemDataDto GetUserItemDataDto(UserItemData data) - { - if (data == null) - { - throw new ArgumentNullException("data"); - } - - return new UserItemDataDto - { - IsFavorite = data.IsFavorite, - Likes = data.Likes, - PlaybackPositionTicks = data.PlaybackPositionTicks, - PlayCount = data.PlayCount, - Rating = data.Rating, - Played = data.Played, - LastPlayedDate = data.LastPlayedDate, - Key = data.Key - }; - } - - public bool UpdatePlayState(BaseItem item, UserItemData data, long? reportedPositionTicks) - { - var playedToCompletion = false; - - var positionTicks = reportedPositionTicks ?? item.RunTimeTicks ?? 0; - var hasRuntime = item.RunTimeTicks.HasValue && item.RunTimeTicks > 0; - - // If a position has been reported, and if we know the duration - if (positionTicks > 0 && hasRuntime) - { - var pctIn = Decimal.Divide(positionTicks, item.RunTimeTicks.Value) * 100; - - // Don't track in very beginning - if (pctIn < _config.Configuration.MinResumePct) - { - positionTicks = 0; - } - - // If we're at the end, assume completed - else if (pctIn > _config.Configuration.MaxResumePct || positionTicks >= item.RunTimeTicks.Value) - { - positionTicks = 0; - data.Played = playedToCompletion = true; - } - - else - { - // Enforce MinResumeDuration - var durationSeconds = TimeSpan.FromTicks(item.RunTimeTicks.Value).TotalSeconds; - - if (durationSeconds < _config.Configuration.MinResumeDurationSeconds) - { - positionTicks = 0; - data.Played = playedToCompletion = true; - } - } - } - else if (!hasRuntime) - { - // If we don't know the runtime we'll just have to assume it was fully played - data.Played = playedToCompletion = true; - positionTicks = 0; - } - - if (!item.SupportsPlayedStatus) - { - positionTicks = 0; - data.Played = false; - } - if (item is Audio) - { - positionTicks = 0; - } - - data.PlaybackPositionTicks = positionTicks; - - return playedToCompletion; - } - } -} diff --git a/MediaBrowser.Server.Implementations/Library/UserManager.cs b/MediaBrowser.Server.Implementations/Library/UserManager.cs deleted file mode 100644 index 794c924eb..000000000 --- a/MediaBrowser.Server.Implementations/Library/UserManager.cs +++ /dev/null @@ -1,1021 +0,0 @@ -using MediaBrowser.Common.Events; -using MediaBrowser.Common.Net; -using MediaBrowser.Controller; -using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.Connect; -using MediaBrowser.Controller.Drawing; -using MediaBrowser.Controller.Dto; -using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Library; -using MediaBrowser.Controller.Net; -using MediaBrowser.Controller.Persistence; -using MediaBrowser.Controller.Providers; -using MediaBrowser.Model.Configuration; -using MediaBrowser.Model.Connect; -using MediaBrowser.Model.Dto; -using MediaBrowser.Model.Entities; -using MediaBrowser.Model.Events; -using MediaBrowser.Model.Logging; -using MediaBrowser.Model.Serialization; -using MediaBrowser.Model.Users; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Security.Cryptography; -using System.Text; -using System.Threading; -using System.Threading.Tasks; -using MediaBrowser.Common.IO; -using MediaBrowser.Controller.IO; -using MediaBrowser.Model.IO; - -namespace MediaBrowser.Server.Implementations.Library -{ - /// <summary> - /// Class UserManager - /// </summary> - public class UserManager : IUserManager - { - /// <summary> - /// Gets the users. - /// </summary> - /// <value>The users.</value> - public IEnumerable<User> Users { get; private set; } - - /// <summary> - /// The _logger - /// </summary> - private readonly ILogger _logger; - - /// <summary> - /// Gets or sets the configuration manager. - /// </summary> - /// <value>The configuration manager.</value> - private IServerConfigurationManager ConfigurationManager { get; set; } - - /// <summary> - /// Gets the active user repository - /// </summary> - /// <value>The user repository.</value> - private IUserRepository UserRepository { get; set; } - public event EventHandler<GenericEventArgs<User>> UserPasswordChanged; - - private readonly IXmlSerializer _xmlSerializer; - private readonly IJsonSerializer _jsonSerializer; - - private readonly INetworkManager _networkManager; - - private readonly Func<IImageProcessor> _imageProcessorFactory; - private readonly Func<IDtoService> _dtoServiceFactory; - private readonly Func<IConnectManager> _connectFactory; - private readonly IServerApplicationHost _appHost; - private readonly IFileSystem _fileSystem; - - public UserManager(ILogger logger, IServerConfigurationManager configurationManager, IUserRepository userRepository, IXmlSerializer xmlSerializer, INetworkManager networkManager, Func<IImageProcessor> imageProcessorFactory, Func<IDtoService> dtoServiceFactory, Func<IConnectManager> connectFactory, IServerApplicationHost appHost, IJsonSerializer jsonSerializer, IFileSystem fileSystem) - { - _logger = logger; - UserRepository = userRepository; - _xmlSerializer = xmlSerializer; - _networkManager = networkManager; - _imageProcessorFactory = imageProcessorFactory; - _dtoServiceFactory = dtoServiceFactory; - _connectFactory = connectFactory; - _appHost = appHost; - _jsonSerializer = jsonSerializer; - _fileSystem = fileSystem; - ConfigurationManager = configurationManager; - Users = new List<User>(); - - DeletePinFile(); - } - - #region UserUpdated Event - /// <summary> - /// Occurs when [user updated]. - /// </summary> - public event EventHandler<GenericEventArgs<User>> UserUpdated; - public event EventHandler<GenericEventArgs<User>> UserConfigurationUpdated; - public event EventHandler<GenericEventArgs<User>> UserLockedOut; - - /// <summary> - /// Called when [user updated]. - /// </summary> - /// <param name="user">The user.</param> - private void OnUserUpdated(User user) - { - EventHelper.FireEventIfNotNull(UserUpdated, this, new GenericEventArgs<User> { Argument = user }, _logger); - } - #endregion - - #region UserDeleted Event - /// <summary> - /// Occurs when [user deleted]. - /// </summary> - public event EventHandler<GenericEventArgs<User>> UserDeleted; - /// <summary> - /// Called when [user deleted]. - /// </summary> - /// <param name="user">The user.</param> - private void OnUserDeleted(User user) - { - EventHelper.QueueEventIfNotNull(UserDeleted, this, new GenericEventArgs<User> { Argument = user }, _logger); - } - #endregion - - /// <summary> - /// Gets a User by Id - /// </summary> - /// <param name="id">The id.</param> - /// <returns>User.</returns> - /// <exception cref="System.ArgumentNullException"></exception> - public User GetUserById(Guid id) - { - if (id == Guid.Empty) - { - throw new ArgumentNullException("id"); - } - - return Users.FirstOrDefault(u => u.Id == id); - } - - /// <summary> - /// Gets the user by identifier. - /// </summary> - /// <param name="id">The identifier.</param> - /// <returns>User.</returns> - public User GetUserById(string id) - { - return GetUserById(new Guid(id)); - } - - public User GetUserByName(string name) - { - if (string.IsNullOrWhiteSpace(name)) - { - throw new ArgumentNullException("name"); - } - - return Users.FirstOrDefault(u => string.Equals(u.Name, name, StringComparison.OrdinalIgnoreCase)); - } - - public async Task Initialize() - { - Users = await LoadUsers().ConfigureAwait(false); - - var users = Users.ToList(); - - // If there are no local users with admin rights, make them all admins - if (!users.Any(i => i.Policy.IsAdministrator)) - { - foreach (var user in users) - { - if (!user.ConnectLinkType.HasValue || user.ConnectLinkType.Value == UserLinkType.LinkedUser) - { - user.Policy.IsAdministrator = true; - await UpdateUserPolicy(user, user.Policy, false).ConfigureAwait(false); - } - } - } - } - - public Task<bool> AuthenticateUser(string username, string passwordSha1, string remoteEndPoint) - { - return AuthenticateUser(username, passwordSha1, null, remoteEndPoint); - } - - public bool IsValidUsername(string username) - { - // Usernames can contain letters (a-z), numbers (0-9), dashes (-), underscores (_), apostrophes ('), and periods (.) - return username.All(IsValidUsernameCharacter); - } - - private bool IsValidUsernameCharacter(char i) - { - return char.IsLetterOrDigit(i) || char.Equals(i, '-') || char.Equals(i, '_') || char.Equals(i, '\'') || - char.Equals(i, '.'); - } - - public string MakeValidUsername(string username) - { - if (IsValidUsername(username)) - { - return username; - } - - // Usernames can contain letters (a-z), numbers (0-9), dashes (-), underscores (_), apostrophes ('), and periods (.) - var builder = new StringBuilder(); - - foreach (var c in username) - { - if (IsValidUsernameCharacter(c)) - { - builder.Append(c); - } - } - return builder.ToString(); - } - - public async Task<bool> AuthenticateUser(string username, string passwordSha1, string passwordMd5, string remoteEndPoint) - { - if (string.IsNullOrWhiteSpace(username)) - { - throw new ArgumentNullException("username"); - } - - var user = Users - .FirstOrDefault(i => string.Equals(username, i.Name, StringComparison.OrdinalIgnoreCase)); - - if (user == null) - { - throw new SecurityException("Invalid username or password entered."); - } - - if (user.Policy.IsDisabled) - { - throw new SecurityException(string.Format("The {0} account is currently disabled. Please consult with your administrator.", user.Name)); - } - - var success = false; - - // Authenticate using local credentials if not a guest - if (!user.ConnectLinkType.HasValue || user.ConnectLinkType.Value != UserLinkType.Guest) - { - success = string.Equals(GetPasswordHash(user), passwordSha1.Replace("-", string.Empty), StringComparison.OrdinalIgnoreCase); - - if (!success && _networkManager.IsInLocalNetwork(remoteEndPoint) && user.Configuration.EnableLocalPassword) - { - success = string.Equals(GetLocalPasswordHash(user), passwordSha1.Replace("-", string.Empty), StringComparison.OrdinalIgnoreCase); - } - } - - // Update LastActivityDate and LastLoginDate, then save - if (success) - { - user.LastActivityDate = user.LastLoginDate = DateTime.UtcNow; - await UpdateUser(user).ConfigureAwait(false); - await UpdateInvalidLoginAttemptCount(user, 0).ConfigureAwait(false); - } - else - { - await UpdateInvalidLoginAttemptCount(user, user.Policy.InvalidLoginAttemptCount + 1).ConfigureAwait(false); - } - - _logger.Info("Authentication request for {0} {1}.", user.Name, success ? "has succeeded" : "has been denied"); - - return success; - } - - private async Task UpdateInvalidLoginAttemptCount(User user, int newValue) - { - if (user.Policy.InvalidLoginAttemptCount != newValue || newValue > 0) - { - user.Policy.InvalidLoginAttemptCount = newValue; - - var maxCount = user.Policy.IsAdministrator ? - 3 : - 5; - - var fireLockout = false; - - if (newValue >= maxCount) - { - //_logger.Debug("Disabling user {0} due to {1} unsuccessful login attempts.", user.Name, newValue.ToString(CultureInfo.InvariantCulture)); - //user.Policy.IsDisabled = true; - - //fireLockout = true; - } - - await UpdateUserPolicy(user, user.Policy, false).ConfigureAwait(false); - - if (fireLockout) - { - if (UserLockedOut != null) - { - EventHelper.FireEventIfNotNull(UserLockedOut, this, new GenericEventArgs<User>(user), _logger); - } - } - } - } - - private string GetPasswordHash(User user) - { - return string.IsNullOrEmpty(user.Password) - ? GetSha1String(string.Empty) - : user.Password; - } - - private string GetLocalPasswordHash(User user) - { - return string.IsNullOrEmpty(user.EasyPassword) - ? GetSha1String(string.Empty) - : user.EasyPassword; - } - - private bool IsPasswordEmpty(string passwordHash) - { - return string.Equals(passwordHash, GetSha1String(string.Empty), StringComparison.OrdinalIgnoreCase); - } - - /// <summary> - /// Gets the sha1 string. - /// </summary> - /// <param name="str">The STR.</param> - /// <returns>System.String.</returns> - private static string GetSha1String(string str) - { - using (var provider = SHA1.Create()) - { - var hash = provider.ComputeHash(Encoding.UTF8.GetBytes(str)); - return BitConverter.ToString(hash).Replace("-", string.Empty); - } - } - - /// <summary> - /// Loads the users from the repository - /// </summary> - /// <returns>IEnumerable{User}.</returns> - private async Task<IEnumerable<User>> LoadUsers() - { - var users = UserRepository.RetrieveAllUsers().ToList(); - - // There always has to be at least one user. - if (users.Count == 0) - { - var name = MakeValidUsername(Environment.UserName); - - var user = InstantiateNewUser(name); - - user.DateLastSaved = DateTime.UtcNow; - - await UserRepository.SaveUser(user, CancellationToken.None).ConfigureAwait(false); - - users.Add(user); - - user.Policy.IsAdministrator = true; - user.Policy.EnableContentDeletion = true; - user.Policy.EnableRemoteControlOfOtherUsers = true; - await UpdateUserPolicy(user, user.Policy, false).ConfigureAwait(false); - } - - return users; - } - - public UserDto GetUserDto(User user, string remoteEndPoint = null) - { - if (user == null) - { - throw new ArgumentNullException("user"); - } - - var passwordHash = GetPasswordHash(user); - - var hasConfiguredPassword = !IsPasswordEmpty(passwordHash); - var hasConfiguredEasyPassword = !IsPasswordEmpty(GetLocalPasswordHash(user)); - - var hasPassword = user.Configuration.EnableLocalPassword && !string.IsNullOrEmpty(remoteEndPoint) && _networkManager.IsInLocalNetwork(remoteEndPoint) ? - hasConfiguredEasyPassword : - hasConfiguredPassword; - - var dto = new UserDto - { - Id = user.Id.ToString("N"), - Name = user.Name, - HasPassword = hasPassword, - HasConfiguredPassword = hasConfiguredPassword, - HasConfiguredEasyPassword = hasConfiguredEasyPassword, - LastActivityDate = user.LastActivityDate, - LastLoginDate = user.LastLoginDate, - Configuration = user.Configuration, - ConnectLinkType = user.ConnectLinkType, - ConnectUserId = user.ConnectUserId, - ConnectUserName = user.ConnectUserName, - ServerId = _appHost.SystemId, - Policy = user.Policy - }; - - var image = user.GetImageInfo(ImageType.Primary, 0); - - if (image != null) - { - dto.PrimaryImageTag = GetImageCacheTag(user, image); - - try - { - _dtoServiceFactory().AttachPrimaryImageAspectRatio(dto, user); - } - catch (Exception ex) - { - // Have to use a catch-all unfortunately because some .net image methods throw plain Exceptions - _logger.ErrorException("Error generating PrimaryImageAspectRatio for {0}", ex, user.Name); - } - } - - return dto; - } - - public UserDto GetOfflineUserDto(User user) - { - var dto = GetUserDto(user); - - var offlinePasswordHash = GetLocalPasswordHash(user); - dto.HasPassword = !IsPasswordEmpty(offlinePasswordHash); - - dto.OfflinePasswordSalt = Guid.NewGuid().ToString("N"); - - // Hash the pin with the device Id to create a unique result for this device - dto.OfflinePassword = GetSha1String((offlinePasswordHash + dto.OfflinePasswordSalt).ToLower()); - - dto.ServerName = _appHost.FriendlyName; - - return dto; - } - - private string GetImageCacheTag(BaseItem item, ItemImageInfo image) - { - try - { - return _imageProcessorFactory().GetImageCacheTag(item, image); - } - catch (Exception ex) - { - _logger.ErrorException("Error getting {0} image info for {1}", ex, image.Type, image.Path); - return null; - } - } - - /// <summary> - /// Refreshes metadata for each user - /// </summary> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns>Task.</returns> - public Task RefreshUsersMetadata(CancellationToken cancellationToken) - { - var tasks = Users.Select(user => user.RefreshMetadata(new MetadataRefreshOptions(_fileSystem), cancellationToken)).ToList(); - - return Task.WhenAll(tasks); - } - - /// <summary> - /// Renames the user. - /// </summary> - /// <param name="user">The user.</param> - /// <param name="newName">The new name.</param> - /// <returns>Task.</returns> - /// <exception cref="System.ArgumentNullException">user</exception> - /// <exception cref="System.ArgumentException"></exception> - public async Task RenameUser(User user, string newName) - { - if (user == null) - { - throw new ArgumentNullException("user"); - } - - if (string.IsNullOrEmpty(newName)) - { - throw new ArgumentNullException("newName"); - } - - if (Users.Any(u => u.Id != user.Id && u.Name.Equals(newName, StringComparison.OrdinalIgnoreCase))) - { - throw new ArgumentException(string.Format("A user with the name '{0}' already exists.", newName)); - } - - if (user.Name.Equals(newName, StringComparison.Ordinal)) - { - throw new ArgumentException("The new and old names must be different."); - } - - await user.Rename(newName); - - OnUserUpdated(user); - } - - /// <summary> - /// Updates the user. - /// </summary> - /// <param name="user">The user.</param> - /// <exception cref="System.ArgumentNullException">user</exception> - /// <exception cref="System.ArgumentException"></exception> - public async Task UpdateUser(User user) - { - if (user == null) - { - throw new ArgumentNullException("user"); - } - - if (user.Id == Guid.Empty || !Users.Any(u => u.Id.Equals(user.Id))) - { - throw new ArgumentException(string.Format("User with name '{0}' and Id {1} does not exist.", user.Name, user.Id)); - } - - user.DateModified = DateTime.UtcNow; - user.DateLastSaved = DateTime.UtcNow; - - await UserRepository.SaveUser(user, CancellationToken.None).ConfigureAwait(false); - - OnUserUpdated(user); - } - - public event EventHandler<GenericEventArgs<User>> UserCreated; - - private readonly SemaphoreSlim _userListLock = new SemaphoreSlim(1, 1); - - /// <summary> - /// Creates the user. - /// </summary> - /// <param name="name">The name.</param> - /// <returns>User.</returns> - /// <exception cref="System.ArgumentNullException">name</exception> - /// <exception cref="System.ArgumentException"></exception> - public async Task<User> CreateUser(string name) - { - if (string.IsNullOrWhiteSpace(name)) - { - throw new ArgumentNullException("name"); - } - - if (!IsValidUsername(name)) - { - throw new ArgumentException("Usernames can contain letters (a-z), numbers (0-9), dashes (-), underscores (_), apostrophes ('), and periods (.)"); - } - - if (Users.Any(u => u.Name.Equals(name, StringComparison.OrdinalIgnoreCase))) - { - throw new ArgumentException(string.Format("A user with the name '{0}' already exists.", name)); - } - - await _userListLock.WaitAsync(CancellationToken.None).ConfigureAwait(false); - - try - { - var user = InstantiateNewUser(name); - - var list = Users.ToList(); - list.Add(user); - Users = list; - - user.DateLastSaved = DateTime.UtcNow; - - await UserRepository.SaveUser(user, CancellationToken.None).ConfigureAwait(false); - - EventHelper.QueueEventIfNotNull(UserCreated, this, new GenericEventArgs<User> { Argument = user }, _logger); - - return user; - } - finally - { - _userListLock.Release(); - } - } - - /// <summary> - /// Deletes the user. - /// </summary> - /// <param name="user">The user.</param> - /// <returns>Task.</returns> - /// <exception cref="System.ArgumentNullException">user</exception> - /// <exception cref="System.ArgumentException"></exception> - public async Task DeleteUser(User user) - { - if (user == null) - { - throw new ArgumentNullException("user"); - } - - if (user.ConnectLinkType.HasValue) - { - await _connectFactory().RemoveConnect(user.Id.ToString("N")).ConfigureAwait(false); - } - - var allUsers = Users.ToList(); - - if (allUsers.FirstOrDefault(u => u.Id == user.Id) == null) - { - throw new ArgumentException(string.Format("The user cannot be deleted because there is no user with the Name {0} and Id {1}.", user.Name, user.Id)); - } - - if (allUsers.Count == 1) - { - throw new ArgumentException(string.Format("The user '{0}' cannot be deleted because there must be at least one user in the system.", user.Name)); - } - - if (user.Policy.IsAdministrator && allUsers.Count(i => i.Policy.IsAdministrator) == 1) - { - throw new ArgumentException(string.Format("The user '{0}' cannot be deleted because there must be at least one admin user in the system.", user.Name)); - } - - await _userListLock.WaitAsync(CancellationToken.None).ConfigureAwait(false); - - try - { - var configPath = GetConfigurationFilePath(user); - - await UserRepository.DeleteUser(user, CancellationToken.None).ConfigureAwait(false); - - try - { - _fileSystem.DeleteFile(configPath); - } - catch (IOException ex) - { - _logger.ErrorException("Error deleting file {0}", ex, configPath); - } - - DeleteUserPolicy(user); - - // Force this to be lazy loaded again - Users = await LoadUsers().ConfigureAwait(false); - - OnUserDeleted(user); - } - finally - { - _userListLock.Release(); - } - } - - /// <summary> - /// Resets the password by clearing it. - /// </summary> - /// <returns>Task.</returns> - public Task ResetPassword(User user) - { - return ChangePassword(user, GetSha1String(string.Empty)); - } - - public Task ResetEasyPassword(User user) - { - return ChangeEasyPassword(user, GetSha1String(string.Empty)); - } - - public async Task ChangePassword(User user, string newPasswordSha1) - { - if (user == null) - { - throw new ArgumentNullException("user"); - } - if (string.IsNullOrWhiteSpace(newPasswordSha1)) - { - throw new ArgumentNullException("newPasswordSha1"); - } - - if (user.ConnectLinkType.HasValue && user.ConnectLinkType.Value == UserLinkType.Guest) - { - throw new ArgumentException("Passwords for guests cannot be changed."); - } - - user.Password = newPasswordSha1; - - await UpdateUser(user).ConfigureAwait(false); - - EventHelper.FireEventIfNotNull(UserPasswordChanged, this, new GenericEventArgs<User>(user), _logger); - } - - public async Task ChangeEasyPassword(User user, string newPasswordSha1) - { - if (user == null) - { - throw new ArgumentNullException("user"); - } - if (string.IsNullOrWhiteSpace(newPasswordSha1)) - { - throw new ArgumentNullException("newPasswordSha1"); - } - - user.EasyPassword = newPasswordSha1; - - await UpdateUser(user).ConfigureAwait(false); - - EventHelper.FireEventIfNotNull(UserPasswordChanged, this, new GenericEventArgs<User>(user), _logger); - } - - /// <summary> - /// Instantiates the new user. - /// </summary> - /// <param name="name">The name.</param> - /// <returns>User.</returns> - private User InstantiateNewUser(string name) - { - return new User - { - Name = name, - Id = Guid.NewGuid(), - DateCreated = DateTime.UtcNow, - DateModified = DateTime.UtcNow, - UsesIdForConfigurationPath = true - }; - } - - private string PasswordResetFile - { - get { return Path.Combine(ConfigurationManager.ApplicationPaths.ProgramDataPath, "passwordreset.txt"); } - } - - private string _lastPin; - private PasswordPinCreationResult _lastPasswordPinCreationResult; - private int _pinAttempts; - - private PasswordPinCreationResult CreatePasswordResetPin() - { - var num = new Random().Next(1, 9999); - - var path = PasswordResetFile; - - var pin = num.ToString("0000", CultureInfo.InvariantCulture); - _lastPin = pin; - - var time = TimeSpan.FromMinutes(5); - var expiration = DateTime.UtcNow.Add(time); - - var text = new StringBuilder(); - - var localAddress = _appHost.GetLocalApiUrl().Result ?? string.Empty; - - text.AppendLine("Use your web browser to visit:"); - text.AppendLine(string.Empty); - text.AppendLine(localAddress + "/web/forgotpasswordpin.html"); - text.AppendLine(string.Empty); - text.AppendLine("Enter the following pin code:"); - text.AppendLine(string.Empty); - text.AppendLine(pin); - text.AppendLine(string.Empty); - text.AppendLine("The pin code will expire at " + expiration.ToLocalTime().ToShortDateString() + " " + expiration.ToLocalTime().ToShortTimeString()); - - _fileSystem.WriteAllText(path, text.ToString(), Encoding.UTF8); - - var result = new PasswordPinCreationResult - { - PinFile = path, - ExpirationDate = expiration - }; - - _lastPasswordPinCreationResult = result; - _pinAttempts = 0; - - return result; - } - - public ForgotPasswordResult StartForgotPasswordProcess(string enteredUsername, bool isInNetwork) - { - DeletePinFile(); - - var user = string.IsNullOrWhiteSpace(enteredUsername) ? - null : - GetUserByName(enteredUsername); - - if (user != null && user.ConnectLinkType.HasValue && user.ConnectLinkType.Value == UserLinkType.Guest) - { - throw new ArgumentException("Unable to process forgot password request for guests."); - } - - var action = ForgotPasswordAction.InNetworkRequired; - string pinFile = null; - DateTime? expirationDate = null; - - if (user != null && !user.Policy.IsAdministrator) - { - action = ForgotPasswordAction.ContactAdmin; - } - else - { - if (isInNetwork) - { - action = ForgotPasswordAction.PinCode; - } - - var result = CreatePasswordResetPin(); - pinFile = result.PinFile; - expirationDate = result.ExpirationDate; - } - - return new ForgotPasswordResult - { - Action = action, - PinFile = pinFile, - PinExpirationDate = expirationDate - }; - } - - public async Task<PinRedeemResult> RedeemPasswordResetPin(string pin) - { - DeletePinFile(); - - var usersReset = new List<string>(); - - var valid = !string.IsNullOrWhiteSpace(_lastPin) && - string.Equals(_lastPin, pin, StringComparison.OrdinalIgnoreCase) && - _lastPasswordPinCreationResult != null && - _lastPasswordPinCreationResult.ExpirationDate > DateTime.UtcNow; - - if (valid) - { - _lastPin = null; - _lastPasswordPinCreationResult = null; - - var users = Users.Where(i => !i.ConnectLinkType.HasValue || i.ConnectLinkType.Value != UserLinkType.Guest) - .ToList(); - - foreach (var user in users) - { - await ResetPassword(user).ConfigureAwait(false); - - if (user.Policy.IsDisabled) - { - user.Policy.IsDisabled = false; - await UpdateUserPolicy(user, user.Policy, true).ConfigureAwait(false); - } - usersReset.Add(user.Name); - } - } - else - { - _pinAttempts++; - if (_pinAttempts >= 3) - { - _lastPin = null; - _lastPasswordPinCreationResult = null; - } - } - - return new PinRedeemResult - { - Success = valid, - UsersReset = usersReset.ToArray() - }; - } - - private void DeletePinFile() - { - try - { - _fileSystem.DeleteFile(PasswordResetFile); - } - catch - { - - } - } - - class PasswordPinCreationResult - { - public string PinFile { get; set; } - public DateTime ExpirationDate { get; set; } - } - - public UserPolicy GetUserPolicy(User user) - { - var path = GetPolifyFilePath(user); - - try - { - lock (_policySyncLock) - { - return (UserPolicy)_xmlSerializer.DeserializeFromFile(typeof(UserPolicy), path); - } - } - catch (DirectoryNotFoundException) - { - return GetDefaultPolicy(user); - } - catch (FileNotFoundException) - { - return GetDefaultPolicy(user); - } - catch (Exception ex) - { - _logger.ErrorException("Error reading policy file: {0}", ex, path); - - return GetDefaultPolicy(user); - } - } - - private UserPolicy GetDefaultPolicy(User user) - { - return new UserPolicy - { - EnableSync = true - }; - } - - private readonly object _policySyncLock = new object(); - public Task UpdateUserPolicy(string userId, UserPolicy userPolicy) - { - var user = GetUserById(userId); - return UpdateUserPolicy(user, userPolicy, true); - } - - private async Task UpdateUserPolicy(User user, UserPolicy userPolicy, bool fireEvent) - { - // The xml serializer will output differently if the type is not exact - if (userPolicy.GetType() != typeof(UserPolicy)) - { - var json = _jsonSerializer.SerializeToString(userPolicy); - userPolicy = _jsonSerializer.DeserializeFromString<UserPolicy>(json); - } - - var path = GetPolifyFilePath(user); - - _fileSystem.CreateDirectory(Path.GetDirectoryName(path)); - - lock (_policySyncLock) - { - _xmlSerializer.SerializeToFile(userPolicy, path); - user.Policy = userPolicy; - } - - await UpdateConfiguration(user, user.Configuration, true).ConfigureAwait(false); - } - - private void DeleteUserPolicy(User user) - { - var path = GetPolifyFilePath(user); - - try - { - lock (_policySyncLock) - { - _fileSystem.DeleteFile(path); - } - } - catch (IOException) - { - - } - catch (Exception ex) - { - _logger.ErrorException("Error deleting policy file", ex); - } - } - - private string GetPolifyFilePath(User user) - { - return Path.Combine(user.ConfigurationDirectoryPath, "policy.xml"); - } - - private string GetConfigurationFilePath(User user) - { - return Path.Combine(user.ConfigurationDirectoryPath, "config.xml"); - } - - public UserConfiguration GetUserConfiguration(User user) - { - var path = GetConfigurationFilePath(user); - - try - { - lock (_configSyncLock) - { - return (UserConfiguration)_xmlSerializer.DeserializeFromFile(typeof(UserConfiguration), path); - } - } - catch (DirectoryNotFoundException) - { - return new UserConfiguration(); - } - catch (FileNotFoundException) - { - return new UserConfiguration(); - } - catch (Exception ex) - { - _logger.ErrorException("Error reading policy file: {0}", ex, path); - - return new UserConfiguration(); - } - } - - private readonly object _configSyncLock = new object(); - public Task UpdateConfiguration(string userId, UserConfiguration config) - { - var user = GetUserById(userId); - return UpdateConfiguration(user, config, true); - } - - private async Task UpdateConfiguration(User user, UserConfiguration config, bool fireEvent) - { - var path = GetConfigurationFilePath(user); - - // The xml serializer will output differently if the type is not exact - if (config.GetType() != typeof(UserConfiguration)) - { - var json = _jsonSerializer.SerializeToString(config); - config = _jsonSerializer.DeserializeFromString<UserConfiguration>(json); - } - - _fileSystem.CreateDirectory(Path.GetDirectoryName(path)); - - lock (_configSyncLock) - { - _xmlSerializer.SerializeToFile(config, path); - user.Configuration = config; - } - - if (fireEvent) - { - EventHelper.FireEventIfNotNull(UserConfigurationUpdated, this, new GenericEventArgs<User> { Argument = user }, _logger); - } - } - } -}
\ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index fc71ef8a0..3fb3ca883 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -111,23 +111,18 @@ <Compile Include="Activity\ActivityRepository.cs" /> <Compile Include="Archiving\ZipClient.cs" /> <Compile Include="Collections\CollectionsDynamicFolder.cs" /> - <Compile Include="Collections\CollectionImageProvider.cs" /> <Compile Include="Configuration\ServerConfigurationManager.cs" /> <Compile Include="Connect\ConnectData.cs" /> <Compile Include="Connect\ConnectEntryPoint.cs" /> <Compile Include="Connect\ConnectManager.cs" /> <Compile Include="Connect\Responses.cs" /> <Compile Include="Connect\Validator.cs" /> - <Compile Include="Devices\DeviceManager.cs" /> <Compile Include="Devices\DeviceRepository.cs" /> <Compile Include="Devices\CameraUploadsFolder.cs" /> - <Compile Include="EntryPoints\ActivityLogEntryPoint.cs" /> <Compile Include="EntryPoints\AutomaticRestartEntryPoint.cs" /> <Compile Include="EntryPoints\ExternalPortForwarding.cs" /> <Compile Include="EntryPoints\LibraryChangedNotifier.cs" /> <Compile Include="EntryPoints\LoadRegistrations.cs" /> - <Compile Include="EntryPoints\Notifications\Notifications.cs" /> - <Compile Include="EntryPoints\Notifications\WebSocketNotifier.cs" /> <Compile Include="EntryPoints\RecordingNotifier.cs" /> <Compile Include="EntryPoints\RefreshUsersMetadata.cs" /> <Compile Include="EntryPoints\UsageEntryPoint.cs" /> @@ -162,8 +157,6 @@ <Compile Include="IO\LibraryMonitor.cs" /> <Compile Include="IO\MemoryStreamProvider.cs" /> <Compile Include="IO\ThrottledStream.cs" /> - <Compile Include="Library\UserDataManager.cs" /> - <Compile Include="Library\UserManager.cs" /> <Compile Include="LiveTv\ChannelImageProvider.cs" /> <Compile Include="LiveTv\EmbyTV\DirectRecorder.cs" /> <Compile Include="LiveTv\EmbyTV\EmbyTV.cs" /> @@ -237,8 +230,6 @@ <Compile Include="TextEncoding\TextEncoding.cs" /> <Compile Include="Threading\PeriodicTimer.cs" /> <Compile Include="TV\SeriesPostScanTask.cs" /> - <Compile Include="UserViews\CollectionFolderImageProvider.cs" /> - <Compile Include="UserViews\DynamicImageProvider.cs" /> <Compile Include="Notifications\CoreNotificationTypes.cs" /> <Compile Include="Notifications\InternalNotificationService.cs" /> <Compile Include="Notifications\NotificationConfigurationFactory.cs" /> @@ -246,10 +237,7 @@ <Compile Include="Persistence\SqliteFileOrganizationRepository.cs" /> <Compile Include="Notifications\SqliteNotificationsRepository.cs" /> <Compile Include="Persistence\TypeMapper.cs" /> - <Compile Include="Photos\BaseDynamicImageProvider.cs" /> <Compile Include="Playlists\ManualPlaylistsFolder.cs" /> - <Compile Include="Photos\PhotoAlbumImageProvider.cs" /> - <Compile Include="Playlists\PlaylistImageProvider.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Security\AuthenticationRepository.cs" /> <Compile Include="Security\EncryptionManager.cs" /> @@ -280,7 +268,6 @@ <Compile Include="Sync\SyncRepository.cs" /> <Compile Include="Sync\SyncConvertScheduledTask.cs" /> <Compile Include="Sync\TargetDataProvider.cs" /> - <Compile Include="TV\TVSeriesManager.cs" /> <Compile Include="Udp\UdpMessageReceivedEventArgs.cs" /> <Compile Include="Udp\UdpServer.cs" /> <Compile Include="Xml\XmlReaderSettingsFactory.cs" /> diff --git a/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs b/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs deleted file mode 100644 index 0dd7672bc..000000000 --- a/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs +++ /dev/null @@ -1,361 +0,0 @@ -using MediaBrowser.Common.Configuration; -using MediaBrowser.Common.Extensions; -using MediaBrowser.Controller.Drawing; -using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Library; -using MediaBrowser.Controller.Playlists; -using MediaBrowser.Controller.Providers; -using MediaBrowser.Model.Entities; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using MediaBrowser.Common.IO; -using MediaBrowser.Model.IO; -using MediaBrowser.Controller.Entities.Audio; -using MediaBrowser.Controller.IO; -using MediaBrowser.Model.Configuration; - -namespace MediaBrowser.Server.Implementations.Photos -{ - public abstract class BaseDynamicImageProvider<T> : IHasItemChangeMonitor, IForcedProvider, ICustomMetadataProvider<T>, IHasOrder - where T : IHasMetadata - { - protected IFileSystem FileSystem { get; private set; } - protected IProviderManager ProviderManager { get; private set; } - protected IApplicationPaths ApplicationPaths { get; private set; } - protected IImageProcessor ImageProcessor { get; set; } - - protected BaseDynamicImageProvider(IFileSystem fileSystem, IProviderManager providerManager, IApplicationPaths applicationPaths, IImageProcessor imageProcessor) - { - ApplicationPaths = applicationPaths; - ProviderManager = providerManager; - FileSystem = fileSystem; - ImageProcessor = imageProcessor; - } - - protected virtual bool Supports(IHasImages item) - { - return true; - } - - public virtual IEnumerable<ImageType> GetSupportedImages(IHasImages item) - { - return new List<ImageType> - { - ImageType.Primary, - ImageType.Thumb - }; - } - - private IEnumerable<ImageType> GetEnabledImages(IHasImages item) - { - //var options = ProviderManager.GetMetadataOptions(item); - - return GetSupportedImages(item); - //return GetSupportedImages(item).Where(i => IsEnabled(options, i, item)).ToList(); - } - - private bool IsEnabled(MetadataOptions options, ImageType type, IHasImages item) - { - if (type == ImageType.Backdrop) - { - if (item.LockedFields.Contains(MetadataFields.Backdrops)) - { - return false; - } - } - else if (type == ImageType.Screenshot) - { - if (item.LockedFields.Contains(MetadataFields.Screenshots)) - { - return false; - } - } - else - { - if (item.LockedFields.Contains(MetadataFields.Images)) - { - return false; - } - } - - return options.IsEnabled(type); - } - - public async Task<ItemUpdateType> FetchAsync(T item, MetadataRefreshOptions options, CancellationToken cancellationToken) - { - if (!Supports(item)) - { - return ItemUpdateType.None; - } - - var updateType = ItemUpdateType.None; - var supportedImages = GetEnabledImages(item).ToList(); - - if (supportedImages.Contains(ImageType.Primary)) - { - var primaryResult = await FetchAsync(item, ImageType.Primary, options, cancellationToken).ConfigureAwait(false); - updateType = updateType | primaryResult; - } - - if (supportedImages.Contains(ImageType.Thumb)) - { - var thumbResult = await FetchAsync(item, ImageType.Thumb, options, cancellationToken).ConfigureAwait(false); - updateType = updateType | thumbResult; - } - - return updateType; - } - - protected async Task<ItemUpdateType> FetchAsync(IHasImages item, ImageType imageType, MetadataRefreshOptions options, CancellationToken cancellationToken) - { - var image = item.GetImageInfo(imageType, 0); - - if (image != null) - { - if (!image.IsLocalFile) - { - return ItemUpdateType.None; - } - - if (!FileSystem.ContainsSubPath(item.GetInternalMetadataPath(), image.Path)) - { - return ItemUpdateType.None; - } - } - - var items = await GetItemsWithImages(item).ConfigureAwait(false); - - return await FetchToFileInternal(item, items, imageType, cancellationToken).ConfigureAwait(false); - } - - protected async Task<ItemUpdateType> FetchToFileInternal(IHasImages item, - List<BaseItem> itemsWithImages, - ImageType imageType, - CancellationToken cancellationToken) - { - var outputPathWithoutExtension = Path.Combine(ApplicationPaths.TempDirectory, Guid.NewGuid().ToString("N")); - FileSystem.CreateDirectory(Path.GetDirectoryName(outputPathWithoutExtension)); - string outputPath = await CreateImage(item, itemsWithImages, outputPathWithoutExtension, imageType, 0).ConfigureAwait(false); - - if (string.IsNullOrWhiteSpace(outputPath)) - { - return ItemUpdateType.None; - } - - await ProviderManager.SaveImage(item, outputPath, "image/png", imageType, null, false, cancellationToken).ConfigureAwait(false); - - return ItemUpdateType.ImageUpdate; - } - - protected abstract Task<List<BaseItem>> GetItemsWithImages(IHasImages item); - - protected Task<string> CreateThumbCollage(IHasImages primaryItem, List<BaseItem> items, string outputPath) - { - return CreateCollage(primaryItem, items, outputPath, 640, 360); - } - - protected virtual IEnumerable<string> GetStripCollageImagePaths(IHasImages primaryItem, IEnumerable<BaseItem> items) - { - return items - .Select(i => - { - var image = i.GetImageInfo(ImageType.Primary, 0); - - if (image != null && image.IsLocalFile) - { - return image.Path; - } - image = i.GetImageInfo(ImageType.Thumb, 0); - - if (image != null && image.IsLocalFile) - { - return image.Path; - } - return null; - }) - .Where(i => !string.IsNullOrWhiteSpace(i)); - } - - protected Task<string> CreatePosterCollage(IHasImages primaryItem, List<BaseItem> items, string outputPath) - { - return CreateCollage(primaryItem, items, outputPath, 400, 600); - } - - protected Task<string> CreateSquareCollage(IHasImages primaryItem, List<BaseItem> items, string outputPath) - { - return CreateCollage(primaryItem, items, outputPath, 600, 600); - } - - protected Task<string> CreateThumbCollage(IHasImages primaryItem, List<BaseItem> items, string outputPath, int width, int height) - { - return CreateCollage(primaryItem, items, outputPath, width, height); - } - - private async Task<string> CreateCollage(IHasImages primaryItem, List<BaseItem> items, string outputPath, int width, int height) - { - FileSystem.CreateDirectory(Path.GetDirectoryName(outputPath)); - - var options = new ImageCollageOptions - { - Height = height, - Width = width, - OutputPath = outputPath, - InputPaths = GetStripCollageImagePaths(primaryItem, items).ToArray() - }; - - if (options.InputPaths.Length == 0) - { - return null; - } - - if (!ImageProcessor.SupportsImageCollageCreation) - { - return null; - } - - await ImageProcessor.CreateImageCollage(options).ConfigureAwait(false); - return outputPath; - } - - public string Name - { - get { return "Dynamic Image Provider"; } - } - - protected virtual async Task<string> CreateImage(IHasImages item, - List<BaseItem> itemsWithImages, - string outputPathWithoutExtension, - ImageType imageType, - int imageIndex) - { - if (itemsWithImages.Count == 0) - { - return null; - } - - string outputPath = Path.ChangeExtension(outputPathWithoutExtension, ".png"); - - if (imageType == ImageType.Thumb) - { - return await CreateThumbCollage(item, itemsWithImages, outputPath).ConfigureAwait(false); - } - - if (imageType == ImageType.Primary) - { - if (item is UserView) - { - return await CreateSquareCollage(item, itemsWithImages, outputPath).ConfigureAwait(false); - } - if (item is Playlist || item is MusicGenre) - { - return await CreateSquareCollage(item, itemsWithImages, outputPath).ConfigureAwait(false); - } - return await CreatePosterCollage(item, itemsWithImages, outputPath).ConfigureAwait(false); - } - - throw new ArgumentException("Unexpected image type"); - } - - protected virtual int MaxImageAgeDays - { - get { return 7; } - } - - public bool HasChanged(IHasMetadata item, IDirectoryService directoryServicee) - { - if (!Supports(item)) - { - return false; - } - - var supportedImages = GetEnabledImages(item).ToList(); - - if (supportedImages.Contains(ImageType.Primary) && HasChanged(item, ImageType.Primary)) - { - return true; - } - if (supportedImages.Contains(ImageType.Thumb) && HasChanged(item, ImageType.Thumb)) - { - return true; - } - - return false; - } - - protected bool HasChanged(IHasImages item, ImageType type) - { - var image = item.GetImageInfo(type, 0); - - if (image != null) - { - if (!image.IsLocalFile) - { - return false; - } - - if (!FileSystem.ContainsSubPath(item.GetInternalMetadataPath(), image.Path)) - { - return false; - } - - var age = DateTime.UtcNow - image.DateModified; - if (age.TotalDays <= MaxImageAgeDays) - { - return false; - } - } - - return true; - } - - protected List<BaseItem> GetFinalItems(List<BaseItem> items) - { - return GetFinalItems(items, 4); - } - - protected virtual List<BaseItem> GetFinalItems(List<BaseItem> items, int limit) - { - // Rotate the images once every x days - var random = DateTime.Now.DayOfYear % MaxImageAgeDays; - - return items - .OrderBy(i => (random + string.Empty + items.IndexOf(i)).GetMD5()) - .Take(limit) - .OrderBy(i => i.Name) - .ToList(); - } - - public int Order - { - get - { - // Run before the default image provider which will download placeholders - return 0; - } - } - - protected async Task<string> CreateSingleImage(List<BaseItem> itemsWithImages, string outputPathWithoutExtension, ImageType imageType) - { - var image = itemsWithImages - .Where(i => i.HasImage(imageType) && i.GetImageInfo(imageType, 0).IsLocalFile && Path.HasExtension(i.GetImagePath(imageType))) - .Select(i => i.GetImagePath(imageType)) - .FirstOrDefault(); - - if (string.IsNullOrWhiteSpace(image)) - { - return null; - } - - var ext = Path.GetExtension(image); - - var outputPath = Path.ChangeExtension(outputPathWithoutExtension, ext); - File.Copy(image, outputPath); - - return outputPath; - } - } -} diff --git a/MediaBrowser.Server.Implementations/Photos/PhotoAlbumImageProvider.cs b/MediaBrowser.Server.Implementations/Photos/PhotoAlbumImageProvider.cs deleted file mode 100644 index ab03f5aaa..000000000 --- a/MediaBrowser.Server.Implementations/Photos/PhotoAlbumImageProvider.cs +++ /dev/null @@ -1,35 +0,0 @@ -using MediaBrowser.Common.Configuration; -using MediaBrowser.Controller.Drawing; -using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Providers; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using MediaBrowser.Common.IO; -using MediaBrowser.Controller.IO; -using MediaBrowser.Model.IO; -using MediaBrowser.Model.Entities; - -namespace MediaBrowser.Server.Implementations.Photos -{ - public class PhotoAlbumImageProvider : BaseDynamicImageProvider<PhotoAlbum> - { - public PhotoAlbumImageProvider(IFileSystem fileSystem, IProviderManager providerManager, IApplicationPaths applicationPaths, IImageProcessor imageProcessor) - : base(fileSystem, providerManager, applicationPaths, imageProcessor) - { - } - - protected override Task<List<BaseItem>> GetItemsWithImages(IHasImages item) - { - var photoAlbum = (PhotoAlbum)item; - var items = GetFinalItems(photoAlbum.Children.ToList()); - - return Task.FromResult(items); - } - - protected override Task<string> CreateImage(IHasImages item, List<BaseItem> itemsWithImages, string outputPathWithoutExtension, ImageType imageType, int imageIndex) - { - return CreateSingleImage(itemsWithImages, outputPathWithoutExtension, ImageType.Primary); - } - } -} diff --git a/MediaBrowser.Server.Implementations/Playlists/PlaylistImageProvider.cs b/MediaBrowser.Server.Implementations/Playlists/PlaylistImageProvider.cs deleted file mode 100644 index 0249b85ee..000000000 --- a/MediaBrowser.Server.Implementations/Playlists/PlaylistImageProvider.cs +++ /dev/null @@ -1,104 +0,0 @@ -using MediaBrowser.Common.Configuration; -using MediaBrowser.Controller.Drawing; -using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Entities.Audio; -using MediaBrowser.Controller.Entities.TV; -using MediaBrowser.Controller.Playlists; -using MediaBrowser.Controller.Providers; -using MediaBrowser.Model.Entities; -using MediaBrowser.Server.Implementations.Photos; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using MediaBrowser.Common.IO; -using MediaBrowser.Controller.IO; -using MediaBrowser.Model.IO; -using MediaBrowser.Controller.Library; -using MediaBrowser.Model.Extensions; -using MediaBrowser.Model.Querying; - -namespace MediaBrowser.Server.Implementations.Playlists -{ - public class PlaylistImageProvider : BaseDynamicImageProvider<Playlist> - { - public PlaylistImageProvider(IFileSystem fileSystem, IProviderManager providerManager, IApplicationPaths applicationPaths, IImageProcessor imageProcessor) : base(fileSystem, providerManager, applicationPaths, imageProcessor) - { - } - - protected override Task<List<BaseItem>> GetItemsWithImages(IHasImages item) - { - var playlist = (Playlist)item; - - var items = playlist.GetManageableItems() - .Select(i => - { - var subItem = i.Item2; - - var episode = subItem as Episode; - - if (episode != null) - { - var series = episode.Series; - if (series != null && series.HasImage(ImageType.Primary)) - { - return series; - } - } - - if (subItem.HasImage(ImageType.Primary)) - { - return subItem; - } - - var parent = subItem.GetParent(); - - if (parent != null && parent.HasImage(ImageType.Primary)) - { - if (parent is MusicAlbum) - { - return parent; - } - } - - return null; - }) - .Where(i => i != null) - .DistinctBy(i => i.Id) - .ToList(); - - return Task.FromResult(GetFinalItems(items)); - } - } - - public class MusicGenreImageProvider : BaseDynamicImageProvider<MusicGenre> - { - private readonly ILibraryManager _libraryManager; - - public MusicGenreImageProvider(IFileSystem fileSystem, IProviderManager providerManager, IApplicationPaths applicationPaths, IImageProcessor imageProcessor, ILibraryManager libraryManager) : base(fileSystem, providerManager, applicationPaths, imageProcessor) - { - _libraryManager = libraryManager; - } - - protected override Task<List<BaseItem>> GetItemsWithImages(IHasImages item) - { - var items = _libraryManager.GetItemList(new InternalItemsQuery - { - Genres = new[] { item.Name }, - IncludeItemTypes = new[] { typeof(MusicAlbum).Name, typeof(MusicVideo).Name, typeof(Audio).Name }, - SortBy = new[] { ItemSortBy.Random }, - Limit = 4, - Recursive = true, - ImageTypes = new[] { ImageType.Primary } - - }).ToList(); - - return Task.FromResult(GetFinalItems(items)); - } - - //protected override Task<string> CreateImage(IHasImages item, List<BaseItem> itemsWithImages, string outputPathWithoutExtension, ImageType imageType, int imageIndex) - //{ - // return CreateSingleImage(itemsWithImages, outputPathWithoutExtension, ImageType.Primary); - //} - } - -} diff --git a/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs b/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs deleted file mode 100644 index 03e8a9178..000000000 --- a/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs +++ /dev/null @@ -1,226 +0,0 @@ -using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Entities.TV; -using MediaBrowser.Controller.Library; -using MediaBrowser.Controller.TV; -using MediaBrowser.Model.Entities; -using MediaBrowser.Model.Querying; -using System; -using System.Collections.Generic; -using System.Linq; -using MediaBrowser.Controller.Configuration; - -namespace MediaBrowser.Server.Implementations.TV -{ - public class TVSeriesManager : ITVSeriesManager - { - private readonly IUserManager _userManager; - private readonly IUserDataManager _userDataManager; - private readonly ILibraryManager _libraryManager; - private readonly IServerConfigurationManager _config; - - public TVSeriesManager(IUserManager userManager, IUserDataManager userDataManager, ILibraryManager libraryManager, IServerConfigurationManager config) - { - _userManager = userManager; - _userDataManager = userDataManager; - _libraryManager = libraryManager; - _config = config; - } - - public QueryResult<BaseItem> GetNextUp(NextUpQuery request) - { - var user = _userManager.GetUserById(request.UserId); - - if (user == null) - { - throw new ArgumentException("User not found"); - } - - var parentIdGuid = string.IsNullOrWhiteSpace(request.ParentId) ? (Guid?)null : new Guid(request.ParentId); - - string presentationUniqueKey = null; - int? limit = null; - if (!string.IsNullOrWhiteSpace(request.SeriesId)) - { - var series = _libraryManager.GetItemById(request.SeriesId); - - if (series != null) - { - presentationUniqueKey = GetUniqueSeriesKey(series); - limit = 1; - } - } - - if (string.IsNullOrWhiteSpace(presentationUniqueKey) && limit.HasValue) - { - limit = limit.Value + 10; - } - - var items = _libraryManager.GetItemList(new InternalItemsQuery(user) - { - IncludeItemTypes = new[] { typeof(Series).Name }, - SortOrder = SortOrder.Ascending, - PresentationUniqueKey = presentationUniqueKey, - Limit = limit, - ParentId = parentIdGuid, - Recursive = true - - }).Cast<Series>(); - - // Avoid implicitly captured closure - var episodes = GetNextUpEpisodes(request, user, items); - - return GetResult(episodes, null, request); - } - - public QueryResult<BaseItem> GetNextUp(NextUpQuery request, IEnumerable<Folder> parentsFolders) - { - var user = _userManager.GetUserById(request.UserId); - - if (user == null) - { - throw new ArgumentException("User not found"); - } - - string presentationUniqueKey = null; - int? limit = null; - if (!string.IsNullOrWhiteSpace(request.SeriesId)) - { - var series = _libraryManager.GetItemById(request.SeriesId); - - if (series != null) - { - presentationUniqueKey = GetUniqueSeriesKey(series); - limit = 1; - } - } - - if (string.IsNullOrWhiteSpace(presentationUniqueKey) && limit.HasValue) - { - limit = limit.Value + 10; - } - - var items = _libraryManager.GetItemList(new InternalItemsQuery(user) - { - IncludeItemTypes = new[] { typeof(Series).Name }, - SortOrder = SortOrder.Ascending, - PresentationUniqueKey = presentationUniqueKey, - Limit = limit - - }, parentsFolders.Select(i => i.Id.ToString("N"))).Cast<Series>(); - - // Avoid implicitly captured closure - var episodes = GetNextUpEpisodes(request, user, items); - - return GetResult(episodes, null, request); - } - - public IEnumerable<Episode> GetNextUpEpisodes(NextUpQuery request, User user, IEnumerable<Series> series) - { - // Avoid implicitly captured closure - var currentUser = user; - - var allNextUp = series - .Select(i => GetNextUp(i, currentUser)) - .Where(i => i.Item1 != null) - // Include if an episode was found, and either the series is not unwatched or the specific series was requested - .OrderByDescending(i => i.Item2) - .ThenByDescending(i => i.Item1.PremiereDate ?? DateTime.MinValue) - .ToList(); - - // If viewing all next up for all series, remove first episodes - if (string.IsNullOrWhiteSpace(request.SeriesId)) - { - var withoutFirstEpisode = allNextUp - .Where(i => !i.Item3) - .ToList(); - - // But if that returns empty, keep those first episodes (avoid completely empty view) - if (withoutFirstEpisode.Count > 0) - { - allNextUp = withoutFirstEpisode; - } - } - - return allNextUp - .Select(i => i.Item1) - .Take(request.Limit ?? int.MaxValue); - } - - private string GetUniqueSeriesKey(BaseItem series) - { - if (_config.Configuration.SchemaVersion < 97) - { - return series.Id.ToString("N"); - } - return series.GetPresentationUniqueKey(); - } - - /// <summary> - /// Gets the next up. - /// </summary> - /// <param name="series">The series.</param> - /// <param name="user">The user.</param> - /// <returns>Task{Episode}.</returns> - private Tuple<Episode, DateTime, bool> GetNextUp(Series series, User user) - { - var lastWatchedEpisode = _libraryManager.GetItemList(new InternalItemsQuery(user) - { - AncestorWithPresentationUniqueKey = GetUniqueSeriesKey(series), - IncludeItemTypes = new[] { typeof(Episode).Name }, - SortBy = new[] { ItemSortBy.SortName }, - SortOrder = SortOrder.Descending, - IsPlayed = true, - Limit = 1, - ParentIndexNumberNotEquals = 0 - - }).FirstOrDefault(); - - var firstUnwatchedEpisode = _libraryManager.GetItemList(new InternalItemsQuery(user) - { - AncestorWithPresentationUniqueKey = GetUniqueSeriesKey(series), - IncludeItemTypes = new[] { typeof(Episode).Name }, - SortBy = new[] { ItemSortBy.SortName }, - SortOrder = SortOrder.Ascending, - Limit = 1, - IsPlayed = false, - IsVirtualItem = false, - ParentIndexNumberNotEquals = 0, - MinSortName = lastWatchedEpisode == null ? null : lastWatchedEpisode.SortName - - }).Cast<Episode>().FirstOrDefault(); - - if (lastWatchedEpisode != null && firstUnwatchedEpisode != null) - { - var userData = _userDataManager.GetUserData(user, lastWatchedEpisode); - - var lastWatchedDate = userData.LastPlayedDate ?? DateTime.MinValue.AddDays(1); - - return new Tuple<Episode, DateTime, bool>(firstUnwatchedEpisode, lastWatchedDate, false); - } - - // Return the first episode - return new Tuple<Episode, DateTime, bool>(firstUnwatchedEpisode, DateTime.MinValue, true); - } - - private QueryResult<BaseItem> GetResult(IEnumerable<BaseItem> items, int? totalRecordLimit, NextUpQuery query) - { - var itemsArray = totalRecordLimit.HasValue ? items.Take(totalRecordLimit.Value).ToArray() : items.ToArray(); - var totalCount = itemsArray.Length; - - if (query.Limit.HasValue) - { - itemsArray = itemsArray.Skip(query.StartIndex ?? 0).Take(query.Limit.Value).ToArray(); - } - else if (query.StartIndex.HasValue) - { - itemsArray = itemsArray.Skip(query.StartIndex.Value).ToArray(); - } - - return new QueryResult<BaseItem> - { - TotalRecordCount = totalCount, - Items = itemsArray - }; - } - } -} diff --git a/MediaBrowser.Server.Implementations/UserViews/CollectionFolderImageProvider.cs b/MediaBrowser.Server.Implementations/UserViews/CollectionFolderImageProvider.cs deleted file mode 100644 index 33a7b6725..000000000 --- a/MediaBrowser.Server.Implementations/UserViews/CollectionFolderImageProvider.cs +++ /dev/null @@ -1,176 +0,0 @@ -using MediaBrowser.Common.Configuration; -using MediaBrowser.Controller.Drawing; -using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Entities.Audio; -using MediaBrowser.Controller.Entities.TV; -using MediaBrowser.Controller.Providers; -using MediaBrowser.Model.Entities; -using MediaBrowser.Server.Implementations.Photos; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading.Tasks; -using MediaBrowser.Common.IO; -using MediaBrowser.Model.IO; -using MediaBrowser.Controller.Collections; -using MediaBrowser.Controller.Entities.Movies; -using MediaBrowser.Controller.IO; -using MediaBrowser.Controller.Library; -using MediaBrowser.Model.Extensions; -using MediaBrowser.Model.Querying; - -namespace MediaBrowser.Server.Implementations.UserViews -{ - public class CollectionFolderImageProvider : BaseDynamicImageProvider<CollectionFolder> - { - public CollectionFolderImageProvider(IFileSystem fileSystem, IProviderManager providerManager, IApplicationPaths applicationPaths, IImageProcessor imageProcessor) : base(fileSystem, providerManager, applicationPaths, imageProcessor) - { - } - - public override IEnumerable<ImageType> GetSupportedImages(IHasImages item) - { - return new List<ImageType> - { - ImageType.Primary - }; - } - - protected override async Task<List<BaseItem>> GetItemsWithImages(IHasImages item) - { - var view = (CollectionFolder)item; - - var recursive = !new[] { CollectionType.Playlists, CollectionType.Channels }.Contains(view.CollectionType ?? string.Empty, StringComparer.OrdinalIgnoreCase); - - var result = await view.GetItems(new InternalItemsQuery - { - CollapseBoxSetItems = false, - Recursive = recursive, - ExcludeItemTypes = new[] { "UserView", "CollectionFolder", "Playlist" } - - }).ConfigureAwait(false); - - var items = result.Items.Select(i => - { - var episode = i as Episode; - if (episode != null) - { - var series = episode.Series; - if (series != null) - { - return series; - } - - return episode; - } - - var season = i as Season; - if (season != null) - { - var series = season.Series; - if (series != null) - { - return series; - } - - return season; - } - - var audio = i as Audio; - if (audio != null) - { - var album = audio.AlbumEntity; - if (album != null && album.HasImage(ImageType.Primary)) - { - return album; - } - } - - return i; - - }).DistinctBy(i => i.Id); - - return GetFinalItems(items.Where(i => i.HasImage(ImageType.Primary) || i.HasImage(ImageType.Thumb)).ToList(), 8); - } - - protected override bool Supports(IHasImages item) - { - return item is CollectionFolder; - } - - protected override async Task<string> CreateImage(IHasImages item, List<BaseItem> itemsWithImages, string outputPathWithoutExtension, ImageType imageType, int imageIndex) - { - var outputPath = Path.ChangeExtension(outputPathWithoutExtension, ".png"); - - if (imageType == ImageType.Primary) - { - if (itemsWithImages.Count == 0) - { - return null; - } - - return await CreateThumbCollage(item, itemsWithImages, outputPath, 960, 540).ConfigureAwait(false); - } - - return await base.CreateImage(item, itemsWithImages, outputPath, imageType, imageIndex).ConfigureAwait(false); - } - } - - public class ManualCollectionFolderImageProvider : BaseDynamicImageProvider<ManualCollectionsFolder> - { - private readonly ILibraryManager _libraryManager; - - public ManualCollectionFolderImageProvider(IFileSystem fileSystem, IProviderManager providerManager, IApplicationPaths applicationPaths, IImageProcessor imageProcessor, ILibraryManager libraryManager) : base(fileSystem, providerManager, applicationPaths, imageProcessor) - { - _libraryManager = libraryManager; - } - - public override IEnumerable<ImageType> GetSupportedImages(IHasImages item) - { - return new List<ImageType> - { - ImageType.Primary - }; - } - - protected override async Task<List<BaseItem>> GetItemsWithImages(IHasImages item) - { - var view = (ManualCollectionsFolder)item; - - var recursive = !new[] { CollectionType.Playlists, CollectionType.Channels }.Contains(view.CollectionType ?? string.Empty, StringComparer.OrdinalIgnoreCase); - - var items = _libraryManager.GetItemList(new InternalItemsQuery - { - Recursive = recursive, - IncludeItemTypes = new[] { typeof(BoxSet).Name }, - Limit = 20, - SortBy = new[] { ItemSortBy.Random } - }); - - return GetFinalItems(items.Where(i => i.HasImage(ImageType.Primary) || i.HasImage(ImageType.Thumb)).ToList(), 8); - } - - protected override bool Supports(IHasImages item) - { - return item is ManualCollectionsFolder; - } - - protected override async Task<string> CreateImage(IHasImages item, List<BaseItem> itemsWithImages, string outputPathWithoutExtension, ImageType imageType, int imageIndex) - { - var outputPath = Path.ChangeExtension(outputPathWithoutExtension, ".png"); - - if (imageType == ImageType.Primary) - { - if (itemsWithImages.Count == 0) - { - return null; - } - - return await CreateThumbCollage(item, itemsWithImages, outputPath, 960, 540).ConfigureAwait(false); - } - - return await base.CreateImage(item, itemsWithImages, outputPath, imageType, imageIndex).ConfigureAwait(false); - } - } - -} diff --git a/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs b/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs deleted file mode 100644 index 61f3c77f0..000000000 --- a/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs +++ /dev/null @@ -1,190 +0,0 @@ -using MediaBrowser.Common.Configuration; -using MediaBrowser.Controller.Drawing; -using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Entities.Audio; -using MediaBrowser.Controller.Entities.TV; -using MediaBrowser.Controller.Library; -using MediaBrowser.Controller.Providers; -using MediaBrowser.Model.Entities; -using MediaBrowser.Server.Implementations.Photos; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading.Tasks; -using MediaBrowser.Common.IO; -using MediaBrowser.Controller.IO; -using MediaBrowser.Model.IO; -using MediaBrowser.Controller.LiveTv; -using MediaBrowser.Model.Extensions; - -namespace MediaBrowser.Server.Implementations.UserViews -{ - public class DynamicImageProvider : BaseDynamicImageProvider<UserView> - { - private readonly IUserManager _userManager; - private readonly ILibraryManager _libraryManager; - - public DynamicImageProvider(IFileSystem fileSystem, IProviderManager providerManager, IApplicationPaths applicationPaths, IImageProcessor imageProcessor, IUserManager userManager, ILibraryManager libraryManager) - : base(fileSystem, providerManager, applicationPaths, imageProcessor) - { - _userManager = userManager; - _libraryManager = libraryManager; - } - - public override IEnumerable<ImageType> GetSupportedImages(IHasImages item) - { - var view = (UserView)item; - if (IsUsingCollectionStrip(view)) - { - return new List<ImageType> - { - ImageType.Primary - }; - } - - return new List<ImageType> - { - ImageType.Primary - }; - } - - protected override async Task<List<BaseItem>> GetItemsWithImages(IHasImages item) - { - var view = (UserView)item; - - if (string.Equals(view.ViewType, CollectionType.LiveTv, StringComparison.OrdinalIgnoreCase)) - { - var programs = _libraryManager.GetItemList(new InternalItemsQuery - { - IncludeItemTypes = new[] { typeof(LiveTvProgram).Name }, - ImageTypes = new[] { ImageType.Primary }, - Limit = 30, - IsMovie = true - }).ToList(); - - return GetFinalItems(programs).ToList(); - } - - if (string.Equals(view.ViewType, SpecialFolder.MovieGenre, StringComparison.OrdinalIgnoreCase) || - string.Equals(view.ViewType, SpecialFolder.TvGenre, StringComparison.OrdinalIgnoreCase)) - { - var userItemsResult = await view.GetItems(new InternalItemsQuery - { - CollapseBoxSetItems = false - }); - - return userItemsResult.Items.ToList(); - } - - var isUsingCollectionStrip = IsUsingCollectionStrip(view); - var recursive = isUsingCollectionStrip && !new[] { CollectionType.Channels, CollectionType.BoxSets, CollectionType.Playlists }.Contains(view.ViewType ?? string.Empty, StringComparer.OrdinalIgnoreCase); - - var result = await view.GetItems(new InternalItemsQuery - { - User = view.UserId.HasValue ? _userManager.GetUserById(view.UserId.Value) : null, - CollapseBoxSetItems = false, - Recursive = recursive, - ExcludeItemTypes = new[] { "UserView", "CollectionFolder", "Person" }, - - }).ConfigureAwait(false); - - var items = result.Items.Select(i => - { - var episode = i as Episode; - if (episode != null) - { - var series = episode.Series; - if (series != null) - { - return series; - } - - return episode; - } - - var season = i as Season; - if (season != null) - { - var series = season.Series; - if (series != null) - { - return series; - } - - return season; - } - - var audio = i as Audio; - if (audio != null) - { - var album = audio.AlbumEntity; - if (album != null && album.HasImage(ImageType.Primary)) - { - return album; - } - } - - return i; - - }).DistinctBy(i => i.Id); - - if (isUsingCollectionStrip) - { - return GetFinalItems(items.Where(i => i.HasImage(ImageType.Primary) || i.HasImage(ImageType.Thumb)).ToList(), 8); - } - - return GetFinalItems(items.Where(i => i.HasImage(ImageType.Primary)).ToList()); - } - - protected override bool Supports(IHasImages item) - { - var view = item as UserView; - if (view != null) - { - return IsUsingCollectionStrip(view); - } - - return false; - } - - private bool IsUsingCollectionStrip(UserView view) - { - string[] collectionStripViewTypes = - { - CollectionType.Movies, - CollectionType.TvShows, - CollectionType.Music, - CollectionType.Games, - CollectionType.Books, - CollectionType.MusicVideos, - CollectionType.HomeVideos, - CollectionType.BoxSets, - CollectionType.LiveTv, - CollectionType.Playlists, - CollectionType.Photos, - string.Empty - }; - - return collectionStripViewTypes.Contains(view.ViewType ?? string.Empty); - } - - protected override async Task<string> CreateImage(IHasImages item, List<BaseItem> itemsWithImages, string outputPathWithoutExtension, ImageType imageType, int imageIndex) - { - var outputPath = Path.ChangeExtension(outputPathWithoutExtension, ".png"); - - var view = (UserView)item; - if (imageType == ImageType.Primary && IsUsingCollectionStrip(view)) - { - if (itemsWithImages.Count == 0) - { - return null; - } - - return await CreateThumbCollage(item, itemsWithImages, outputPath, 960, 540).ConfigureAwait(false); - } - - return await base.CreateImage(item, itemsWithImages, outputPath, imageType, imageIndex).ConfigureAwait(false); - } - } -} |
