aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Pulverenti <luke.pulverenti@gmail.com>2013-04-13 14:02:30 -0400
committerLuke Pulverenti <luke.pulverenti@gmail.com>2013-04-13 14:02:30 -0400
commit785deff188ba51243739b827dbe42b5645404367 (patch)
tree236515b0e5502b65c6eee3d23412093588c9c5e6
parent6688d35e65352fbf9b0a06a5fdf5a31eaaf425d8 (diff)
removed excess hashing in providers and made user data key-based
-rw-r--r--MediaBrowser.Api/Images/ImageService.cs1
-rw-r--r--MediaBrowser.Api/Library/LibraryService.cs18
-rw-r--r--MediaBrowser.Api/Playback/BaseStreamingService.cs1
-rw-r--r--MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs36
-rw-r--r--MediaBrowser.Api/UserLibrary/GenresService.cs68
-rw-r--r--MediaBrowser.Api/UserLibrary/ItemsService.cs54
-rw-r--r--MediaBrowser.Api/UserLibrary/PersonsService.cs65
-rw-r--r--MediaBrowser.Api/UserLibrary/StudiosService.cs65
-rw-r--r--MediaBrowser.Api/UserLibrary/UserLibraryService.cs43
-rw-r--r--MediaBrowser.Api/UserLibrary/YearsService.cs7
-rw-r--r--MediaBrowser.Api/UserService.cs11
-rw-r--r--MediaBrowser.Common/Extensions/BaseExtensions.cs22
-rw-r--r--MediaBrowser.Common/Plugins/BasePlugin.cs2
-rw-r--r--MediaBrowser.Controller/Dto/DtoBuilder.cs (renamed from MediaBrowser.Controller/Library/DtoBuilder.cs)72
-rw-r--r--MediaBrowser.Controller/Dto/UserDtoBuilder.cs71
-rw-r--r--MediaBrowser.Controller/Entities/BaseItem.cs43
-rw-r--r--MediaBrowser.Controller/Entities/Folder.cs3
-rw-r--r--MediaBrowser.Controller/Entities/Genre.cs8
-rw-r--r--MediaBrowser.Controller/Entities/Movies/Movie.cs21
-rw-r--r--MediaBrowser.Controller/Entities/Person.cs8
-rw-r--r--MediaBrowser.Controller/Entities/Studio.cs8
-rw-r--r--MediaBrowser.Controller/Entities/TV/Episode.cs26
-rw-r--r--MediaBrowser.Controller/Entities/TV/Season.cs25
-rw-r--r--MediaBrowser.Controller/Entities/TV/Series.cs17
-rw-r--r--MediaBrowser.Controller/Entities/Year.cs8
-rw-r--r--MediaBrowser.Controller/Library/IUserManager.cs19
-rw-r--r--MediaBrowser.Controller/MediaBrowser.Controller.csproj3
-rw-r--r--MediaBrowser.Controller/Persistence/IUserDataRepository.cs12
-rw-r--r--MediaBrowser.Controller/Providers/BaseMetadataProvider.cs44
-rw-r--r--MediaBrowser.Controller/Providers/BaseProviderInfo.cs12
-rw-r--r--MediaBrowser.Controller/Providers/Movies/FanArtMovieProvider.cs9
-rw-r--r--MediaBrowser.Controller/Providers/Movies/MovieDbProvider.cs18
-rw-r--r--MediaBrowser.Controller/Providers/Music/FanArtAlbumProvider.cs28
-rw-r--r--MediaBrowser.Controller/Providers/Music/FanArtArtistProvider.cs10
-rw-r--r--MediaBrowser.Controller/Providers/Music/LastfmBaseProvider.cs8
-rw-r--r--MediaBrowser.Controller/Providers/TV/FanArtTVProvider.cs10
-rw-r--r--MediaBrowser.Controller/Sorting/IUserBaseItemComparer.cs7
-rw-r--r--MediaBrowser.Model/Configuration/ServerConfiguration.cs28
-rw-r--r--MediaBrowser.Model/Connectivity/ClientConnectionInfo.cs2
-rw-r--r--MediaBrowser.Model/DTO/UserDto.cs2
-rw-r--r--MediaBrowser.Model/Plugins/PluginInfo.cs2
-rw-r--r--MediaBrowser.Model/Querying/ItemQuery.cs2
-rw-r--r--MediaBrowser.Model/Querying/ItemsByNameQuery.cs3
-rw-r--r--MediaBrowser.Model/System/SystemInfo.cs2
-rw-r--r--MediaBrowser.Server.Implementations/Library/LibraryManager.cs7
-rw-r--r--MediaBrowser.Server.Implementations/Library/UserManager.cs81
-rw-r--r--MediaBrowser.Server.Implementations/Providers/ProviderManager.cs28
-rw-r--r--MediaBrowser.Server.Implementations/Sorting/DatePlayedComparer.cs9
-rw-r--r--MediaBrowser.Server.Implementations/Sorting/PlayCountComparer.cs9
-rw-r--r--MediaBrowser.Server.Implementations/Sqlite/SQLiteDisplayPreferencesRepository.cs2
-rw-r--r--MediaBrowser.Server.Implementations/Sqlite/SQLiteUserDataRepository.cs86
-rw-r--r--MediaBrowser.ServerApplication/ApplicationHost.cs36
-rw-r--r--MediaBrowser.ServerApplication/EntryPoints/WebSocketEvents.cs3
-rw-r--r--MediaBrowser.WebDashboard/Api/DashboardService.cs5
54 files changed, 512 insertions, 678 deletions
diff --git a/MediaBrowser.Api/Images/ImageService.cs b/MediaBrowser.Api/Images/ImageService.cs
index cb26688e3..07bbaff74 100644
--- a/MediaBrowser.Api/Images/ImageService.cs
+++ b/MediaBrowser.Api/Images/ImageService.cs
@@ -2,6 +2,7 @@
using MediaBrowser.Common.IO;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller;
+using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Entities;
diff --git a/MediaBrowser.Api/Library/LibraryService.cs b/MediaBrowser.Api/Library/LibraryService.cs
index 9c68df771..5b34119de 100644
--- a/MediaBrowser.Api/Library/LibraryService.cs
+++ b/MediaBrowser.Api/Library/LibraryService.cs
@@ -1,6 +1,8 @@
using MediaBrowser.Common;
+using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Persistence;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Querying;
using ServiceStack.ServiceHost;
@@ -104,16 +106,16 @@ namespace MediaBrowser.Api.Library
/// </summary>
private readonly IApplicationHost _appHost;
private readonly ILibraryManager _libraryManager;
- private readonly IUserManager _userManager;
+ private readonly IUserDataRepository _userDataRepository;
/// <summary>
/// Initializes a new instance of the <see cref="LibraryService" /> class.
/// </summary>
/// <param name="appHost">The app host.</param>
/// <param name="libraryManager">The library manager.</param>
- /// <param name="userManager">The user manager.</param>
+ /// <param name="userDataRepository">The user data repository.</param>
/// <exception cref="System.ArgumentNullException">appHost</exception>
- public LibraryService(IApplicationHost appHost, ILibraryManager libraryManager, IUserManager userManager)
+ public LibraryService(IApplicationHost appHost, ILibraryManager libraryManager, IUserDataRepository userDataRepository)
{
if (appHost == null)
{
@@ -122,7 +124,7 @@ namespace MediaBrowser.Api.Library
_appHost = appHost;
_libraryManager = libraryManager;
- _userManager = userManager;
+ _userDataRepository = userDataRepository;
}
/// <summary>
@@ -137,7 +139,7 @@ namespace MediaBrowser.Api.Library
// Get everything
var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true));
- var result = new DtoBuilder(Logger, _libraryManager, _userManager).GetBaseItemDto(item, fields.ToList()).Result;
+ var result = new DtoBuilder(Logger, _libraryManager, _userDataRepository).GetBaseItemDto(item, fields.ToList()).Result;
return ToOptimizedResult(result);
}
@@ -154,7 +156,7 @@ namespace MediaBrowser.Api.Library
// Get everything
var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true));
- var result = new DtoBuilder(Logger, _libraryManager, _userManager).GetBaseItemDto(item, fields.ToList()).Result;
+ var result = new DtoBuilder(Logger, _libraryManager, _userDataRepository).GetBaseItemDto(item, fields.ToList()).Result;
return ToOptimizedResult(result);
}
@@ -171,7 +173,7 @@ namespace MediaBrowser.Api.Library
// Get everything
var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true));
- var result = new DtoBuilder(Logger, _libraryManager, _userManager).GetBaseItemDto(item, fields.ToList()).Result;
+ var result = new DtoBuilder(Logger, _libraryManager, _userDataRepository).GetBaseItemDto(item, fields.ToList()).Result;
return ToOptimizedResult(result);
}
@@ -188,7 +190,7 @@ namespace MediaBrowser.Api.Library
// Get everything
var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true));
- var result = new DtoBuilder(Logger, _libraryManager, _userManager).GetBaseItemDto(item, fields.ToList()).Result;
+ var result = new DtoBuilder(Logger, _libraryManager, _userDataRepository).GetBaseItemDto(item, fields.ToList()).Result;
return ToOptimizedResult(result);
}
diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs
index 3c6731e71..1510dd472 100644
--- a/MediaBrowser.Api/Playback/BaseStreamingService.cs
+++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs
@@ -2,6 +2,7 @@
using MediaBrowser.Common.IO;
using MediaBrowser.Common.MediaInfo;
using MediaBrowser.Controller;
+using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers.MediaInfo;
diff --git a/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs b/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs
index 6801e14f0..42aafd2cd 100644
--- a/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs
+++ b/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs
@@ -1,6 +1,7 @@
-using System.Threading;
+using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Persistence;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Querying;
using ServiceStack.ServiceHost;
@@ -8,6 +9,7 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
+using System.Threading;
using System.Threading.Tasks;
namespace MediaBrowser.Api.UserLibrary
@@ -27,16 +29,19 @@ namespace MediaBrowser.Api.UserLibrary
/// The library manager
/// </summary>
protected readonly ILibraryManager LibraryManager;
+ protected readonly IUserDataRepository UserDataRepository;
/// <summary>
/// Initializes a new instance of the <see cref="BaseItemsByNameService{TItemType}" /> class.
/// </summary>
/// <param name="userManager">The user manager.</param>
/// <param name="libraryManager">The library manager.</param>
- protected BaseItemsByNameService(IUserManager userManager, ILibraryManager libraryManager)
+ /// <param name="userDataRepository">The user data repository.</param>
+ protected BaseItemsByNameService(IUserManager userManager, ILibraryManager libraryManager, IUserDataRepository userDataRepository)
{
UserManager = userManager;
LibraryManager = libraryManager;
+ UserDataRepository = userDataRepository;
}
/// <summary>
@@ -132,18 +137,19 @@ namespace MediaBrowser.Api.UserLibrary
/// <returns>IEnumerable{BaseItem}.</returns>
private IEnumerable<BaseItem> FilterItems(GetItemsByName request, IEnumerable<BaseItem> items, User user)
{
- items = items.AsParallel();
-
- items = ItemsService.ApplyAdditionalFilters(request, items);
-
- // Apply filters
- // Run them starting with the ones that are likely to reduce the list the most
- foreach (var filter in request.GetFilters().OrderByDescending(f => (int)f))
+ // Exclude item types
+ if (!string.IsNullOrEmpty(request.ExcludeItemTypes))
{
- items = ItemsService.ApplyFilter(items, filter, user, UserManager);
+ var vals = request.ExcludeItemTypes.Split(',');
+ items = items.Where(f => !vals.Contains(f.GetType().Name, StringComparer.OrdinalIgnoreCase));
}
- items = items.AsEnumerable();
+ // Include item types
+ if (!string.IsNullOrEmpty(request.IncludeItemTypes))
+ {
+ var vals = request.IncludeItemTypes.Split(',');
+ items = items.Where(f => vals.Contains(f.GetType().Name, StringComparer.OrdinalIgnoreCase));
+ }
return items;
}
@@ -185,7 +191,7 @@ namespace MediaBrowser.Api.UserLibrary
return null;
}
- var dto = await new DtoBuilder(Logger, LibraryManager, UserManager).GetBaseItemDto(item, user, fields).ConfigureAwait(false);
+ var dto = await new DtoBuilder(Logger, LibraryManager, UserDataRepository).GetBaseItemDto(item, user, fields).ConfigureAwait(false);
if (fields.Contains(ItemFields.ItemCounts))
{
@@ -211,13 +217,15 @@ namespace MediaBrowser.Api.UserLibrary
var item = await getItem().ConfigureAwait(false);
+ var key = item.GetUserDataKey();
+
// Get the user data for this item
- var data = await UserManager.GetUserData(user.Id, item.UserDataId).ConfigureAwait(false);
+ var data = await UserDataRepository.GetUserData(user.Id, key).ConfigureAwait(false);
// Set favorite status
data.IsFavorite = isFavorite;
- await UserManager.SaveUserData(user.Id, item.UserDataId, data, CancellationToken.None).ConfigureAwait(false);
+ await UserDataRepository.SaveUserData(user.Id, key, data, CancellationToken.None).ConfigureAwait(false);
}
}
diff --git a/MediaBrowser.Api/UserLibrary/GenresService.cs b/MediaBrowser.Api/UserLibrary/GenresService.cs
index 54561f400..e275b6ed0 100644
--- a/MediaBrowser.Api/UserLibrary/GenresService.cs
+++ b/MediaBrowser.Api/UserLibrary/GenresService.cs
@@ -1,6 +1,6 @@
-using System.Threading;
-using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Persistence;
using ServiceStack.ServiceHost;
using System;
using System.Collections.Generic;
@@ -18,52 +18,14 @@ namespace MediaBrowser.Api.UserLibrary
public class GetGenres : GetItemsByName
{
}
-
- [Route("/Users/{UserId}/FavoriteGenres/{Name}", "POST")]
- [Api(Description = "Marks a genre as a favorite")]
- public class MarkFavoriteGenre : IReturnVoid
- {
- /// <summary>
- /// Gets or sets the user id.
- /// </summary>
- /// <value>The user id.</value>
- [ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
- public Guid UserId { get; set; }
-
- /// <summary>
- /// Gets or sets the name.
- /// </summary>
- /// <value>The name.</value>
- [ApiMember(Name = "Name", Description = "Name", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")]
- public string Name { get; set; }
- }
-
- [Route("/Users/{UserId}/FavoriteGenres/{Name}", "DELETE")]
- [Api(Description = "Unmarks a genre as a favorite")]
- public class UnmarkFavoriteGenre : IReturnVoid
- {
- /// <summary>
- /// Gets or sets the user id.
- /// </summary>
- /// <value>The user id.</value>
- [ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")]
- public Guid UserId { get; set; }
-
- /// <summary>
- /// Gets or sets the name.
- /// </summary>
- /// <value>The name.</value>
- [ApiMember(Name = "Name", Description = "Name", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")]
- public string Name { get; set; }
- }
/// <summary>
/// Class GenresService
/// </summary>
public class GenresService : BaseItemsByNameService<Genre>
{
- public GenresService(IUserManager userManager, ILibraryManager libraryManager)
- : base(userManager, libraryManager)
+ public GenresService(IUserManager userManager, ILibraryManager libraryManager, IUserDataRepository userDataRepository)
+ : base(userManager, libraryManager, userDataRepository)
{
}
@@ -80,28 +42,6 @@ namespace MediaBrowser.Api.UserLibrary
}
/// <summary>
- /// Posts the specified request.
- /// </summary>
- /// <param name="request">The request.</param>
- public void Post(MarkFavoriteGenre request)
- {
- var task = MarkFavorite(() => LibraryManager.GetGenre(request.Name), request.UserId, true);
-
- Task.WaitAll(task);
- }
-
- /// <summary>
- /// Deletes the specified request.
- /// </summary>
- /// <param name="request">The request.</param>
- public void Delete(UnmarkFavoriteGenre request)
- {
- var task = MarkFavorite(() => LibraryManager.GetGenre(request.Name), request.UserId, false);
-
- Task.WaitAll(task);
- }
-
- /// <summary>
/// Gets all items.
/// </summary>
/// <param name="request">The request.</param>
diff --git a/MediaBrowser.Api/UserLibrary/ItemsService.cs b/MediaBrowser.Api/UserLibrary/ItemsService.cs
index aed84e07f..675ac0cd5 100644
--- a/MediaBrowser.Api/UserLibrary/ItemsService.cs
+++ b/MediaBrowser.Api/UserLibrary/ItemsService.cs
@@ -1,6 +1,8 @@
-using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Dto;
+using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Persistence;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Querying;
using ServiceStack.ServiceHost;
@@ -148,6 +150,7 @@ namespace MediaBrowser.Api.UserLibrary
/// The _user manager
/// </summary>
private readonly IUserManager _userManager;
+ private readonly IUserDataRepository _userDataRepository;
/// <summary>
/// The _library manager
@@ -161,11 +164,13 @@ namespace MediaBrowser.Api.UserLibrary
/// <param name="userManager">The user manager.</param>
/// <param name="libraryManager">The library manager.</param>
/// <param name="searchEngine">The search engine.</param>
- public ItemsService(IUserManager userManager, ILibraryManager libraryManager, ILibrarySearchEngine searchEngine)
+ /// <param name="userDataRepository">The user data repository.</param>
+ public ItemsService(IUserManager userManager, ILibraryManager libraryManager, ILibrarySearchEngine searchEngine, IUserDataRepository userDataRepository)
{
_userManager = userManager;
_libraryManager = libraryManager;
_searchEngine = searchEngine;
+ _userDataRepository = userDataRepository;
}
/// <summary>
@@ -199,7 +204,7 @@ namespace MediaBrowser.Api.UserLibrary
// Run them starting with the ones that are likely to reduce the list the most
foreach (var filter in request.GetFilters().OrderByDescending(f => (int)f))
{
- items = ApplyFilter(items, filter, user, _userManager);
+ items = ApplyFilter(items, filter, user, _userDataRepository);
}
items = items.AsEnumerable();
@@ -214,7 +219,7 @@ namespace MediaBrowser.Api.UserLibrary
var fields = request.GetItemFields().ToList();
- var dtoBuilder = new DtoBuilder(Logger, _libraryManager, _userManager);
+ var dtoBuilder = new DtoBuilder(Logger, _libraryManager, _userDataRepository);
var returnItems = await Task.WhenAll(pagedItems.Select(i => dtoBuilder.GetBaseItemDto(i, user, fields))).ConfigureAwait(false);
@@ -274,9 +279,9 @@ namespace MediaBrowser.Api.UserLibrary
/// <param name="items">The items.</param>
/// <param name="filter">The filter.</param>
/// <param name="user">The user.</param>
- /// <param name="userManager">The user manager.</param>
+ /// <param name="repository">The repository.</param>
/// <returns>IEnumerable{BaseItem}.</returns>
- internal static IEnumerable<BaseItem> ApplyFilter(IEnumerable<BaseItem> items, ItemFilter filter, User user, IUserManager userManager)
+ internal static IEnumerable<BaseItem> ApplyFilter(IEnumerable<BaseItem> items, ItemFilter filter, User user, IUserDataRepository repository)
{
// Avoids implicitly captured closure
var currentUser = user;
@@ -286,7 +291,7 @@ namespace MediaBrowser.Api.UserLibrary
case ItemFilter.Likes:
return items.Where(item =>
{
- var userdata = userManager.GetUserData(user.Id, item.UserDataId).Result;
+ var userdata = repository.GetUserData(user.Id, item.GetUserDataKey()).Result;
return userdata != null && userdata.Likes.HasValue && userdata.Likes.Value;
});
@@ -294,7 +299,7 @@ namespace MediaBrowser.Api.UserLibrary
case ItemFilter.Dislikes:
return items.Where(item =>
{
- var userdata = userManager.GetUserData(user.Id, item.UserDataId).Result;
+ var userdata = repository.GetUserData(user.Id, item.GetUserDataKey()).Result;
return userdata != null && userdata.Likes.HasValue && !userdata.Likes.Value;
});
@@ -302,7 +307,7 @@ namespace MediaBrowser.Api.UserLibrary
case ItemFilter.IsFavorite:
return items.Where(item =>
{
- var userdata = userManager.GetUserData(user.Id, item.UserDataId).Result;
+ var userdata = repository.GetUserData(user.Id, item.GetUserDataKey()).Result;
return userdata != null && userdata.IsFavorite;
});
@@ -313,7 +318,7 @@ namespace MediaBrowser.Api.UserLibrary
case ItemFilter.IsResumable:
return items.Where(item =>
{
- var userdata = userManager.GetUserData(user.Id, item.UserDataId).Result;
+ var userdata = repository.GetUserData(user.Id, item.GetUserDataKey()).Result;
return userdata != null && userdata.PlaybackPositionTicks > 0;
});
@@ -321,7 +326,7 @@ namespace MediaBrowser.Api.UserLibrary
case ItemFilter.IsPlayed:
return items.Where(item =>
{
- var userdata = userManager.GetUserData(user.Id, item.UserDataId).Result;
+ var userdata = repository.GetUserData(user.Id, item.GetUserDataKey()).Result;
return userdata != null && userdata.PlayCount > 0;
});
@@ -329,7 +334,7 @@ namespace MediaBrowser.Api.UserLibrary
case ItemFilter.IsUnplayed:
return items.Where(item =>
{
- var userdata = userManager.GetUserData(user.Id, item.UserDataId).Result;
+ var userdata = repository.GetUserData(user.Id, item.GetUserDataKey()).Result;
return userdata == null || userdata.PlayCount == 0;
});
@@ -347,32 +352,11 @@ namespace MediaBrowser.Api.UserLibrary
/// <summary>
/// Applies the additional filters.
/// </summary>
- /// <param name="itemsRequest">The items request.</param>
+ /// <param name="request">The request.</param>
/// <param name="items">The items.</param>
/// <returns>IEnumerable{BaseItem}.</returns>
- internal static IEnumerable<BaseItem> ApplyAdditionalFilters(BaseItemsRequest itemsRequest, IEnumerable<BaseItem> items)
+ internal static IEnumerable<BaseItem> ApplyAdditionalFilters(GetItems request, IEnumerable<BaseItem> items)
{
- // Exclude item types
- if (!string.IsNullOrEmpty(itemsRequest.ExcludeItemTypes))
- {
- var vals = itemsRequest.ExcludeItemTypes.Split(',');
- items = items.Where(f => !vals.Contains(f.GetType().Name, StringComparer.OrdinalIgnoreCase));
- }
-
- // Include item types
- if (!string.IsNullOrEmpty(itemsRequest.IncludeItemTypes))
- {
- var vals = itemsRequest.IncludeItemTypes.Split(',');
- items = items.Where(f => vals.Contains(f.GetType().Name, StringComparer.OrdinalIgnoreCase));
- }
-
- var request = itemsRequest as GetItems;
-
- if (request == null)
- {
- return items;
- }
-
// Filter by Series Status
if (!string.IsNullOrEmpty(request.SeriesStatus))
{
diff --git a/MediaBrowser.Api/UserLibrary/PersonsService.cs b/MediaBrowser.Api/UserLibrary/PersonsService.cs
index 4253ddc80..974b8c002 100644
--- a/MediaBrowser.Api/UserLibrary/PersonsService.cs
+++ b/MediaBrowser.Api/UserLibrary/PersonsService.cs
@@ -1,5 +1,6 @@
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Persistence;
using ServiceStack.ServiceHost;
using System;
using System.Collections.Generic;
@@ -22,52 +23,14 @@ namespace MediaBrowser.Api.UserLibrary
/// <value>The person types.</value>
public string PersonTypes { get; set; }
}
-
- [Route("/Users/{UserId}/FavoritePersons/{Name}", "POST")]
- [Api(Description = "Marks a person as a favorite")]
- public class MarkFavoritePerson : IReturnVoid
- {
- /// <summary>
- /// Gets or sets the user id.
- /// </summary>
- /// <value>The user id.</value>
- [ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
- public Guid UserId { get; set; }
-
- /// <summary>
- /// Gets or sets the name.
- /// </summary>
- /// <value>The name.</value>
- [ApiMember(Name = "Name", Description = "Name", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")]
- public string Name { get; set; }
- }
-
- [Route("/Users/{UserId}/FavoritePersons/{Name}", "DELETE")]
- [Api(Description = "Unmarks a person as a favorite")]
- public class UnmarkFavoritePerson : IReturnVoid
- {
- /// <summary>
- /// Gets or sets the user id.
- /// </summary>
- /// <value>The user id.</value>
- [ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")]
- public Guid UserId { get; set; }
-
- /// <summary>
- /// Gets or sets the name.
- /// </summary>
- /// <value>The name.</value>
- [ApiMember(Name = "Name", Description = "Name", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")]
- public string Name { get; set; }
- }
/// <summary>
/// Class PersonsService
/// </summary>
public class PersonsService : BaseItemsByNameService<Person>
{
- public PersonsService(IUserManager userManager, ILibraryManager libraryManager)
- : base(userManager, libraryManager)
+ public PersonsService(IUserManager userManager, ILibraryManager libraryManager, IUserDataRepository userDataRepository)
+ : base(userManager, libraryManager, userDataRepository)
{
}
@@ -84,28 +47,6 @@ namespace MediaBrowser.Api.UserLibrary
}
/// <summary>
- /// Posts the specified request.
- /// </summary>
- /// <param name="request">The request.</param>
- public void Post(MarkFavoritePerson request)
- {
- var task = MarkFavorite(() => LibraryManager.GetPerson(request.Name), request.UserId, true);
-
- Task.WaitAll(task);
- }
-
- /// <summary>
- /// Deletes the specified request.
- /// </summary>
- /// <param name="request">The request.</param>
- public void Delete(UnmarkFavoritePerson request)
- {
- var task = MarkFavorite(() => LibraryManager.GetPerson(request.Name), request.UserId, false);
-
- Task.WaitAll(task);
- }
-
- /// <summary>
/// Gets all items.
/// </summary>
/// <param name="request">The request.</param>
diff --git a/MediaBrowser.Api/UserLibrary/StudiosService.cs b/MediaBrowser.Api/UserLibrary/StudiosService.cs
index 24f09c5ef..77f20d8e8 100644
--- a/MediaBrowser.Api/UserLibrary/StudiosService.cs
+++ b/MediaBrowser.Api/UserLibrary/StudiosService.cs
@@ -1,5 +1,6 @@
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Persistence;
using ServiceStack.ServiceHost;
using System;
using System.Collections.Generic;
@@ -17,52 +18,14 @@ namespace MediaBrowser.Api.UserLibrary
public class GetStudios : GetItemsByName
{
}
-
- [Route("/Users/{UserId}/FavoriteStudios/{Name}", "POST")]
- [Api(Description = "Marks a studio as a favorite")]
- public class MarkFavoriteStudio : IReturnVoid
- {
- /// <summary>
- /// Gets or sets the user id.
- /// </summary>
- /// <value>The user id.</value>
- [ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
- public Guid UserId { get; set; }
-
- /// <summary>
- /// Gets or sets the name.
- /// </summary>
- /// <value>The name.</value>
- [ApiMember(Name = "Name", Description = "Name", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")]
- public string Name { get; set; }
- }
-
- [Route("/Users/{UserId}/FavoriteStudios/{Name}", "DELETE")]
- [Api(Description = "Unmarks a studio as a favorite")]
- public class UnmarkFavoriteStudio : IReturnVoid
- {
- /// <summary>
- /// Gets or sets the user id.
- /// </summary>
- /// <value>The user id.</value>
- [ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")]
- public Guid UserId { get; set; }
-
- /// <summary>
- /// Gets or sets the name.
- /// </summary>
- /// <value>The name.</value>
- [ApiMember(Name = "Name", Description = "Name", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")]
- public string Name { get; set; }
- }
/// <summary>
/// Class StudiosService
/// </summary>
public class StudiosService : BaseItemsByNameService<Studio>
{
- public StudiosService(IUserManager userManager, ILibraryManager libraryManager)
- : base(userManager, libraryManager)
+ public StudiosService(IUserManager userManager, ILibraryManager libraryManager, IUserDataRepository userDataRepository)
+ : base(userManager, libraryManager, userDataRepository)
{
}
@@ -77,28 +40,6 @@ namespace MediaBrowser.Api.UserLibrary
return ToOptimizedResult(result);
}
-
- /// <summary>
- /// Posts the specified request.
- /// </summary>
- /// <param name="request">The request.</param>
- public void Post(MarkFavoriteStudio request)
- {
- var task = MarkFavorite(() => LibraryManager.GetStudio(request.Name), request.UserId, true);
-
- Task.WaitAll(task);
- }
-
- /// <summary>
- /// Deletes the specified request.
- /// </summary>
- /// <param name="request">The request.</param>
- public void Delete(UnmarkFavoriteStudio request)
- {
- var task = MarkFavorite(() => LibraryManager.GetStudio(request.Name), request.UserId, false);
-
- Task.WaitAll(task);
- }
/// <summary>
/// Gets all items.
diff --git a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs
index e24e63819..70e5287a1 100644
--- a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs
+++ b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs
@@ -1,6 +1,8 @@
-using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Dto;
+using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Persistence;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Querying;
using ServiceStack.ServiceHost;
@@ -335,18 +337,19 @@ namespace MediaBrowser.Api.UserLibrary
/// The _user manager
/// </summary>
private readonly IUserManager _userManager;
-
+ private readonly IUserDataRepository _userDataRepository;
private readonly ILibraryManager _libraryManager;
/// <summary>
/// Initializes a new instance of the <see cref="UserLibraryService" /> class.
/// </summary>
/// <exception cref="System.ArgumentNullException">jsonSerializer</exception>
- public UserLibraryService(IUserManager userManager, ILibraryManager libraryManager)
+ public UserLibraryService(IUserManager userManager, ILibraryManager libraryManager, IUserDataRepository userDataRepository)
: base()
{
_userManager = userManager;
_libraryManager = libraryManager;
+ _userDataRepository = userDataRepository;
}
/// <summary>
@@ -365,7 +368,7 @@ namespace MediaBrowser.Api.UserLibrary
var movie = (Movie)item;
- var dtoBuilder = new DtoBuilder(Logger, _libraryManager, _userManager);
+ var dtoBuilder = new DtoBuilder(Logger, _libraryManager, _userDataRepository);
var items = movie.SpecialFeatures.Select(i => dtoBuilder.GetBaseItemDto(i, user, fields)).AsParallel().Select(t => t.Result).ToList();
@@ -386,7 +389,7 @@ namespace MediaBrowser.Api.UserLibrary
// Get everything
var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true)).ToList();
- var dtoBuilder = new DtoBuilder(Logger, _libraryManager, _userManager);
+ var dtoBuilder = new DtoBuilder(Logger, _libraryManager, _userDataRepository);
var items = item.LocalTrailers.Select(i => dtoBuilder.GetBaseItemDto(i, user, fields)).AsParallel().Select(t => t.Result).ToList();
@@ -407,7 +410,7 @@ namespace MediaBrowser.Api.UserLibrary
// Get everything
var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true)).ToList();
- var dtoBuilder = new DtoBuilder(Logger, _libraryManager, _userManager);
+ var dtoBuilder = new DtoBuilder(Logger, _libraryManager, _userDataRepository);
var result = dtoBuilder.GetBaseItemDto(item, user, fields).Result;
@@ -423,7 +426,7 @@ namespace MediaBrowser.Api.UserLibrary
// Get everything
var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true)).ToList();
- var dtoBuilder = new DtoBuilder(Logger, _libraryManager, _userManager);
+ var dtoBuilder = new DtoBuilder(Logger, _libraryManager, _userDataRepository);
var result = dtoBuilder.GetBaseItemDto(item, user, fields).Result;
@@ -457,12 +460,14 @@ namespace MediaBrowser.Api.UserLibrary
var item = string.IsNullOrEmpty(request.Id) ? user.RootFolder : DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager, user.Id);
// Get the user data for this item
- var data = _userManager.GetUserData(user.Id, item.UserDataId).Result;
+ var key = item.GetUserDataKey();
+
+ var data = _userDataRepository.GetUserData(user.Id, key).Result;
// Set favorite status
data.IsFavorite = true;
- var task = _userManager.SaveUserData(user.Id, item.UserDataId, data, CancellationToken.None);
+ var task = _userDataRepository.SaveUserData(user.Id, key, data, CancellationToken.None);
Task.WaitAll(task);
}
@@ -477,13 +482,15 @@ namespace MediaBrowser.Api.UserLibrary
var item = string.IsNullOrEmpty(request.Id) ? user.RootFolder : DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager, user.Id);
+ var key = item.GetUserDataKey();
+
// Get the user data for this item
- var data = _userManager.GetUserData(user.Id, item.UserDataId).Result;
+ var data = _userDataRepository.GetUserData(user.Id, key).Result;
// Set favorite status
data.IsFavorite = false;
- var task = _userManager.SaveUserData(user.Id, item.UserDataId, data, CancellationToken.None);
+ var task = _userDataRepository.SaveUserData(user.Id, key, data, CancellationToken.None);
Task.WaitAll(task);
}
@@ -498,12 +505,14 @@ namespace MediaBrowser.Api.UserLibrary
var item = string.IsNullOrEmpty(request.Id) ? user.RootFolder : DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager, user.Id);
+ var key = item.GetUserDataKey();
+
// Get the user data for this item
- var data = _userManager.GetUserData(user.Id, item.UserDataId).Result;
+ var data = _userDataRepository.GetUserData(user.Id, key).Result;
data.Rating = null;
- var task = _userManager.SaveUserData(user.Id, item.UserDataId, data, CancellationToken.None);
+ var task = _userDataRepository.SaveUserData(user.Id, key, data, CancellationToken.None);
Task.WaitAll(task);
}
@@ -518,12 +527,14 @@ namespace MediaBrowser.Api.UserLibrary
var item = string.IsNullOrEmpty(request.Id) ? user.RootFolder : DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager, user.Id);
+ var key = item.GetUserDataKey();
+
// Get the user data for this item
- var data = _userManager.GetUserData(user.Id, item.UserDataId).Result;
+ var data = _userDataRepository.GetUserData(user.Id, key).Result;
data.Likes = request.Likes;
- var task = _userManager.SaveUserData(user.Id, item.UserDataId, data, CancellationToken.None);
+ var task = _userDataRepository.SaveUserData(user.Id, key, data, CancellationToken.None);
Task.WaitAll(task);
}
@@ -623,7 +634,7 @@ namespace MediaBrowser.Api.UserLibrary
{
var item = DtoBuilder.GetItemByClientId(itemId, _userManager, _libraryManager, user.Id);
- return item.SetPlayedStatus(user, wasPlayed, _userManager);
+ return item.SetPlayedStatus(user, wasPlayed, _userDataRepository);
}
}
}
diff --git a/MediaBrowser.Api/UserLibrary/YearsService.cs b/MediaBrowser.Api/UserLibrary/YearsService.cs
index f2cf36750..481645c24 100644
--- a/MediaBrowser.Api/UserLibrary/YearsService.cs
+++ b/MediaBrowser.Api/UserLibrary/YearsService.cs
@@ -1,5 +1,6 @@
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Persistence;
using ServiceStack.ServiceHost;
using System;
using System.Collections.Generic;
@@ -28,9 +29,9 @@ namespace MediaBrowser.Api.UserLibrary
/// The us culture
/// </summary>
private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
-
- public YearsService(IUserManager userManager, ILibraryManager libraryManager)
- : base(userManager, libraryManager)
+
+ public YearsService(IUserManager userManager, ILibraryManager libraryManager, IUserDataRepository userDataRepository)
+ : base(userManager, libraryManager, userDataRepository)
{
}
diff --git a/MediaBrowser.Api/UserService.cs b/MediaBrowser.Api/UserService.cs
index 76c67cd2f..3f3af743d 100644
--- a/MediaBrowser.Api/UserService.cs
+++ b/MediaBrowser.Api/UserService.cs
@@ -1,4 +1,5 @@
using MediaBrowser.Common.Extensions;
+using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Serialization;
@@ -165,7 +166,7 @@ namespace MediaBrowser.Api
/// <returns>System.Object.</returns>
public object Get(GetUsers request)
{
- var dtoBuilder = new DtoBuilder(Logger, _libraryManager, _userManager);
+ var dtoBuilder = new UserDtoBuilder(Logger);
var users = _userManager.Users.OrderBy(u => u.Name).Select(dtoBuilder.GetUserDto).ToArray();
@@ -186,7 +187,9 @@ namespace MediaBrowser.Api
throw new ResourceNotFoundException("User not found");
}
- var result = new DtoBuilder(Logger, _libraryManager, _userManager).GetUserDto(user);
+ var dtoBuilder = new UserDtoBuilder(Logger);
+
+ var result = dtoBuilder.GetUserDto(user);
return ToOptimizedResult(result);
}
@@ -300,7 +303,9 @@ namespace MediaBrowser.Api
newUser.UpdateConfiguration(dtoUser.Configuration, _xmlSerializer);
- var result = new DtoBuilder(Logger, _libraryManager, _userManager).GetUserDto(newUser);
+ var dtoBuilder = new UserDtoBuilder(Logger);
+
+ var result = dtoBuilder.GetUserDto(newUser);
return ToOptimizedResult(result);
}
diff --git a/MediaBrowser.Common/Extensions/BaseExtensions.cs b/MediaBrowser.Common/Extensions/BaseExtensions.cs
index 9591862e7..b4ad90168 100644
--- a/MediaBrowser.Common/Extensions/BaseExtensions.cs
+++ b/MediaBrowser.Common/Extensions/BaseExtensions.cs
@@ -1,6 +1,4 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
@@ -56,26 +54,6 @@ namespace MediaBrowser.Common.Extensions
}
/// <summary>
- /// Helper method for Dictionaries since they throw on not-found keys
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <typeparam name="U"></typeparam>
- /// <param name="dictionary">The dictionary.</param>
- /// <param name="key">The key.</param>
- /// <param name="defaultValue">The default value.</param>
- /// <returns>``1.</returns>
- public static U GetValueOrDefault<T, U>(this Dictionary<T, U> dictionary, T key, U defaultValue)
- {
- U val;
- if (!dictionary.TryGetValue(key, out val))
- {
- val = defaultValue;
- }
- return val;
-
- }
-
- /// <summary>
/// Gets the attribute value.
/// </summary>
/// <param name="str">The STR.</param>
diff --git a/MediaBrowser.Common/Plugins/BasePlugin.cs b/MediaBrowser.Common/Plugins/BasePlugin.cs
index ca2891734..f90cd2c0f 100644
--- a/MediaBrowser.Common/Plugins/BasePlugin.cs
+++ b/MediaBrowser.Common/Plugins/BasePlugin.cs
@@ -302,7 +302,7 @@ namespace MediaBrowser.Common.Plugins
AssemblyFileName = AssemblyFileName,
ConfigurationDateLastModified = ConfigurationDateLastModified,
Description = Description,
- Id = Id,
+ Id = Id.ToString(),
EnableAutoUpdate = Configuration.EnableAutoUpdate,
UpdateClass = Configuration.UpdateClass,
ConfigurationFileName = ConfigurationFileName
diff --git a/MediaBrowser.Controller/Library/DtoBuilder.cs b/MediaBrowser.Controller/Dto/DtoBuilder.cs
index 7f9a6f187..0da4da356 100644
--- a/MediaBrowser.Controller/Library/DtoBuilder.cs
+++ b/MediaBrowser.Controller/Dto/DtoBuilder.cs
@@ -3,6 +3,8 @@ using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Entities.TV;
+using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Persistence;
using MediaBrowser.Model.Drawing;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
@@ -14,7 +16,7 @@ using System.IO;
using System.Linq;
using System.Threading.Tasks;
-namespace MediaBrowser.Controller.Library
+namespace MediaBrowser.Controller.Dto
{
/// <summary>
/// Generates DTO's from domain entities
@@ -28,13 +30,13 @@ namespace MediaBrowser.Controller.Library
private readonly ILogger _logger;
private readonly ILibraryManager _libraryManager;
- private readonly IUserManager _userManager;
+ private readonly IUserDataRepository _userDataRepository;
- public DtoBuilder(ILogger logger, ILibraryManager libraryManager, IUserManager userManager)
+ public DtoBuilder(ILogger logger, ILibraryManager libraryManager, IUserDataRepository userDataRepository)
{
_logger = logger;
_libraryManager = libraryManager;
- _userManager = userManager;
+ _userDataRepository = userDataRepository;
}
/// <summary>
@@ -73,7 +75,7 @@ namespace MediaBrowser.Controller.Library
{
try
{
- AttachPrimaryImageAspectRatio(dto, item);
+ AttachPrimaryImageAspectRatio(dto, item, _logger);
}
catch (Exception ex)
{
@@ -136,7 +138,7 @@ namespace MediaBrowser.Controller.Library
{
try
{
- AttachPrimaryImageAspectRatio(dto, item);
+ AttachPrimaryImageAspectRatio(dto, item, _logger);
}
catch (Exception ex)
{
@@ -167,7 +169,7 @@ namespace MediaBrowser.Controller.Library
{
if (fields.Contains(ItemFields.UserData))
{
- var userData = await _userManager.GetUserData(user.Id, item.UserDataId).ConfigureAwait(false);
+ var userData = await _userDataRepository.GetUserData(user.Id, item.GetUserDataKey()).ConfigureAwait(false);
dto.UserData = GetUserItemDataDto(userData);
}
@@ -186,18 +188,19 @@ namespace MediaBrowser.Controller.Library
// Skip sorting since all we want is a count
dto.ChildCount = folder.GetChildren(user).Count();
- await SetSpecialCounts(folder, user, dto, _userManager).ConfigureAwait(false);
+ await SetSpecialCounts(folder, user, dto, _userDataRepository).ConfigureAwait(false);
}
}
}
-
+
/// <summary>
/// Attaches the primary image aspect ratio.
/// </summary>
/// <param name="dto">The dto.</param>
/// <param name="item">The item.</param>
+ /// <param name="_logger">The _logger.</param>
/// <returns>Task.</returns>
- private void AttachPrimaryImageAspectRatio(IItemDto dto, BaseItem item)
+ internal static void AttachPrimaryImageAspectRatio(IItemDto dto, BaseItem item, ILogger _logger)
{
var path = item.PrimaryImagePath;
@@ -503,9 +506,9 @@ namespace MediaBrowser.Controller.Library
/// <param name="folder">The folder.</param>
/// <param name="user">The user.</param>
/// <param name="dto">The dto.</param>
- /// <param name="userManager">The user manager.</param>
+ /// <param name="userDataRepository">The user data repository.</param>
/// <returns>Task.</returns>
- private static async Task SetSpecialCounts(Folder folder, User user, BaseItemDto dto, IUserManager userManager)
+ private static async Task SetSpecialCounts(Folder folder, User user, BaseItemDto dto, IUserDataRepository userDataRepository)
{
var rcentlyAddedItemCount = 0;
var recursiveItemCount = 0;
@@ -515,7 +518,7 @@ namespace MediaBrowser.Controller.Library
// Loop through each recursive child
foreach (var child in folder.GetRecursiveChildren(user).Where(i => !i.IsFolder))
{
- var userdata = await userManager.GetUserData(user.Id, child.UserDataId).ConfigureAwait(false);
+ var userdata = await userDataRepository.GetUserData(user.Id, child.GetUserDataKey()).ConfigureAwait(false);
recursiveItemCount++;
@@ -786,49 +789,6 @@ namespace MediaBrowser.Controller.Library
}
/// <summary>
- /// Converts a User to a DTOUser
- /// </summary>
- /// <param name="user">The user.</param>
- /// <returns>DtoUser.</returns>
- /// <exception cref="System.ArgumentNullException">user</exception>
- public UserDto GetUserDto(User user)
- {
- if (user == null)
- {
- throw new ArgumentNullException("user");
- }
-
- var dto = new UserDto
- {
- Id = user.Id,
- Name = user.Name,
- HasPassword = !String.IsNullOrEmpty(user.Password),
- LastActivityDate = user.LastActivityDate,
- LastLoginDate = user.LastLoginDate,
- Configuration = user.Configuration
- };
-
- var image = user.PrimaryImagePath;
-
- if (!string.IsNullOrEmpty(image))
- {
- dto.PrimaryImageTag = Kernel.Instance.ImageManager.GetImageCacheTag(user, ImageType.Primary, image);
-
- try
- {
- 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;
- }
-
- /// <summary>
/// Gets a BaseItem based upon it's client-side item id
/// </summary>
/// <param name="id">The id.</param>
diff --git a/MediaBrowser.Controller/Dto/UserDtoBuilder.cs b/MediaBrowser.Controller/Dto/UserDtoBuilder.cs
new file mode 100644
index 000000000..5c717529a
--- /dev/null
+++ b/MediaBrowser.Controller/Dto/UserDtoBuilder.cs
@@ -0,0 +1,71 @@
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Model.Dto;
+using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.Logging;
+using System;
+
+namespace MediaBrowser.Controller.Dto
+{
+ /// <summary>
+ /// Class UserDtoBuilder
+ /// </summary>
+ public class UserDtoBuilder
+ {
+ /// <summary>
+ /// The _logger
+ /// </summary>
+ private readonly ILogger _logger;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="UserDtoBuilder"/> class.
+ /// </summary>
+ /// <param name="logger">The logger.</param>
+ public UserDtoBuilder(ILogger logger)
+ {
+ _logger = logger;
+ }
+
+ /// <summary>
+ /// Converts a User to a DTOUser
+ /// </summary>
+ /// <param name="user">The user.</param>
+ /// <returns>DtoUser.</returns>
+ /// <exception cref="System.ArgumentNullException">user</exception>
+ public UserDto GetUserDto(User user)
+ {
+ if (user == null)
+ {
+ throw new ArgumentNullException("user");
+ }
+
+ var dto = new UserDto
+ {
+ Id = user.Id.ToString(),
+ Name = user.Name,
+ HasPassword = !String.IsNullOrEmpty(user.Password),
+ LastActivityDate = user.LastActivityDate,
+ LastLoginDate = user.LastLoginDate,
+ Configuration = user.Configuration
+ };
+
+ var image = user.PrimaryImagePath;
+
+ if (!string.IsNullOrEmpty(image))
+ {
+ dto.PrimaryImageTag = Kernel.Instance.ImageManager.GetImageCacheTag(user, ImageType.Primary, image);
+
+ try
+ {
+ DtoBuilder.AttachPrimaryImageAspectRatio(dto, user, _logger);
+ }
+ 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;
+ }
+ }
+}
diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs
index 2cb8ac794..ccaabd438 100644
--- a/MediaBrowser.Controller/Entities/BaseItem.cs
+++ b/MediaBrowser.Controller/Entities/BaseItem.cs
@@ -3,6 +3,7 @@ using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.IO;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Localization;
+using MediaBrowser.Controller.Persistence;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Controller.Resolvers;
using MediaBrowser.Model.Entities;
@@ -183,23 +184,18 @@ namespace MediaBrowser.Controller.Entities
/// <summary>
/// The _file system stamp
/// </summary>
- private Guid? _fileSystemStamp;
+ private string _fileSystemStamp;
/// <summary>
/// Gets a directory stamp, in the form of a string, that can be used for
/// comparison purposes to determine if the file system entries for this item have changed.
/// </summary>
/// <value>The file system stamp.</value>
[IgnoreDataMember]
- public Guid FileSystemStamp
+ public string FileSystemStamp
{
get
{
- if (!_fileSystemStamp.HasValue)
- {
- _fileSystemStamp = GetFileSystemStamp();
- }
-
- return _fileSystemStamp.Value;
+ return _fileSystemStamp ?? (_fileSystemStamp = GetFileSystemStamp());
}
}
@@ -221,12 +217,12 @@ namespace MediaBrowser.Controller.Entities
/// comparison purposes to determine if the file system entries for this item have changed.
/// </summary>
/// <returns>Guid.</returns>
- private Guid GetFileSystemStamp()
+ private string GetFileSystemStamp()
{
// If there's no path or the item is a file, there's nothing to do
if (LocationType != LocationType.FileSystem || !ResolveArgs.IsDirectory)
{
- return Guid.Empty;
+ return string.Empty;
}
var sb = new StringBuilder();
@@ -242,7 +238,7 @@ namespace MediaBrowser.Controller.Entities
sb.Append(file.cFileName);
}
- return sb.ToString().GetMD5();
+ return sb.ToString();
}
/// <summary>
@@ -820,21 +816,12 @@ namespace MediaBrowser.Controller.Entities
}
/// <summary>
- /// The _user data id
+ /// Gets the user data key.
/// </summary>
- protected Guid _userDataId; //cache this so it doesn't have to be re-constructed on every reference
- /// <summary>
- /// Return the id that should be used to key user data for this item.
- /// Default is just this Id but subclasses can use provider Ids for transportability.
- /// </summary>
- /// <value>The user data id.</value>
- [IgnoreDataMember]
- public virtual Guid UserDataId
+ /// <returns>System.String.</returns>
+ public virtual string GetUserDataKey()
{
- get
- {
- return _userDataId == Guid.Empty ? (_userDataId = Id) : _userDataId;
- }
+ return Id.ToString();
}
/// <summary>
@@ -1151,14 +1138,16 @@ namespace MediaBrowser.Controller.Entities
/// <param name="userManager">The user manager.</param>
/// <returns>Task.</returns>
/// <exception cref="System.ArgumentNullException"></exception>
- public virtual async Task SetPlayedStatus(User user, bool wasPlayed, IUserManager userManager)
+ public virtual async Task SetPlayedStatus(User user, bool wasPlayed, IUserDataRepository userManager)
{
if (user == null)
{
throw new ArgumentNullException();
}
- var data = await userManager.GetUserData(user.Id, UserDataId).ConfigureAwait(false);
+ var key = GetUserDataKey();
+
+ var data = await userManager.GetUserData(user.Id, key).ConfigureAwait(false);
if (wasPlayed)
{
@@ -1181,7 +1170,7 @@ namespace MediaBrowser.Controller.Entities
data.Played = wasPlayed;
- await userManager.SaveUserData(user.Id, UserDataId, data, CancellationToken.None).ConfigureAwait(false);
+ await userManager.SaveUserData(user.Id, key, data, CancellationToken.None).ConfigureAwait(false);
}
/// <summary>
diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs
index eefce2fd3..fed6bb7de 100644
--- a/MediaBrowser.Controller/Entities/Folder.cs
+++ b/MediaBrowser.Controller/Entities/Folder.cs
@@ -3,6 +3,7 @@ using MediaBrowser.Common.Progress;
using MediaBrowser.Controller.IO;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Localization;
+using MediaBrowser.Controller.Persistence;
using MediaBrowser.Controller.Resolvers;
using MediaBrowser.Model.Entities;
using System;
@@ -809,7 +810,7 @@ namespace MediaBrowser.Controller.Entities
/// <param name="wasPlayed">if set to <c>true</c> [was played].</param>
/// <param name="userManager">The user manager.</param>
/// <returns>Task.</returns>
- public override async Task SetPlayedStatus(User user, bool wasPlayed, IUserManager userManager)
+ public override async Task SetPlayedStatus(User user, bool wasPlayed, IUserDataRepository userManager)
{
await base.SetPlayedStatus(user, wasPlayed, userManager).ConfigureAwait(false);
diff --git a/MediaBrowser.Controller/Entities/Genre.cs b/MediaBrowser.Controller/Entities/Genre.cs
index d5e8afb20..619c7a12b 100644
--- a/MediaBrowser.Controller/Entities/Genre.cs
+++ b/MediaBrowser.Controller/Entities/Genre.cs
@@ -6,5 +6,13 @@ namespace MediaBrowser.Controller.Entities
/// </summary>
public class Genre : BaseItem
{
+ /// <summary>
+ /// Gets the user data key.
+ /// </summary>
+ /// <returns>System.String.</returns>
+ public override string GetUserDataKey()
+ {
+ return Name;
+ }
}
}
diff --git a/MediaBrowser.Controller/Entities/Movies/Movie.cs b/MediaBrowser.Controller/Entities/Movies/Movie.cs
index d08588077..b70ac2b3b 100644
--- a/MediaBrowser.Controller/Entities/Movies/Movie.cs
+++ b/MediaBrowser.Controller/Entities/Movies/Movie.cs
@@ -1,7 +1,5 @@
-using MediaBrowser.Common.Extensions;
-using MediaBrowser.Controller.IO;
+using MediaBrowser.Controller.IO;
using MediaBrowser.Model.Entities;
-using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -30,21 +28,12 @@ namespace MediaBrowser.Controller.Entities.Movies
}
/// <summary>
- /// Override to use tmdb or imdb id so it will stick if the item moves physical locations
+ /// Gets the user data key.
/// </summary>
- /// <value>The user data id.</value>
- [IgnoreDataMember]
- public override Guid UserDataId
+ /// <returns>System.String.</returns>
+ public override string GetUserDataKey()
{
- get
- {
- if (_userDataId == Guid.Empty)
- {
- var baseId = this.GetProviderId(MetadataProviders.Tmdb) ?? this.GetProviderId(MetadataProviders.Imdb);
- _userDataId = baseId != null ? baseId.GetMD5() : Id;
- }
- return _userDataId;
- }
+ return this.GetProviderId(MetadataProviders.Tmdb) ?? this.GetProviderId(MetadataProviders.Imdb) ?? base.GetUserDataKey();
}
/// <summary>
diff --git a/MediaBrowser.Controller/Entities/Person.cs b/MediaBrowser.Controller/Entities/Person.cs
index 5c92c019b..f5570448d 100644
--- a/MediaBrowser.Controller/Entities/Person.cs
+++ b/MediaBrowser.Controller/Entities/Person.cs
@@ -6,6 +6,14 @@ namespace MediaBrowser.Controller.Entities
/// </summary>
public class Person : BaseItem
{
+ /// <summary>
+ /// Gets the user data key.
+ /// </summary>
+ /// <returns>System.String.</returns>
+ public override string GetUserDataKey()
+ {
+ return Name;
+ }
}
/// <summary>
diff --git a/MediaBrowser.Controller/Entities/Studio.cs b/MediaBrowser.Controller/Entities/Studio.cs
index a255849e6..06511d959 100644
--- a/MediaBrowser.Controller/Entities/Studio.cs
+++ b/MediaBrowser.Controller/Entities/Studio.cs
@@ -6,5 +6,13 @@ namespace MediaBrowser.Controller.Entities
/// </summary>
public class Studio : BaseItem
{
+ /// <summary>
+ /// Gets the user data key.
+ /// </summary>
+ /// <returns>System.String.</returns>
+ public override string GetUserDataKey()
+ {
+ return Name;
+ }
}
}
diff --git a/MediaBrowser.Controller/Entities/TV/Episode.cs b/MediaBrowser.Controller/Entities/TV/Episode.cs
index 7588e4e69..dd1434cea 100644
--- a/MediaBrowser.Controller/Entities/TV/Episode.cs
+++ b/MediaBrowser.Controller/Entities/TV/Episode.cs
@@ -49,27 +49,19 @@ namespace MediaBrowser.Controller.Entities.TV
}
/// <summary>
- /// Override to use the provider Ids + season and episode number so it will be portable
+ /// Gets the user data key.
/// </summary>
- /// <value>The user data id.</value>
- [IgnoreDataMember]
- public override Guid UserDataId
+ /// <returns>System.String.</returns>
+ public override string GetUserDataKey()
{
- get
+ if (Series != null)
{
- if (_userDataId == Guid.Empty)
- {
- var baseId = Series != null ? Series.GetProviderId(MetadataProviders.Tvdb) ?? Series.GetProviderId(MetadataProviders.Tvcom) : null;
- if (baseId != null)
- {
- var seasonNo = Season != null ? Season.IndexNumber ?? 0 : 0;
- var epNo = IndexNumber ?? 0;
- baseId = baseId + seasonNo.ToString("000") + epNo.ToString("000");
- }
- _userDataId = baseId != null ? baseId.GetMD5() : Id;
- }
- return _userDataId;
+ var seasonNo = Season != null ? Season.IndexNumber ?? 0 : 0;
+ var epNo = IndexNumber ?? 0;
+ return Series.GetUserDataKey() + seasonNo.ToString("000") + epNo.ToString("000");
}
+
+ return base.GetUserDataKey();
}
/// <summary>
diff --git a/MediaBrowser.Controller/Entities/TV/Season.cs b/MediaBrowser.Controller/Entities/TV/Season.cs
index 2f2bee172..2f3f7387c 100644
--- a/MediaBrowser.Controller/Entities/TV/Season.cs
+++ b/MediaBrowser.Controller/Entities/TV/Season.cs
@@ -67,27 +67,18 @@ namespace MediaBrowser.Controller.Entities.TV
}
/// <summary>
- /// Override to use the provider Ids + season number so it will be portable
+ /// Gets the user data key.
/// </summary>
- /// <value>The user data id.</value>
- [IgnoreDataMember]
- public override Guid UserDataId
+ /// <returns>System.String.</returns>
+ public override string GetUserDataKey()
{
- get
+ if (Series != null)
{
- if (_userDataId == Guid.Empty)
- {
- var baseId = Series != null ? Series.GetProviderId(MetadataProviders.Tvdb) ?? Series.GetProviderId(MetadataProviders.Tvcom) : null;
- if (baseId != null)
- {
- var seasonNo = IndexNumber ?? 0;
- baseId = baseId + seasonNo.ToString("000");
- }
-
- _userDataId = baseId != null ? baseId.GetMD5() : Id;
- }
- return _userDataId;
+ var seasonNo = IndexNumber ?? 0;
+ return Series.GetUserDataKey() + seasonNo.ToString("000");
}
+
+ return base.GetUserDataKey();
}
/// <summary>
diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs
index 8a56e45cd..15b97f694 100644
--- a/MediaBrowser.Controller/Entities/TV/Series.cs
+++ b/MediaBrowser.Controller/Entities/TV/Series.cs
@@ -44,21 +44,12 @@ namespace MediaBrowser.Controller.Entities.TV
}
/// <summary>
- /// Override to use the provider Ids so it will be portable
+ /// Gets the user data key.
/// </summary>
- /// <value>The user data id.</value>
- [IgnoreDataMember]
- public override Guid UserDataId
+ /// <returns>System.String.</returns>
+ public override string GetUserDataKey()
{
- get
- {
- if (_userDataId == Guid.Empty)
- {
- var baseId = this.GetProviderId(MetadataProviders.Tvdb) ?? this.GetProviderId(MetadataProviders.Tvcom);
- _userDataId = baseId != null ? baseId.GetMD5() : Id;
- }
- return _userDataId;
- }
+ return this.GetProviderId(MetadataProviders.Tvdb) ?? this.GetProviderId(MetadataProviders.Tvcom) ?? base.GetUserDataKey();
}
// Studio, Genre and Rating will all be the same so makes no sense to index by these
diff --git a/MediaBrowser.Controller/Entities/Year.cs b/MediaBrowser.Controller/Entities/Year.cs
index 9150057c8..1e4e6cb06 100644
--- a/MediaBrowser.Controller/Entities/Year.cs
+++ b/MediaBrowser.Controller/Entities/Year.cs
@@ -6,5 +6,13 @@ namespace MediaBrowser.Controller.Entities
/// </summary>
public class Year : BaseItem
{
+ /// <summary>
+ /// Gets the user data key.
+ /// </summary>
+ /// <returns>System.String.</returns>
+ public override string GetUserDataKey()
+ {
+ return Name;
+ }
}
}
diff --git a/MediaBrowser.Controller/Library/IUserManager.cs b/MediaBrowser.Controller/Library/IUserManager.cs
index ad46cf7c3..0fad1d05d 100644
--- a/MediaBrowser.Controller/Library/IUserManager.cs
+++ b/MediaBrowser.Controller/Library/IUserManager.cs
@@ -173,24 +173,5 @@ namespace MediaBrowser.Controller.Library
/// <param name="newPassword">The new password.</param>
/// <returns>Task.</returns>
Task ChangePassword(User user, string newPassword);
-
- /// <summary>
- /// Saves the user data.
- /// </summary>
- /// <param name="userId">The user id.</param>
- /// <param name="userDataId">The user data id.</param>
- /// <param name="userData">The user data.</param>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <returns>Task.</returns>
- Task SaveUserData(Guid userId, Guid userDataId, UserItemData userData,
- CancellationToken cancellationToken);
-
- /// <summary>
- /// Gets the user data.
- /// </summary>
- /// <param name="userId">The user id.</param>
- /// <param name="userDataId">The user data id.</param>
- /// <returns>Task{UserItemData}.</returns>
- Task<UserItemData> GetUserData(Guid userId, Guid userDataId);
}
}
diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
index 558a9d8e3..71245a3bb 100644
--- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj
+++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
@@ -72,6 +72,7 @@
<Compile Include="Drawing\ImageExtensions.cs" />
<Compile Include="Drawing\ImageHeader.cs" />
<Compile Include="Drawing\ImageManager.cs" />
+ <Compile Include="Dto\UserDtoBuilder.cs" />
<Compile Include="Entities\AggregateFolder.cs" />
<Compile Include="Entities\Audio\Audio.cs" />
<Compile Include="Entities\Audio\MusicAlbum.cs" />
@@ -107,7 +108,7 @@
<Compile Include="IServerApplicationHost.cs" />
<Compile Include="IServerApplicationPaths.cs" />
<Compile Include="Library\ChildrenChangedEventArgs.cs" />
- <Compile Include="Library\DtoBuilder.cs" />
+ <Compile Include="Dto\DtoBuilder.cs" />
<Compile Include="Providers\IProviderManager.cs" />
<Compile Include="Providers\MediaInfo\MediaEncoderHelpers.cs" />
<Compile Include="Providers\MetadataProviderPriority.cs" />
diff --git a/MediaBrowser.Controller/Persistence/IUserDataRepository.cs b/MediaBrowser.Controller/Persistence/IUserDataRepository.cs
index 592206faf..1b4efc58b 100644
--- a/MediaBrowser.Controller/Persistence/IUserDataRepository.cs
+++ b/MediaBrowser.Controller/Persistence/IUserDataRepository.cs
@@ -1,5 +1,5 @@
-using MediaBrowser.Controller.Entities;
-using System;
+using System;
+using MediaBrowser.Controller.Entities;
using System.Threading;
using System.Threading.Tasks;
@@ -14,19 +14,19 @@ namespace MediaBrowser.Controller.Persistence
/// Saves the user data.
/// </summary>
/// <param name="userId">The user id.</param>
- /// <param name="userDataId">The user data id.</param>
+ /// <param name="key">The key.</param>
/// <param name="userData">The user data.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
- Task SaveUserData(Guid userId, Guid userDataId, UserItemData userData,
+ Task SaveUserData(Guid userId, string key, UserItemData userData,
CancellationToken cancellationToken);
/// <summary>
/// Gets the user data.
/// </summary>
/// <param name="userId">The user id.</param>
- /// <param name="userDataId">The user data id.</param>
+ /// <param name="key">The key.</param>
/// <returns>Task{UserItemData}.</returns>
- Task<UserItemData> GetUserData(Guid userId, Guid userDataId);
+ Task<UserItemData> GetUserData(Guid userId, string key);
}
}
diff --git a/MediaBrowser.Controller/Providers/BaseMetadataProvider.cs b/MediaBrowser.Controller/Providers/BaseMetadataProvider.cs
index aaf3fe6bf..3f71e398a 100644
--- a/MediaBrowser.Controller/Providers/BaseMetadataProvider.cs
+++ b/MediaBrowser.Controller/Providers/BaseMetadataProvider.cs
@@ -29,19 +29,7 @@ namespace MediaBrowser.Controller.Providers
/// <summary>
/// The _id
/// </summary>
- protected Guid _id;
- /// <summary>
- /// Gets the id.
- /// </summary>
- /// <value>The id.</value>
- public virtual Guid Id
- {
- get
- {
- if (_id == Guid.Empty) _id = GetType().FullName.GetMD5();
- return _id;
- }
- }
+ protected readonly Guid Id;
/// <summary>
/// Supportses the specified item.
@@ -105,6 +93,7 @@ namespace MediaBrowser.Controller.Providers
Logger = logManager.GetLogger(GetType().Name);
LogManager = logManager;
ConfigurationManager = configurationManager;
+ Id = GetType().FullName.GetMD5();
Initialize();
}
@@ -130,8 +119,14 @@ namespace MediaBrowser.Controller.Providers
{
throw new ArgumentNullException("item");
}
-
- var data = item.ProviderData.GetValueOrDefault(Id, new BaseProviderInfo { ProviderId = Id });
+
+ BaseProviderInfo data;
+
+ if (!item.ProviderData.TryGetValue(Id, out data))
+ {
+ data = new BaseProviderInfo();
+ }
+
data.LastRefreshed = value;
data.LastRefreshStatus = status;
data.ProviderVersion = providerVersion;
@@ -155,7 +150,7 @@ namespace MediaBrowser.Controller.Providers
{
SetLastRefreshed(item, value, ProviderVersion, status);
}
-
+
/// <summary>
/// Returns whether or not this provider should be re-fetched. Default functionality can
/// compare a provided date with a last refresh time. This can be overridden for more complex
@@ -171,9 +166,14 @@ namespace MediaBrowser.Controller.Providers
throw new ArgumentNullException();
}
- var providerInfo = item.ProviderData.GetValueOrDefault(Id, new BaseProviderInfo());
+ BaseProviderInfo data;
- return NeedsRefreshInternal(item, providerInfo);
+ if (!item.ProviderData.TryGetValue(Id, out data))
+ {
+ data = new BaseProviderInfo();
+ }
+
+ return NeedsRefreshInternal(item, data);
}
/// <summary>
@@ -194,7 +194,7 @@ namespace MediaBrowser.Controller.Providers
{
throw new ArgumentNullException("providerInfo");
}
-
+
if (CompareDate(item) > providerInfo.LastRefreshed)
{
return true;
@@ -209,7 +209,7 @@ namespace MediaBrowser.Controller.Providers
{
return true;
}
-
+
return false;
}
@@ -221,7 +221,7 @@ namespace MediaBrowser.Controller.Providers
/// <returns><c>true</c> if [has file system stamp changed] [the specified item]; otherwise, <c>false</c>.</returns>
protected bool HasFileSystemStampChanged(BaseItem item, BaseProviderInfo providerInfo)
{
- return GetCurrentFileSystemStamp(item) != providerInfo.FileSystemStamp;
+ return !string.Equals(GetCurrentFileSystemStamp(item), providerInfo.FileSystemStamp);
}
/// <summary>
@@ -279,7 +279,7 @@ namespace MediaBrowser.Controller.Providers
/// </summary>
/// <param name="item">The item.</param>
/// <returns>Guid.</returns>
- private Guid GetCurrentFileSystemStamp(BaseItem item)
+ private string GetCurrentFileSystemStamp(BaseItem item)
{
if (UseParentFileSystemStamp(item) && item.Parent != null)
{
diff --git a/MediaBrowser.Controller/Providers/BaseProviderInfo.cs b/MediaBrowser.Controller/Providers/BaseProviderInfo.cs
index 877ba5c4b..5a72491c1 100644
--- a/MediaBrowser.Controller/Providers/BaseProviderInfo.cs
+++ b/MediaBrowser.Controller/Providers/BaseProviderInfo.cs
@@ -8,11 +8,6 @@ namespace MediaBrowser.Controller.Providers
public class BaseProviderInfo
{
/// <summary>
- /// Gets or sets the provider id.
- /// </summary>
- /// <value>The provider id.</value>
- public Guid ProviderId { get; set; }
- /// <summary>
/// Gets or sets the last refreshed.
/// </summary>
/// <value>The last refreshed.</value>
@@ -21,7 +16,7 @@ namespace MediaBrowser.Controller.Providers
/// Gets or sets the file system stamp.
/// </summary>
/// <value>The file system stamp.</value>
- public Guid FileSystemStamp { get; set; }
+ public string FileSystemStamp { get; set; }
/// <summary>
/// Gets or sets the last refresh status.
/// </summary>
@@ -32,11 +27,6 @@ namespace MediaBrowser.Controller.Providers
/// </summary>
/// <value>The provider version.</value>
public string ProviderVersion { get; set; }
- /// <summary>
- /// Gets or sets the data hash.
- /// </summary>
- /// <value>The data hash.</value>
- public Guid DataHash { get; set; }
}
/// <summary>
diff --git a/MediaBrowser.Controller/Providers/Movies/FanArtMovieProvider.cs b/MediaBrowser.Controller/Providers/Movies/FanArtMovieProvider.cs
index 3152ceac9..94fe38680 100644
--- a/MediaBrowser.Controller/Providers/Movies/FanArtMovieProvider.cs
+++ b/MediaBrowser.Controller/Providers/Movies/FanArtMovieProvider.cs
@@ -104,7 +104,14 @@ namespace MediaBrowser.Controller.Providers.Movies
cancellationToken.ThrowIfCancellationRequested();
var movie = item;
- if (ShouldFetch(movie, movie.ProviderData.GetValueOrDefault(Id, new BaseProviderInfo { ProviderId = Id })))
+
+ BaseProviderInfo providerData;
+
+ if (!item.ProviderData.TryGetValue(Id, out providerData))
+ {
+ providerData = new BaseProviderInfo();
+ }
+ if (ShouldFetch(movie, providerData))
{
var language = ConfigurationManager.Configuration.PreferredMetadataLanguage.ToLower();
var url = string.Format(FanArtBaseUrl, APIKey, movie.GetProviderId(MetadataProviders.Tmdb));
diff --git a/MediaBrowser.Controller/Providers/Movies/MovieDbProvider.cs b/MediaBrowser.Controller/Providers/Movies/MovieDbProvider.cs
index fb8370248..8e20f0fad 100644
--- a/MediaBrowser.Controller/Providers/Movies/MovieDbProvider.cs
+++ b/MediaBrowser.Controller/Providers/Movies/MovieDbProvider.cs
@@ -22,10 +22,11 @@ namespace MediaBrowser.Controller.Providers.Movies
{
class MovieDbProviderException : ApplicationException
{
- public MovieDbProviderException(string msg) : base(msg)
+ public MovieDbProviderException(string msg)
+ : base(msg)
{
}
-
+
}
/// <summary>
/// Class MovieDbProvider
@@ -33,7 +34,7 @@ namespace MediaBrowser.Controller.Providers.Movies
public class MovieDbProvider : BaseMetadataProvider, IDisposable
{
protected readonly IProviderManager ProviderManager;
-
+
/// <summary>
/// The movie db
/// </summary>
@@ -198,7 +199,7 @@ namespace MediaBrowser.Controller.Providers.Movies
base_url = "http://cf2.imgobject.com/t/p/"
}
- };
+ };
}
}
@@ -223,7 +224,14 @@ namespace MediaBrowser.Controller.Providers.Movies
//in addition to ours, we need to set the last refreshed time for the local data provider
//so it won't see the new files we download and process them all over again
if (JsonProvider == null) JsonProvider = new MovieProviderFromJson(LogManager, ConfigurationManager, JsonSerializer, HttpClient, ProviderManager);
- var data = item.ProviderData.GetValueOrDefault(JsonProvider.Id, new BaseProviderInfo { ProviderId = JsonProvider.Id });
+
+ BaseProviderInfo data;
+
+ if (!item.ProviderData.TryGetValue(JsonProvider.Id, out data))
+ {
+ data = new BaseProviderInfo();
+ }
+
data.LastRefreshed = value;
item.ProviderData[JsonProvider.Id] = data;
}
diff --git a/MediaBrowser.Controller/Providers/Music/FanArtAlbumProvider.cs b/MediaBrowser.Controller/Providers/Music/FanArtAlbumProvider.cs
index b53384841..72169f245 100644
--- a/MediaBrowser.Controller/Providers/Music/FanArtAlbumProvider.cs
+++ b/MediaBrowser.Controller/Providers/Music/FanArtAlbumProvider.cs
@@ -1,4 +1,5 @@
-using MediaBrowser.Common.Extensions;
+using System.Collections.Generic;
+using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
@@ -52,14 +53,15 @@ namespace MediaBrowser.Controller.Providers.Music
//Look at our parent for our album cover
var artist = (MusicArtist)item.Parent;
- var cover = artist.AlbumCovers != null ? artist.AlbumCovers.GetValueOrDefault(mbid, null) : null;
+
+ var cover = artist.AlbumCovers != null ? GetValueOrDefault(artist.AlbumCovers, mbid, null) : null;
if (cover == null)
{
// Not there - maybe it is new since artist last refreshed so refresh it and try again
await artist.RefreshMetadata(cancellationToken).ConfigureAwait(false);
cancellationToken.ThrowIfCancellationRequested();
- cover = artist.AlbumCovers != null ? artist.AlbumCovers.GetValueOrDefault(mbid, null) : null;
+ cover = artist.AlbumCovers != null ? GetValueOrDefault(artist.AlbumCovers, mbid, null) : null;
}
if (cover == null)
{
@@ -71,5 +73,25 @@ namespace MediaBrowser.Controller.Providers.Music
item.SetImage(ImageType.Primary, await _providerManager.DownloadAndSaveImage(item, cover, "folder.jpg", FanArtResourcePool, cancellationToken).ConfigureAwait(false));
return true;
}
+
+ /// <summary>
+ /// Helper method for Dictionaries since they throw on not-found keys
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <typeparam name="U"></typeparam>
+ /// <param name="dictionary">The dictionary.</param>
+ /// <param name="key">The key.</param>
+ /// <param name="defaultValue">The default value.</param>
+ /// <returns>``1.</returns>
+ private static U GetValueOrDefault<T, U>(Dictionary<T, U> dictionary, T key, U defaultValue)
+ {
+ U val;
+ if (!dictionary.TryGetValue(key, out val))
+ {
+ val = defaultValue;
+ }
+ return val;
+
+ }
}
}
diff --git a/MediaBrowser.Controller/Providers/Music/FanArtArtistProvider.cs b/MediaBrowser.Controller/Providers/Music/FanArtArtistProvider.cs
index ec7a96d99..1dd5c7cd2 100644
--- a/MediaBrowser.Controller/Providers/Music/FanArtArtistProvider.cs
+++ b/MediaBrowser.Controller/Providers/Music/FanArtArtistProvider.cs
@@ -86,7 +86,15 @@ namespace MediaBrowser.Controller.Providers.Music
cancellationToken.ThrowIfCancellationRequested();
var artist = (MusicArtist)item;
- if (ShouldFetch(artist, artist.ProviderData.GetValueOrDefault(Id, new BaseProviderInfo { ProviderId = Id })))
+
+ BaseProviderInfo providerData;
+
+ if (!item.ProviderData.TryGetValue(Id, out providerData))
+ {
+ providerData = new BaseProviderInfo();
+ }
+
+ if (ShouldFetch(artist, providerData))
{
var url = string.Format(FanArtBaseUrl, APIKey, artist.GetProviderId(MetadataProviders.Musicbrainz));
var doc = new XmlDocument();
diff --git a/MediaBrowser.Controller/Providers/Music/LastfmBaseProvider.cs b/MediaBrowser.Controller/Providers/Music/LastfmBaseProvider.cs
index f58bd3bb7..f7e0eef48 100644
--- a/MediaBrowser.Controller/Providers/Music/LastfmBaseProvider.cs
+++ b/MediaBrowser.Controller/Providers/Music/LastfmBaseProvider.cs
@@ -229,7 +229,13 @@ namespace MediaBrowser.Controller.Providers.Music
cancellationToken.ThrowIfCancellationRequested();
- var providerData = item.ProviderData.GetValueOrDefault(Id, new BaseProviderInfo { ProviderId = Id });
+ BaseProviderInfo providerData;
+
+ if (!item.ProviderData.TryGetValue(Id, out providerData))
+ {
+ providerData = new BaseProviderInfo();
+ }
+
if (!ConfigurationManager.Configuration.SaveLocalMeta || !HasLocalMeta(item) || (force && !HasLocalMeta(item)) || (RefreshOnVersionChange && providerData.ProviderVersion != ProviderVersion))
{
try
diff --git a/MediaBrowser.Controller/Providers/TV/FanArtTVProvider.cs b/MediaBrowser.Controller/Providers/TV/FanArtTVProvider.cs
index 4d06143fc..a7fc4586f 100644
--- a/MediaBrowser.Controller/Providers/TV/FanArtTVProvider.cs
+++ b/MediaBrowser.Controller/Providers/TV/FanArtTVProvider.cs
@@ -60,7 +60,15 @@ namespace MediaBrowser.Controller.Providers.TV
cancellationToken.ThrowIfCancellationRequested();
var series = (Series)item;
- if (ShouldFetch(series, series.ProviderData.GetValueOrDefault(Id, new BaseProviderInfo { ProviderId = Id })))
+
+ BaseProviderInfo providerData;
+
+ if (!item.ProviderData.TryGetValue(Id, out providerData))
+ {
+ providerData = new BaseProviderInfo();
+ }
+
+ if (ShouldFetch(series, providerData))
{
string language = ConfigurationManager.Configuration.PreferredMetadataLanguage.ToLower();
string url = string.Format(FanArtBaseUrl, APIKey, series.GetProviderId(MetadataProviders.Tvdb));
diff --git a/MediaBrowser.Controller/Sorting/IUserBaseItemComparer.cs b/MediaBrowser.Controller/Sorting/IUserBaseItemComparer.cs
index 76d84a653..d464a64a0 100644
--- a/MediaBrowser.Controller/Sorting/IUserBaseItemComparer.cs
+++ b/MediaBrowser.Controller/Sorting/IUserBaseItemComparer.cs
@@ -1,5 +1,6 @@
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Persistence;
namespace MediaBrowser.Controller.Sorting
{
@@ -19,5 +20,11 @@ namespace MediaBrowser.Controller.Sorting
/// </summary>
/// <value>The user manager.</value>
IUserManager UserManager { get; set; }
+
+ /// <summary>
+ /// Gets or sets the user data repository.
+ /// </summary>
+ /// <value>The user data repository.</value>
+ IUserDataRepository UserDataRepository { get; set; }
}
}
diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs
index eb2b4ddeb..0c18564ec 100644
--- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs
+++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs
@@ -154,27 +154,6 @@ namespace MediaBrowser.Model.Configuration
public bool DownloadHDFanArt { get; set; }
/// <summary>
- /// Gets or sets the name of the item repository that should be used
- /// </summary>
- /// <value>The item repository.</value>
- [ProtoMember(24)]
- public string ItemRepository { get; set; }
-
- /// <summary>
- /// Gets or sets the name of the user repository that should be used
- /// </summary>
- /// <value>The user repository.</value>
- [ProtoMember(25)]
- public string UserRepository { get; set; }
-
- /// <summary>
- /// Gets or sets the name of the user data repository that should be used
- /// </summary>
- /// <value>The user data repository.</value>
- [ProtoMember(26)]
- public string UserDataRepository { get; set; }
-
- /// <summary>
/// Characters to be replaced with a ' ' in strings to create a sort name
/// </summary>
/// <value>The sort replace characters.</value>
@@ -203,13 +182,6 @@ namespace MediaBrowser.Model.Configuration
public bool ShowLogWindow { get; set; }
/// <summary>
- /// Gets or sets the name of the user data repository that should be used
- /// </summary>
- /// <value>The display preferences repository.</value>
- [ProtoMember(31)]
- public string DisplayPreferencesRepository { get; set; }
-
- /// <summary>
/// The list of types that will NOT be allowed to have internet providers run against them even if they are turned on.
/// </summary>
/// <value>The internet provider exclude types.</value>
diff --git a/MediaBrowser.Model/Connectivity/ClientConnectionInfo.cs b/MediaBrowser.Model/Connectivity/ClientConnectionInfo.cs
index 565ce6ec2..a5e44f22e 100644
--- a/MediaBrowser.Model/Connectivity/ClientConnectionInfo.cs
+++ b/MediaBrowser.Model/Connectivity/ClientConnectionInfo.cs
@@ -15,7 +15,7 @@ namespace MediaBrowser.Model.Connectivity
/// </summary>
/// <value>The user id.</value>
[ProtoMember(1)]
- public Guid UserId { get; set; }
+ public string UserId { get; set; }
/// <summary>
/// Gets or sets the type of the client.
diff --git a/MediaBrowser.Model/DTO/UserDto.cs b/MediaBrowser.Model/DTO/UserDto.cs
index 979422dbe..b2afa90c0 100644
--- a/MediaBrowser.Model/DTO/UserDto.cs
+++ b/MediaBrowser.Model/DTO/UserDto.cs
@@ -24,7 +24,7 @@ namespace MediaBrowser.Model.Dto
/// </summary>
/// <value>The id.</value>
[ProtoMember(2)]
- public Guid Id { get; set; }
+ public string Id { get; set; }
/// <summary>
/// Gets or sets the primary image tag.
diff --git a/MediaBrowser.Model/Plugins/PluginInfo.cs b/MediaBrowser.Model/Plugins/PluginInfo.cs
index 2df635db0..fd4cfa78c 100644
--- a/MediaBrowser.Model/Plugins/PluginInfo.cs
+++ b/MediaBrowser.Model/Plugins/PluginInfo.cs
@@ -57,7 +57,7 @@ namespace MediaBrowser.Model.Plugins
/// </summary>
/// <value>The unique id.</value>
[ProtoMember(9)]
- public Guid Id { get; set; }
+ public string Id { get; set; }
/// <summary>
/// Whether or not this plug-in should be automatically updated when a
diff --git a/MediaBrowser.Model/Querying/ItemQuery.cs b/MediaBrowser.Model/Querying/ItemQuery.cs
index 3a1d14065..86886d751 100644
--- a/MediaBrowser.Model/Querying/ItemQuery.cs
+++ b/MediaBrowser.Model/Querying/ItemQuery.cs
@@ -12,7 +12,7 @@ namespace MediaBrowser.Model.Querying
/// The user to localize search results for
/// </summary>
/// <value>The user id.</value>
- public Guid UserId { get; set; }
+ public string UserId { get; set; }
/// <summary>
/// Specify this to localize the search to a specific item or folder. Omit to use the root.
diff --git a/MediaBrowser.Model/Querying/ItemsByNameQuery.cs b/MediaBrowser.Model/Querying/ItemsByNameQuery.cs
index 0bebb085e..eae2dc042 100644
--- a/MediaBrowser.Model/Querying/ItemsByNameQuery.cs
+++ b/MediaBrowser.Model/Querying/ItemsByNameQuery.cs
@@ -1,5 +1,4 @@
using MediaBrowser.Model.Entities;
-using System;
namespace MediaBrowser.Model.Querying
{
@@ -12,7 +11,7 @@ namespace MediaBrowser.Model.Querying
/// Gets or sets the user id.
/// </summary>
/// <value>The user id.</value>
- public Guid UserId { get; set; }
+ public string UserId { get; set; }
/// <summary>
/// Gets or sets the start index.
/// </summary>
diff --git a/MediaBrowser.Model/System/SystemInfo.cs b/MediaBrowser.Model/System/SystemInfo.cs
index 20716ecc5..afe074088 100644
--- a/MediaBrowser.Model/System/SystemInfo.cs
+++ b/MediaBrowser.Model/System/SystemInfo.cs
@@ -71,6 +71,6 @@ namespace MediaBrowser.Model.System
/// </summary>
/// <value>The id.</value>
[ProtoMember(9)]
- public Guid Id { get; set; }
+ public string Id { get; set; }
}
}
diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs
index d397b1548..3bb5472df 100644
--- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs
+++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs
@@ -101,6 +101,8 @@ namespace MediaBrowser.Server.Implementations.Library
/// </summary>
private readonly IUserManager _userManager;
+ private readonly IUserDataRepository _userDataRepository;
+
/// <summary>
/// Gets or sets the configuration manager.
/// </summary>
@@ -136,12 +138,14 @@ namespace MediaBrowser.Server.Implementations.Library
/// <param name="taskManager">The task manager.</param>
/// <param name="userManager">The user manager.</param>
/// <param name="configurationManager">The configuration manager.</param>
- public LibraryManager(ILogger logger, ITaskManager taskManager, IUserManager userManager, IServerConfigurationManager configurationManager)
+ /// <param name="userDataRepository">The user data repository.</param>
+ public LibraryManager(ILogger logger, ITaskManager taskManager, IUserManager userManager, IServerConfigurationManager configurationManager, IUserDataRepository userDataRepository)
{
_logger = logger;
_taskManager = taskManager;
_userManager = userManager;
ConfigurationManager = configurationManager;
+ _userDataRepository = userDataRepository;
ByReferenceItems = new ConcurrentDictionary<Guid, BaseItem>();
ConfigurationManager.ConfigurationUpdated += ConfigurationUpdated;
@@ -903,6 +907,7 @@ namespace MediaBrowser.Server.Implementations.Library
userComparer.User = user;
userComparer.UserManager = _userManager;
+ userComparer.UserDataRepository = _userDataRepository;
return userComparer;
}
diff --git a/MediaBrowser.Server.Implementations/Library/UserManager.cs b/MediaBrowser.Server.Implementations/Library/UserManager.cs
index 311a31264..dbb2d7b32 100644
--- a/MediaBrowser.Server.Implementations/Library/UserManager.cs
+++ b/MediaBrowser.Server.Implementations/Library/UserManager.cs
@@ -1,6 +1,7 @@
using MediaBrowser.Common.Events;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Persistence;
@@ -86,20 +87,14 @@ namespace MediaBrowser.Server.Implementations.Library
/// </summary>
private readonly ILogger _logger;
+ private readonly IUserDataRepository _userDataRepository;
+
/// <summary>
/// Gets or sets the configuration manager.
/// </summary>
/// <value>The configuration manager.</value>
private IServerConfigurationManager ConfigurationManager { get; set; }
- private readonly ConcurrentDictionary<string, Task<UserItemData>> _userData = new ConcurrentDictionary<string, Task<UserItemData>>();
-
- /// <summary>
- /// Gets the active user data repository
- /// </summary>
- /// <value>The user data repository.</value>
- public IUserDataRepository UserDataRepository { get; set; }
-
/// <summary>
/// Gets the active user repository
/// </summary>
@@ -321,13 +316,13 @@ namespace MediaBrowser.Server.Implementations.Library
var connection = _activeConnections.GetOrAdd(key, keyName => new ClientConnectionInfo
{
- UserId = userId,
+ UserId = userId.ToString(),
Client = clientType,
DeviceName = deviceName,
DeviceId = deviceId
});
- connection.UserId = userId;
+ connection.UserId = userId.ToString();
return connection;
}
@@ -591,12 +586,14 @@ namespace MediaBrowser.Server.Implementations.Library
UpdateNowPlayingItemId(user, clientType, deviceId, deviceName, item, positionTicks);
+ var key = item.GetUserDataKey();
+
if (positionTicks.HasValue)
{
- var data = await GetUserData(user.Id, item.UserDataId).ConfigureAwait(false);
+ var data = await _userDataRepository.GetUserData(user.Id, key).ConfigureAwait(false);
UpdatePlayState(item, data, positionTicks.Value, false);
- await SaveUserData(user.Id, item.UserDataId, data, CancellationToken.None).ConfigureAwait(false);
+ await _userDataRepository.SaveUserData(user.Id, key, data, CancellationToken.None).ConfigureAwait(false);
}
EventHelper.QueueEventIfNotNull(PlaybackProgress, this, new PlaybackProgressEventArgs
@@ -631,7 +628,9 @@ namespace MediaBrowser.Server.Implementations.Library
RemoveNowPlayingItemId(user, clientType, deviceId, deviceName, item);
- var data = await GetUserData(user.Id, item.UserDataId).ConfigureAwait(false);
+ var key = item.GetUserDataKey();
+
+ var data = await _userDataRepository.GetUserData(user.Id, key).ConfigureAwait(false);
if (positionTicks.HasValue)
{
@@ -644,7 +643,7 @@ namespace MediaBrowser.Server.Implementations.Library
data.Played = true;
}
- await SaveUserData(user.Id, item.UserDataId, data, CancellationToken.None).ConfigureAwait(false);
+ await _userDataRepository.SaveUserData(user.Id, key, data, CancellationToken.None).ConfigureAwait(false);
EventHelper.QueueEventIfNotNull(PlaybackStopped, this, new PlaybackProgressEventArgs
{
@@ -703,59 +702,5 @@ namespace MediaBrowser.Server.Implementations.Library
data.LastPlayedDate = DateTime.UtcNow;
}
}
-
- /// <summary>
- /// Saves display preferences for an item
- /// </summary>
- /// <param name="userId">The user id.</param>
- /// <param name="userDataId">The user data id.</param>
- /// <param name="userData">The user data.</param>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <returns>Task.</returns>
- public async Task SaveUserData(Guid userId, Guid userDataId, UserItemData userData, CancellationToken cancellationToken)
- {
- var key = userId + userDataId.ToString();
- try
- {
- await UserDataRepository.SaveUserData(userId, userDataId, userData, cancellationToken).ConfigureAwait(false);
-
- var newValue = Task.FromResult(userData);
-
- // Once it succeeds, put it into the dictionary to make it available to everyone else
- _userData.AddOrUpdate(key, newValue, delegate { return newValue; });
- }
- catch (Exception ex)
- {
- _logger.ErrorException("Error saving user data", ex);
-
- throw;
- }
- }
-
- /// <summary>
- /// Gets the user data.
- /// </summary>
- /// <param name="userId">The user id.</param>
- /// <param name="userDataId">The user data id.</param>
- /// <returns>Task{UserItemData}.</returns>
- public Task<UserItemData> GetUserData(Guid userId, Guid userDataId)
- {
- var key = userId + userDataId.ToString();
-
- return _userData.GetOrAdd(key, keyName => RetrieveUserData(userId, userDataId));
- }
-
- /// <summary>
- /// Retrieves the user data.
- /// </summary>
- /// <param name="userId">The user id.</param>
- /// <param name="userDataId">The user data id.</param>
- /// <returns>Task{UserItemData}.</returns>
- private async Task<UserItemData> RetrieveUserData(Guid userId, Guid userDataId)
- {
- var userdata = await UserDataRepository.GetUserData(userId, userDataId).ConfigureAwait(false);
-
- return userdata ?? new UserItemData();
- }
}
}
diff --git a/MediaBrowser.Server.Implementations/Providers/ProviderManager.cs b/MediaBrowser.Server.Implementations/Providers/ProviderManager.cs
index 8b135db5a..ff7222e7c 100644
--- a/MediaBrowser.Server.Implementations/Providers/ProviderManager.cs
+++ b/MediaBrowser.Server.Implementations/Providers/ProviderManager.cs
@@ -89,12 +89,6 @@ namespace MediaBrowser.Server.Implementations.Providers
}
/// <summary>
- /// Gets or sets the supported providers key.
- /// </summary>
- /// <value>The supported providers key.</value>
- private Guid SupportedProvidersKey { get; set; }
-
- /// <summary>
/// Adds the metadata providers.
/// </summary>
/// <param name="providers">The providers.</param>
@@ -104,6 +98,11 @@ namespace MediaBrowser.Server.Implementations.Providers
}
/// <summary>
+ /// The _supported providers key
+ /// </summary>
+ private readonly Guid _supportedProvidersKey = "SupportedProviders".GetMD5();
+
+ /// <summary>
/// Runs all metadata providers for an entity, and returns true or false indicating if at least one was refreshed and requires persistence
/// </summary>
/// <param name="item">The item.</param>
@@ -126,19 +125,14 @@ namespace MediaBrowser.Server.Implementations.Providers
BaseProviderInfo supportedProvidersInfo;
- if (SupportedProvidersKey == Guid.Empty)
- {
- SupportedProvidersKey = "SupportedProviders".GetMD5();
- }
-
- var supportedProvidersHash = string.Join("+", supportedProviders.Select(i => i.GetType().Name)).GetMD5();
- bool providersChanged = false;
+ var supportedProvidersValue = string.Join("+", supportedProviders.Select(i => i.GetType().Name));
+ var providersChanged = false;
- item.ProviderData.TryGetValue(SupportedProvidersKey, out supportedProvidersInfo);
+ item.ProviderData.TryGetValue(_supportedProvidersKey, out supportedProvidersInfo);
if (supportedProvidersInfo != null)
{
// Force refresh if the supported providers have changed
- providersChanged = force = force || supportedProvidersInfo.FileSystemStamp != supportedProvidersHash;
+ providersChanged = force = force || !string.Equals(supportedProvidersInfo.FileSystemStamp, supportedProvidersValue);
// If providers have changed, clear provider info and update the supported providers hash
if (providersChanged)
@@ -150,7 +144,7 @@ namespace MediaBrowser.Server.Implementations.Providers
if (providersChanged)
{
- supportedProvidersInfo.FileSystemStamp = supportedProvidersHash;
+ supportedProvidersInfo.FileSystemStamp = supportedProvidersValue;
}
if (force) item.ClearMetaValues();
@@ -206,7 +200,7 @@ namespace MediaBrowser.Server.Implementations.Providers
if (providersChanged)
{
- item.ProviderData[SupportedProvidersKey] = supportedProvidersInfo;
+ item.ProviderData[_supportedProvidersKey] = supportedProvidersInfo;
}
return result || providersChanged;
diff --git a/MediaBrowser.Server.Implementations/Sorting/DatePlayedComparer.cs b/MediaBrowser.Server.Implementations/Sorting/DatePlayedComparer.cs
index 905d5413a..c634c760e 100644
--- a/MediaBrowser.Server.Implementations/Sorting/DatePlayedComparer.cs
+++ b/MediaBrowser.Server.Implementations/Sorting/DatePlayedComparer.cs
@@ -1,5 +1,6 @@
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Persistence;
using MediaBrowser.Controller.Sorting;
using MediaBrowser.Model.Querying;
using System;
@@ -24,6 +25,12 @@ namespace MediaBrowser.Server.Implementations.Sorting
public IUserManager UserManager { get; set; }
/// <summary>
+ /// Gets or sets the user data repository.
+ /// </summary>
+ /// <value>The user data repository.</value>
+ public IUserDataRepository UserDataRepository { get; set; }
+
+ /// <summary>
/// Compares the specified x.
/// </summary>
/// <param name="x">The x.</param>
@@ -41,7 +48,7 @@ namespace MediaBrowser.Server.Implementations.Sorting
/// <returns>DateTime.</returns>
private DateTime GetDate(BaseItem x)
{
- var userdata = UserManager.GetUserData(User.Id, x.UserDataId).Result;
+ var userdata = UserDataRepository.GetUserData(User.Id, x.GetUserDataKey()).Result;
if (userdata != null && userdata.LastPlayedDate.HasValue)
{
diff --git a/MediaBrowser.Server.Implementations/Sorting/PlayCountComparer.cs b/MediaBrowser.Server.Implementations/Sorting/PlayCountComparer.cs
index 82e76e78d..a7cbd2149 100644
--- a/MediaBrowser.Server.Implementations/Sorting/PlayCountComparer.cs
+++ b/MediaBrowser.Server.Implementations/Sorting/PlayCountComparer.cs
@@ -1,5 +1,6 @@
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Persistence;
using MediaBrowser.Controller.Sorting;
using MediaBrowser.Model.Querying;
@@ -34,7 +35,7 @@ namespace MediaBrowser.Server.Implementations.Sorting
/// <returns>DateTime.</returns>
private int GetValue(BaseItem x)
{
- var userdata = UserManager.GetUserData(User.Id, x.UserDataId).Result;
+ var userdata = UserDataRepository.GetUserData(User.Id, x.GetUserDataKey()).Result;
return userdata == null ? 0 : userdata.PlayCount;
}
@@ -49,6 +50,12 @@ namespace MediaBrowser.Server.Implementations.Sorting
}
/// <summary>
+ /// Gets or sets the user data repository.
+ /// </summary>
+ /// <value>The user data repository.</value>
+ public IUserDataRepository UserDataRepository { get; set; }
+
+ /// <summary>
/// Gets or sets the user manager.
/// </summary>
/// <value>The user manager.</value>
diff --git a/MediaBrowser.Server.Implementations/Sqlite/SQLiteDisplayPreferencesRepository.cs b/MediaBrowser.Server.Implementations/Sqlite/SQLiteDisplayPreferencesRepository.cs
index 501635800..fbb0e4f8c 100644
--- a/MediaBrowser.Server.Implementations/Sqlite/SQLiteDisplayPreferencesRepository.cs
+++ b/MediaBrowser.Server.Implementations/Sqlite/SQLiteDisplayPreferencesRepository.cs
@@ -14,7 +14,7 @@ namespace MediaBrowser.Server.Implementations.Sqlite
/// <summary>
/// Class SQLiteDisplayPreferencesRepository
/// </summary>
- class SQLiteDisplayPreferencesRepository : SqliteRepository, IDisplayPreferencesRepository
+ public class SQLiteDisplayPreferencesRepository : SqliteRepository, IDisplayPreferencesRepository
{
/// <summary>
/// The repository name
diff --git a/MediaBrowser.Server.Implementations/Sqlite/SQLiteUserDataRepository.cs b/MediaBrowser.Server.Implementations/Sqlite/SQLiteUserDataRepository.cs
index 467628a78..4df81aacc 100644
--- a/MediaBrowser.Server.Implementations/Sqlite/SQLiteUserDataRepository.cs
+++ b/MediaBrowser.Server.Implementations/Sqlite/SQLiteUserDataRepository.cs
@@ -4,6 +4,7 @@ using MediaBrowser.Controller.Persistence;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Serialization;
using System;
+using System.Collections.Concurrent;
using System.Data;
using System.IO;
using System.Threading;
@@ -16,6 +17,8 @@ namespace MediaBrowser.Server.Implementations.Sqlite
/// </summary>
public class SQLiteUserDataRepository : SqliteRepository, IUserDataRepository
{
+ private readonly ConcurrentDictionary<string, Task<UserItemData>> _userData = new ConcurrentDictionary<string, Task<UserItemData>>();
+
/// <summary>
/// The repository name
/// </summary>
@@ -45,9 +48,6 @@ namespace MediaBrowser.Server.Implementations.Sqlite
}
}
- /// <summary>
- /// The _protobuf serializer
- /// </summary>
private readonly IJsonSerializer _jsonSerializer;
/// <summary>
@@ -90,8 +90,8 @@ namespace MediaBrowser.Server.Implementations.Sqlite
string[] queries = {
- "create table if not exists userdata (id GUID, userId GUID, data BLOB)",
- "create unique index if not exists userdataindex on userdata (id, userId)",
+ "create table if not exists userdata (key nvarchar, userId GUID, data BLOB)",
+ "create unique index if not exists userdataindex on userdata (key, userId)",
"create table if not exists schema_version (table_name primary key, version)",
//pragmas
"pragma temp_store = memory"
@@ -104,20 +104,18 @@ namespace MediaBrowser.Server.Implementations.Sqlite
/// Saves the user data.
/// </summary>
/// <param name="userId">The user id.</param>
- /// <param name="userDataId">The user data id.</param>
+ /// <param name="key">The key.</param>
/// <param name="userData">The user data.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
- /// <exception cref="System.ArgumentNullException">
- /// userData
+ /// <exception cref="System.ArgumentNullException">userData
/// or
/// cancellationToken
/// or
/// userId
/// or
- /// userDataId
- /// </exception>
- public async Task SaveUserData(Guid userId, Guid userDataId, UserItemData userData, CancellationToken cancellationToken)
+ /// userDataId</exception>
+ public async Task SaveUserData(Guid userId, string key, UserItemData userData, CancellationToken cancellationToken)
{
if (userData == null)
{
@@ -131,20 +129,49 @@ namespace MediaBrowser.Server.Implementations.Sqlite
{
throw new ArgumentNullException("userId");
}
- if (userDataId == Guid.Empty)
+ if (string.IsNullOrEmpty(key))
{
- throw new ArgumentNullException("userDataId");
+ throw new ArgumentNullException("key");
}
cancellationToken.ThrowIfCancellationRequested();
+ try
+ {
+ await PersistUserData(userId, key, userData, cancellationToken).ConfigureAwait(false);
+
+ var newValue = Task.FromResult(userData);
+
+ // Once it succeeds, put it into the dictionary to make it available to everyone else
+ _userData.AddOrUpdate(key, newValue, delegate { return newValue; });
+ }
+ catch (Exception ex)
+ {
+ Logger.ErrorException("Error saving user data", ex);
+
+ throw;
+ }
+ }
+
+ /// <summary>
+ /// Persists the user data.
+ /// </summary>
+ /// <param name="userId">The user id.</param>
+ /// <param name="key">The key.</param>
+ /// <param name="userData">The user data.</param>
+ /// <param name="cancellationToken">The cancellation token.</param>
+ /// <returns>Task.</returns>
+ public async Task PersistUserData(Guid userId, string key, UserItemData userData, CancellationToken cancellationToken)
+ {
+ cancellationToken.ThrowIfCancellationRequested();
+
var serialized = _jsonSerializer.SerializeToBytes(userData);
cancellationToken.ThrowIfCancellationRequested();
var cmd = connection.CreateCommand();
- cmd.CommandText = "replace into userdata (id, userId, data) values (@1, @2, @3)";
- cmd.AddParam("@1", userDataId);
+ cmd.CommandText = "replace into userdata (key, userId, data) values (@1, @2, @3)";
+ cmd.AddParam("@1", key);
cmd.AddParam("@2", userId);
cmd.AddParam("@3", serialized);
@@ -174,29 +201,40 @@ namespace MediaBrowser.Server.Implementations.Sqlite
/// Gets the user data.
/// </summary>
/// <param name="userId">The user id.</param>
- /// <param name="userDataId">The user data id.</param>
+ /// <param name="key">The key.</param>
/// <returns>Task{UserItemData}.</returns>
/// <exception cref="System.ArgumentNullException">
/// userId
/// or
- /// userDataId
+ /// key
/// </exception>
- public async Task<UserItemData> GetUserData(Guid userId, Guid userDataId)
+ public Task<UserItemData> GetUserData(Guid userId, string key)
{
if (userId == Guid.Empty)
{
throw new ArgumentNullException("userId");
}
- if (userDataId == Guid.Empty)
+ if (string.IsNullOrEmpty(key))
{
- throw new ArgumentNullException("userDataId");
+ throw new ArgumentNullException("key");
}
+
+ return _userData.GetOrAdd(key, keyName => RetrieveUserData(userId, key));
+ }
+ /// <summary>
+ /// Retrieves the user data.
+ /// </summary>
+ /// <param name="userId">The user id.</param>
+ /// <param name="key">The key.</param>
+ /// <returns>Task{UserItemData}.</returns>
+ private async Task<UserItemData> RetrieveUserData(Guid userId, string key)
+ {
var cmd = connection.CreateCommand();
- cmd.CommandText = "select data from userdata where id = @id and userId=@userId";
+ cmd.CommandText = "select data from userdata where key = @key and userId=@userId";
- var idParam = cmd.Parameters.Add("@id", DbType.Guid);
- idParam.Value = userDataId;
+ var idParam = cmd.Parameters.Add("@key", DbType.Guid);
+ idParam.Value = key;
var userIdParam = cmd.Parameters.Add("@userId", DbType.Guid);
userIdParam.Value = userId;
@@ -212,7 +250,7 @@ namespace MediaBrowser.Server.Implementations.Sqlite
}
}
- return null;
+ return new UserItemData();
}
}
}
diff --git a/MediaBrowser.ServerApplication/ApplicationHost.cs b/MediaBrowser.ServerApplication/ApplicationHost.cs
index afc68fe67..59395e469 100644
--- a/MediaBrowser.ServerApplication/ApplicationHost.cs
+++ b/MediaBrowser.ServerApplication/ApplicationHost.cs
@@ -37,6 +37,7 @@ using MediaBrowser.Server.Implementations.Library;
using MediaBrowser.Server.Implementations.MediaEncoder;
using MediaBrowser.Server.Implementations.Providers;
using MediaBrowser.Server.Implementations.ServerManager;
+using MediaBrowser.Server.Implementations.Sqlite;
using MediaBrowser.Server.Implementations.Udp;
using MediaBrowser.Server.Implementations.Updates;
using MediaBrowser.Server.Implementations.WebSocket;
@@ -153,6 +154,12 @@ namespace MediaBrowser.ServerApplication
private IMediaEncoder MediaEncoder { get; set; }
/// <summary>
+ /// Gets or sets the user data repository.
+ /// </summary>
+ /// <value>The user data repository.</value>
+ private IUserDataRepository UserDataRepository { get; set; }
+
+ /// <summary>
/// The full path to our startmenu shortcut
/// </summary>
protected override string ProductShortcutPath
@@ -216,7 +223,10 @@ namespace MediaBrowser.ServerApplication
UserManager = new UserManager(Logger, ServerConfigurationManager);
RegisterSingleInstance(UserManager);
- LibraryManager = new LibraryManager(Logger, TaskManager, UserManager, ServerConfigurationManager);
+ UserDataRepository = new SQLiteUserDataRepository(ApplicationPaths, JsonSerializer, LogManager);
+ RegisterSingleInstance(UserDataRepository);
+
+ LibraryManager = new LibraryManager(Logger, TaskManager, UserManager, ServerConfigurationManager, UserDataRepository);
RegisterSingleInstance(LibraryManager);
InstallationManager = new InstallationManager(HttpClient, PackageManager, JsonSerializer, Logger, this);
@@ -273,9 +283,7 @@ namespace MediaBrowser.ServerApplication
/// <returns>Task.</returns>
private async Task ConfigureDisplayPreferencesRepositories()
{
- var repositories = GetExports<IDisplayPreferencesRepository>();
-
- var repository = GetRepository(repositories, ServerConfigurationManager.Configuration.DisplayPreferencesRepository);
+ var repository = new SQLiteDisplayPreferencesRepository(ApplicationPaths, JsonSerializer, LogManager);
await repository.Initialize().ConfigureAwait(false);
@@ -288,9 +296,7 @@ namespace MediaBrowser.ServerApplication
/// <returns>Task.</returns>
private async Task ConfigureItemRepositories()
{
- var repositories = GetExports<IItemRepository>();
-
- var repository = GetRepository(repositories, ServerConfigurationManager.Configuration.ItemRepository);
+ var repository = new SQLiteItemRepository(ApplicationPaths, JsonSerializer, LogManager);
await repository.Initialize().ConfigureAwait(false);
@@ -301,22 +307,14 @@ namespace MediaBrowser.ServerApplication
/// Configures the user data repositories.
/// </summary>
/// <returns>Task.</returns>
- private async Task ConfigureUserDataRepositories()
+ private Task ConfigureUserDataRepositories()
{
- var repositories = GetExports<IUserDataRepository>();
-
- var repository = GetRepository(repositories, ServerConfigurationManager.Configuration.UserDataRepository);
-
- await repository.Initialize().ConfigureAwait(false);
-
- ((UserManager)UserManager).UserDataRepository = repository;
+ return UserDataRepository.Initialize();
}
private async Task ConfigureUserRepositories()
{
- var repositories = GetExports<IUserRepository>();
-
- var repository = GetRepository(repositories, ServerConfigurationManager.Configuration.UserRepository);
+ var repository = new SQLiteUserRepository(ApplicationPaths, JsonSerializer, LogManager);
await repository.Initialize().ConfigureAwait(false);
@@ -470,7 +468,7 @@ namespace MediaBrowser.ServerApplication
yield return GetType().Assembly;
}
- private readonly Guid _systemId = Environment.MachineName.GetMD5();
+ private readonly string _systemId = Environment.MachineName.GetMD5().ToString();
/// <summary>
/// Gets the system status.
diff --git a/MediaBrowser.ServerApplication/EntryPoints/WebSocketEvents.cs b/MediaBrowser.ServerApplication/EntryPoints/WebSocketEvents.cs
index 98d7fb477..19c42e8d8 100644
--- a/MediaBrowser.ServerApplication/EntryPoints/WebSocketEvents.cs
+++ b/MediaBrowser.ServerApplication/EntryPoints/WebSocketEvents.cs
@@ -3,6 +3,7 @@ using MediaBrowser.Common.Net;
using MediaBrowser.Common.Plugins;
using MediaBrowser.Common.ScheduledTasks;
using MediaBrowser.Controller;
+using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Plugins;
@@ -174,7 +175,7 @@ namespace MediaBrowser.ServerApplication.EntryPoints
/// <param name="e">The e.</param>
void userManager_UserUpdated(object sender, GenericEventArgs<User> e)
{
- var dto = new DtoBuilder(_logger, _libraryManager, _userManager).GetUserDto(e.Argument);
+ var dto = new UserDtoBuilder(_logger).GetUserDto(e.Argument);
_serverManager.SendWebSocketMessage("UserUpdated", dto);
}
diff --git a/MediaBrowser.WebDashboard/Api/DashboardService.cs b/MediaBrowser.WebDashboard/Api/DashboardService.cs
index 7756fb5b9..c773503b0 100644
--- a/MediaBrowser.WebDashboard/Api/DashboardService.cs
+++ b/MediaBrowser.WebDashboard/Api/DashboardService.cs
@@ -4,6 +4,7 @@ using MediaBrowser.Common.Net;
using MediaBrowser.Common.ScheduledTasks;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Plugins;
using MediaBrowser.Model.Logging;
@@ -192,9 +193,9 @@ namespace MediaBrowser.WebDashboard.Api
{
var connections = userManager.RecentConnections.ToArray();
- var dtoBuilder = new DtoBuilder(logger, libraryManager, userManager);
+ var dtoBuilder = new UserDtoBuilder(logger);
- var users = userManager.Users.Where(u => connections.Any(c => c.UserId == u.Id)).Select(dtoBuilder.GetUserDto);
+ var users = userManager.Users.Where(u => connections.Any(c => new Guid(c.UserId) == u.Id)).Select(dtoBuilder.GetUserDto);
return new DashboardInfo
{