aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Server.Implementations
diff options
context:
space:
mode:
authorAlex Stevens <ads@chubbymusic.co.uk>2016-06-05 21:20:54 +0100
committerAlex Stevens <ads@chubbymusic.co.uk>2016-06-05 21:20:54 +0100
commit4c52fc094fa409f926b5076639902ee9cd4a41a3 (patch)
treebc1024cd7f324c496f2d786cdd4441207c60ea29 /MediaBrowser.Server.Implementations
parent79b5d3e19549f04ee301e1e0ecac94d3b3e18e8e (diff)
parent2e040f9c0c3d8cca834687a7c729f14097f7a83b (diff)
Merge remote-tracking branch 'upstream/dev' into dev
Diffstat (limited to 'MediaBrowser.Server.Implementations')
-rw-r--r--MediaBrowser.Server.Implementations/Connect/Responses.cs1
-rw-r--r--MediaBrowser.Server.Implementations/Dto/DtoService.cs11
-rw-r--r--MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs7
-rw-r--r--MediaBrowser.Server.Implementations/Library/UserDataManager.cs98
-rw-r--r--MediaBrowser.Server.Implementations/Library/UserViewManager.cs6
-rw-r--r--MediaBrowser.Server.Implementations/Persistence/IDbConnector.cs1
-rw-r--r--MediaBrowser.Server.Implementations/Persistence/SqliteExtensions.cs118
-rw-r--r--MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs142
-rw-r--r--MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs48
-rw-r--r--MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs42
10 files changed, 215 insertions, 259 deletions
diff --git a/MediaBrowser.Server.Implementations/Connect/Responses.cs b/MediaBrowser.Server.Implementations/Connect/Responses.cs
index e7c3f8154..f86527829 100644
--- a/MediaBrowser.Server.Implementations/Connect/Responses.cs
+++ b/MediaBrowser.Server.Implementations/Connect/Responses.cs
@@ -60,7 +60,6 @@ namespace MediaBrowser.Server.Implementations.Connect
{
return new ConnectUserPreferences
{
- GroupMoviesIntoBoxSets = config.GroupMoviesIntoBoxSets,
PlayDefaultAudioTrack = config.PlayDefaultAudioTrack,
SubtitleMode = config.SubtitleMode,
PreferredAudioLanguages = string.IsNullOrWhiteSpace(config.AudioLanguagePreference) ? new string[] { } : new[] { config.AudioLanguagePreference },
diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs
index bfcdb2a26..5588405e3 100644
--- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs
+++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs
@@ -969,16 +969,7 @@ namespace MediaBrowser.Server.Implementations.Dto
if (fields.Contains(ItemFields.Tags))
{
- var hasTags = item as IHasTags;
- if (hasTags != null)
- {
- dto.Tags = hasTags.Tags;
- }
-
- if (dto.Tags == null)
- {
- dto.Tags = new List<string>();
- }
+ dto.Tags = item.Tags;
}
if (fields.Contains(ItemFields.Keywords))
diff --git a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs
index 83801b3e7..2109f8d59 100644
--- a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs
+++ b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs
@@ -562,9 +562,10 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
series = _libraryManager.GetItemList(new Controller.Entities.InternalItemsQuery
{
IncludeItemTypes = new[] { typeof(Series).Name },
- Recursive = true
- }).Cast<Series>()
- .FirstOrDefault(i => string.Equals(i.Name, info.ItemName, StringComparison.OrdinalIgnoreCase));
+ Recursive = true,
+ Name = info.ItemName
+
+ }).Cast<Series>().FirstOrDefault();
}
}
diff --git a/MediaBrowser.Server.Implementations/Library/UserDataManager.cs b/MediaBrowser.Server.Implementations/Library/UserDataManager.cs
index afbce87a9..c2606dc4b 100644
--- a/MediaBrowser.Server.Implementations/Library/UserDataManager.cs
+++ b/MediaBrowser.Server.Implementations/Library/UserDataManager.cs
@@ -23,7 +23,8 @@ namespace MediaBrowser.Server.Implementations.Library
{
public event EventHandler<UserDataSaveEventArgs> UserDataSaved;
- private readonly Dictionary<string, UserItemData> _userData = new Dictionary<string, UserItemData>(StringComparer.OrdinalIgnoreCase);
+ private readonly ConcurrentDictionary<string, UserItemData> _userData =
+ new ConcurrentDictionary<string, UserItemData>(StringComparer.OrdinalIgnoreCase);
private readonly ILogger _logger;
private readonly IServerConfigurationManager _config;
@@ -64,13 +65,6 @@ namespace MediaBrowser.Server.Implementations.Library
try
{
await Repository.SaveUserData(userId, key, userData, cancellationToken).ConfigureAwait(false);
-
- var newValue = userData;
-
- lock (_userData)
- {
- _userData[GetCacheKey(userId, key)] = newValue;
- }
}
catch (Exception ex)
{
@@ -80,6 +74,9 @@ namespace MediaBrowser.Server.Implementations.Library
}
}
+ var cacheKey = GetCacheKey(userId, item.Id);
+ _userData.AddOrUpdate(cacheKey, userData, (k, v) => userData);
+
EventHelper.FireEventIfNotNull(UserDataSaved, this, new UserDataSaveEventArgs
{
Keys = keys,
@@ -122,7 +119,7 @@ namespace MediaBrowser.Server.Implementations.Library
throw;
}
-
+
}
/// <summary>
@@ -140,7 +137,7 @@ namespace MediaBrowser.Server.Implementations.Library
return Repository.GetAllUserData(userId);
}
- public UserItemData GetUserData(Guid userId, List<string> keys)
+ public UserItemData GetUserData(Guid userId, Guid itemId, List<string> keys)
{
if (userId == Guid.Empty)
{
@@ -150,26 +147,23 @@ namespace MediaBrowser.Server.Implementations.Library
{
throw new ArgumentNullException("keys");
}
-
- lock (_userData)
+ if (keys.Count == 0)
{
- foreach (var key in keys)
- {
- var cacheKey = GetCacheKey(userId, key);
- UserItemData value;
- if (_userData.TryGetValue(cacheKey, out value))
- {
- return value;
- }
+ throw new ArgumentException("UserData keys cannot be empty.");
+ }
- value = Repository.GetUserData(userId, key);
+ var cacheKey = GetCacheKey(userId, itemId);
- if (value != null)
- {
- _userData[cacheKey] = value;
- return value;
- }
- }
+ return _userData.GetOrAdd(cacheKey, k => GetUserDataInternal(userId, keys));
+ }
+
+ private UserItemData GetUserDataInternal(Guid userId, List<string> keys)
+ {
+ var userData = Repository.GetUserData(userId, keys);
+
+ if (userData != null)
+ {
+ return userData;
}
if (keys.Count > 0)
@@ -185,56 +179,12 @@ namespace MediaBrowser.Server.Implementations.Library
}
/// <summary>
- /// Gets the user data.
- /// </summary>
- /// <param name="userId">The user id.</param>
- /// <param name="key">The key.</param>
- /// <returns>Task{UserItemData}.</returns>
- public UserItemData GetUserData(Guid userId, string key)
- {
- if (userId == Guid.Empty)
- {
- throw new ArgumentNullException("userId");
- }
- if (string.IsNullOrEmpty(key))
- {
- throw new ArgumentNullException("key");
- }
-
- lock (_userData)
- {
- var cacheKey = GetCacheKey(userId, key);
- UserItemData value;
- if (_userData.TryGetValue(cacheKey, out value))
- {
- return value;
- }
-
- value = Repository.GetUserData(userId, key);
-
- if (value == null)
- {
- value = new UserItemData
- {
- UserId = userId,
- Key = key
- };
- }
-
- _userData[cacheKey] = value;
- return value;
- }
- }
-
- /// <summary>
/// Gets the internal key.
/// </summary>
- /// <param name="userId">The user id.</param>
- /// <param name="key">The key.</param>
/// <returns>System.String.</returns>
- private string GetCacheKey(Guid userId, string key)
+ private string GetCacheKey(Guid userId, Guid itemId)
{
- return userId + key;
+ return userId.ToString("N") + itemId.ToString("N");
}
public UserItemData GetUserData(IHasUserData user, IHasUserData item)
@@ -249,7 +199,7 @@ namespace MediaBrowser.Server.Implementations.Library
public UserItemData GetUserData(Guid userId, IHasUserData item)
{
- return GetUserData(userId, item.GetUserDataKeys());
+ return GetUserData(userId, item.Id, item.GetUserDataKeys());
}
public UserItemDataDto GetUserDataDto(IHasUserData item, User user)
diff --git a/MediaBrowser.Server.Implementations/Library/UserViewManager.cs b/MediaBrowser.Server.Implementations/Library/UserViewManager.cs
index 6c88f506b..e6a571f07 100644
--- a/MediaBrowser.Server.Implementations/Library/UserViewManager.cs
+++ b/MediaBrowser.Server.Implementations/Library/UserViewManager.cs
@@ -105,6 +105,12 @@ namespace MediaBrowser.Server.Implementations.Library
}
}
+ if (_config.Configuration.EnableFolderView)
+ {
+ var name = _localizationManager.GetLocalizedString("ViewType" + CollectionType.Folders);
+ list.Add(await _libraryManager.GetNamedView(name, CollectionType.Folders, string.Empty, cancellationToken).ConfigureAwait(false));
+ }
+
if (query.IncludeExternalContent)
{
var channelResult = await _channelManager.GetChannelsInternal(new ChannelQuery
diff --git a/MediaBrowser.Server.Implementations/Persistence/IDbConnector.cs b/MediaBrowser.Server.Implementations/Persistence/IDbConnector.cs
index 985d79a0a..cac9fe983 100644
--- a/MediaBrowser.Server.Implementations/Persistence/IDbConnector.cs
+++ b/MediaBrowser.Server.Implementations/Persistence/IDbConnector.cs
@@ -6,6 +6,5 @@ namespace MediaBrowser.Server.Implementations.Persistence
public interface IDbConnector
{
Task<IDbConnection> Connect(string dbPath);
- void BindSimilarityScoreFunction(IDbConnection connection);
}
}
diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteExtensions.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteExtensions.cs
index 5e07bac31..dd2f15cfd 100644
--- a/MediaBrowser.Server.Implementations/Persistence/SqliteExtensions.cs
+++ b/MediaBrowser.Server.Implementations/Persistence/SqliteExtensions.cs
@@ -5,6 +5,8 @@ using System.Data.SQLite;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
namespace MediaBrowser.Server.Implementations.Persistence
@@ -46,13 +48,6 @@ namespace MediaBrowser.Server.Implementations.Persistence
return connection;
}
- public static void BindGetSimilarityScore(IDbConnection connection, ILogger logger)
- {
- var sqlConnection = (SQLiteConnection) connection;
- SimiliarToFunction.Logger = logger;
- sqlConnection.BindFunction(new SimiliarToFunction());
- }
-
public static void BindFunction(this SQLiteConnection connection, SQLiteFunction function)
{
var attributes = function.GetType().GetCustomAttributes(typeof(SQLiteFunctionAttribute), true).Cast<SQLiteFunctionAttribute>().ToArray();
@@ -63,113 +58,4 @@ namespace MediaBrowser.Server.Implementations.Persistence
connection.BindFunction(attributes[0], function);
}
}
-
- [SQLiteFunction(Name = "GetSimilarityScore", Arguments = 12, FuncType = FunctionType.Scalar)]
- public class SimiliarToFunction : SQLiteFunction
- {
- internal static ILogger Logger;
-
- public override object Invoke(object[] args)
- {
- var score = 0;
-
- var inputOfficialRating = args[0] as string;
- var rowOfficialRating = args[1] as string;
- if (!string.IsNullOrWhiteSpace(inputOfficialRating) && string.Equals(inputOfficialRating, rowOfficialRating))
- {
- score += 10;
- }
-
- long? inputYear = args[2] == null ? (long?)null : (long)args[2];
- long? rowYear = args[3] == null ? (long?)null : (long)args[3];
-
- if (inputYear.HasValue && rowYear.HasValue)
- {
- var diff = Math.Abs(inputYear.Value - rowYear.Value);
-
- // Add if they came out within the same decade
- if (diff < 10)
- {
- score += 2;
- }
-
- // And more if within five years
- if (diff < 5)
- {
- score += 2;
- }
- }
-
- // genres
- score += GetListScore(args, 4, 5);
-
- // tags
- score += GetListScore(args, 6, 7);
-
- // keywords
- score += GetListScore(args, 8, 9);
-
- // studios
- score += GetListScore(args, 10, 11, 3);
-
-
- // TODO: People
- // var item2PeopleNames = allPeople.Where(i => i.ItemId == item2.Id)
- //.Select(i => i.Name)
- //.Where(i => !string.IsNullOrWhiteSpace(i))
- //.DistinctNames()
- //.ToDictionary(i => i, StringComparer.OrdinalIgnoreCase);
-
- // points += item1People.Where(i => item2PeopleNames.ContainsKey(i.Name)).Sum(i =>
- // {
- // if (string.Equals(i.Type, PersonType.Director, StringComparison.OrdinalIgnoreCase) || string.Equals(i.Role, PersonType.Director, StringComparison.OrdinalIgnoreCase))
- // {
- // return 5;
- // }
- // if (string.Equals(i.Type, PersonType.Actor, StringComparison.OrdinalIgnoreCase) || string.Equals(i.Role, PersonType.Actor, StringComparison.OrdinalIgnoreCase))
- // {
- // return 3;
- // }
- // if (string.Equals(i.Type, PersonType.Composer, StringComparison.OrdinalIgnoreCase) || string.Equals(i.Role, PersonType.Composer, StringComparison.OrdinalIgnoreCase))
- // {
- // return 3;
- // }
- // if (string.Equals(i.Type, PersonType.GuestStar, StringComparison.OrdinalIgnoreCase) || string.Equals(i.Role, PersonType.GuestStar, StringComparison.OrdinalIgnoreCase))
- // {
- // return 3;
- // }
- // if (string.Equals(i.Type, PersonType.Writer, StringComparison.OrdinalIgnoreCase) || string.Equals(i.Role, PersonType.Writer, StringComparison.OrdinalIgnoreCase))
- // {
- // return 2;
- // }
-
- // return 1;
- // });
-
- // return points;
-
- //Logger.Debug("Returning score {0}", score);
- return score;
- }
-
- private int GetListScore(object[] args, int index1, int index2, int value = 10)
- {
- var score = 0;
-
- var inputGenres = args[index1] as string;
- var rowGenres = args[index2] as string;
- var inputGenreList = string.IsNullOrWhiteSpace(inputGenres) ? new string[] { } : inputGenres.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
- var rowGenresList = string.IsNullOrWhiteSpace(rowGenres) ? new string[] { } : rowGenres.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
-
- foreach (var genre in inputGenreList)
- {
- if (rowGenresList.Contains(genre, StringComparer.OrdinalIgnoreCase))
- {
- score += value;
- }
- }
-
- return score;
- }
- }
}
diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs
index 13f7a0d37..460a67ca7 100644
--- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs
+++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs
@@ -88,10 +88,13 @@ namespace MediaBrowser.Server.Implementations.Persistence
private IDbCommand _deleteProviderIdsCommand;
private IDbCommand _saveProviderIdsCommand;
+ private IDbCommand _deleteImagesCommand;
+ private IDbCommand _saveImagesCommand;
+
private IDbCommand _updateInheritedRatingCommand;
private IDbCommand _updateInheritedTagsCommand;
- public const int LatestSchemaVersion = 83;
+ public const int LatestSchemaVersion = 89;
/// <summary>
/// Initializes a new instance of the <see cref="SqliteItemRepository"/> class.
@@ -132,9 +135,9 @@ namespace MediaBrowser.Server.Implementations.Persistence
string[] queries = {
"create table if not exists TypedBaseItems (guid GUID primary key, type TEXT, data BLOB, ParentId GUID, Path TEXT)",
- "create index if not exists idx_TypedBaseItems on TypedBaseItems(guid)",
"create index if not exists idx_PathTypedBaseItems on TypedBaseItems(Path)",
"create index if not exists idx_ParentIdTypedBaseItems on TypedBaseItems(ParentId)",
+ "create index if not exists idx_TypedBaseItems2 on TypedBaseItems(Type,Guid)",
"create table if not exists AncestorIds (ItemId GUID, AncestorId GUID, AncestorIdText TEXT, PRIMARY KEY (ItemId, AncestorId))",
"create index if not exists idx_AncestorIds1 on AncestorIds(AncestorId)",
@@ -145,10 +148,14 @@ namespace MediaBrowser.Server.Implementations.Persistence
"create table if not exists ItemValues (ItemId GUID, Type INT, Value TEXT)",
"create index if not exists idx_ItemValues on ItemValues(ItemId)",
+ "create index if not exists idx_ItemValues2 on ItemValues(ItemId,Type)",
- "create table if not exists ProviderIds (ItemId GUID, Name TEXT, Value TEXT)",
+ "create table if not exists ProviderIds (ItemId GUID, Name TEXT, Value TEXT, PRIMARY KEY (ItemId, Name))",
"create index if not exists Idx_ProviderIds on ProviderIds(ItemId)",
+ "create table if not exists Images (ItemId GUID NOT NULL, Path TEXT NOT NULL, ImageType INT NOT NULL, DateModified DATETIME, IsPlaceHolder BIT NOT NULL, SortOrder INT)",
+ "create index if not exists idx_Images on Images(ItemId)",
+
"create table if not exists People (ItemId GUID, Name TEXT NOT NULL, Role TEXT, PersonType TEXT, SortOrder int, ListOrder int)",
"create index if not exists idxPeopleItemId on People(ItemId)",
"create index if not exists idxPeopleName on People(Name)",
@@ -265,8 +272,6 @@ namespace MediaBrowser.Server.Implementations.Persistence
new MediaStreamColumns(_connection, Logger).AddColumns();
DataExtensions.Attach(_connection, Path.Combine(_config.ApplicationPaths.DataPath, "userdata_v2.db"), "UserDataDb");
-
- dbConnector.BindSimilarityScoreFunction(_connection);
}
private readonly string[] _retriveItemColumns =
@@ -565,6 +570,19 @@ namespace MediaBrowser.Server.Implementations.Persistence
_saveProviderIdsCommand.Parameters.Add(_saveProviderIdsCommand, "@Name");
_saveProviderIdsCommand.Parameters.Add(_saveProviderIdsCommand, "@Value");
+ // images
+ _deleteImagesCommand = _connection.CreateCommand();
+ _deleteImagesCommand.CommandText = "delete from Images where ItemId=@Id";
+ _deleteImagesCommand.Parameters.Add(_deleteImagesCommand, "@Id");
+
+ _saveImagesCommand = _connection.CreateCommand();
+ _saveImagesCommand.CommandText = "insert into Images (ItemId, ImageType, Path, DateModified, IsPlaceHolder, SortOrder) values (@ItemId, @ImageType, @Path, @DateModified, @IsPlaceHolder, @SortOrder)";
+ _saveImagesCommand.Parameters.Add(_saveImagesCommand, "@ItemId");
+ _saveImagesCommand.Parameters.Add(_saveImagesCommand, "@ImageType");
+ _saveImagesCommand.Parameters.Add(_saveImagesCommand, "@Path");
+ _saveImagesCommand.Parameters.Add(_saveImagesCommand, "@DateModified");
+ _saveImagesCommand.Parameters.Add(_saveImagesCommand, "@IsPlaceHolder");
+ _saveImagesCommand.Parameters.Add(_saveImagesCommand, "@SortOrder");
}
/// <summary>
@@ -879,6 +897,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
}
UpdateUserDataKeys(item.Id, item.GetUserDataKeys().Distinct(StringComparer.OrdinalIgnoreCase).ToList(), transaction);
+ UpdateImages(item.Id, item.ImageInfos, transaction);
UpdateProviderIds(item.Id, item.ProviderIds, transaction);
UpdateItemValues(item.Id, GetItemValues(item), transaction);
}
@@ -956,7 +975,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
if (type == null)
{
- Logger.Debug("Unknown type {0}", typeString);
+ //Logger.Debug("Unknown type {0}", typeString);
return null;
}
@@ -1621,34 +1640,34 @@ namespace MediaBrowser.Server.Implementations.Persistence
var item = query.SimilarTo;
var builder = new StringBuilder();
- builder.Append("GetSimilarityScore(");
+ builder.Append("(");
+
+ builder.Append("((OfficialRating=@ItemOfficialRating) * 10)");
+ //builder.Append("+ ((ProductionYear=@ItemProductionYear) * 10)");
+
+ builder.Append("+(Select Case When Abs(COALESCE(ProductionYear, 0) - @ItemProductionYear) < 10 Then 2 Else 0 End )");
+ builder.Append("+(Select Case When Abs(COALESCE(ProductionYear, 0) - @ItemProductionYear) < 5 Then 2 Else 0 End )");
+
+ //// genres
+ builder.Append("+ ((Select count(value) from ItemValues where ItemId=Guid and Type=2 and value in (select value from itemvalues where ItemId=@SimilarItemId and type=2)) * 10)");
- builder.Append("@ItemOfficialRating,");
- builder.Append("OfficialRating,");
+ //// tags
+ builder.Append("+ ((Select count(value) from ItemValues where ItemId=Guid and Type=4 and value in (select value from itemvalues where ItemId=@SimilarItemId and type=4)) * 10)");
- builder.Append("@ItemProductionYear,");
- builder.Append("ProductionYear,");
+ builder.Append("+ ((Select count(value) from ItemValues where ItemId=Guid and Type=5 and value in (select value from itemvalues where ItemId=@SimilarItemId and type=5)) * 10)");
- builder.Append("@ItemGenres,");
- builder.Append("Genres,");
+ builder.Append("+ ((Select count(value) from ItemValues where ItemId=Guid and Type=3 and value in (select value from itemvalues where ItemId=@SimilarItemId and type=3)) * 3)");
- builder.Append("@ItemTags,");
- builder.Append("Tags,");
+ //builder.Append("+ ((Select count(Name) from People where ItemId=Guid and Name in (select Name from People where ItemId=@SimilarItemId)) * 3)");
- builder.Append("@ItemKeywords,");
- builder.Append("(select group_concat((Select Value from ItemValues where ItemId=Guid and Type=5), '|')),");
+ ////builder.Append("(select group_concat((Select Name from People where ItemId=Guid and Name in (Select Name from People where ItemId=@SimilarItemId)), '|'))");
- builder.Append("@ItemStudios,");
- builder.Append("Studios");
builder.Append(") as SimilarityScore");
list.Add(builder.ToString());
cmd.Parameters.Add(cmd, "@ItemOfficialRating", DbType.String).Value = item.OfficialRating;
- cmd.Parameters.Add(cmd, "@ItemProductionYear", DbType.Int32).Value = item.ProductionYear ?? -1;
- cmd.Parameters.Add(cmd, "@ItemGenres", DbType.String).Value = string.Join("|", item.Genres.ToArray());
- cmd.Parameters.Add(cmd, "@ItemTags", DbType.String).Value = string.Join("|", item.Tags.ToArray());
- cmd.Parameters.Add(cmd, "@ItemKeywords", DbType.String).Value = string.Join("|", item.Keywords.ToArray());
- cmd.Parameters.Add(cmd, "@ItemStudios", DbType.String).Value = string.Join("|", item.Studios.ToArray());
+ cmd.Parameters.Add(cmd, "@ItemProductionYear", DbType.Int32).Value = item.ProductionYear ?? 0;
+ cmd.Parameters.Add(cmd, "@SimilarItemId", DbType.Guid).Value = item.Id;
var excludeIds = query.ExcludeItemIds.ToList();
excludeIds.Add(item.Id.ToString("N"));
@@ -1862,7 +1881,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
{
if (query.User != null)
{
- query.SortBy = new[] { "SimilarityScore", "IsUnplayed", "Random" };
+ query.SortBy = new[] { "SimilarityScore", "IsPlayed", "Random" };
}
else
{
@@ -2475,6 +2494,19 @@ namespace MediaBrowser.Server.Implementations.Persistence
cmd.Parameters.Add(cmd, "@NameLessThan", DbType.String).Value = query.NameLessThan.ToLower();
}
+ if (query.ImageTypes.Length > 0 && _config.Configuration.SchemaVersion >= 87)
+ {
+ var requiredImageIndex = 0;
+
+ foreach (var requiredImage in query.ImageTypes)
+ {
+ var paramName = "@RequiredImageType" + requiredImageIndex;
+ whereClauses.Add("(select path from images where ItemId=Guid and ImageType=" + paramName + " limit 1) not null");
+ cmd.Parameters.Add(cmd, paramName, DbType.Int32).Value = (int)requiredImage;
+ requiredImageIndex++;
+ }
+ }
+
if (query.IsLiked.HasValue)
{
if (query.IsLiked.Value)
@@ -2738,8 +2770,13 @@ namespace MediaBrowser.Server.Implementations.Persistence
var index = 0;
foreach (var pair in query.ExcludeProviderIds)
{
+ if (string.Equals(pair.Key, MetadataProviders.TmdbCollection.ToString(), StringComparison.OrdinalIgnoreCase))
+ {
+ continue;
+ }
+
var paramName = "@ExcludeProviderId" + index;
- excludeIds.Add("(COALESCE((select value from ProviderIds where ItemId=Guid and Name = 'Imdb'), '') <> " + paramName + ")");
+ excludeIds.Add("(COALESCE((select value from ProviderIds where ItemId=Guid and Name = '" + pair.Key + "'), '') <> " + paramName + ")");
cmd.Parameters.Add(cmd, paramName, DbType.String).Value = pair.Value;
index++;
}
@@ -3180,6 +3217,11 @@ namespace MediaBrowser.Server.Implementations.Persistence
_deleteProviderIdsCommand.Transaction = transaction;
_deleteProviderIdsCommand.ExecuteNonQuery();
+ // Delete images
+ _deleteImagesCommand.GetParameter(0).Value = id;
+ _deleteImagesCommand.Transaction = transaction;
+ _deleteImagesCommand.ExecuteNonQuery();
+
// Delete the item
_deleteItemCommand.GetParameter(0).Value = id;
_deleteItemCommand.Transaction = transaction;
@@ -3396,6 +3438,52 @@ namespace MediaBrowser.Server.Implementations.Persistence
return list;
}
+ private void UpdateImages(Guid itemId, List<ItemImageInfo> images, IDbTransaction transaction)
+ {
+ if (itemId == Guid.Empty)
+ {
+ throw new ArgumentNullException("itemId");
+ }
+
+ if (images == null)
+ {
+ throw new ArgumentNullException("images");
+ }
+
+ CheckDisposed();
+
+ // First delete
+ _deleteImagesCommand.GetParameter(0).Value = itemId;
+ _deleteImagesCommand.Transaction = transaction;
+
+ _deleteImagesCommand.ExecuteNonQuery();
+
+ var index = 0;
+ foreach (var image in images)
+ {
+ _saveImagesCommand.GetParameter(0).Value = itemId;
+ _saveImagesCommand.GetParameter(1).Value = image.Type;
+ _saveImagesCommand.GetParameter(2).Value = image.Path;
+
+ if (image.DateModified == default(DateTime))
+ {
+ _saveImagesCommand.GetParameter(3).Value = null;
+ }
+ else
+ {
+ _saveImagesCommand.GetParameter(3).Value = image.DateModified;
+ }
+
+ _saveImagesCommand.GetParameter(4).Value = image.IsPlaceholder;
+ _saveImagesCommand.GetParameter(5).Value = index;
+
+ _saveImagesCommand.Transaction = transaction;
+
+ _saveImagesCommand.ExecuteNonQuery();
+ index++;
+ }
+ }
+
private void UpdateProviderIds(Guid itemId, Dictionary<string, string> values, IDbTransaction transaction)
{
if (itemId == Guid.Empty)
@@ -3405,7 +3493,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
if (values == null)
{
- throw new ArgumentNullException("keys");
+ throw new ArgumentNullException("values");
}
CheckDisposed();
diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs
index 7f3b32e06..bfdb9e0c7 100644
--- a/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs
+++ b/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs
@@ -5,7 +5,9 @@ using MediaBrowser.Model.Logging;
using System;
using System.Collections.Generic;
using System.Data;
+using System.Globalization;
using System.IO;
+using System.Text;
using System.Threading;
using System.Threading.Tasks;
@@ -300,6 +302,52 @@ namespace MediaBrowser.Server.Implementations.Persistence
}
}
+ public UserItemData GetUserData(Guid userId, List<string> keys)
+ {
+ if (userId == Guid.Empty)
+ {
+ throw new ArgumentNullException("userId");
+ }
+ if (keys == null)
+ {
+ throw new ArgumentNullException("keys");
+ }
+
+ using (var cmd = _connection.CreateCommand())
+ {
+ var index = 0;
+ var excludeIds = new List<string>();
+ var builder = new StringBuilder();
+ foreach (var key in keys)
+ {
+ var paramName = "@Key" + index;
+ excludeIds.Add("Key =" + paramName);
+ cmd.Parameters.Add(cmd, paramName, DbType.String).Value = key;
+ builder.Append(" WHEN Key=" + paramName + " THEN " + index);
+ index++;
+ }
+
+ var keyText = string.Join(" OR ", excludeIds.ToArray());
+
+ cmd.CommandText = "select key,userid,rating,played,playCount,isFavorite,playbackPositionTicks,lastPlayedDate,AudioStreamIndex,SubtitleStreamIndex from userdata where userId=@userId AND (" + keyText + ") ";
+
+ cmd.CommandText += " ORDER BY (Case " + builder + " Else " + keys.Count.ToString(CultureInfo.InvariantCulture) + " End )";
+ cmd.CommandText += " LIMIT 1";
+
+ cmd.Parameters.Add(cmd, "@userId", DbType.Guid).Value = userId;
+
+ using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult | CommandBehavior.SingleRow))
+ {
+ if (reader.Read())
+ {
+ return ReadRow(reader);
+ }
+ }
+
+ return null;
+ }
+ }
+
/// <summary>
/// Return all user-data associated with the given user
/// </summary>
diff --git a/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs b/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs
index ec91dc1b7..d57aea08e 100644
--- a/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs
+++ b/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs
@@ -111,24 +111,6 @@ namespace MediaBrowser.Server.Implementations.TV
.Select(i => GetNextUp(i, currentUser))
// Include if an episode was found, and either the series is not unwatched or the specific series was requested
.Where(i => i.Item1 != null && (!i.Item3 || !string.IsNullOrWhiteSpace(request.SeriesId)))
- //.OrderByDescending(i =>
- //{
- // var episode = i.Item1;
-
- // var seriesUserData = _userDataManager.GetUserData(user, episode.Series);
-
- // if (seriesUserData.IsFavorite)
- // {
- // return 2;
- // }
-
- // if (seriesUserData.Likes.HasValue)
- // {
- // return seriesUserData.Likes.Value ? 1 : -1;
- // }
-
- // return 0;
- //})
.OrderByDescending(i => i.Item2)
.ThenByDescending(i => i.Item1.PremiereDate ?? DateTime.MinValue)
.Select(i => i.Item1);
@@ -143,9 +125,8 @@ namespace MediaBrowser.Server.Implementations.TV
private Tuple<Episode, DateTime, bool> GetNextUp(Series series, User user)
{
// Get them in display order, then reverse
- var allEpisodes = series.GetSeasons(user, true, true)
- .Where(i => !i.IndexNumber.HasValue || i.IndexNumber.Value != 0)
- .SelectMany(i => i.GetEpisodes(user))
+ var allEpisodes = series.GetEpisodes(user, false, false)
+ .Where(i => !i.ParentIndexNumber.HasValue || i.ParentIndexNumber.Value != 0)
.Reverse()
.ToList();
@@ -153,7 +134,7 @@ namespace MediaBrowser.Server.Implementations.TV
var lastWatchedDate = DateTime.MinValue;
Episode nextUp = null;
- var includeMissing = user.Configuration.DisplayMissingEpisodes;
+ var unplayedEpisodes = new List<Episode>();
// Go back starting with the most recent episodes
foreach (var episode in allEpisodes)
@@ -172,10 +153,9 @@ namespace MediaBrowser.Server.Implementations.TV
}
else
{
- if (!episode.IsVirtualUnaired && (includeMissing || !episode.IsMissingEpisode))
- {
- nextUp = episode;
- }
+ unplayedEpisodes.Add(episode);
+
+ nextUp = episode;
}
}
@@ -184,7 +164,15 @@ namespace MediaBrowser.Server.Implementations.TV
return new Tuple<Episode, DateTime, bool>(nextUp, lastWatchedDate, false);
}
- var firstEpisode = allEpisodes.LastOrDefault(i => !i.IsVirtualUnaired && (includeMissing || !i.IsMissingEpisode) && !i.IsPlayed(user));
+ Episode firstEpisode = null;
+ // Find the first unplayed episode. Start from the back of the list since they're in reverse order
+ for (var i = unplayedEpisodes.Count - 1; i >= 0; i--)
+ {
+ var unplayedEpisode = unplayedEpisodes[i];
+
+ firstEpisode = unplayedEpisode;
+ break;
+ }
// Return the first episode
return new Tuple<Episode, DateTime, bool>(firstEpisode, DateTime.MinValue, true);