aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Server.Implementations/Library
diff options
context:
space:
mode:
Diffstat (limited to 'MediaBrowser.Server.Implementations/Library')
-rw-r--r--MediaBrowser.Server.Implementations/Library/LibraryManager.cs73
-rw-r--r--MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs247
-rw-r--r--MediaBrowser.Server.Implementations/Library/MusicManager.cs2
-rw-r--r--MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs13
-rw-r--r--MediaBrowser.Server.Implementations/Library/Resolvers/PhotoResolver.cs3
-rw-r--r--MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs11
-rw-r--r--MediaBrowser.Server.Implementations/Library/UserManager.cs59
-rw-r--r--MediaBrowser.Server.Implementations/Library/UserViewManager.cs67
8 files changed, 402 insertions, 73 deletions
diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs
index e6e6b8c74..1f82e7ef1 100644
--- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs
+++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs
@@ -1584,15 +1584,22 @@ namespace MediaBrowser.Server.Implementations.Library
.FirstOrDefault(i => !string.IsNullOrWhiteSpace(i));
}
- public async Task<UserView> GetNamedView(string name,
- string type,
+ public async Task<UserView> GetNamedView(User user,
+ string name,
+ string viewType,
string sortName,
CancellationToken cancellationToken)
{
+ if (ConfigurationManager.Configuration.EnableUserSpecificUserViews)
+ {
+ return await GetNamedViewInternal(user, name, null, viewType, sortName, cancellationToken)
+ .ConfigureAwait(false);
+ }
+
var path = Path.Combine(ConfigurationManager.ApplicationPaths.ItemsByNamePath,
"views");
- path = Path.Combine(path, _fileSystem.GetValidFilename(type));
+ path = Path.Combine(path, _fileSystem.GetValidFilename(viewType));
var id = GetNewItemId(path + "_namedview_" + name, typeof(UserView));
@@ -1611,7 +1618,7 @@ namespace MediaBrowser.Server.Implementations.Library
Id = id,
DateCreated = DateTime.UtcNow,
Name = name,
- ViewType = type,
+ ViewType = viewType,
ForcedSortName = sortName
};
@@ -1627,31 +1634,38 @@ namespace MediaBrowser.Server.Implementations.Library
if (refresh)
{
- await item.RefreshMetadata(new MetadataRefreshOptions
- {
- ForceSave = true
-
- }, cancellationToken).ConfigureAwait(false);
+ await item.UpdateToRepository(ItemUpdateType.MetadataImport, CancellationToken.None).ConfigureAwait(false);
+ _providerManagerFactory().QueueRefresh(item.Id, new MetadataRefreshOptions());
}
return item;
}
- public async Task<UserView> GetSpecialFolder(User user,
+ public Task<UserView> GetNamedView(User user,
string name,
string parentId,
string viewType,
string sortName,
CancellationToken cancellationToken)
{
- if (string.IsNullOrWhiteSpace(name))
+ if (string.IsNullOrWhiteSpace(parentId))
{
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException("parentId");
}
- if (string.IsNullOrWhiteSpace(parentId))
+ return GetNamedViewInternal(user, name, parentId, viewType, sortName, cancellationToken);
+ }
+
+ private async Task<UserView> GetNamedViewInternal(User user,
+ string name,
+ string parentId,
+ string viewType,
+ string sortName,
+ CancellationToken cancellationToken)
+ {
+ if (string.IsNullOrWhiteSpace(name))
{
- throw new ArgumentNullException("parentId");
+ throw new ArgumentNullException("name");
}
if (string.IsNullOrWhiteSpace(viewType))
@@ -1659,13 +1673,13 @@ namespace MediaBrowser.Server.Implementations.Library
throw new ArgumentNullException("viewType");
}
- var id = GetNewItemId("7_namedview_" + name + user.Id.ToString("N") + parentId, typeof(UserView));
+ var id = GetNewItemId("37_namedview_" + name + user.Id.ToString("N") + (parentId ?? string.Empty), typeof(UserView));
- var path = Path.Combine(ConfigurationManager.ApplicationPaths.InternalMetadataPath, "views", "specialviews", id.ToString("N"));
+ var path = Path.Combine(ConfigurationManager.ApplicationPaths.InternalMetadataPath, "views", id.ToString("N"));
var item = GetItemById(id) as UserView;
- var refresh = false;
+ var isNew = false;
if (item == null)
{
@@ -1679,27 +1693,24 @@ namespace MediaBrowser.Server.Implementations.Library
Name = name,
ViewType = viewType,
ForcedSortName = sortName,
- UserId = user.Id,
- ParentId = new Guid(parentId)
+ UserId = user.Id
};
+ if (!string.IsNullOrWhiteSpace(parentId))
+ {
+ item.ParentId = new Guid(parentId);
+ }
+
await CreateItem(item, cancellationToken).ConfigureAwait(false);
- refresh = true;
+ isNew = true;
}
- if (!refresh && item != null)
- {
- refresh = (DateTime.UtcNow - item.DateLastSaved).TotalHours >= 24;
- }
+ var refresh = isNew || (DateTime.UtcNow - item.DateLastSaved).TotalHours >= 6;
if (refresh)
{
- await item.RefreshMetadata(new MetadataRefreshOptions
- {
- ForceSave = true
-
- }, cancellationToken).ConfigureAwait(false);
+ _providerManagerFactory().QueueRefresh(item.Id, new MetadataRefreshOptions());
}
return item;
@@ -1846,6 +1857,10 @@ namespace MediaBrowser.Server.Implementations.Library
{
var options = new ExtendedNamingOptions();
+ // These cause apps to have problems
+ options.AudioFileExtensions.Remove(".m3u");
+ options.AudioFileExtensions.Remove(".wpl");
+
if (!ConfigurationManager.Configuration.EnableAudioArchiveFiles)
{
options.AudioFileExtensions.Remove(".rar");
diff --git a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs
index a45757d13..2880c9e16 100644
--- a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs
+++ b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs
@@ -1,18 +1,43 @@
-using MediaBrowser.Controller.Library;
+using System.IO;
+using MediaBrowser.Controller.Channels;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Controller.Persistence;
+using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.Logging;
+using System;
using System.Collections.Generic;
using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using MediaBrowser.Model.MediaInfo;
namespace MediaBrowser.Server.Implementations.Library
{
public class MediaSourceManager : IMediaSourceManager
{
private readonly IItemRepository _itemRepo;
+ private readonly IUserManager _userManager;
+ private readonly ILibraryManager _libraryManager;
+ private readonly IChannelManager _channelManager;
- public MediaSourceManager(IItemRepository itemRepo)
+ private IMediaSourceProvider[] _providers;
+ private readonly ILogger _logger;
+
+ public MediaSourceManager(IItemRepository itemRepo, IUserManager userManager, ILibraryManager libraryManager, IChannelManager channelManager, ILogger logger)
{
_itemRepo = itemRepo;
+ _userManager = userManager;
+ _libraryManager = libraryManager;
+ _channelManager = channelManager;
+ _logger = logger;
+ }
+
+ public void AddParts(IEnumerable<IMediaSourceProvider> providers)
+ {
+ _providers = providers.ToArray();
}
public IEnumerable<MediaStream> GetMediaStreams(MediaStreamQuery query)
@@ -47,5 +72,223 @@ namespace MediaBrowser.Server.Implementations.Library
{
return true;
}
+
+ public IEnumerable<MediaStream> GetMediaStreams(string mediaSourceId)
+ {
+ var list = GetMediaStreams(new MediaStreamQuery
+ {
+ ItemId = new Guid(mediaSourceId)
+ });
+
+ return GetMediaStreamsForItem(list);
+ }
+
+ public IEnumerable<MediaStream> GetMediaStreams(Guid itemId)
+ {
+ var list = GetMediaStreams(new MediaStreamQuery
+ {
+ ItemId = itemId
+ });
+
+ return GetMediaStreamsForItem(list);
+ }
+
+ private IEnumerable<MediaStream> GetMediaStreamsForItem(IEnumerable<MediaStream> streams)
+ {
+ var list = streams.ToList();
+
+ var subtitleStreams = list
+ .Where(i => i.Type == MediaStreamType.Subtitle)
+ .ToList();
+
+ if (subtitleStreams.Count > 0)
+ {
+ var videoStream = list.FirstOrDefault(i => i.Type == MediaStreamType.Video);
+
+ // This is abitrary but at some point it becomes too slow to extract subtitles on the fly
+ // We need to learn more about when this is the case vs. when it isn't
+ const int maxAllowedBitrateForExternalSubtitleStream = 10000000;
+
+ var videoBitrate = videoStream == null ? maxAllowedBitrateForExternalSubtitleStream : videoStream.BitRate ?? maxAllowedBitrateForExternalSubtitleStream;
+
+ foreach (var subStream in subtitleStreams)
+ {
+ var supportsExternalStream = StreamSupportsExternalStream(subStream);
+
+ if (supportsExternalStream && videoBitrate >= maxAllowedBitrateForExternalSubtitleStream)
+ {
+ supportsExternalStream = false;
+ }
+
+ subStream.SupportsExternalStream = supportsExternalStream;
+ }
+ }
+
+ return list;
+ }
+
+ public async Task<IEnumerable<MediaSourceInfo>> GetPlayackMediaSources(string id, string userId, bool enablePathSubstitution, CancellationToken cancellationToken)
+ {
+ var item = _libraryManager.GetItemById(id);
+ IEnumerable<MediaSourceInfo> mediaSources;
+
+ var hasMediaSources = (IHasMediaSources)item;
+ var channelItem = item as IChannelMediaItem;
+
+ if (channelItem != null)
+ {
+ mediaSources = await _channelManager.GetChannelItemMediaSources(id, true, cancellationToken)
+ .ConfigureAwait(false);
+ }
+ else
+ {
+ if (string.IsNullOrWhiteSpace(userId))
+ {
+ mediaSources = hasMediaSources.GetMediaSources(enablePathSubstitution);
+ }
+ else
+ {
+ var user = _userManager.GetUserById(userId);
+ mediaSources = GetStaticMediaSources(hasMediaSources, enablePathSubstitution, user);
+ }
+ }
+
+ var dynamicMediaSources = await GetDynamicMediaSources(hasMediaSources, cancellationToken).ConfigureAwait(false);
+
+ var list = new List<MediaSourceInfo>();
+
+ list.AddRange(mediaSources);
+
+ foreach (var source in dynamicMediaSources)
+ {
+ source.SupportsTranscoding = false;
+
+ if (source.Protocol == MediaProtocol.File)
+ {
+ source.SupportsDirectStream = File.Exists(source.Path);
+ }
+
+ list.Add(source);
+ }
+
+ return SortMediaSources(list);
+ }
+
+ private async Task<IEnumerable<MediaSourceInfo>> GetDynamicMediaSources(IHasMediaSources item, CancellationToken cancellationToken)
+ {
+ var tasks = _providers.Select(i => GetDynamicMediaSources(item, i, cancellationToken));
+ var results = await Task.WhenAll(tasks).ConfigureAwait(false);
+
+ return results.SelectMany(i => i.ToList());
+ }
+
+ private async Task<IEnumerable<MediaSourceInfo>> GetDynamicMediaSources(IHasMediaSources item, IMediaSourceProvider provider, CancellationToken cancellationToken)
+ {
+ try
+ {
+ return await provider.GetMediaSources(item, cancellationToken).ConfigureAwait(false);
+ }
+ catch (Exception ex)
+ {
+ _logger.ErrorException("Error getting media sources", ex);
+ return new List<MediaSourceInfo>();
+ }
+ }
+
+ public Task<IEnumerable<MediaSourceInfo>> GetPlayackMediaSources(string id, bool enablePathSubstitution, CancellationToken cancellationToken)
+ {
+ return GetPlayackMediaSources(id, null, enablePathSubstitution, cancellationToken);
+ }
+
+ public IEnumerable<MediaSourceInfo> GetStaticMediaSources(IHasMediaSources item, bool enablePathSubstitution)
+ {
+ if (item == null)
+ {
+ throw new ArgumentNullException("item");
+ }
+
+ if (!(item is Video))
+ {
+ return item.GetMediaSources(enablePathSubstitution);
+ }
+
+ return item.GetMediaSources(enablePathSubstitution);
+ }
+
+ public IEnumerable<MediaSourceInfo> GetStaticMediaSources(IHasMediaSources item, bool enablePathSubstitution, User user)
+ {
+ if (item == null)
+ {
+ throw new ArgumentNullException("item");
+ }
+
+ if (!(item is Video))
+ {
+ return item.GetMediaSources(enablePathSubstitution);
+ }
+
+ if (user == null)
+ {
+ throw new ArgumentNullException("user");
+ }
+
+ var sources = item.GetMediaSources(enablePathSubstitution).ToList();
+
+ foreach (var source in sources)
+ {
+ SetUserProperties(source, user);
+ }
+
+ return sources;
+ }
+
+ private void SetUserProperties(MediaSourceInfo source, User user)
+ {
+ var preferredAudio = string.IsNullOrEmpty(user.Configuration.AudioLanguagePreference)
+ ? new string[] { }
+ : new[] { user.Configuration.AudioLanguagePreference };
+
+ var preferredSubs = string.IsNullOrEmpty(user.Configuration.SubtitleLanguagePreference)
+ ? new List<string> { }
+ : new List<string> { user.Configuration.SubtitleLanguagePreference };
+
+ source.DefaultAudioStreamIndex = MediaStreamSelector.GetDefaultAudioStreamIndex(source.MediaStreams, preferredAudio, user.Configuration.PlayDefaultAudioTrack);
+
+ var defaultAudioIndex = source.DefaultAudioStreamIndex;
+ var audioLangage = defaultAudioIndex == null
+ ? null
+ : source.MediaStreams.Where(i => i.Type == MediaStreamType.Audio && i.Index == defaultAudioIndex).Select(i => i.Language).FirstOrDefault();
+
+ source.DefaultSubtitleStreamIndex = MediaStreamSelector.GetDefaultSubtitleStreamIndex(source.MediaStreams,
+ preferredSubs,
+ user.Configuration.SubtitleMode,
+ audioLangage);
+ }
+
+ private IEnumerable<MediaSourceInfo> SortMediaSources(IEnumerable<MediaSourceInfo> sources)
+ {
+ return sources.OrderBy(i =>
+ {
+ if (i.VideoType.HasValue && i.VideoType.Value == VideoType.VideoFile)
+ {
+ return 0;
+ }
+
+ return 1;
+
+ }).ThenBy(i => i.Video3DFormat.HasValue ? 1 : 0)
+ .ThenByDescending(i =>
+ {
+ var stream = i.VideoStream;
+
+ return stream == null || stream.Width == null ? 0 : stream.Width.Value;
+ })
+ .ToList();
+ }
+
+ public MediaSourceInfo GetStaticMediaSource(IHasMediaSources item, string mediaSourceId, bool enablePathSubstitution)
+ {
+ return GetStaticMediaSources(item, enablePathSubstitution).FirstOrDefault(i => string.Equals(i.Id, mediaSourceId, StringComparison.OrdinalIgnoreCase));
+ }
}
}
diff --git a/MediaBrowser.Server.Implementations/Library/MusicManager.cs b/MediaBrowser.Server.Implementations/Library/MusicManager.cs
index 7733e7d37..3a854f2fe 100644
--- a/MediaBrowser.Server.Implementations/Library/MusicManager.cs
+++ b/MediaBrowser.Server.Implementations/Library/MusicManager.cs
@@ -34,7 +34,7 @@ namespace MediaBrowser.Server.Implementations.Library
var genres = user.RootFolder
.GetRecursiveChildren(user, i => i is Audio)
.Cast<Audio>()
- .Where(i => i.HasArtist(name))
+ .Where(i => i.HasAnyArtist(name))
.SelectMany(i => i.Genres)
.Concat(artist.Genres)
.Distinct(StringComparer.OrdinalIgnoreCase);
diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
index 95dcee98a..71daf2b0c 100644
--- a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
+++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
@@ -62,6 +62,11 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies
return ResolveVideos<Video>(parent, files, directoryService, collectionType, false);
}
+ if (string.Equals(collectionType, CollectionType.Photos, StringComparison.OrdinalIgnoreCase))
+ {
+ return ResolveVideos<Video>(parent, files, directoryService, collectionType, false);
+ }
+
if (string.IsNullOrEmpty(collectionType))
{
// Owned items should just use the plain video type
@@ -225,6 +230,10 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies
{
item = ResolveVideo<Video>(args, false);
}
+ else if (string.Equals(collectionType, CollectionType.Photos, StringComparison.OrdinalIgnoreCase))
+ {
+ item = ResolveVideo<Video>(args, false);
+ }
else if (string.IsNullOrEmpty(collectionType))
{
if (args.HasParent<Series>())
@@ -358,6 +367,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies
}
var supportsMultiVersion = !string.Equals(collectionType, CollectionType.HomeVideos) &&
+ !string.Equals(collectionType, CollectionType.Photos) &&
!string.Equals(collectionType, CollectionType.MusicVideos);
var result = ResolveVideos<T>(parent, fileSystemEntries, directoryService, collectionType, supportsMultiVersion);
@@ -474,7 +484,8 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies
CollectionType.Movies,
CollectionType.HomeVideos,
CollectionType.MusicVideos,
- CollectionType.Movies
+ CollectionType.Movies,
+ CollectionType.Photos
};
return !validCollectionTypes.Contains(collectionType ?? string.Empty, StringComparer.OrdinalIgnoreCase);
diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/PhotoResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/PhotoResolver.cs
index 02960ea7e..b714e968b 100644
--- a/MediaBrowser.Server.Implementations/Library/Resolvers/PhotoResolver.cs
+++ b/MediaBrowser.Server.Implementations/Library/Resolvers/PhotoResolver.cs
@@ -30,7 +30,8 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers
return null;
}
- protected static string[] ImageExtensions = { ".tiff", ".jpeg", ".jpg", ".png", ".aiff" };
+ // Some common file name extensions for RAW picture files include: .cr2, .crw, .dng, .nef, .orf, .rw2, .pef, .arw, .sr2, .srf, and .tif.
+ protected static string[] ImageExtensions = { ".tiff", ".jpeg", ".jpg", ".png", ".aiff", ".cr2", ".crw", ".dng", ".nef", ".orf", ".pef", ".arw", ".webp" };
private static readonly string[] IgnoreFiles =
{
diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs
index 7371ca5a9..3551b71b7 100644
--- a/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs
+++ b/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs
@@ -1,19 +1,18 @@
-using System.Collections.Generic;
-using System.Linq;
-using MediaBrowser.Common.IO;
+using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Controller.Resolvers;
using MediaBrowser.Model.Entities;
-using System;
-using System.IO;
using MediaBrowser.Model.Logging;
using MediaBrowser.Naming.Common;
using MediaBrowser.Naming.IO;
using MediaBrowser.Naming.TV;
using MediaBrowser.Server.Implementations.Logging;
-using EpisodeInfo = MediaBrowser.Controller.Providers.EpisodeInfo;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV
{
diff --git a/MediaBrowser.Server.Implementations/Library/UserManager.cs b/MediaBrowser.Server.Implementations/Library/UserManager.cs
index 59fecc857..b101f6ae1 100644
--- a/MediaBrowser.Server.Implementations/Library/UserManager.cs
+++ b/MediaBrowser.Server.Implementations/Library/UserManager.cs
@@ -97,6 +97,7 @@ namespace MediaBrowser.Server.Implementations.Library
/// </summary>
public event EventHandler<GenericEventArgs<User>> UserUpdated;
public event EventHandler<GenericEventArgs<User>> UserConfigurationUpdated;
+ public event EventHandler<GenericEventArgs<User>> UserLockedOut;
/// <summary>
/// Called when [user updated].
@@ -192,10 +193,10 @@ namespace MediaBrowser.Server.Implementations.Library
public bool IsValidUsername(string username)
{
// Usernames can contain letters (a-z), numbers (0-9), dashes (-), underscores (_), apostrophes ('), and periods (.)
- return username.All(IsValidCharacter);
+ return username.All(IsValidUsernameCharacter);
}
- private bool IsValidCharacter(char i)
+ private bool IsValidUsernameCharacter(char i)
{
return char.IsLetterOrDigit(i) || char.Equals(i, '-') || char.Equals(i, '_') || char.Equals(i, '\'') ||
char.Equals(i, '.');
@@ -213,7 +214,7 @@ namespace MediaBrowser.Server.Implementations.Library
foreach (var c in username)
{
- if (IsValidCharacter(c))
+ if (IsValidUsernameCharacter(c))
{
builder.Append(c);
}
@@ -259,6 +260,11 @@ namespace MediaBrowser.Server.Implementations.Library
{
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"));
@@ -266,6 +272,38 @@ namespace MediaBrowser.Server.Implementations.Library
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)
@@ -332,11 +370,6 @@ namespace MediaBrowser.Server.Implementations.Library
{
if (!user.Configuration.HasMigratedToPolicy)
{
- user.Policy.BlockUnratedItems = user.Configuration.BlockUnratedItems;
- user.Policy.EnableContentDeletion = user.Configuration.EnableContentDeletion;
- user.Policy.EnableLiveTvAccess = user.Configuration.EnableLiveTvAccess;
- user.Policy.EnableLiveTvManagement = user.Configuration.EnableLiveTvManagement;
- user.Policy.EnableMediaPlayback = user.Configuration.EnableMediaPlayback;
user.Policy.IsAdministrator = user.Configuration.IsAdministrator;
await UpdateUserPolicy(user, user.Policy, false);
@@ -815,6 +848,12 @@ namespace MediaBrowser.Server.Implementations.Library
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);
}
}
@@ -915,10 +954,6 @@ namespace MediaBrowser.Server.Implementations.Library
}
user.Configuration.IsAdministrator = user.Policy.IsAdministrator;
- user.Configuration.EnableLiveTvManagement = user.Policy.EnableLiveTvManagement;
- user.Configuration.EnableLiveTvAccess = user.Policy.EnableLiveTvAccess;
- user.Configuration.EnableMediaPlayback = user.Policy.EnableMediaPlayback;
- user.Configuration.EnableContentDeletion = user.Policy.EnableContentDeletion;
await UpdateConfiguration(user, user.Configuration, true).ConfigureAwait(false);
}
diff --git a/MediaBrowser.Server.Implementations/Library/UserViewManager.cs b/MediaBrowser.Server.Implementations/Library/UserViewManager.cs
index a8ca1a2e0..e63a27551 100644
--- a/MediaBrowser.Server.Implementations/Library/UserViewManager.cs
+++ b/MediaBrowser.Server.Implementations/Library/UserViewManager.cs
@@ -2,7 +2,6 @@
using MediaBrowser.Controller.Collections;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Controller.Localization;
@@ -11,12 +10,12 @@ using MediaBrowser.Model.Channels;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Library;
using MediaBrowser.Model.Querying;
+using MoreLinq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
-using MoreLinq;
namespace MediaBrowser.Server.Implementations.Library
{
@@ -53,8 +52,6 @@ namespace MediaBrowser.Server.Implementations.Library
.OfType<Folder>()
.ToList();
- var list = new List<Folder>();
-
var excludeFolderIds = user.Configuration.ExcludeFoldersFromGrouping.Select(i => new Guid(i)).ToList();
var standaloneFolders = folders
@@ -66,46 +63,68 @@ namespace MediaBrowser.Server.Implementations.Library
.OfType<ICollectionFolder>()
.ToList();
- list.AddRange(standaloneFolders);
+ var list = new List<Folder>();
+
+ if (_config.Configuration.EnableUserSpecificUserViews)
+ {
+ foreach (var folder in standaloneFolders)
+ {
+ var collectionFolder = folder as ICollectionFolder;
+ var folderViewType = collectionFolder == null ? null : collectionFolder.CollectionType;
+
+ if (string.IsNullOrWhiteSpace(folderViewType))
+ {
+ list.Add(folder);
+ }
+ else
+ {
+ list.Add(await GetUserView(folder.Id, folder.Name, folderViewType, string.Empty, user, cancellationToken).ConfigureAwait(false));
+ }
+ }
+ }
+ else
+ {
+ list.AddRange(standaloneFolders);
+ }
if (foldersWithViewTypes.Any(i => string.Equals(i.CollectionType, CollectionType.TvShows, StringComparison.OrdinalIgnoreCase)) ||
foldersWithViewTypes.Any(i => string.IsNullOrWhiteSpace(i.CollectionType)))
{
- list.Add(await GetUserView(CollectionType.TvShows, string.Empty, cancellationToken).ConfigureAwait(false));
+ list.Add(await GetUserView(CollectionType.TvShows, string.Empty, user, cancellationToken).ConfigureAwait(false));
}
if (foldersWithViewTypes.Any(i => string.Equals(i.CollectionType, CollectionType.Music, StringComparison.OrdinalIgnoreCase)) ||
foldersWithViewTypes.Any(i => string.Equals(i.CollectionType, CollectionType.MusicVideos, StringComparison.OrdinalIgnoreCase)))
{
- list.Add(await GetUserView(CollectionType.Music, string.Empty, cancellationToken).ConfigureAwait(false));
+ list.Add(await GetUserView(CollectionType.Music, string.Empty, user, cancellationToken).ConfigureAwait(false));
}
if (foldersWithViewTypes.Any(i => string.Equals(i.CollectionType, CollectionType.Movies, StringComparison.OrdinalIgnoreCase)) ||
foldersWithViewTypes.Any(i => string.IsNullOrWhiteSpace(i.CollectionType)))
{
- list.Add(await GetUserView(CollectionType.Movies, string.Empty, cancellationToken).ConfigureAwait(false));
+ list.Add(await GetUserView(CollectionType.Movies, string.Empty, user, cancellationToken).ConfigureAwait(false));
}
- if (foldersWithViewTypes.Any(i => string.Equals(i.CollectionType, CollectionType.Games, StringComparison.OrdinalIgnoreCase))
- || _config.Configuration.EnableLegacyCollectionInView)
+ if (foldersWithViewTypes.Any(i => string.Equals(i.CollectionType, CollectionType.Games, StringComparison.OrdinalIgnoreCase)))
{
- list.Add(await GetUserView(CollectionType.Games, string.Empty, cancellationToken).ConfigureAwait(false));
+ list.Add(await GetUserView(CollectionType.Games, string.Empty, user, cancellationToken).ConfigureAwait(false));
}
if (foldersWithViewTypes.Any(i => string.Equals(i.CollectionType, CollectionType.BoxSets, StringComparison.OrdinalIgnoreCase)))
{
//list.Add(_collectionManager.GetCollectionsFolder(user.Id.ToString("N")));
- list.Add(await GetUserView(CollectionType.BoxSets, string.Empty, cancellationToken).ConfigureAwait(false));
+ list.Add(await GetUserView(CollectionType.BoxSets, string.Empty, user, cancellationToken).ConfigureAwait(false));
}
if (foldersWithViewTypes.Any(i => string.Equals(i.CollectionType, CollectionType.Playlists, StringComparison.OrdinalIgnoreCase)))
{
- list.Add(_playlists.GetPlaylistsFolder(user.Id.ToString("N")));
+ //list.Add(_playlists.GetPlaylistsFolder(user.Id.ToString("N")));
+ list.Add(await GetUserView(CollectionType.Playlists, string.Empty, user, cancellationToken).ConfigureAwait(false));
}
if (user.Configuration.DisplayFoldersView)
{
- list.Add(await GetUserView(CollectionType.Folders, "zz_" + CollectionType.Folders, cancellationToken).ConfigureAwait(false));
+ list.Add(await GetUserView(CollectionType.Folders, "zz_" + CollectionType.Folders, user, cancellationToken).ConfigureAwait(false));
}
if (query.IncludeExternalContent)
@@ -131,7 +150,8 @@ namespace MediaBrowser.Server.Implementations.Library
if (_liveTvManager.GetEnabledUsers().Select(i => i.Id.ToString("N")).Contains(query.UserId))
{
- list.Add(await _liveTvManager.GetInternalLiveTvFolder(query.UserId, cancellationToken).ConfigureAwait(false));
+ //list.Add(await _liveTvManager.GetInternalLiveTvFolder(query.UserId, cancellationToken).ConfigureAwait(false));
+ list.Add(await GetUserView(CollectionType.LiveTv, string.Empty, user, cancellationToken).ConfigureAwait(false));
}
}
@@ -150,23 +170,28 @@ namespace MediaBrowser.Server.Implementations.Library
.ThenBy(i => i.SortName);
}
- public Task<UserView> GetUserView(string name, string parentId, string type, User user, string sortName, CancellationToken cancellationToken)
+ public Task<UserView> GetUserSubView(string name, string parentId, string type, User user, string sortName, CancellationToken cancellationToken)
{
- return _libraryManager.GetSpecialFolder(user, name, parentId, type, sortName, cancellationToken);
+ return _libraryManager.GetNamedView(user, name, parentId, type, sortName, cancellationToken);
}
- public Task<UserView> GetUserView(string parentId, string type, User user, string sortName, CancellationToken cancellationToken)
+ public Task<UserView> GetUserSubView(string parentId, string type, User user, string sortName, CancellationToken cancellationToken)
{
var name = _localizationManager.GetLocalizedString("ViewType" + type);
- return GetUserView(name, parentId, type, user, sortName, cancellationToken);
+ return GetUserSubView(name, parentId, type, user, sortName, cancellationToken);
}
- public Task<UserView> GetUserView(string type, string sortName, CancellationToken cancellationToken)
+ public Task<UserView> GetUserView(string type, string sortName, User user, CancellationToken cancellationToken)
{
var name = _localizationManager.GetLocalizedString("ViewType" + type);
- return _libraryManager.GetNamedView(name, type, sortName, cancellationToken);
+ return _libraryManager.GetNamedView(user, name, type, sortName, cancellationToken);
+ }
+
+ public Task<UserView> GetUserView(Guid parentId, string name, string type, string sortName, User user, CancellationToken cancellationToken)
+ {
+ return _libraryManager.GetNamedView(user, name, parentId.ToString("N"), type, sortName, cancellationToken);
}
public List<Tuple<BaseItem, List<BaseItem>>> GetLatestItems(LatestItemsQuery request)