diff --git a/BDInfo/BDInfo.csproj b/BDInfo/BDInfo.csproj index 8c0404c4de..a8f5060e69 100644 --- a/BDInfo/BDInfo.csproj +++ b/BDInfo/BDInfo.csproj @@ -34,10 +34,10 @@ - ..\packages\MediaBrowser.Common.3.3.50-beta\lib\netstandard2.0\MediaBrowser.Common.dll + ..\packages\MediaBrowser.Common.3.3.53-beta\lib\netstandard2.0\MediaBrowser.Common.dll - ..\packages\MediaBrowser.Common.3.3.50-beta\lib\netstandard2.0\MediaBrowser.Model.dll + ..\packages\MediaBrowser.Common.3.3.53-beta\lib\netstandard2.0\MediaBrowser.Model.dll diff --git a/BDInfo/packages.config b/BDInfo/packages.config index 76aa4bb8c7..85e552f7ee 100644 --- a/BDInfo/packages.config +++ b/BDInfo/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/DvdLib/DvdLib.csproj b/DvdLib/DvdLib.csproj index 91fb09c058..ea1b43767a 100644 --- a/DvdLib/DvdLib.csproj +++ b/DvdLib/DvdLib.csproj @@ -49,10 +49,10 @@ - ..\packages\MediaBrowser.Common.3.3.50-beta\lib\netstandard2.0\MediaBrowser.Common.dll + ..\packages\MediaBrowser.Common.3.3.53-beta\lib\netstandard2.0\MediaBrowser.Common.dll - ..\packages\MediaBrowser.Common.3.3.50-beta\lib\netstandard2.0\MediaBrowser.Model.dll + ..\packages\MediaBrowser.Common.3.3.53-beta\lib\netstandard2.0\MediaBrowser.Model.dll diff --git a/DvdLib/packages.config b/DvdLib/packages.config index 76aa4bb8c7..85e552f7ee 100644 --- a/DvdLib/packages.config +++ b/DvdLib/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/Emby.Dlna/Emby.Dlna.csproj b/Emby.Dlna/Emby.Dlna.csproj index 3bac21a93b..33d2c31aad 100644 --- a/Emby.Dlna/Emby.Dlna.csproj +++ b/Emby.Dlna/Emby.Dlna.csproj @@ -174,19 +174,19 @@ - ..\packages\MediaBrowser.Common.3.3.50-beta\lib\netstandard2.0\MediaBrowser.Common.dll + ..\packages\MediaBrowser.Common.3.3.53-beta\lib\netstandard2.0\MediaBrowser.Common.dll - ..\packages\MediaBrowser.Server.Core.3.3.50-beta\lib\netstandard2.0\MediaBrowser.Controller.dll + ..\packages\MediaBrowser.Server.Core.3.3.53-beta\lib\netstandard2.0\MediaBrowser.Controller.dll - ..\packages\MediaBrowser.Common.3.3.50-beta\lib\netstandard2.0\MediaBrowser.Model.dll + ..\packages\MediaBrowser.Common.3.3.53-beta\lib\netstandard2.0\MediaBrowser.Model.dll - ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll + ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.1\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll diff --git a/Emby.Dlna/packages.config b/Emby.Dlna/packages.config index d7821eae0f..b5355baf69 100644 --- a/Emby.Dlna/packages.config +++ b/Emby.Dlna/packages.config @@ -1,6 +1,6 @@  - - - + + + \ No newline at end of file diff --git a/Emby.Drawing.ImageMagick/Emby.Drawing.ImageMagick.csproj b/Emby.Drawing.ImageMagick/Emby.Drawing.ImageMagick.csproj index f674e9945a..3e0583e5bb 100644 --- a/Emby.Drawing.ImageMagick/Emby.Drawing.ImageMagick.csproj +++ b/Emby.Drawing.ImageMagick/Emby.Drawing.ImageMagick.csproj @@ -35,13 +35,13 @@ ..\packages\ImageMagickSharp.1.0.0.19\lib\net45\ImageMagickSharp.dll - ..\packages\MediaBrowser.Common.3.3.50-beta\lib\netstandard2.0\MediaBrowser.Common.dll + ..\packages\MediaBrowser.Common.3.3.53-beta\lib\netstandard2.0\MediaBrowser.Common.dll - ..\packages\MediaBrowser.Server.Core.3.3.50-beta\lib\netstandard2.0\MediaBrowser.Controller.dll + ..\packages\MediaBrowser.Server.Core.3.3.53-beta\lib\netstandard2.0\MediaBrowser.Controller.dll - ..\packages\MediaBrowser.Common.3.3.50-beta\lib\netstandard2.0\MediaBrowser.Model.dll + ..\packages\MediaBrowser.Common.3.3.53-beta\lib\netstandard2.0\MediaBrowser.Model.dll diff --git a/Emby.Drawing.ImageMagick/packages.config b/Emby.Drawing.ImageMagick/packages.config index 57284567b2..46dca35426 100644 --- a/Emby.Drawing.ImageMagick/packages.config +++ b/Emby.Drawing.ImageMagick/packages.config @@ -1,6 +1,6 @@  - - + + \ No newline at end of file diff --git a/Emby.Drawing.Skia/Emby.Drawing.Skia.csproj b/Emby.Drawing.Skia/Emby.Drawing.Skia.csproj index 9af5d94331..864e8f1844 100644 --- a/Emby.Drawing.Skia/Emby.Drawing.Skia.csproj +++ b/Emby.Drawing.Skia/Emby.Drawing.Skia.csproj @@ -43,13 +43,13 @@ - ..\packages\MediaBrowser.Common.3.3.50-beta\lib\netstandard2.0\MediaBrowser.Common.dll + ..\packages\MediaBrowser.Common.3.3.53-beta\lib\netstandard2.0\MediaBrowser.Common.dll - ..\packages\MediaBrowser.Server.Core.3.3.50-beta\lib\netstandard2.0\MediaBrowser.Controller.dll + ..\packages\MediaBrowser.Server.Core.3.3.53-beta\lib\netstandard2.0\MediaBrowser.Controller.dll - ..\packages\MediaBrowser.Common.3.3.50-beta\lib\netstandard2.0\MediaBrowser.Model.dll + ..\packages\MediaBrowser.Common.3.3.53-beta\lib\netstandard2.0\MediaBrowser.Model.dll diff --git a/Emby.Drawing.Skia/packages.config b/Emby.Drawing.Skia/packages.config index 272298aec8..9756e911d7 100644 --- a/Emby.Drawing.Skia/packages.config +++ b/Emby.Drawing.Skia/packages.config @@ -1,6 +1,6 @@  - - + + \ No newline at end of file diff --git a/Emby.Drawing/Emby.Drawing.csproj b/Emby.Drawing/Emby.Drawing.csproj index 4b5d7dde4f..725e8d28c8 100644 --- a/Emby.Drawing/Emby.Drawing.csproj +++ b/Emby.Drawing/Emby.Drawing.csproj @@ -41,13 +41,13 @@ - ..\packages\MediaBrowser.Common.3.3.50-beta\lib\netstandard2.0\MediaBrowser.Common.dll + ..\packages\MediaBrowser.Common.3.3.53-beta\lib\netstandard2.0\MediaBrowser.Common.dll - ..\packages\MediaBrowser.Server.Core.3.3.50-beta\lib\netstandard2.0\MediaBrowser.Controller.dll + ..\packages\MediaBrowser.Server.Core.3.3.53-beta\lib\netstandard2.0\MediaBrowser.Controller.dll - ..\packages\MediaBrowser.Common.3.3.50-beta\lib\netstandard2.0\MediaBrowser.Model.dll + ..\packages\MediaBrowser.Common.3.3.53-beta\lib\netstandard2.0\MediaBrowser.Model.dll diff --git a/Emby.Drawing/packages.config b/Emby.Drawing/packages.config index 1c4aaf7ddf..c26580a70a 100644 --- a/Emby.Drawing/packages.config +++ b/Emby.Drawing/packages.config @@ -1,5 +1,5 @@  - - + + \ No newline at end of file diff --git a/Emby.Photos/Emby.Photos.csproj b/Emby.Photos/Emby.Photos.csproj index 92201bfc37..05be07fa92 100644 --- a/Emby.Photos/Emby.Photos.csproj +++ b/Emby.Photos/Emby.Photos.csproj @@ -32,13 +32,13 @@ - ..\packages\MediaBrowser.Common.3.3.50-beta\lib\netstandard2.0\MediaBrowser.Common.dll + ..\packages\MediaBrowser.Common.3.3.53-beta\lib\netstandard2.0\MediaBrowser.Common.dll - ..\packages\MediaBrowser.Server.Core.3.3.50-beta\lib\netstandard2.0\MediaBrowser.Controller.dll + ..\packages\MediaBrowser.Server.Core.3.3.53-beta\lib\netstandard2.0\MediaBrowser.Controller.dll - ..\packages\MediaBrowser.Common.3.3.50-beta\lib\netstandard2.0\MediaBrowser.Model.dll + ..\packages\MediaBrowser.Common.3.3.53-beta\lib\netstandard2.0\MediaBrowser.Model.dll ..\ThirdParty\taglib\TagLib.Portable.dll diff --git a/Emby.Photos/packages.config b/Emby.Photos/packages.config index 1c4aaf7ddf..c26580a70a 100644 --- a/Emby.Photos/packages.config +++ b/Emby.Photos/packages.config @@ -1,5 +1,5 @@  - - + + \ No newline at end of file diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 8bd4a6e485..8cdcc9c6b5 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -1008,7 +1008,7 @@ protected void RegisterResources() var deviceRepo = new SqliteDeviceRepository(LogManager.GetLogger("DeviceManager"), ServerConfigurationManager, FileSystemManager, JsonSerializer); deviceRepo.Initialize(); - DeviceManager = new DeviceManager(deviceRepo, LibraryManager, LocalizationManager, UserManager, FileSystemManager, LibraryMonitor, ServerConfigurationManager, LogManager.GetLogger("DeviceManager"), NetworkManager); + DeviceManager = new DeviceManager(AuthenticationRepository, deviceRepo, LibraryManager, LocalizationManager, UserManager, FileSystemManager, LibraryMonitor, ServerConfigurationManager, LogManager.GetLogger("DeviceManager"), NetworkManager); RegisterSingleInstance(deviceRepo); RegisterSingleInstance(DeviceManager); @@ -1065,7 +1065,7 @@ protected void RegisterResources() RegisterSingleInstance(activityLogRepo); RegisterSingleInstance(new ActivityManager(LogManager.GetLogger("ActivityManager"), activityLogRepo, UserManager)); - var authContext = new AuthorizationContext(AuthenticationRepository, ConnectManager); + var authContext = new AuthorizationContext(AuthenticationRepository, ConnectManager, UserManager); RegisterSingleInstance(authContext); RegisterSingleInstance(new SessionContext(UserManager, authContext, SessionManager)); @@ -1930,6 +1930,7 @@ private bool EnablePlugin(string path) "mbintros.dll", "embytv.dll", "Messenger.dll", + "Messages.dll", "MediaBrowser.Plugins.TvMazeProvider.dll", "MBBookshelf.dll", "MediaBrowser.Channels.Adult.YouJizz.dll", diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs index 4164463bab..00e3e65fc0 100644 --- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs @@ -221,7 +221,7 @@ var createMediaStreamsTableCommand AddColumn(db, "TypedBaseItems", "ProviderIds", "Text", existingColumnNames); AddColumn(db, "TypedBaseItems", "Images", "Text", existingColumnNames); AddColumn(db, "TypedBaseItems", "ProductionLocations", "Text", existingColumnNames); - AddColumn(db, "TypedBaseItems", "ThemeSongIds", "Text", existingColumnNames); + AddColumn(db, "TypedBaseItems", "ExtraIds", "Text", existingColumnNames); AddColumn(db, "TypedBaseItems", "TotalBitrate", "INT", existingColumnNames); AddColumn(db, "TypedBaseItems", "ExtraType", "Text", existingColumnNames); AddColumn(db, "TypedBaseItems", "Artists", "Text", existingColumnNames); @@ -404,7 +404,7 @@ var createMediaStreamsTableCommand "ProviderIds", "Images", "ProductionLocations", - "ThemeSongIds", + "ExtraIds", "TotalBitrate", "ExtraType", "Artists", @@ -522,7 +522,7 @@ private string GetSaveItemCommandText() "ProviderIds", "Images", "ProductionLocations", - "ThemeSongIds", + "ExtraIds", "TotalBitrate", "ExtraType", "Artists", @@ -1007,13 +1007,13 @@ private void SaveItem(BaseItem item, BaseItem topParent, string userDataKey, ISt saveItemStatement.TryBindNull("@ProductionLocations"); } - if (item.ThemeSongIds.Length > 0) + if (item.ExtraIds.Length > 0) { - saveItemStatement.TryBind("@ThemeSongIds", string.Join("|", item.ThemeSongIds.ToArray())); + saveItemStatement.TryBind("@ExtraIds", string.Join("|", item.ExtraIds.ToArray())); } else { - saveItemStatement.TryBindNull("@ThemeSongIds"); + saveItemStatement.TryBindNull("@ExtraIds"); } saveItemStatement.TryBind("@TotalBitrate", item.TotalBitrate); @@ -1864,11 +1864,11 @@ private BaseItem GetItem(IReadOnlyList reader, InternalItemsQue index++; } - if (HasField(query, ItemFields.ThemeSongIds)) + if (HasField(query, ItemFields.ExtraIds)) { if (!reader.IsDBNull(index)) { - item.ThemeSongIds = SplitToGuids(reader.GetString(index)); + item.ExtraIds = SplitToGuids(reader.GetString(index)); } index++; } @@ -2230,7 +2230,7 @@ private bool HasField(InternalItemsQuery query, ItemFields name) case ItemFields.Taglines: case ItemFields.SortName: case ItemFields.Studios: - case ItemFields.ThemeSongIds: + case ItemFields.ExtraIds: case ItemFields.DateCreated: case ItemFields.Overview: case ItemFields.Genres: @@ -2534,11 +2534,7 @@ private string[] GetFinalColumnsToSelect(InternalItemsQuery query, string[] star if (query.IncludeItemTypes.Length == 0 || query.IncludeItemTypes.Contains(typeof(Trailer).Name)) { - var hasTrailers = item as IHasTrailers; - if (hasTrailers != null) - { - excludeIds.AddRange(hasTrailers.GetTrailerIds()); - } + excludeIds.AddRange(item.ExtraIds); } query.ExcludeItemIds = excludeIds.ToArray(excludeIds.Count); @@ -3436,12 +3432,42 @@ private List GetWhereClauses(InternalItemsQuery query, IStatement statem { //whereClauses.Add("(UserId is null or UserId=@UserId)"); } - if (query.MinWidth.HasValue) + + var minWidth = query.MinWidth; + var maxWidth = query.MaxWidth; + + if (query.IsHD.HasValue) + { + var threshold = 1200; + if (query.IsHD.Value) + { + minWidth = threshold; + } + else + { + maxWidth = threshold - 1; + } + } + + if (query.Is4K.HasValue) + { + var threshold = 3800; + if (query.Is4K.Value) + { + minWidth = threshold; + } + else + { + maxWidth = threshold - 1; + } + } + + if (minWidth.HasValue) { whereClauses.Add("Width>=@MinWidth"); if (statement != null) { - statement.TryBind("@MinWidth", query.MinWidth); + statement.TryBind("@MinWidth", minWidth); } } if (query.MinHeight.HasValue) @@ -3452,12 +3478,12 @@ private List GetWhereClauses(InternalItemsQuery query, IStatement statem statement.TryBind("@MinHeight", query.MinHeight); } } - if (query.MaxWidth.HasValue) + if (maxWidth.HasValue) { whereClauses.Add("Width<=@MaxWidth"); if (statement != null) { - statement.TryBind("@MaxWidth", query.MaxWidth); + statement.TryBind("@MaxWidth", maxWidth); } } if (query.MaxHeight.HasValue) @@ -4079,6 +4105,25 @@ private List GetWhereClauses(InternalItemsQuery query, IStatement statem whereClauses.Add(clause); } + if (query.AlbumArtistIds.Length > 0) + { + var clauses = new List(); + var index = 0; + foreach (var artistId in query.AlbumArtistIds) + { + var paramName = "@ArtistIds" + index; + + clauses.Add("(select CleanName from TypedBaseItems where guid=" + paramName + ") in (select CleanValue from itemvalues where ItemId=Guid and Type=1)"); + if (statement != null) + { + statement.TryBind(paramName, artistId.ToGuidBlob()); + } + index++; + } + var clause = "(" + string.Join(" OR ", clauses.ToArray()) + ")"; + whereClauses.Add(clause); + } + if (query.AlbumIds.Length > 0) { var clauses = new List(); @@ -4253,6 +4298,18 @@ private List GetWhereClauses(InternalItemsQuery query, IStatement statem } } + if (query.HasOfficialRating.HasValue) + { + if (query.HasOfficialRating.Value) + { + whereClauses.Add("(OfficialRating not null AND OfficialRating<>'')"); + } + else + { + whereClauses.Add("(OfficialRating is null OR OfficialRating='')"); + } + } + if (query.HasOverview.HasValue) { if (query.HasOverview.Value) @@ -4265,6 +4322,18 @@ private List GetWhereClauses(InternalItemsQuery query, IStatement statem } } + if (query.HasOwnerId.HasValue) + { + if (query.HasOwnerId.Value) + { + whereClauses.Add("OwnerId not null"); + } + else + { + whereClauses.Add("OwnerId is null"); + } + } + if (!string.IsNullOrWhiteSpace(query.HasNoAudioTrackWithLanguage)) { whereClauses.Add("((select language from MediaStreams where MediaStreams.ItemId=A.Guid and MediaStreams.StreamType='Audio' and MediaStreams.Language=@HasNoAudioTrackWithLanguage limit 1) is null)"); @@ -4301,6 +4370,18 @@ private List GetWhereClauses(InternalItemsQuery query, IStatement statem } } + if (query.HasSubtitles.HasValue) + { + if (query.HasSubtitles.Value) + { + whereClauses.Add("((select type from MediaStreams where MediaStreams.ItemId=A.Guid and MediaStreams.StreamType='Subtitle' limit 1) not null)"); + } + else + { + whereClauses.Add("((select type from MediaStreams where MediaStreams.ItemId=A.Guid and MediaStreams.StreamType='Subtitle' limit 1) is null)"); + } + } + if (query.HasChapterImages.HasValue) { if (query.HasChapterImages.Value) @@ -4453,7 +4534,40 @@ private List GetWhereClauses(InternalItemsQuery query, IStatement statem break; } - whereClauses.Add(string.Join(" AND ", excludeIds.ToArray())); + if (excludeIds.Count > 0) + { + whereClauses.Add(string.Join(" AND ", excludeIds.ToArray())); + } + } + + if (query.HasAnyProviderId.Count > 0) + { + var hasProviderIds = new List(); + + var index = 0; + foreach (var pair in query.HasAnyProviderId) + { + if (string.Equals(pair.Key, MetadataProviders.TmdbCollection.ToString(), StringComparison.OrdinalIgnoreCase)) + { + continue; + } + + var paramName = "@HasAnyProviderId" + index; + //hasProviderIds.Add("(COALESCE((select value from ProviderIds where ItemId=Guid and Name = '" + pair.Key + "'), '') <> " + paramName + ")"); + hasProviderIds.Add("ProviderIds like " + paramName + ""); + if (statement != null) + { + statement.TryBind(paramName, "%" + pair.Key + "=" + pair.Value + "%"); + } + index++; + + break; + } + + if (hasProviderIds.Count > 0) + { + whereClauses.Add("(" + string.Join(" OR ", hasProviderIds.ToArray()) + ")"); + } } if (query.HasImdbId.HasValue) @@ -4470,17 +4584,6 @@ private List GetWhereClauses(InternalItemsQuery query, IStatement statem { whereClauses.Add("ProviderIds like '%tvdb=%'"); } - if (query.HasThemeSong.HasValue) - { - if (query.HasThemeSong.Value) - { - whereClauses.Add("ThemeSongIds not null"); - } - else - { - whereClauses.Add("ThemeSongIds is null"); - } - } var includedItemByNameTypes = GetItemByNameTypesInQuery(query).SelectMany(MapIncludeItemTypes).ToList(); var enableItemsByName = (query.IncludeItemsByName ?? false) && includedItemByNameTypes.Count > 0; @@ -4590,6 +4693,102 @@ private List GetWhereClauses(InternalItemsQuery query, IStatement statem whereClauses.Add("((select CleanValue from itemvalues where ItemId=Guid and Type=6 and cleanvalue in (" + tagValuesList + ")) is null)"); } + if (query.SeriesStatuses.Length > 0) + { + var statuses = new List(); + + foreach (var seriesStatus in query.SeriesStatuses) + { + statuses.Add("data like '%" + seriesStatus + "%'"); + } + + whereClauses.Add("(" + string.Join(" OR ", statuses.ToArray()) + ")"); + } + + if (query.VideoTypes.Length > 0) + { + var videoTypes = new List(); + + foreach (var videoType in query.VideoTypes) + { + videoTypes.Add("data like '%" + videoType + "%'"); + } + + whereClauses.Add("(" + string.Join(" OR ", videoTypes.ToArray()) + ")"); + } + + if (query.Is3D.HasValue) + { + if (query.Is3D.Value) + { + whereClauses.Add("data like '%Video3DFormat%'"); + } + else + { + whereClauses.Add("data not like '%Video3DFormat%'"); + } + } + + if (query.IsPlaceHolder.HasValue) + { + if (query.IsPlaceHolder.Value) + { + whereClauses.Add("data like '\"IsPlaceHolder\":true"); + } + else + { + whereClauses.Add("data not like '\"IsPlaceHolder\":true"); + } + } + + if (query.HasSpecialFeature.HasValue) + { + if (query.HasSpecialFeature.Value) + { + whereClauses.Add("(data not like '%\"ExtraIds\":[]%' and data like '%ExtraIds%')"); + } + else + { + whereClauses.Add("(data like '%\"ExtraIds\":[]%' or data not like '%ExtraIds%')"); + } + } + + if (query.HasTrailer.HasValue) + { + if (query.HasTrailer.Value) + { + whereClauses.Add("((data not like '%\"LocalTrailerIds\":[]%' and data like '%LocalTrailerIds%') or (data not like '%\"RemoteTrailerIds\":[]%' and data like '%RemoteTrailerIds%') or (data not like '%\"RemoteTrailers\":[]%' and data like '%RemoteTrailers%'))"); + } + else + { + whereClauses.Add("((data like '%\"LocalTrailerIds\":[]%' or data not like '%LocalTrailerIds%') and (data like '%\"RemoteTrailerIds\":[]%' or data not like '%RemoteTrailerIds%') and (data like '%\"RemoteTrailers\":[]%' or data not like '%RemoteTrailers%'))"); + } + } + + if (query.HasThemeSong.HasValue) + { + if (query.HasThemeSong.Value) + { + whereClauses.Add("(data not like '%\"ExtraIds\":[]%' and data like '%ExtraIds%')"); + } + else + { + whereClauses.Add("(data like '%\"ExtraIds\":[]%' or data not like '%ExtraIds%')"); + } + } + + if (query.HasThemeVideo.HasValue) + { + if (query.HasThemeVideo.Value) + { + whereClauses.Add("(data not like '%\"ExtraIds\":[]%' and data like '%ExtraIds%')"); + } + else + { + whereClauses.Add("(data like '%\"ExtraIds\":[]%' or data not like '%ExtraIds%')"); + } + } + return whereClauses; } diff --git a/Emby.Server.Implementations/Devices/DeviceManager.cs b/Emby.Server.Implementations/Devices/DeviceManager.cs index 882ebc3b3a..93af05bdbb 100644 --- a/Emby.Server.Implementations/Devices/DeviceManager.cs +++ b/Emby.Server.Implementations/Devices/DeviceManager.cs @@ -23,6 +23,7 @@ using MediaBrowser.Model.Configuration; using MediaBrowser.Controller.Plugins; using MediaBrowser.Model.Globalization; +using MediaBrowser.Controller.Security; namespace Emby.Server.Implementations.Devices { @@ -38,14 +39,11 @@ public class DeviceManager : IDeviceManager private readonly ILibraryManager _libraryManager; private readonly ILocalizationManager _localizationManager; - public event EventHandler> CameraImageUploaded; + private readonly IAuthenticationRepository _authRepo; - /// - /// Occurs when [device options updated]. - /// - public event EventHandler> DeviceOptionsUpdated; + public event EventHandler> CameraImageUploaded; - public DeviceManager(IDeviceRepository repo, ILibraryManager libraryManager, ILocalizationManager localizationManager, IUserManager userManager, IFileSystem fileSystem, ILibraryMonitor libraryMonitor, IServerConfigurationManager config, ILogger logger, INetworkManager network) + public DeviceManager(IAuthenticationRepository authRepo, IDeviceRepository repo, ILibraryManager libraryManager, ILocalizationManager localizationManager, IUserManager userManager, IFileSystem fileSystem, ILibraryMonitor libraryMonitor, IServerConfigurationManager config, ILogger logger, INetworkManager network) { _repo = repo; _userManager = userManager; @@ -56,68 +54,7 @@ public DeviceManager(IDeviceRepository repo, ILibraryManager libraryManager, ILo _network = network; _libraryManager = libraryManager; _localizationManager = localizationManager; - } - - public DeviceInfo RegisterDevice(string reportedId, string name, string appName, string appVersion, string usedByUserId, string usedByUserName) - { - if (string.IsNullOrEmpty(reportedId)) - { - throw new ArgumentNullException("reportedId"); - } - - var save = false; - var device = GetDevice(reportedId); - - if (device == null) - { - device = new DeviceInfo - { - Id = reportedId - }; - save = true; - } - - if (!string.Equals(device.ReportedName, name, StringComparison.Ordinal)) - { - device.ReportedName = name; - save = true; - } - if (!string.Equals(device.AppName, appName, StringComparison.Ordinal)) - { - device.AppName = appName; - save = true; - } - if (!string.Equals(device.AppVersion, appVersion, StringComparison.Ordinal)) - { - device.AppVersion = appVersion; - save = true; - } - - if (!string.IsNullOrEmpty(usedByUserId)) - { - if (!string.Equals(device.LastUserId, usedByUserId, StringComparison.Ordinal) || - !string.Equals(device.LastUserName, usedByUserName, StringComparison.Ordinal)) - { - device.LastUserId = usedByUserId; - device.LastUserName = usedByUserName; - save = true; - } - } - - var displayName = string.IsNullOrWhiteSpace(device.CustomName) ? device.ReportedName : device.CustomName; - if (!string.Equals(device.Name, displayName, StringComparison.Ordinal)) - { - device.Name = displayName; - save = true; - } - - if (save) - { - device.DateLastModified = DateTime.UtcNow; - _repo.SaveDevice(device); - } - - return device; + _authRepo = authRepo; } public void SaveCapabilities(string reportedId, ClientCapabilities capabilities) @@ -127,44 +64,53 @@ public void SaveCapabilities(string reportedId, ClientCapabilities capabilities) public ClientCapabilities GetCapabilities(string reportedId) { - return _repo.GetCapabilities(reportedId); + return _repo.GetCapabilities(reportedId) ?? new ClientCapabilities(); } public DeviceInfo GetDevice(string id) { - return _repo.GetDevice(id); + return GetDevice(id, true); } - public QueryResult GetDevices(DeviceQuery query) + private DeviceInfo GetDevice(string id, bool includeCapabilities) { - IEnumerable devices = _repo.GetDevices(); + var session = _authRepo.Get(new AuthenticationInfoQuery + { + DeviceId = id - if (query.SupportsSync.HasValue) + }).Items.FirstOrDefault(); + + var device = session == null ? null : ToDeviceInfo(session); + + return device; + } + + public QueryResult GetDevices(DeviceQuery query) + { + var sessions = _authRepo.Get(new AuthenticationInfoQuery { - var val = query.SupportsSync.Value; + //UserId = query.UserId + IsActive = true, + HasUser = true - devices = devices.Where(i => i.Capabilities.SupportsSync == val); - } + }).Items; - if (query.SupportsPersistentIdentifier.HasValue) + if (query.SupportsSync.HasValue) { - var val = query.SupportsPersistentIdentifier.Value; + var val = query.SupportsSync.Value; - devices = devices.Where(i => - { - var deviceVal = i.Capabilities.SupportsPersistentIdentifier; - return deviceVal == val; - }); + sessions = sessions.Where(i => GetCapabilities(i.DeviceId).SupportsSync == val).ToArray(); } if (!query.UserId.Equals(Guid.Empty)) { var user = _userManager.GetUserById(query.UserId); - devices = devices.Where(i => CanAccessDevice(user, i.Id)); + sessions = sessions.Where(i => CanAccessDevice(user, i.DeviceId)).ToArray(); } - var array = devices.ToArray(); + var array = sessions.Select(ToDeviceInfo).ToArray(); + return new QueryResult { Items = array, @@ -172,9 +118,18 @@ public QueryResult GetDevices(DeviceQuery query) }; } - public void DeleteDevice(string id) + private DeviceInfo ToDeviceInfo(AuthenticationInfo authInfo) { - _repo.DeleteDevice(id); + return new DeviceInfo + { + AppName = authInfo.AppName, + AppVersion = authInfo.AppVersion, + Id = authInfo.DeviceId, + LastUserId = authInfo.UserId, + LastUserName = authInfo.UserName, + Name = authInfo.DeviceName, + DateLastActivity = authInfo.DateLastActivity + }; } public ContentUploadHistory GetCameraUploadHistory(string deviceId) @@ -184,7 +139,7 @@ public ContentUploadHistory GetCameraUploadHistory(string deviceId) public async Task AcceptCameraUpload(string deviceId, Stream stream, LocalFileInfo file) { - var device = GetDevice(deviceId); + var device = GetDevice(deviceId, false); var uploadPathInfo = GetUploadPath(device); var path = uploadPathInfo.Item1; @@ -264,11 +219,6 @@ internal Task EnsureLibraryFolder(string path, string name) private Tuple GetUploadPath(DeviceInfo device) { - if (!string.IsNullOrWhiteSpace(device.CameraUploadPath)) - { - return new Tuple(device.CameraUploadPath, device.CameraUploadPath, _fileSystem.GetDirectoryName(device.CameraUploadPath)); - } - var config = _config.GetUploadOptions(); var path = config.CameraUploadPath; @@ -305,20 +255,6 @@ private string DefaultCameraUploadsPath get { return Path.Combine(_config.CommonApplicationPaths.DataPath, "camerauploads"); } } - public void UpdateDeviceInfo(string id, DeviceOptions options) - { - var device = GetDevice(id); - - device.CustomName = options.CustomName; - device.CameraUploadPath = options.CameraUploadPath; - - device.Name = string.IsNullOrWhiteSpace(device.CustomName) ? device.ReportedName : device.CustomName; - - _repo.SaveDevice(device); - - EventHelper.FireEventIfNotNull(DeviceOptionsUpdated, this, new GenericEventArgs(device), _logger); - } - public bool CanAccessDevice(User user, string deviceId) { if (user == null) diff --git a/Emby.Server.Implementations/Devices/SqliteDeviceRepository.cs b/Emby.Server.Implementations/Devices/SqliteDeviceRepository.cs index d80b11d6f7..408c41a25b 100644 --- a/Emby.Server.Implementations/Devices/SqliteDeviceRepository.cs +++ b/Emby.Server.Implementations/Devices/SqliteDeviceRepository.cs @@ -22,10 +22,13 @@ public class SqliteDeviceRepository : BaseSqliteRepository, IDeviceRepository { private readonly CultureInfo _usCulture = new CultureInfo("en-US"); protected IFileSystem FileSystem { get; private set; } - private readonly object _syncLock = new object(); + private readonly object _cameraUploadSyncLock = new object(); + private readonly object _capabilitiesSyncLock = new object(); private readonly IJsonSerializer _json; private IServerApplicationPaths _appPaths; + private bool _enableDatabase; + public SqliteDeviceRepository(ILogger logger, IServerConfigurationManager config, IFileSystem fileSystem, IJsonSerializer json) : base(logger) { @@ -35,325 +38,108 @@ public SqliteDeviceRepository(ILogger logger, IServerConfigurationManager config FileSystem = fileSystem; _json = json; _appPaths = appPaths; + } public void Initialize() { - try - { - InitializeInternal(); - } - catch (Exception ex) - { - Logger.ErrorException("Error loading database file. Will reset and retry.", ex); + _enableDatabase = FileSystem.FileExists(DbFilePath); - FileSystem.DeleteFile(DbFilePath); - - InitializeInternal(); - } - } - - private void InitializeInternal() - { - using (var connection = CreateConnection()) + if (_enableDatabase) { - RunDefaultInitialization(connection); + try + { + using (var connection = CreateConnection()) + { + RunDefaultInitialization(connection); - string[] queries = { + string[] queries = { "create table if not exists Devices (Id TEXT PRIMARY KEY, Name TEXT NOT NULL, ReportedName TEXT NOT NULL, CustomName TEXT, CameraUploadPath TEXT, LastUserName TEXT, AppName TEXT NOT NULL, AppVersion TEXT NOT NULL, LastUserId TEXT, DateLastModified DATETIME NOT NULL, Capabilities TEXT NOT NULL)", "create index if not exists idx_id on Devices(Id)" }; - connection.RunQueries(queries); - - MigrateDevices(); - } - } - - private void MigrateDevices() - { - List files; - try - { - files = FileSystem - .GetFilePaths(GetDevicesPath(), true) - .Where(i => string.Equals(Path.GetFileName(i), "device.json", StringComparison.OrdinalIgnoreCase)) - .ToList(); - } - catch (IOException) - { - return; - } - - foreach (var file in files) - { - try - { - var device = _json.DeserializeFromFile(file); - - device.Name = string.IsNullOrWhiteSpace(device.CustomName) ? device.ReportedName : device.CustomName; - - SaveDevice(device); - } - catch (Exception ex) - { - Logger.ErrorException("Error reading {0}", ex, file); - } - finally - { - try - { - FileSystem.DeleteFile(file); - } - catch (IOException) - { - try - { - FileSystem.MoveFile(file, Path.ChangeExtension(file, ".old")); - } - catch (IOException) - { - } + connection.RunQueries(queries); } } - } - } - - private const string BaseSelectText = "select Id, Name, ReportedName, CustomName, CameraUploadPath, LastUserName, AppName, AppVersion, LastUserId, DateLastModified, Capabilities from Devices"; - - public void SaveCapabilities(string deviceId, ClientCapabilities capabilities) - { - using (WriteLock.Write()) - { - using (var connection = CreateConnection()) + catch (Exception ex) { - connection.RunInTransaction(db => - { - using (var statement = db.PrepareStatement("update devices set Capabilities=@Capabilities where Id=@Id")) - { - statement.TryBind("@Id", deviceId); + Logger.ErrorException("Error loading database file. Will reset and retry.", ex); - if (capabilities == null) - { - statement.TryBindNull("@Capabilities"); - } - else - { - statement.TryBind("@Capabilities", _json.SerializeToString(capabilities)); - } + FileSystem.DeleteFile(DbFilePath); - statement.MoveNext(); - } - }, TransactionMode); + _enableDatabase = false; } } } - public void SaveDevice(DeviceInfo entry) + public void SaveCapabilities(string deviceId, ClientCapabilities capabilities) { - if (entry == null) - { - throw new ArgumentNullException("entry"); - } + var path = Path.Combine(GetDevicePath(deviceId), "capabilities.json"); + FileSystem.CreateDirectory(FileSystem.GetDirectoryName(path)); - using (WriteLock.Write()) + lock (_capabilitiesSyncLock) { - using (var connection = CreateConnection()) - { - connection.RunInTransaction(db => - { - using (var statement = db.PrepareStatement("replace into Devices (Id, Name, ReportedName, CustomName, CameraUploadPath, LastUserName, AppName, AppVersion, LastUserId, DateLastModified, Capabilities) values (@Id, @Name, @ReportedName, @CustomName, @CameraUploadPath, @LastUserName, @AppName, @AppVersion, @LastUserId, @DateLastModified, @Capabilities)")) - { - statement.TryBind("@Id", entry.Id); - statement.TryBind("@Name", entry.Name); - statement.TryBind("@ReportedName", entry.ReportedName); - statement.TryBind("@CustomName", entry.CustomName); - statement.TryBind("@CameraUploadPath", entry.CameraUploadPath); - statement.TryBind("@LastUserId", entry.LastUserId); - statement.TryBind("@LastUserName", entry.LastUserName); - statement.TryBind("@AppName", entry.AppName); - statement.TryBind("@AppVersion", entry.AppVersion); - statement.TryBind("@DateLastModified", entry.DateLastModified); - - if (entry.Capabilities == null) - { - statement.TryBindNull("@Capabilities"); - } - else - { - statement.TryBind("@Capabilities", _json.SerializeToString(entry.Capabilities)); - } + _capabilitiesCache[deviceId] = capabilities; - statement.MoveNext(); - } - }, TransactionMode); - } + _json.SerializeToFile(capabilities, path); } } - public DeviceInfo GetDevice(string id) + private Dictionary _capabilitiesCache = new Dictionary(StringComparer.OrdinalIgnoreCase); + public ClientCapabilities GetCapabilities(string id) { - using (WriteLock.Read()) + lock (_capabilitiesSyncLock) { - using (var connection = CreateConnection(true)) + ClientCapabilities result; + if (_capabilitiesCache.TryGetValue(id, out result)) { - var statementTexts = new List(); - statementTexts.Add(BaseSelectText + " where Id=@Id"); - - return connection.RunInTransaction(db => - { - var statements = PrepareAllSafe(db, statementTexts).ToList(); - - using (var statement = statements[0]) - { - statement.TryBind("@Id", id); - - foreach (var row in statement.ExecuteQuery()) - { - return GetEntry(row); - } - } - - return null; - - }, ReadTransactionMode); + return result; } - } - } - public List GetDevices() - { - using (WriteLock.Read()) - { - using (var connection = CreateConnection(true)) + var path = Path.Combine(GetDevicePath(id), "capabilities.json"); + try + { + return _json.DeserializeFromFile(path); + } + catch { - var statementTexts = new List(); - statementTexts.Add(BaseSelectText + " order by DateLastModified desc"); - - return connection.RunInTransaction(db => - { - var list = new List(); - - var statements = PrepareAllSafe(db, statementTexts).ToList(); - - using (var statement = statements[0]) - { - foreach (var row in statement.ExecuteQuery()) - { - list.Add(GetEntry(row)); - } - } - - return list; - - }, ReadTransactionMode); } } - } - public ClientCapabilities GetCapabilities(string id) - { - using (WriteLock.Read()) + if (_enableDatabase) { - using (var connection = CreateConnection(true)) + using (WriteLock.Read()) { - var statementTexts = new List(); - statementTexts.Add("Select Capabilities from Devices where Id=@Id"); - - return connection.RunInTransaction(db => + using (var connection = CreateConnection(true)) { - var statements = PrepareAllSafe(db, statementTexts).ToList(); + var statementTexts = new List(); + statementTexts.Add("Select Capabilities from Devices where Id=@Id"); - using (var statement = statements[0]) + return connection.RunInTransaction(db => { - statement.TryBind("@Id", id); + var statements = PrepareAllSafe(db, statementTexts).ToList(); - foreach (var row in statement.ExecuteQuery()) + using (var statement = statements[0]) { - if (row[0].SQLiteType != SQLiteType.Null) + statement.TryBind("@Id", id); + + foreach (var row in statement.ExecuteQuery()) { - return _json.DeserializeFromString(row.GetString(0)); + if (row[0].SQLiteType != SQLiteType.Null) + { + return _json.DeserializeFromString(row.GetString(0)); + } } - } - } - return null; + return new ClientCapabilities(); + } - }, ReadTransactionMode); + }, ReadTransactionMode); + } } } - } - - private DeviceInfo GetEntry(IReadOnlyList reader) - { - var index = 0; - - var info = new DeviceInfo - { - Id = reader.GetString(index) - }; - - index++; - if (reader[index].SQLiteType != SQLiteType.Null) - { - info.Name = reader.GetString(index); - } - - index++; - if (reader[index].SQLiteType != SQLiteType.Null) - { - info.ReportedName = reader.GetString(index); - } - - index++; - if (reader[index].SQLiteType != SQLiteType.Null) - { - info.CustomName = reader.GetString(index); - } - - index++; - if (reader[index].SQLiteType != SQLiteType.Null) - { - info.CameraUploadPath = reader.GetString(index); - } - index++; - if (reader[index].SQLiteType != SQLiteType.Null) - { - info.LastUserName = reader.GetString(index); - } - - index++; - if (reader[index].SQLiteType != SQLiteType.Null) - { - info.AppName = reader.GetString(index); - } - - index++; - if (reader[index].SQLiteType != SQLiteType.Null) - { - info.AppVersion = reader.GetString(index); - } - - index++; - if (reader[index].SQLiteType != SQLiteType.Null) - { - info.LastUserId = reader.GetString(index); - } - - index++; - if (reader[index].SQLiteType != SQLiteType.Null) - { - info.DateLastModified = reader[index].ReadDateTime(); - } - - index++; - if (reader[index].SQLiteType != SQLiteType.Null) - { - info.Capabilities = _json.DeserializeFromString(reader.GetString(index)); - } - - return info; + return new ClientCapabilities(); } private string GetDevicesPath() @@ -370,7 +156,7 @@ public ContentUploadHistory GetCameraUploadHistory(string deviceId) { var path = Path.Combine(GetDevicePath(deviceId), "camerauploads.json"); - lock (_syncLock) + lock (_cameraUploadSyncLock) { try { @@ -391,7 +177,7 @@ public void AddCameraUpload(string deviceId, LocalFileInfo file) var path = Path.Combine(GetDevicePath(deviceId), "camerauploads.json"); FileSystem.CreateDirectory(FileSystem.GetDirectoryName(path)); - lock (_syncLock) + lock (_cameraUploadSyncLock) { ContentUploadHistory history; @@ -416,37 +202,5 @@ public void AddCameraUpload(string deviceId, LocalFileInfo file) _json.SerializeToFile(history, path); } } - - public void DeleteDevice(string id) - { - using (WriteLock.Write()) - { - using (var connection = CreateConnection()) - { - connection.RunInTransaction(db => - { - using (var statement = db.PrepareStatement("delete from devices where Id=@Id")) - { - statement.TryBind("@Id", id); - - statement.MoveNext(); - } - }, TransactionMode); - } - } - - var path = GetDevicePath(id); - - lock (_syncLock) - { - try - { - FileSystem.DeleteDirectory(path, true); - } - catch (IOException) - { - } - } - } } } diff --git a/Emby.Server.Implementations/Dto/DtoService.cs b/Emby.Server.Implementations/Dto/DtoService.cs index e0f8fc11a3..5e67a44158 100644 --- a/Emby.Server.Implementations/Dto/DtoService.cs +++ b/Emby.Server.Implementations/Dto/DtoService.cs @@ -841,12 +841,6 @@ private void AttachBasicFields(BaseItemDto dto, BaseItem item, BaseItem owner, D dto.CriticRating = item.CriticRating; - var hasTrailers = item as IHasTrailers; - if (hasTrailers != null) - { - dto.LocalTrailerCount = hasTrailers.GetTrailerIds().Count; - } - var hasDisplayOrder = item as IHasDisplayOrder; if (hasDisplayOrder != null) { @@ -861,9 +855,7 @@ private void AttachBasicFields(BaseItemDto dto, BaseItem item, BaseItem owner, D if (fields.Contains(ItemFields.RemoteTrailers)) { - dto.RemoteTrailers = hasTrailers != null ? - hasTrailers.RemoteTrailers : - new MediaUrl[] { }; + dto.RemoteTrailers = item.RemoteTrailers; } dto.Name = item.Name; @@ -1139,15 +1131,26 @@ private void AttachBasicFields(BaseItemDto dto, BaseItem item, BaseItem owner, D } } - var hasSpecialFeatures = item as IHasSpecialFeatures; - if (hasSpecialFeatures != null) + BaseItem[] allExtras = null; + + if (fields.Contains(ItemFields.SpecialFeatureCount)) { - var specialFeatureCount = hasSpecialFeatures.SpecialFeatureIds.Length; + if (allExtras == null) + { + allExtras = item.GetExtras().ToArray(); + } + + dto.SpecialFeatureCount = allExtras.Count(i => i.ExtraType.HasValue && BaseItem.DisplayExtraTypes.Contains(i.ExtraType.Value)); + } - if (specialFeatureCount > 0) + if (fields.Contains(ItemFields.LocalTrailerCount)) + { + if (allExtras == null) { - dto.SpecialFeatureCount = specialFeatureCount; + allExtras = item.GetExtras().ToArray(); } + + dto.LocalTrailerCount = allExtras.Count(i => i.ExtraType.HasValue && i.ExtraType.Value == ExtraType.Trailer); } // Add EpisodeInfo diff --git a/Emby.Server.Implementations/Emby.Server.Implementations.csproj b/Emby.Server.Implementations/Emby.Server.Implementations.csproj index a715782485..47cf2df8c5 100644 --- a/Emby.Server.Implementations/Emby.Server.Implementations.csproj +++ b/Emby.Server.Implementations/Emby.Server.Implementations.csproj @@ -338,7 +338,6 @@ - @@ -605,7 +604,7 @@ Mono.Nat - ..\packages\MediaBrowser.Naming.1.1.5-beta\lib\netstandard2.0\Emby.Naming.dll + ..\packages\MediaBrowser.Naming.1.1.6-beta\lib\netstandard2.0\Emby.Naming.dll ..\ThirdParty\emby\Emby.Server.MediaEncoding.dll @@ -614,13 +613,13 @@ ..\packages\Emby.XmlTv.1.0.14\lib\portable-net45+netstandard2.0+win8\Emby.XmlTv.dll - ..\packages\MediaBrowser.Common.3.3.50-beta\lib\netstandard2.0\MediaBrowser.Common.dll + ..\packages\MediaBrowser.Common.3.3.53-beta\lib\netstandard2.0\MediaBrowser.Common.dll - ..\packages\MediaBrowser.Server.Core.3.3.50-beta\lib\netstandard2.0\MediaBrowser.Controller.dll + ..\packages\MediaBrowser.Server.Core.3.3.53-beta\lib\netstandard2.0\MediaBrowser.Controller.dll - ..\packages\MediaBrowser.Common.3.3.50-beta\lib\netstandard2.0\MediaBrowser.Model.dll + ..\packages\MediaBrowser.Common.3.3.53-beta\lib\netstandard2.0\MediaBrowser.Model.dll ..\packages\Microsoft.Win32.Primitives.4.3.0\lib\net46\Microsoft.Win32.Primitives.dll @@ -630,12 +629,11 @@ ..\packages\PlaylistsNET.1.0.0\lib\netstandard1.4\PlaylistsNET.dll - - ..\packages\ServiceStack.Text.4.5.8\lib\net45\ServiceStack.Text.dll - True + + ..\packages\ServiceStack.Text.5.1.0\lib\net45\ServiceStack.Text.dll - - ..\packages\SharpCompress.0.18.2\lib\net45\SharpCompress.dll + + ..\packages\SharpCompress.0.21.1\lib\net45\SharpCompress.dll ..\packages\SimpleInjector.4.3.0\lib\net45\SimpleInjector.dll @@ -644,6 +642,9 @@ ..\packages\SQLitePCL.pretty.1.1.0\lib\portable-net45+netcore45+wpa81+wp8\SQLitePCL.pretty.dll True + + ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.1\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll + ..\packages\System.Xml.ReaderWriter.4.3.1\lib\net46\System.Xml.ReaderWriter.dll True @@ -741,9 +742,6 @@ True True - - ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll - ..\packages\System.Runtime.Extensions.4.3.0\lib\net462\System.Runtime.Extensions.dll True diff --git a/Emby.Server.Implementations/HttpServer/Security/AuthService.cs b/Emby.Server.Implementations/HttpServer/Security/AuthService.cs index fa6fbc0bd2..09157c1bf8 100644 --- a/Emby.Server.Implementations/HttpServer/Security/AuthService.cs +++ b/Emby.Server.Implementations/HttpServer/Security/AuthService.cs @@ -64,9 +64,7 @@ private void ValidateUser(IRequest request, IAuthenticationAttributes authAttrib throw new SecurityException("Operation not found."); } - var user = auth.UserId.Equals(Guid.Empty) - ? null - : UserManager.GetUserById(auth.UserId); + var user = auth.User; if (user == null & !auth.UserId.Equals(Guid.Empty)) { diff --git a/Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs b/Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs index 5693b8ce0a..c0d520a92a 100644 --- a/Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs +++ b/Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs @@ -6,6 +6,7 @@ using MediaBrowser.Model.Services; using System.Linq; using System.Threading; +using MediaBrowser.Controller.Library; namespace Emby.Server.Implementations.HttpServer.Security { @@ -13,11 +14,13 @@ public class AuthorizationContext : IAuthorizationContext { private readonly IAuthenticationRepository _authRepo; private readonly IConnectManager _connectManager; + private readonly IUserManager _userManager; - public AuthorizationContext(IAuthenticationRepository authRepo, IConnectManager connectManager) + public AuthorizationContext(IAuthenticationRepository authRepo, IConnectManager connectManager, IUserManager userManager) { _authRepo = authRepo; _connectManager = connectManager; + _userManager = userManager; } public AuthorizationInfo GetAuthorizationInfo(object requestContext) @@ -94,8 +97,6 @@ private AuthorizationInfo GetAuthorization(IRequest httpReq) if (tokenInfo != null) { - info.UserId = tokenInfo.UserId; - var updateToken = false; // TODO: Remove these checks for IsNullOrWhiteSpace @@ -109,15 +110,21 @@ private AuthorizationInfo GetAuthorization(IRequest httpReq) info.DeviceId = tokenInfo.DeviceId; } + // Temporary. TODO - allow clients to specify that the token has been shared with a casting device + var allowTokenInfoUpdate = info.Client == null || info.Client.IndexOf("chromecast", StringComparison.OrdinalIgnoreCase) == -1; if (string.IsNullOrWhiteSpace(info.Device)) { info.Device = tokenInfo.DeviceName; } + else if (!string.Equals(info.Device, tokenInfo.DeviceName, StringComparison.OrdinalIgnoreCase)) { - updateToken = true; - tokenInfo.DeviceName = info.Device; + if (allowTokenInfoUpdate) + { + updateToken = true; + tokenInfo.DeviceName = info.Device; + } } if (string.IsNullOrWhiteSpace(info.Version)) @@ -126,8 +133,28 @@ private AuthorizationInfo GetAuthorization(IRequest httpReq) } else if (!string.Equals(info.Version, tokenInfo.AppVersion, StringComparison.OrdinalIgnoreCase)) { + if (allowTokenInfoUpdate) + { + updateToken = true; + tokenInfo.AppVersion = info.Version; + } + } + + if ((DateTime.UtcNow - tokenInfo.DateLastActivity).TotalMinutes > 3) + { + tokenInfo.DateLastActivity = DateTime.UtcNow; updateToken = true; - tokenInfo.AppVersion = info.Version; + } + + if (!tokenInfo.UserId.Equals(Guid.Empty)) + { + info.User = _userManager.GetUserById(tokenInfo.UserId); + + if (info.User != null && !string.Equals(info.User.Name, tokenInfo.UserName, StringComparison.OrdinalIgnoreCase)) + { + tokenInfo.UserName = info.User.Name; + updateToken = true; + } } if (updateToken) @@ -137,11 +164,7 @@ private AuthorizationInfo GetAuthorization(IRequest httpReq) } else { - var user = _connectManager.GetUserFromExchangeToken(token); - if (user != null) - { - info.UserId = user.Id; - } + info.User = _connectManager.GetUserFromExchangeToken(token); } httpReq.Items["OriginalAuthenticationInfo"] = tokenInfo; } diff --git a/Emby.Server.Implementations/HttpServer/Security/SessionContext.cs b/Emby.Server.Implementations/HttpServer/Security/SessionContext.cs index b25daf554d..a919ce0083 100644 --- a/Emby.Server.Implementations/HttpServer/Security/SessionContext.cs +++ b/Emby.Server.Implementations/HttpServer/Security/SessionContext.cs @@ -26,7 +26,7 @@ public SessionInfo GetSession(IRequest requestContext) { var authorization = _authContext.GetAuthorizationInfo(requestContext); - var user = authorization.UserId.Equals(Guid.Empty) ? null : _userManager.GetUserById(authorization.UserId); + var user = authorization.User; return _sessionManager.LogSessionActivity(authorization.Client, authorization.Version, authorization.DeviceId, authorization.Device, requestContext.RemoteIp, user); } diff --git a/Emby.Server.Implementations/IO/ManagedFileSystem.cs b/Emby.Server.Implementations/IO/ManagedFileSystem.cs index 7978b82548..66d7802c6f 100644 --- a/Emby.Server.Implementations/IO/ManagedFileSystem.cs +++ b/Emby.Server.Implementations/IO/ManagedFileSystem.cs @@ -30,7 +30,7 @@ public class ManagedFileSystem : IFileSystem private string _defaultDirectory; - public ManagedFileSystem(ILogger logger, IEnvironmentInfo environmentInfo, string defaultDirectory, string tempPath) + public ManagedFileSystem(ILogger logger, IEnvironmentInfo environmentInfo, string defaultDirectory, string tempPath, bool enableSeparateFileAndDirectoryQueries) { Logger = logger; _supportsAsyncFileStreams = true; @@ -38,10 +38,8 @@ public ManagedFileSystem(ILogger logger, IEnvironmentInfo environmentInfo, strin _environmentInfo = environmentInfo; _defaultDirectory = defaultDirectory; - // On Linux, this needs to be true or symbolic links are ignored - // TODO: See if still needed under .NET Core - EnableSeparateFileAndDirectoryQueries = environmentInfo.OperatingSystem != MediaBrowser.Model.System.OperatingSystem.Windows && - environmentInfo.OperatingSystem != MediaBrowser.Model.System.OperatingSystem.OSX; + // On Linux with mono, this needs to be true or symbolic links are ignored + EnableSeparateFileAndDirectoryQueries = enableSeparateFileAndDirectoryQueries; SetInvalidFileNameChars(environmentInfo.OperatingSystem == MediaBrowser.Model.System.OperatingSystem.Windows); diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs index fabe0c434e..31af9370c7 100644 --- a/Emby.Server.Implementations/Library/LibraryManager.cs +++ b/Emby.Server.Implementations/Library/LibraryManager.cs @@ -2593,11 +2593,10 @@ public IEnumerable