aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Server.Implementations
diff options
context:
space:
mode:
authorLuke Pulverenti <luke.pulverenti@gmail.com>2016-11-03 03:14:14 -0400
committerLuke Pulverenti <luke.pulverenti@gmail.com>2016-11-03 03:14:14 -0400
commitb76a1abda578b8ff64bad2997b036b0fc43e264f (patch)
tree7b73000abcf71e90c290b6107525969cb904ed2d /MediaBrowser.Server.Implementations
parent3eb4091808735858b01855d298226d239be464af (diff)
move classes to portable server lib
Diffstat (limited to 'MediaBrowser.Server.Implementations')
-rw-r--r--MediaBrowser.Server.Implementations/Collections/CollectionImageProvider.cs86
-rw-r--r--MediaBrowser.Server.Implementations/Devices/DeviceManager.cs306
-rw-r--r--MediaBrowser.Server.Implementations/EntryPoints/ActivityLogEntryPoint.cs561
-rw-r--r--MediaBrowser.Server.Implementations/EntryPoints/Notifications/Notifications.cs544
-rw-r--r--MediaBrowser.Server.Implementations/EntryPoints/Notifications/WebSocketNotifier.cs54
-rw-r--r--MediaBrowser.Server.Implementations/Library/UserDataManager.cs287
-rw-r--r--MediaBrowser.Server.Implementations/Library/UserManager.cs1021
-rw-r--r--MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj13
-rw-r--r--MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs361
-rw-r--r--MediaBrowser.Server.Implementations/Photos/PhotoAlbumImageProvider.cs35
-rw-r--r--MediaBrowser.Server.Implementations/Playlists/PlaylistImageProvider.cs104
-rw-r--r--MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs226
-rw-r--r--MediaBrowser.Server.Implementations/UserViews/CollectionFolderImageProvider.cs176
-rw-r--r--MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs190
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);
- }
- }
-}